@mulmoclaude/shapescript-plugin 2.7.0 → 2.8.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.
@@ -7,7 +7,9 @@ export declare const SHAPE_GALLERY_URL = "https://server.mulmocast.com";
7
7
  export declare const SHAPE_POST_LIMITS: {
8
8
  readonly titleMax: 120;
9
9
  readonly descriptionMax: 2000;
10
- readonly scriptMax: 100000;
10
+ /** In UTF-8 BYTES — the gallery's rule measures `toUtf8().size()`, since Firestore's 1 MiB
11
+ * document cap is in bytes and a script with Japanese comments is up to three a character. */
12
+ readonly scriptMax: 900000;
11
13
  readonly promptMax: 4000;
12
14
  readonly authorNameMax: 80;
13
15
  readonly keywordsMax: 10;
@@ -1 +1 @@
1
- {"version":3,"file":"publish.d.ts","sourceRoot":"","sources":["../../src/core/publish.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"publish.d.ts","sourceRoot":"","sources":["../../src/core/publish.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,5 @@
1
- import { _ as e, a as t, u as n } from "./samples-BZSbBJmx.js";
2
- import { a as r, r as i, s as a, t as o } from "./toThreeJS-Bo3j0vOj.js";
1
+ import { _ as e, a as t, u as n } from "./samples-CfppG9Bk.js";
2
+ import { a as r, r as i, s as a, t as o } from "./toThreeJS-MMc_OzvN.js";
3
3
  //#region src/export/tool.ts
4
4
  var s = "exportShapeScriptUsdz", c = o + 3e4, l = "Export a ShapeScript model to a USDZ file (Apple's AR / 3D format, openable with AR Quick Look on iPhone, iPad and Mac) and save it under artifacts/shapes/. Returns the saved path. Takes the same source as presentShapeScript: inline `script`, or `path` to a saved .shape file. USDZ units are metres, so a `size 1` cube becomes a one-metre object in AR — scale the model in the script if that is not what the user wants.", u = "Use exportShapeScriptUsdz when the user wants to take a 3D model out of the chat — to view it in AR, open it in a 3D app, or share the file. It saves a .usdz next to the model's .shape file and returns the path; tell the user where it is. The user can also press \"Download USDZ\" in the model's view themselves.", d = {
5
5
  type: "object",
@@ -54,7 +54,7 @@ async function h(n, r) {
54
54
  var g = "publishShapeScript", _ = "https://server.mulmocast.com", v = {
55
55
  titleMax: 120,
56
56
  descriptionMax: 2e3,
57
- scriptMax: 1e5,
57
+ scriptMax: 9e5,
58
58
  promptMax: 4e3,
59
59
  authorNameMax: 80,
60
60
  keywordsMax: 10,
@@ -116,13 +116,19 @@ function D(e, t, n, r = 0) {
116
116
  if (t.length > n) throw Error(`\`${e}\` is too long (${t.length} characters; the gallery allows ${n})`);
117
117
  return t;
118
118
  }
119
- function O(e, t) {
119
+ function O(e) {
120
+ if (e.length < 1) throw Error("`script` is required");
121
+ let t = new TextEncoder().encode(e).length;
122
+ if (t > v.scriptMax) throw Error(`\`script\` is too long (${t} bytes; the gallery allows ${v.scriptMax})`);
123
+ return e;
124
+ }
125
+ function k(e, t) {
120
126
  return {
121
127
  uid: e.uid,
122
128
  authorName: e.authorName.slice(0, v.authorNameMax),
123
129
  title: D("title", t.title.trim(), v.titleMax, 1),
124
130
  description: D("description", t.description ?? "", v.descriptionMax),
125
- script: D("script", t.script, v.scriptMax, 1),
131
+ script: O(t.script),
126
132
  source: "prompt",
127
133
  prompt: D("prompt", t.prompt ?? "", v.promptMax),
128
134
  photoIds: [],
@@ -132,49 +138,49 @@ function O(e, t) {
132
138
  published: t.published !== !1
133
139
  };
134
140
  }
135
- function k(e, t = _) {
141
+ function A(e, t = _) {
136
142
  return `${t.endsWith("/") ? t.slice(0, -1) : t}/shapes/${e}`;
137
143
  }
138
- function A(e) {
144
+ function j(e) {
139
145
  r(i(a(e)));
140
146
  }
141
- var j = (e) => e instanceof Error ? e.message : String(e);
142
- async function M(e, t, n, r) {
147
+ var M = (e) => e instanceof Error ? e.message : String(e);
148
+ async function N(e, t, n, r) {
143
149
  try {
144
150
  let i = await e.renderThumbnail(r);
145
151
  return i ? await t.uploadThumbnail(n, i) : "";
146
152
  } catch (t) {
147
- return e.onWarning?.(`thumbnail skipped: ${j(t)}`), "";
153
+ return e.onWarning?.(`thumbnail skipped: ${M(t)}`), "";
148
154
  }
149
155
  }
150
- async function N(e, t, n, r) {
156
+ async function P(e, t, n, r) {
151
157
  try {
152
158
  await t.createPost(n, r);
153
159
  } catch (i) {
154
- throw r.thumbnailId && await t.deleteObject(n, r.thumbnailId).catch((t) => e.onWarning?.(`orphaned thumbnail ${r.thumbnailId}: ${j(t)}`)), i;
160
+ throw r.thumbnailId && await t.deleteObject(n, r.thumbnailId).catch((t) => e.onWarning?.(`orphaned thumbnail ${r.thumbnailId}: ${M(t)}`)), i;
155
161
  }
156
162
  }
157
- var P = () => globalThis.crypto.randomUUID();
158
- async function F(e, t) {
163
+ var F = () => globalThis.crypto.randomUUID();
164
+ async function I(e, t) {
159
165
  let n = e.gallery;
160
166
  if (!n) throw Error(C);
161
167
  let r = w(t.title);
162
168
  if (!r) throw Error("`title` is required");
163
169
  let { script: i } = await m(e, t);
164
- A(i);
165
- let a = O(n, {
170
+ j(i);
171
+ let a = k(n, {
166
172
  title: r,
167
173
  script: i,
168
174
  description: w(t.description),
169
175
  prompt: w(t.prompt),
170
176
  keywords: t.keywords,
171
177
  published: t.published !== !1
172
- }), o = P(), s = await M(e, n, o, i), c = {
178
+ }), o = F(), s = await N(e, n, o, i), c = {
173
179
  ...a,
174
180
  thumbnailId: s
175
181
  };
176
- await N(e, n, o, c);
177
- let l = k(o, n.siteUrl), u = c.published ? "Published" : "Saved as a draft (only the user can see it, under My models)", d = s ? "" : " No thumbnail could be attached; the gallery shows a placeholder until the user edits the post.";
182
+ await P(e, n, o, c);
183
+ let l = A(o, n.siteUrl), u = c.published ? "Published" : "Saved as a draft (only the user can see it, under My models)", d = s ? "" : " No thumbnail could be attached; the gallery shows a placeholder until the user edits the post.";
178
184
  return {
179
185
  message: `${u}: "${c.title}" is at ${l}.${d}`,
180
186
  id: o,
@@ -183,4 +189,4 @@ async function F(e, t) {
183
189
  };
184
190
  }
185
191
  //#endregion
186
- export { c as _, g as a, v as c, O as d, k as f, s as g, d as h, x as i, F as l, u as m, y as n, _ as o, l as p, b as r, S as s, C as t, E as u, h as v, m as y };
192
+ export { c as _, g as a, v as c, k as d, A as f, s as g, d as h, x as i, I as l, u as m, y as n, _ as o, l as p, b as r, S as s, C as t, E as u, h as v, m as y };
@@ -1 +1 @@
1
- const e=require("./samples-C8zn1JOi.cjs"),t=require("./toThreeJS-BBwttw4K.cjs");var n=`exportShapeScriptUsdz`,r=t.t+3e4,i="Export a ShapeScript model to a USDZ file (Apple's AR / 3D format, openable with AR Quick Look on iPhone, iPad and Mac) and save it under artifacts/shapes/. Returns the saved path. Takes the same source as presentShapeScript: inline `script`, or `path` to a saved .shape file. USDZ units are metres, so a `size 1` cube becomes a one-metre object in AR — scale the model in the script if that is not what the user wants.",a=`Use exportShapeScriptUsdz when the user wants to take a 3D model out of the chat — to view it in AR, open it in a 3D app, or share the file. It saves a .usdz next to the model's .shape file and returns the path; tell the user where it is. The user can also press "Download USDZ" in the model's view themselves.`,o={type:`object`,properties:{script:{type:`string`,description:"ShapeScript source to export. Provide either this or `path`, not both."},path:{type:`string`,description:`Path to an existing .shape file to export (e.g. one presentShapeScript saved under artifacts/shapes/).`},title:{type:`string`,description:"Name for the exported file; it is slugified into the filename. Defaults to the .shape file's own name when `path` is given."}},required:[]};function s(e){return typeof e==`string`&&e.trim()!==``?e:void 0}function c(e){return(e.split(/[\\/]/).pop()??e).replace(/\.shape$/i,``)}async function l(t,n){let r=s(n.script),i=s(n.path),a=s(n.title);if(r&&i)throw Error("Provide either `script` or `path`, not both");if(r)return{script:r,title:a};if(!i)throw Error("Provide either `script` (inline source) or `path` (an existing .shape file)");let o=e.u(t,i);if(!o)throw Error("`path` must name a .shape file, without `.` / `..` segments");if(!await o.files.exists(o.rel))throw Error(`No ShapeScript exists at ${i}`);return{script:await o.files.read(o.rel),title:a??c(i)}}async function u(t,n){let{script:r,title:i}=await l(t,n),a=await e.a(r),{relPath:o,filePath:s}=e._(i);return await t.files.artifacts.write(o,a),{message:`Saved USDZ to ${s} (${a.byteLength} bytes). Open it with AR Quick Look or any USD viewer.`,filePath:s,bytes:a.byteLength}}var d=`publishShapeScript`,f=`https://server.mulmocast.com`,p={titleMax:120,descriptionMax:2e3,scriptMax:1e5,promptMax:4e3,authorNameMax:80,keywordsMax:10,keywordMax:30},m="Publish a ShapeScript model to the public gallery at server.mulmocast.com/shapes, where anyone can view it in 3D, read the source, download the USDZ and fork it. Takes the same source as presentShapeScript: inline `script`, or `path` to a saved .shape file. Posts under the user's own Google account — the app must be connected to Remote Host (signed in) first — and returns the model's URL. A thumbnail is rendered and attached when the host can rasterise; the post still lands without one.",h="Use publishShapeScript ONLY when the user asks to publish, post or share a model to the gallery — never on your own initiative, since it makes the model public under their name. Before calling it, make sure the model previews correctly (presentShapeScript / renderShapeScript) and give it a short title, a sentence of description and a few lowercase keywords someone would search for. Pass the user's original request as `prompt` so the post records how the model was made. If the tool answers that Remote Host is not connected, tell the user to connect it (the Remote Host control in the app, Google sign-in) and offer to try again.",g={type:`object`,properties:{title:{type:`string`,description:`The model's title (1–${p.titleMax} characters).`},script:{type:`string`,description:"ShapeScript source to publish. Provide either this or `path`, not both."},path:{type:`string`,description:"Path to an existing .shape file — an `artifacts/shapes/...` path presentShapeScript saved, or any .shape the host can read. Provide either this or `script`, not both."},description:{type:`string`,description:`What the model is, for the gallery page (up to ${p.descriptionMax} characters). Optional.`},keywords:{type:`array`,items:{type:`string`},description:`Up to ${p.keywordsMax} short lowercase tags someone would search for. Optional.`},prompt:{type:`string`,description:`The request the model was made from, recorded as its provenance (up to ${p.promptMax} characters). Optional.`},published:{type:`boolean`,description:`false saves a draft only the user can see in the gallery's My models. Default true.`}},required:[`title`]},_=[`uid`,`authorName`,`title`,`description`,`script`,`source`,`prompt`,`photoIds`,`thumbnailId`,`forkedFrom`,`keywords`,`published`],v=`Not connected to the gallery: publishing posts under the user's Google account, which needs the app's Remote Host connected (sign in with Google in the Remote Host control), then try again.`,y=e=>typeof e==`string`&&e.trim()!==``?e:void 0,b=e=>typeof e==`string`?e.trim().toLowerCase().slice(0,p.keywordMax):``;function x(e){let t=(Array.isArray(e)?e:typeof e==`string`?e.split(`,`):[]).map(b).filter(e=>e!==``);return[...new Set(t)].slice(0,p.keywordsMax)}function S(e,t,n,r=0){if(t.length<r)throw Error(`\`${e}\` is required`);if(t.length>n)throw Error(`\`${e}\` is too long (${t.length} characters; the gallery allows ${n})`);return t}function C(e,t){return{uid:e.uid,authorName:e.authorName.slice(0,p.authorNameMax),title:S(`title`,t.title.trim(),p.titleMax,1),description:S(`description`,t.description??``,p.descriptionMax),script:S(`script`,t.script,p.scriptMax,1),source:`prompt`,prompt:S(`prompt`,t.prompt??``,p.promptMax),photoIds:[],thumbnailId:t.thumbnailId??``,forkedFrom:null,keywords:x(t.keywords),published:t.published!==!1}}function w(e,t=f){return`${t.endsWith(`/`)?t.slice(0,-1):t}/shapes/${e}`}function T(e){t.a(t.r(t.s(e)))}var E=e=>e instanceof Error?e.message:String(e);async function D(e,t,n,r){try{let i=await e.renderThumbnail(r);return i?await t.uploadThumbnail(n,i):``}catch(t){return e.onWarning?.(`thumbnail skipped: ${E(t)}`),``}}async function O(e,t,n,r){try{await t.createPost(n,r)}catch(i){throw r.thumbnailId&&await t.deleteObject(n,r.thumbnailId).catch(t=>e.onWarning?.(`orphaned thumbnail ${r.thumbnailId}: ${E(t)}`)),i}}var k=()=>globalThis.crypto.randomUUID();async function A(e,t){let n=e.gallery;if(!n)throw Error(v);let r=y(t.title);if(!r)throw Error("`title` is required");let{script:i}=await l(e,t);T(i);let a=C(n,{title:r,script:i,description:y(t.description),prompt:y(t.prompt),keywords:t.keywords,published:t.published!==!1}),o=k(),s=await D(e,n,o,i),c={...a,thumbnailId:s};await O(e,n,o,c);let u=w(o,n.siteUrl),d=c.published?`Published`:`Saved as a draft (only the user can see it, under My models)`,f=s?``:` No thumbnail could be attached; the gallery shows a placeholder until the user edits the post.`;return{message:`${d}: "${c.title}" is at ${u}.${f}`,id:o,url:u,thumbnail:s!==``}}Object.defineProperty(exports,"_",{enumerable:!0,get:function(){return r}}),Object.defineProperty(exports,"a",{enumerable:!0,get:function(){return d}}),Object.defineProperty(exports,"c",{enumerable:!0,get:function(){return p}}),Object.defineProperty(exports,"d",{enumerable:!0,get:function(){return C}}),Object.defineProperty(exports,"f",{enumerable:!0,get:function(){return w}}),Object.defineProperty(exports,"g",{enumerable:!0,get:function(){return n}}),Object.defineProperty(exports,"h",{enumerable:!0,get:function(){return o}}),Object.defineProperty(exports,"i",{enumerable:!0,get:function(){return g}}),Object.defineProperty(exports,"l",{enumerable:!0,get:function(){return A}}),Object.defineProperty(exports,"m",{enumerable:!0,get:function(){return a}}),Object.defineProperty(exports,"n",{enumerable:!0,get:function(){return m}}),Object.defineProperty(exports,"o",{enumerable:!0,get:function(){return f}}),Object.defineProperty(exports,"p",{enumerable:!0,get:function(){return i}}),Object.defineProperty(exports,"r",{enumerable:!0,get:function(){return h}}),Object.defineProperty(exports,"s",{enumerable:!0,get:function(){return _}}),Object.defineProperty(exports,"t",{enumerable:!0,get:function(){return v}}),Object.defineProperty(exports,"u",{enumerable:!0,get:function(){return x}}),Object.defineProperty(exports,"v",{enumerable:!0,get:function(){return u}}),Object.defineProperty(exports,"y",{enumerable:!0,get:function(){return l}});
1
+ const e=require("./samples-BO-oAFPZ.cjs"),t=require("./toThreeJS-CDRtoJt7.cjs");var n=`exportShapeScriptUsdz`,r=t.t+3e4,i="Export a ShapeScript model to a USDZ file (Apple's AR / 3D format, openable with AR Quick Look on iPhone, iPad and Mac) and save it under artifacts/shapes/. Returns the saved path. Takes the same source as presentShapeScript: inline `script`, or `path` to a saved .shape file. USDZ units are metres, so a `size 1` cube becomes a one-metre object in AR — scale the model in the script if that is not what the user wants.",a=`Use exportShapeScriptUsdz when the user wants to take a 3D model out of the chat — to view it in AR, open it in a 3D app, or share the file. It saves a .usdz next to the model's .shape file and returns the path; tell the user where it is. The user can also press "Download USDZ" in the model's view themselves.`,o={type:`object`,properties:{script:{type:`string`,description:"ShapeScript source to export. Provide either this or `path`, not both."},path:{type:`string`,description:`Path to an existing .shape file to export (e.g. one presentShapeScript saved under artifacts/shapes/).`},title:{type:`string`,description:"Name for the exported file; it is slugified into the filename. Defaults to the .shape file's own name when `path` is given."}},required:[]};function s(e){return typeof e==`string`&&e.trim()!==``?e:void 0}function c(e){return(e.split(/[\\/]/).pop()??e).replace(/\.shape$/i,``)}async function l(t,n){let r=s(n.script),i=s(n.path),a=s(n.title);if(r&&i)throw Error("Provide either `script` or `path`, not both");if(r)return{script:r,title:a};if(!i)throw Error("Provide either `script` (inline source) or `path` (an existing .shape file)");let o=e.u(t,i);if(!o)throw Error("`path` must name a .shape file, without `.` / `..` segments");if(!await o.files.exists(o.rel))throw Error(`No ShapeScript exists at ${i}`);return{script:await o.files.read(o.rel),title:a??c(i)}}async function u(t,n){let{script:r,title:i}=await l(t,n),a=await e.a(r),{relPath:o,filePath:s}=e._(i);return await t.files.artifacts.write(o,a),{message:`Saved USDZ to ${s} (${a.byteLength} bytes). Open it with AR Quick Look or any USD viewer.`,filePath:s,bytes:a.byteLength}}var d=`publishShapeScript`,f=`https://server.mulmocast.com`,p={titleMax:120,descriptionMax:2e3,scriptMax:9e5,promptMax:4e3,authorNameMax:80,keywordsMax:10,keywordMax:30},m="Publish a ShapeScript model to the public gallery at server.mulmocast.com/shapes, where anyone can view it in 3D, read the source, download the USDZ and fork it. Takes the same source as presentShapeScript: inline `script`, or `path` to a saved .shape file. Posts under the user's own Google account — the app must be connected to Remote Host (signed in) first — and returns the model's URL. A thumbnail is rendered and attached when the host can rasterise; the post still lands without one.",h="Use publishShapeScript ONLY when the user asks to publish, post or share a model to the gallery — never on your own initiative, since it makes the model public under their name. Before calling it, make sure the model previews correctly (presentShapeScript / renderShapeScript) and give it a short title, a sentence of description and a few lowercase keywords someone would search for. Pass the user's original request as `prompt` so the post records how the model was made. If the tool answers that Remote Host is not connected, tell the user to connect it (the Remote Host control in the app, Google sign-in) and offer to try again.",g={type:`object`,properties:{title:{type:`string`,description:`The model's title (1–${p.titleMax} characters).`},script:{type:`string`,description:"ShapeScript source to publish. Provide either this or `path`, not both."},path:{type:`string`,description:"Path to an existing .shape file — an `artifacts/shapes/...` path presentShapeScript saved, or any .shape the host can read. Provide either this or `script`, not both."},description:{type:`string`,description:`What the model is, for the gallery page (up to ${p.descriptionMax} characters). Optional.`},keywords:{type:`array`,items:{type:`string`},description:`Up to ${p.keywordsMax} short lowercase tags someone would search for. Optional.`},prompt:{type:`string`,description:`The request the model was made from, recorded as its provenance (up to ${p.promptMax} characters). Optional.`},published:{type:`boolean`,description:`false saves a draft only the user can see in the gallery's My models. Default true.`}},required:[`title`]},_=[`uid`,`authorName`,`title`,`description`,`script`,`source`,`prompt`,`photoIds`,`thumbnailId`,`forkedFrom`,`keywords`,`published`],v=`Not connected to the gallery: publishing posts under the user's Google account, which needs the app's Remote Host connected (sign in with Google in the Remote Host control), then try again.`,y=e=>typeof e==`string`&&e.trim()!==``?e:void 0,b=e=>typeof e==`string`?e.trim().toLowerCase().slice(0,p.keywordMax):``;function x(e){let t=(Array.isArray(e)?e:typeof e==`string`?e.split(`,`):[]).map(b).filter(e=>e!==``);return[...new Set(t)].slice(0,p.keywordsMax)}function S(e,t,n,r=0){if(t.length<r)throw Error(`\`${e}\` is required`);if(t.length>n)throw Error(`\`${e}\` is too long (${t.length} characters; the gallery allows ${n})`);return t}function C(e){if(e.length<1)throw Error("`script` is required");let t=new TextEncoder().encode(e).length;if(t>p.scriptMax)throw Error(`\`script\` is too long (${t} bytes; the gallery allows ${p.scriptMax})`);return e}function w(e,t){return{uid:e.uid,authorName:e.authorName.slice(0,p.authorNameMax),title:S(`title`,t.title.trim(),p.titleMax,1),description:S(`description`,t.description??``,p.descriptionMax),script:C(t.script),source:`prompt`,prompt:S(`prompt`,t.prompt??``,p.promptMax),photoIds:[],thumbnailId:t.thumbnailId??``,forkedFrom:null,keywords:x(t.keywords),published:t.published!==!1}}function T(e,t=f){return`${t.endsWith(`/`)?t.slice(0,-1):t}/shapes/${e}`}function E(e){t.a(t.r(t.s(e)))}var D=e=>e instanceof Error?e.message:String(e);async function O(e,t,n,r){try{let i=await e.renderThumbnail(r);return i?await t.uploadThumbnail(n,i):``}catch(t){return e.onWarning?.(`thumbnail skipped: ${D(t)}`),``}}async function k(e,t,n,r){try{await t.createPost(n,r)}catch(i){throw r.thumbnailId&&await t.deleteObject(n,r.thumbnailId).catch(t=>e.onWarning?.(`orphaned thumbnail ${r.thumbnailId}: ${D(t)}`)),i}}var A=()=>globalThis.crypto.randomUUID();async function j(e,t){let n=e.gallery;if(!n)throw Error(v);let r=y(t.title);if(!r)throw Error("`title` is required");let{script:i}=await l(e,t);E(i);let a=w(n,{title:r,script:i,description:y(t.description),prompt:y(t.prompt),keywords:t.keywords,published:t.published!==!1}),o=A(),s=await O(e,n,o,i),c={...a,thumbnailId:s};await k(e,n,o,c);let u=T(o,n.siteUrl),d=c.published?`Published`:`Saved as a draft (only the user can see it, under My models)`,f=s?``:` No thumbnail could be attached; the gallery shows a placeholder until the user edits the post.`;return{message:`${d}: "${c.title}" is at ${u}.${f}`,id:o,url:u,thumbnail:s!==``}}Object.defineProperty(exports,"_",{enumerable:!0,get:function(){return r}}),Object.defineProperty(exports,"a",{enumerable:!0,get:function(){return d}}),Object.defineProperty(exports,"c",{enumerable:!0,get:function(){return p}}),Object.defineProperty(exports,"d",{enumerable:!0,get:function(){return w}}),Object.defineProperty(exports,"f",{enumerable:!0,get:function(){return T}}),Object.defineProperty(exports,"g",{enumerable:!0,get:function(){return n}}),Object.defineProperty(exports,"h",{enumerable:!0,get:function(){return o}}),Object.defineProperty(exports,"i",{enumerable:!0,get:function(){return g}}),Object.defineProperty(exports,"l",{enumerable:!0,get:function(){return j}}),Object.defineProperty(exports,"m",{enumerable:!0,get:function(){return a}}),Object.defineProperty(exports,"n",{enumerable:!0,get:function(){return m}}),Object.defineProperty(exports,"o",{enumerable:!0,get:function(){return f}}),Object.defineProperty(exports,"p",{enumerable:!0,get:function(){return i}}),Object.defineProperty(exports,"r",{enumerable:!0,get:function(){return h}}),Object.defineProperty(exports,"s",{enumerable:!0,get:function(){return _}}),Object.defineProperty(exports,"t",{enumerable:!0,get:function(){return v}}),Object.defineProperty(exports,"u",{enumerable:!0,get:function(){return x}}),Object.defineProperty(exports,"v",{enumerable:!0,get:function(){return u}}),Object.defineProperty(exports,"y",{enumerable:!0,get:function(){return l}});
package/dist/core.cjs CHANGED
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./samples-C8zn1JOi.cjs"),t=require("./toThreeJS-BBwttw4K.cjs"),n=require("./core-DfEbc4Me.cjs");exports.EXPORT_USDZ_DESCRIPTION=n.p,exports.EXPORT_USDZ_PROMPT=n.m,exports.EXPORT_USDZ_SCHEMA=n.h,exports.EXPORT_USDZ_TOOL_NAME=n.g,exports.EXPORT_USDZ_TOOL_TIMEOUT_MS=n._,exports.NOT_CONNECTED_MESSAGE=n.t,exports.PUBLISH_DESCRIPTION=n.n,exports.PUBLISH_PROMPT=n.r,exports.PUBLISH_SCHEMA=n.i,exports.PUBLISH_TOOL_NAME=n.a,exports.SHAPE_EXTENSIONS=e.d,exports.SHAPE_GALLERY_URL=n.o,exports.SHAPE_POST_KEYS=n.s,exports.SHAPE_POST_LIMITS=n.c,exports.TOOL_DEFINITION=e.v,exports.TOOL_NAME=e.y,exports.USDZ_EXTENSION=e.n,exports.USDZ_MIME_TYPE=e.r,exports.astToThreeJS=t.r,exports.executeExportShapeScriptUsdz=n.v,exports.executePresentShapeScript=e.o,exports.executePublishShapeScript=n.l,exports.executeShapeScriptDispatch=e.l,exports.isPresentableShapePath=e.f,exports.isShapeArtifactPath=e.p,exports.isShapeScriptDispatchArgs=t.Vn,exports.locateShape=e.u,exports.normalizeShapeKeywords=n.u,exports.parseShapeScript=t.s,exports.pluginCore=e.s,exports.presentShapeScript=e.c,exports.readLoadShapeResult=t.Hn,exports.readSaveShapeResult=t.Un,exports.resolveShapeSource=n.y,exports.samples=e.t,exports.sceneInfoOf=t.i,exports.sceneToUsdz=e.i,exports.shapeArtifactPath=e.m,exports.shapePostFrom=n.d,exports.shapePostUrl=n.f,exports.shapeScriptToUsdz=e.a,exports.toArtifactsRelative=e.g,exports.usdzArtifactPath=e._;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./samples-BO-oAFPZ.cjs"),t=require("./toThreeJS-CDRtoJt7.cjs"),n=require("./core-CcNfRjfb.cjs");exports.EXPORT_USDZ_DESCRIPTION=n.p,exports.EXPORT_USDZ_PROMPT=n.m,exports.EXPORT_USDZ_SCHEMA=n.h,exports.EXPORT_USDZ_TOOL_NAME=n.g,exports.EXPORT_USDZ_TOOL_TIMEOUT_MS=n._,exports.NOT_CONNECTED_MESSAGE=n.t,exports.PUBLISH_DESCRIPTION=n.n,exports.PUBLISH_PROMPT=n.r,exports.PUBLISH_SCHEMA=n.i,exports.PUBLISH_TOOL_NAME=n.a,exports.SHAPE_EXTENSIONS=e.d,exports.SHAPE_GALLERY_URL=n.o,exports.SHAPE_POST_KEYS=n.s,exports.SHAPE_POST_LIMITS=n.c,exports.TOOL_DEFINITION=e.v,exports.TOOL_NAME=e.y,exports.USDZ_EXTENSION=e.n,exports.USDZ_MIME_TYPE=e.r,exports.astToThreeJS=t.r,exports.executeExportShapeScriptUsdz=n.v,exports.executePresentShapeScript=e.o,exports.executePublishShapeScript=n.l,exports.executeShapeScriptDispatch=e.l,exports.isPresentableShapePath=e.f,exports.isShapeArtifactPath=e.p,exports.isShapeScriptDispatchArgs=t.Vn,exports.locateShape=e.u,exports.normalizeShapeKeywords=n.u,exports.parseShapeScript=t.s,exports.pluginCore=e.s,exports.presentShapeScript=e.c,exports.readLoadShapeResult=t.Hn,exports.readSaveShapeResult=t.Un,exports.resolveShapeSource=n.y,exports.samples=e.t,exports.sceneInfoOf=t.i,exports.sceneToUsdz=e.i,exports.shapeArtifactPath=e.m,exports.shapePostFrom=n.d,exports.shapePostUrl=n.f,exports.shapeScriptToUsdz=e.a,exports.toArtifactsRelative=e.g,exports.usdzArtifactPath=e._;
package/dist/core.js CHANGED
@@ -1,4 +1,4 @@
1
- import { _ as e, a as t, c as n, d as r, f as i, g as a, i as o, l as s, m as c, n as l, o as u, p as d, r as f, s as p, t as m, u as h, v as g, y as _ } from "./samples-BZSbBJmx.js";
2
- import { Hn as v, Un as y, Vn as b, i as x, r as S, s as C } from "./toThreeJS-Bo3j0vOj.js";
3
- import { _ as w, a as T, c as E, d as D, f as O, g as k, h as A, i as j, l as M, m as N, n as P, o as F, p as I, r as L, s as R, t as z, u as B, v as V, y as H } from "./core-BW88rCqf.js";
1
+ import { _ as e, a as t, c as n, d as r, f as i, g as a, i as o, l as s, m as c, n as l, o as u, p as d, r as f, s as p, t as m, u as h, v as g, y as _ } from "./samples-CfppG9Bk.js";
2
+ import { Hn as v, Un as y, Vn as b, i as x, r as S, s as C } from "./toThreeJS-MMc_OzvN.js";
3
+ import { _ as w, a as T, c as E, d as D, f as O, g as k, h as A, i as j, l as M, m as N, n as P, o as F, p as I, r as L, s as R, t as z, u as B, v as V, y as H } from "./core-BP7kPYyW.js";
4
4
  export { I as EXPORT_USDZ_DESCRIPTION, N as EXPORT_USDZ_PROMPT, A as EXPORT_USDZ_SCHEMA, k as EXPORT_USDZ_TOOL_NAME, w as EXPORT_USDZ_TOOL_TIMEOUT_MS, z as NOT_CONNECTED_MESSAGE, P as PUBLISH_DESCRIPTION, L as PUBLISH_PROMPT, j as PUBLISH_SCHEMA, T as PUBLISH_TOOL_NAME, r as SHAPE_EXTENSIONS, F as SHAPE_GALLERY_URL, R as SHAPE_POST_KEYS, E as SHAPE_POST_LIMITS, g as TOOL_DEFINITION, _ as TOOL_NAME, l as USDZ_EXTENSION, f as USDZ_MIME_TYPE, S as astToThreeJS, V as executeExportShapeScriptUsdz, u as executePresentShapeScript, M as executePublishShapeScript, s as executeShapeScriptDispatch, i as isPresentableShapePath, d as isShapeArtifactPath, b as isShapeScriptDispatchArgs, h as locateShape, B as normalizeShapeKeywords, C as parseShapeScript, p as pluginCore, n as presentShapeScript, v as readLoadShapeResult, y as readSaveShapeResult, H as resolveShapeSource, m as samples, x as sceneInfoOf, o as sceneToUsdz, c as shapeArtifactPath, D as shapePostFrom, O as shapePostUrl, t as shapeScriptToUsdz, a as toArtifactsRelative, e as usdzArtifactPath };
package/dist/index.cjs CHANGED
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./samples-C8zn1JOi.cjs"),t=require("./toThreeJS-BBwttw4K.cjs"),n=require("./core-DfEbc4Me.cjs");exports.EXPORT_USDZ_DESCRIPTION=n.p,exports.EXPORT_USDZ_PROMPT=n.m,exports.EXPORT_USDZ_SCHEMA=n.h,exports.EXPORT_USDZ_TOOL_NAME=n.g,exports.EXPORT_USDZ_TOOL_TIMEOUT_MS=n._,exports.NOT_CONNECTED_MESSAGE=n.t,exports.PUBLISH_DESCRIPTION=n.n,exports.PUBLISH_PROMPT=n.r,exports.PUBLISH_SCHEMA=n.i,exports.PUBLISH_TOOL_NAME=n.a,exports.SHAPE_EXTENSIONS=e.d,exports.SHAPE_GALLERY_URL=n.o,exports.SHAPE_POST_KEYS=n.s,exports.SHAPE_POST_LIMITS=n.c,exports.TOOL_DEFINITION=e.v,exports.TOOL_NAME=e.y,exports.USDZ_EXTENSION=e.n,exports.USDZ_MIME_TYPE=e.r,exports.astToThreeJS=t.r,exports.executeExportShapeScriptUsdz=n.v,exports.executePresentShapeScript=e.o,exports.executePublishShapeScript=n.l,exports.executeShapeScriptDispatch=e.l,exports.isPresentableShapePath=e.f,exports.isShapeArtifactPath=e.p,exports.isShapeScriptDispatchArgs=t.Vn,exports.locateShape=e.u,exports.normalizeShapeKeywords=n.u,exports.parseShapeScript=t.s,exports.pluginCore=e.s,exports.presentShapeScript=e.c,exports.readLoadShapeResult=t.Hn,exports.readSaveShapeResult=t.Un,exports.resolveShapeSource=n.y,exports.samples=e.t,exports.sceneInfoOf=t.i,exports.sceneToUsdz=e.i,exports.shapeArtifactPath=e.m,exports.shapePostFrom=n.d,exports.shapePostUrl=n.f,exports.shapeScriptToUsdz=e.a,exports.toArtifactsRelative=e.g,exports.usdzArtifactPath=e._;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./samples-BO-oAFPZ.cjs"),t=require("./toThreeJS-CDRtoJt7.cjs"),n=require("./core-CcNfRjfb.cjs");exports.EXPORT_USDZ_DESCRIPTION=n.p,exports.EXPORT_USDZ_PROMPT=n.m,exports.EXPORT_USDZ_SCHEMA=n.h,exports.EXPORT_USDZ_TOOL_NAME=n.g,exports.EXPORT_USDZ_TOOL_TIMEOUT_MS=n._,exports.NOT_CONNECTED_MESSAGE=n.t,exports.PUBLISH_DESCRIPTION=n.n,exports.PUBLISH_PROMPT=n.r,exports.PUBLISH_SCHEMA=n.i,exports.PUBLISH_TOOL_NAME=n.a,exports.SHAPE_EXTENSIONS=e.d,exports.SHAPE_GALLERY_URL=n.o,exports.SHAPE_POST_KEYS=n.s,exports.SHAPE_POST_LIMITS=n.c,exports.TOOL_DEFINITION=e.v,exports.TOOL_NAME=e.y,exports.USDZ_EXTENSION=e.n,exports.USDZ_MIME_TYPE=e.r,exports.astToThreeJS=t.r,exports.executeExportShapeScriptUsdz=n.v,exports.executePresentShapeScript=e.o,exports.executePublishShapeScript=n.l,exports.executeShapeScriptDispatch=e.l,exports.isPresentableShapePath=e.f,exports.isShapeArtifactPath=e.p,exports.isShapeScriptDispatchArgs=t.Vn,exports.locateShape=e.u,exports.normalizeShapeKeywords=n.u,exports.parseShapeScript=t.s,exports.pluginCore=e.s,exports.presentShapeScript=e.c,exports.readLoadShapeResult=t.Hn,exports.readSaveShapeResult=t.Un,exports.resolveShapeSource=n.y,exports.samples=e.t,exports.sceneInfoOf=t.i,exports.sceneToUsdz=e.i,exports.shapeArtifactPath=e.m,exports.shapePostFrom=n.d,exports.shapePostUrl=n.f,exports.shapeScriptToUsdz=e.a,exports.toArtifactsRelative=e.g,exports.usdzArtifactPath=e._;
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { _ as e, a as t, c as n, d as r, f as i, g as a, i as o, l as s, m as c, n as l, o as u, p as d, r as f, s as p, t as m, u as h, v as g, y as _ } from "./samples-BZSbBJmx.js";
2
- import { Hn as v, Un as y, Vn as b, i as x, r as S, s as C } from "./toThreeJS-Bo3j0vOj.js";
3
- import { _ as w, a as T, c as E, d as D, f as O, g as k, h as A, i as j, l as M, m as N, n as P, o as F, p as I, r as L, s as R, t as z, u as B, v as V, y as H } from "./core-BW88rCqf.js";
1
+ import { _ as e, a as t, c as n, d as r, f as i, g as a, i as o, l as s, m as c, n as l, o as u, p as d, r as f, s as p, t as m, u as h, v as g, y as _ } from "./samples-CfppG9Bk.js";
2
+ import { Hn as v, Un as y, Vn as b, i as x, r as S, s as C } from "./toThreeJS-MMc_OzvN.js";
3
+ import { _ as w, a as T, c as E, d as D, f as O, g as k, h as A, i as j, l as M, m as N, n as P, o as F, p as I, r as L, s as R, t as z, u as B, v as V, y as H } from "./core-BP7kPYyW.js";
4
4
  export { I as EXPORT_USDZ_DESCRIPTION, N as EXPORT_USDZ_PROMPT, A as EXPORT_USDZ_SCHEMA, k as EXPORT_USDZ_TOOL_NAME, w as EXPORT_USDZ_TOOL_TIMEOUT_MS, z as NOT_CONNECTED_MESSAGE, P as PUBLISH_DESCRIPTION, L as PUBLISH_PROMPT, j as PUBLISH_SCHEMA, T as PUBLISH_TOOL_NAME, r as SHAPE_EXTENSIONS, F as SHAPE_GALLERY_URL, R as SHAPE_POST_KEYS, E as SHAPE_POST_LIMITS, g as TOOL_DEFINITION, _ as TOOL_NAME, l as USDZ_EXTENSION, f as USDZ_MIME_TYPE, S as astToThreeJS, V as executeExportShapeScriptUsdz, u as executePresentShapeScript, M as executePublishShapeScript, s as executeShapeScriptDispatch, i as isPresentableShapePath, d as isShapeArtifactPath, b as isShapeScriptDispatchArgs, h as locateShape, B as normalizeShapeKeywords, C as parseShapeScript, p as pluginCore, n as presentShapeScript, v as readLoadShapeResult, y as readSaveShapeResult, H as resolveShapeSource, m as samples, x as sceneInfoOf, o as sceneToUsdz, c as shapeArtifactPath, D as shapePostFrom, O as shapePostUrl, t as shapeScriptToUsdz, a as toArtifactsRelative, e as usdzArtifactPath };
@@ -1 +1 @@
1
- {"version":3,"file":"de.d.ts","sourceRoot":"","sources":["../../src/lang/de.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE3C,QAAA,MAAM,EAAE,EAAE,QAcT,CAAC;AAEF,eAAe,EAAE,CAAC"}
1
+ {"version":3,"file":"de.d.ts","sourceRoot":"","sources":["../../src/lang/de.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE3C,QAAA,MAAM,EAAE,EAAE,QAgBT,CAAC;AAEF,eAAe,EAAE,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"en.d.ts","sourceRoot":"","sources":["../../src/lang/en.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE3C,QAAA,MAAM,EAAE,EAAE,QAcT,CAAC;AAEF,eAAe,EAAE,CAAC"}
1
+ {"version":3,"file":"en.d.ts","sourceRoot":"","sources":["../../src/lang/en.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE3C,QAAA,MAAM,EAAE,EAAE,QAgBT,CAAC;AAEF,eAAe,EAAE,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"es.d.ts","sourceRoot":"","sources":["../../src/lang/es.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE3C,QAAA,MAAM,EAAE,EAAE,QAcT,CAAC;AAEF,eAAe,EAAE,CAAC"}
1
+ {"version":3,"file":"es.d.ts","sourceRoot":"","sources":["../../src/lang/es.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE3C,QAAA,MAAM,EAAE,EAAE,QAgBT,CAAC;AAEF,eAAe,EAAE,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"fr.d.ts","sourceRoot":"","sources":["../../src/lang/fr.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE3C,QAAA,MAAM,EAAE,EAAE,QAcT,CAAC;AAEF,eAAe,EAAE,CAAC"}
1
+ {"version":3,"file":"fr.d.ts","sourceRoot":"","sources":["../../src/lang/fr.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE3C,QAAA,MAAM,EAAE,EAAE,QAgBT,CAAC;AAEF,eAAe,EAAE,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"ja.d.ts","sourceRoot":"","sources":["../../src/lang/ja.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE3C,QAAA,MAAM,EAAE,EAAE,QAcT,CAAC;AAEF,eAAe,EAAE,CAAC"}
1
+ {"version":3,"file":"ja.d.ts","sourceRoot":"","sources":["../../src/lang/ja.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE3C,QAAA,MAAM,EAAE,EAAE,QAgBT,CAAC;AAEF,eAAe,EAAE,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"ko.d.ts","sourceRoot":"","sources":["../../src/lang/ko.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE3C,QAAA,MAAM,EAAE,EAAE,QAcT,CAAC;AAEF,eAAe,EAAE,CAAC"}
1
+ {"version":3,"file":"ko.d.ts","sourceRoot":"","sources":["../../src/lang/ko.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE3C,QAAA,MAAM,EAAE,EAAE,QAgBT,CAAC;AAEF,eAAe,EAAE,CAAC"}
@@ -10,6 +10,10 @@ export interface Messages {
10
10
  saveError: string;
11
11
  downloadUsdz: string;
12
12
  exportError: string;
13
+ /** Copies the ShapeScript source to the clipboard. */
14
+ copyScript: string;
15
+ /** Transient label after a successful copy. */
16
+ copied: string;
13
17
  /** Heading for commands the script used that this viewer does not draw. */
14
18
  sceneWarnings: string;
15
19
  /** Heading for the script's `print` lines. */
@@ -1 +1 @@
1
- {"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../../src/lang/messages.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,QAAQ;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,2EAA2E;IAC3E,aAAa,EAAE,MAAM,CAAC;IACtB,8CAA8C;IAC9C,WAAW,EAAE,MAAM,CAAC;CACrB"}
1
+ {"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../../src/lang/messages.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,QAAQ;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,sDAAsD;IACtD,UAAU,EAAE,MAAM,CAAC;IACnB,+CAA+C;IAC/C,MAAM,EAAE,MAAM,CAAC;IACf,2EAA2E;IAC3E,aAAa,EAAE,MAAM,CAAC;IACtB,8CAA8C;IAC9C,WAAW,EAAE,MAAM,CAAC;CACrB"}
@@ -1 +1 @@
1
- {"version":3,"file":"ptBR.d.ts","sourceRoot":"","sources":["../../src/lang/ptBR.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE3C,QAAA,MAAM,IAAI,EAAE,QAcX,CAAC;AAEF,eAAe,IAAI,CAAC"}
1
+ {"version":3,"file":"ptBR.d.ts","sourceRoot":"","sources":["../../src/lang/ptBR.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE3C,QAAA,MAAM,IAAI,EAAE,QAgBX,CAAC;AAEF,eAAe,IAAI,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"zh.d.ts","sourceRoot":"","sources":["../../src/lang/zh.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE3C,QAAA,MAAM,EAAE,EAAE,QAcT,CAAC;AAEF,eAAe,EAAE,CAAC"}
1
+ {"version":3,"file":"zh.d.ts","sourceRoot":"","sources":["../../src/lang/zh.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE3C,QAAA,MAAM,EAAE,EAAE,QAgBT,CAAC;AAEF,eAAe,EAAE,CAAC"}
package/dist/render.cjs CHANGED
@@ -1,4 +1,4 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});var e=Object.create,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.getPrototypeOf,a=Object.prototype.hasOwnProperty,o=(e,i,o,s)=>{if(i&&typeof i==`object`||typeof i==`function`)for(var c=r(i),l=0,u=c.length,d;l<u;l++)d=c[l],!a.call(e,d)&&d!==o&&t(e,d,{get:(e=>i[e]).bind(null,d),enumerable:!(s=n(i,d))||s.enumerable});return e},s=(n,r,s)=>(s=n==null?{}:e(i(n)),o(r||!n||!n.__esModule||!a.call(n,`default`)?t(s,`default`,{value:n,enumerable:!0}):s,n));const c=require("./toThreeJS-BBwttw4K.cjs");let l=require("node:fs/promises"),u=require("node:module"),d=require("node:url"),f=require("node:path");f=s(f,1);function p(e){let t=Math.ceil(Math.sqrt(e));return{columns:t,rows:Math.ceil(e/t)}}function ee(e,t,n){return`import { AmbientLight, Box3, Color, DirectionalLight, GridHelper, MathUtils, ObjectLoader, OrthographicCamera, PerspectiveCamera, Scene, Sphere, Vector3, WebGLRenderer } from ${JSON.stringify(e)};
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});var e=Object.create,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.getPrototypeOf,a=Object.prototype.hasOwnProperty,o=(e,i,o,s)=>{if(i&&typeof i==`object`||typeof i==`function`)for(var c=r(i),l=0,u=c.length,d;l<u;l++)d=c[l],!a.call(e,d)&&d!==o&&t(e,d,{get:(e=>i[e]).bind(null,d),enumerable:!(s=n(i,d))||s.enumerable});return e},s=(n,r,s)=>(s=n==null?{}:e(i(n)),o(r||!n||!n.__esModule||!a.call(n,`default`)?t(s,`default`,{value:n,enumerable:!0}):s,n));const c=require("./toThreeJS-CDRtoJt7.cjs");let l=require("node:fs/promises"),u=require("node:module"),d=require("node:url"),f=require("node:path");f=s(f,1);function p(e){let t=Math.ceil(Math.sqrt(e));return{columns:t,rows:Math.ceil(e/t)}}function ee(e,t,n){return`import { AmbientLight, Box3, Color, DirectionalLight, GridHelper, MathUtils, ObjectLoader, OrthographicCamera, PerspectiveCamera, Scene, Sphere, Vector3, WebGLRenderer } from ${JSON.stringify(e)};
2
2
 
3
3
  const config = ${t};
4
4
  const { columns, rows } = ${n};
package/dist/render.js CHANGED
@@ -1,4 +1,4 @@
1
- import { Bn as e, r as t, s as n } from "./toThreeJS-Bo3j0vOj.js";
1
+ import { Bn as e, r as t, s as n } from "./toThreeJS-MMc_OzvN.js";
2
2
  import { readFile as r } from "node:fs/promises";
3
3
  import { createRequire as i } from "node:module";
4
4
  import { pathToFileURL as a } from "node:url";
@@ -1,4 +1,4 @@
1
- const e=require("./toThreeJS-BBwttw4K.cjs");let t=require("@mulmoclaude/core/artifacts");var n=`presentShapeScript`,r={type:`function`,name:n,description:"Display interactive 3D visualizations using ShapeScript with expressions, variables, control flow, and functions. A new `script` is saved to `artifacts/shapes/` and the returned `filePath` names it; pass `path` instead to present a source that already exists.",parameters:{type:`object`,properties:{title:{type:`string`,description:`Title for the 3D visualization`},script:{type:`string`,description:`ShapeScript code defining the 3D scene. Supported features and syntax are listed below. Syntax, evaluation, geometry and resource-limit errors are returned as diagnostics; correct the script and retry.
1
+ const e=require("./toThreeJS-CDRtoJt7.cjs");let t=require("@mulmoclaude/core/artifacts");var n=`presentShapeScript`,r={type:`function`,name:n,description:"Display interactive 3D visualizations using ShapeScript with expressions, variables, control flow, and functions. A new `script` is saved to `artifacts/shapes/` and the returned `filePath` names it; pass `path` instead to present a source that already exists.",parameters:{type:`object`,properties:{title:{type:`string`,description:`Title for the 3D visualization`},script:{type:`string`,description:`ShapeScript code defining the 3D scene. Supported features and syntax are listed below. Syntax, evaluation, geometry and resource-limit errors are returned as diagnostics; correct the script and retry.
2
2
 
3
3
  ## SYNTAX OVERVIEW:
4
4
 
@@ -271,7 +271,7 @@ for x in -5 to 5 {
271
271
  `);return`${t}def ${this.type?this.type+` `:``}"${this.name}"${r}\n${t}{\n${s}\n${t}}`}},we=class{constructor(){this.textureUtils=null}setTextureUtils(e){this.textureUtils=e}parse(e,t,n,r){this.parseAsync(e,r).then(t).catch(n)}async parseAsync(e,t={}){t=Object.assign({ar:{anchoring:{type:`plane`},planeAnchoring:{alignment:`horizontal`}},includeAnchoringProperties:!0,onlyVisible:!0,quickLookCompatible:!1,maxTextureSize:1024,animations:[],animationFrameRate:60},t);let n=new Set,r={},i=`model.usda`;r[i]=null;let a=ke(e,t.animations);t.animationTracks=a;let o=new Q(`Root`,`Xform`),s=new Q(`Scenes`,`Scope`);s.addMetadata(`kind`,`"sceneLibrary"`),o.addChild(s);let c=`Scene`,l=new Q(c,`Xform`);l.addMetadata(`customData`,[`bool preliminary_collidesWithEnvironment = 0`,`string sceneName = "${c}"`]),l.addMetadata(`sceneName`,`"${c}"`),t.includeAnchoringProperties&&(l.addProperty(`token preliminary:anchoring:type = "${t.ar.anchoring.type}"`),l.addProperty(`token preliminary:planeAnchoring:alignment = "${t.ar.planeAnchoring.alignment}"`)),s.addChild(l);let u,d={},f={};e.isScene?Ne(e,l,d,n,r,t):Pe(e,l,d,n,r,t);let p=Ke(d,f,t.quickLookCompatible);u=Oe(a.size>0?{fps:t.animationFrameRate,endTimeCode:Ae(t.animations)*t.animationFrameRate}:null)+`
272
272
  `+o.toString()+`
273
273
 
274
- `+p.toString(),r[i]=ye(u),u=null;for(let e in f){let n=f[e];if(n.isCompressedTexture===!0){if(this.textureUtils===null)throw Error(`THREE.USDZExporter: setTextureUtils() must be called to process compressed textures.`);n=await this.textureUtils.decompress(n)}let i=De(n.image,n.flipY,t.maxTextureSize),a=n.userData.mimeType===`image/jpeg`?`image/jpeg`:`image/png`,o=await new Promise(e=>i.toBlob(e,a));r[`textures/Texture_${e}.${Ee(n)}`]=new Uint8Array(await o.arrayBuffer())}let m=0;for(let e in r){let t=r[e],n=34+e.length;m+=n;let i=m&63;if(i!==4){let n=64-i;r[e]=[t,{extra:{12345:new Uint8Array(n)}}]}m=t.length}return Ce(r,{level:0})}};function Te(e,t){let n=e.name;return n=n.replace(/[^A-Za-z0-9_]/g,``),/^[0-9]/.test(n)&&(n=`_`+n),n===``&&(n=e.isCamera?`Camera`:`Object`),t.has(n)&&(n=n+`_`+e.id),t.add(n),n}function Ee(e){return e.userData.mimeType===`image/jpeg`?`jpg`:`png`}function De(e,t,n){if(typeof HTMLImageElement<`u`&&e instanceof HTMLImageElement||typeof HTMLCanvasElement<`u`&&e instanceof HTMLCanvasElement||typeof OffscreenCanvas<`u`&&e instanceof OffscreenCanvas||typeof ImageBitmap<`u`&&e instanceof ImageBitmap){let r=n/Math.max(e.width,e.height),i=document.createElement(`canvas`);i.width=e.width*Math.min(1,r),i.height=e.height*Math.min(1,r);let a=i.getContext(`2d`);return t===!0&&(a.translate(0,i.height),a.scale(1,-1)),a.drawImage(e,0,0,i.width,i.height),i}throw Error(`THREE.USDZExporter: No valid image data found. Unable to process texture.`)}var $=7;function Oe(e=null){return`#usda 1.0
274
+ `+p.toString(),r[i]=ye(u),u=null;for(let e in f){let n=f[e];if(n.isCompressedTexture===!0){if(this.textureUtils===null)throw Error(`THREE.USDZExporter: setTextureUtils() must be called to process compressed textures.`);n=await this.textureUtils.decompress(n)}let i=De(n.image,n.flipY,t.maxTextureSize),a=n.userData.mimeType===`image/jpeg`?`image/jpeg`:`image/png`,o=await new Promise(e=>i.toBlob(e,a));r[`textures/Texture_${e}.${Ee(n)}`]=new Uint8Array(await o.arrayBuffer())}let m=0;for(let e in r){let t=r[e],n=34+e.length;m+=n;let i=m&63;if(i!==4){let n=64-i;r[e]=[t,{extra:{12345:new Uint8Array(n)}}]}m=t.length}return Ce(r,{level:0,mtime:new Date})}};function Te(e,t){let n=e.name;return n=n.replace(/[^A-Za-z0-9_]/g,``),/^[0-9]/.test(n)&&(n=`_`+n),n===``&&(n=e.isCamera?`Camera`:`Object`),t.has(n)&&(n=n+`_`+e.id),t.add(n),n}function Ee(e){return e.userData.mimeType===`image/jpeg`?`jpg`:`png`}function De(e,t,n){if(typeof HTMLImageElement<`u`&&e instanceof HTMLImageElement||typeof HTMLCanvasElement<`u`&&e instanceof HTMLCanvasElement||typeof OffscreenCanvas<`u`&&e instanceof OffscreenCanvas||typeof ImageBitmap<`u`&&e instanceof ImageBitmap){let r=n/Math.max(e.width,e.height),i=document.createElement(`canvas`);i.width=e.width*Math.min(1,r),i.height=e.height*Math.min(1,r);let a=i.getContext(`2d`);return t===!0&&(a.translate(0,i.height),a.scale(1,-1)),a.drawImage(e,0,0,i.width,i.height),i}throw Error(`THREE.USDZExporter: No valid image data found. Unable to process texture.`)}var $=7;function Oe(e=null){return`#usda 1.0
275
275
  (
276
276
  customLayerData = {
277
277
  string creator = "Three.js USDZExporter"
@@ -1,4 +1,4 @@
1
- import { Bn as e, I as t, Y as n, a as r, g as i, i as a, j as o, n as s, p as c, r as l, s as u, st as d, zn as f } from "./toThreeJS-Bo3j0vOj.js";
1
+ import { Bn as e, I as t, Y as n, a as r, g as i, i as a, j as o, n as s, p as c, r as l, s as u, st as d, zn as f } from "./toThreeJS-MMc_OzvN.js";
2
2
  import { ARTIFACTS_ROOT as p, buildArtifactRelPath as m, classifyFilePath as h, hasUnsafePathSegment as g, slugifyArtifact as _, toWorkspaceArtifactPath as v } from "@mulmoclaude/core/artifacts";
3
3
  //#region src/core/definition.ts
4
4
  var y = "presentShapeScript", b = {
@@ -707,7 +707,10 @@ var Q = class {
707
707
  }
708
708
  m = t.length;
709
709
  }
710
- return Be(r, { level: 0 });
710
+ return Be(r, {
711
+ level: 0,
712
+ mtime: /* @__PURE__ */ new Date()
713
+ });
711
714
  }
712
715
  };
713
716
  function He(e, t) {
package/dist/style.css CHANGED
@@ -1,3 +1,3 @@
1
1
  /*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */
2
- @layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-border-style:solid;--tw-ordinal:initial;--tw-slashed-zero:initial;--tw-numeric-figure:initial;--tw-numeric-spacing:initial;--tw-numeric-fraction:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid}}}@layer theme{:root,:host{--font-sans:-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--font-mono:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring:where(:not(iframe)){outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab, red, red)){::placeholder{color:color-mix(in oklab, currentcolor 50%, transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer components;@layer utilities{.collapse{visibility:collapse}.invisible{visibility:hidden}.visible{visibility:visible}.absolute{position:absolute}.relative{position:relative}.static{position:static}.block{display:block}.contents{display:contents}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline{display:inline}.transform{transform:var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.resize{resize:both}.rounded{border-radius:.25rem}.border{border-style:var(--tw-border-style);border-width:1px}.lowercase{text-transform:lowercase}.ordinal{--tw-ordinal:ordinal;font-variant-numeric:var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,)}.shadow{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.ring{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.outline{outline-style:var(--tw-outline-style);outline-width:1px}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-ordinal{syntax:"*";inherits:false}@property --tw-slashed-zero{syntax:"*";inherits:false}@property --tw-numeric-figure{syntax:"*";inherits:false}@property --tw-numeric-spacing{syntax:"*";inherits:false}@property --tw-numeric-fraction{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}.present3d-container[data-v-792dc725]{color:#fff;background:#1a1a1a;flex-direction:column;width:100%;height:100%;display:flex}.header[data-v-792dc725]{background:#2a2a2a;border-bottom:1px solid #444;justify-content:space-between;align-items:center;padding:1rem;display:flex}.header h1[data-v-792dc725]{margin:0;font-size:1.5rem;font-weight:600}.controls[data-v-792dc725]{gap:.5rem;display:flex}.control-btn[data-v-792dc725]{color:#fff;cursor:pointer;background:#3a3a3a;border:1px solid #555;border-radius:4px;align-items:center;gap:.25rem;padding:.5rem 1rem;font-size:.9rem;transition:background .2s;display:flex}.control-btn[data-v-792dc725]:hover{background:#4a4a4a}.control-btn[data-v-792dc725]:disabled{cursor:not-allowed;opacity:.5}.control-btn[data-v-792dc725]:disabled:hover{background:#3a3a3a}.control-btn .material-icons[data-v-792dc725]{font-size:1.2rem}.viewport[data-v-792dc725]{flex:1;min-height:0;position:relative}.error[data-v-792dc725]{color:#f66;background:#ff000020;border-bottom:1px solid #ff000040;padding:1rem;font-family:monospace}.notice[data-v-792dc725]{color:#e0b060;background:#ffaa0020;border-bottom:1px solid #ffaa0040;padding:.5rem 1rem;font-family:monospace;font-size:.85rem}.output[data-v-792dc725]{color:#ccc;white-space:pre-wrap;background:#ffffff10;margin:0}.script-source[data-v-792dc725]{background:#00000040;border-top:1px solid #444;padding:.5rem;font-family:monospace;font-size:.85rem}.script-source summary[data-v-792dc725]{cursor:pointer;-webkit-user-select:none;user-select:none;background:#2a2a2a;border-radius:4px;padding:.5rem}.script-source[open] summary[data-v-792dc725]{margin-bottom:.5rem}.script-source summary[data-v-792dc725]:hover{background:#3a3a3a}.script-editor[data-v-792dc725]{color:#aaa;resize:vertical;background:#1a1a1a;border:1px solid #444;border-radius:4px;width:100%;min-height:150px;margin-bottom:.5rem;padding:1rem;font-family:Courier New,monospace;font-size:.9rem}.script-editor[data-v-792dc725]:focus{background:#222;border-color:#666;outline:none}.apply-btn[data-v-792dc725]{color:#fff;cursor:pointer;background:#4caf50;border:none;border-radius:4px;padding:.5rem 1rem;font-size:.9rem;transition:background .2s}.apply-btn[data-v-792dc725]:hover{background:#45a049}.apply-btn[data-v-792dc725]:active{background:#3d8b40}.apply-btn[data-v-792dc725]:disabled{color:#666;cursor:not-allowed;opacity:.6;background:#ccc}.apply-btn[data-v-792dc725]:disabled:hover{background:#ccc}.preview-container[data-v-6844181e]{background:linear-gradient(135deg,#667eea 0%,#764ba2 100%);border-radius:8px;width:100%;height:100%;min-height:150px;position:relative;overflow:hidden}.preview-viewport[data-v-6844181e]{width:100%;height:100%}.preview-title[data-v-6844181e]{color:#fff;text-align:center;white-space:nowrap;text-overflow:ellipsis;background:#000000b3;padding:.5rem;font-size:.75rem;font-weight:500;position:absolute;bottom:0;left:0;right:0;overflow:hidden}
2
+ @layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-border-style:solid;--tw-ordinal:initial;--tw-slashed-zero:initial;--tw-numeric-figure:initial;--tw-numeric-spacing:initial;--tw-numeric-fraction:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid}}}@layer theme{:root,:host{--font-sans:-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--font-mono:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring:where(:not(iframe)){outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab, red, red)){::placeholder{color:color-mix(in oklab, currentcolor 50%, transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer components;@layer utilities{.collapse{visibility:collapse}.invisible{visibility:hidden}.visible{visibility:visible}.absolute{position:absolute}.relative{position:relative}.static{position:static}.block{display:block}.contents{display:contents}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline{display:inline}.transform{transform:var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.resize{resize:both}.rounded{border-radius:.25rem}.border{border-style:var(--tw-border-style);border-width:1px}.lowercase{text-transform:lowercase}.ordinal{--tw-ordinal:ordinal;font-variant-numeric:var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,)}.shadow{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.ring{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.outline{outline-style:var(--tw-outline-style);outline-width:1px}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-ordinal{syntax:"*";inherits:false}@property --tw-slashed-zero{syntax:"*";inherits:false}@property --tw-numeric-figure{syntax:"*";inherits:false}@property --tw-numeric-spacing{syntax:"*";inherits:false}@property --tw-numeric-fraction{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}.present3d-container[data-v-6a625e86]{color:#fff;background:#1a1a1a;flex-direction:column;width:100%;height:100%;display:flex}.header[data-v-6a625e86]{background:#2a2a2a;border-bottom:1px solid #444;justify-content:space-between;align-items:center;padding:1rem;display:flex}.header h1[data-v-6a625e86]{margin:0;font-size:1.5rem;font-weight:600}.controls[data-v-6a625e86]{gap:.5rem;display:flex}.control-btn[data-v-6a625e86]{color:#fff;cursor:pointer;background:#3a3a3a;border:1px solid #555;border-radius:4px;align-items:center;gap:.25rem;padding:.5rem 1rem;font-size:.9rem;transition:background .2s;display:flex}.control-btn[data-v-6a625e86]:hover{background:#4a4a4a}.control-btn[data-v-6a625e86]:disabled{cursor:not-allowed;opacity:.5}.control-btn[data-v-6a625e86]:disabled:hover{background:#3a3a3a}.control-btn .material-icons[data-v-6a625e86]{font-size:1.2rem}.viewport[data-v-6a625e86]{flex:1;min-height:0;position:relative}.error[data-v-6a625e86]{color:#f66;background:#ff000020;border-bottom:1px solid #ff000040;padding:1rem;font-family:monospace}.notice[data-v-6a625e86]{color:#e0b060;background:#ffaa0020;border-bottom:1px solid #ffaa0040;padding:.5rem 1rem;font-family:monospace;font-size:.85rem}.output[data-v-6a625e86]{color:#ccc;white-space:pre-wrap;background:#ffffff10;margin:0}.script-source[data-v-6a625e86]{background:#00000040;border-top:1px solid #444;padding:.5rem;font-family:monospace;font-size:.85rem}.script-source summary[data-v-6a625e86]{cursor:pointer;-webkit-user-select:none;user-select:none;background:#2a2a2a;border-radius:4px;padding:.5rem}.script-source[open] summary[data-v-6a625e86]{margin-bottom:.5rem}.script-source summary[data-v-6a625e86]:hover{background:#3a3a3a}.script-editor[data-v-6a625e86]{color:#aaa;resize:vertical;background:#1a1a1a;border:1px solid #444;border-radius:4px;width:100%;min-height:150px;margin-bottom:.5rem;padding:1rem;font-family:Courier New,monospace;font-size:.9rem}.script-editor[data-v-6a625e86]:focus{background:#222;border-color:#666;outline:none}.apply-btn[data-v-6a625e86]{color:#fff;cursor:pointer;background:#4caf50;border:none;border-radius:4px;padding:.5rem 1rem;font-size:.9rem;transition:background .2s}.apply-btn[data-v-6a625e86]:hover{background:#45a049}.apply-btn[data-v-6a625e86]:active{background:#3d8b40}.apply-btn[data-v-6a625e86]:disabled{color:#666;cursor:not-allowed;opacity:.6;background:#ccc}.apply-btn[data-v-6a625e86]:disabled:hover{background:#ccc}.preview-container[data-v-6844181e]{background:linear-gradient(135deg,#667eea 0%,#764ba2 100%);border-radius:8px;width:100%;height:100%;min-height:150px;position:relative;overflow:hidden}.preview-viewport[data-v-6844181e]{width:100%;height:100%}.preview-title[data-v-6844181e]{color:#fff;text-align:center;white-space:nowrap;text-overflow:ellipsis;background:#000000b3;padding:.5rem;font-size:.75rem;font-weight:500;position:absolute;bottom:0;left:0;right:0;overflow:hidden}
3
3
  /*$vite$:1*/