@mulmoclaude/shapescript-plugin 2.8.0 → 3.0.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.
@@ -10,7 +10,7 @@ export { isPresentableShapePath, isShapeArtifactPath, shapeArtifactPath, usdzArt
10
10
  export { sceneToUsdz, shapeScriptToUsdz, USDZ_MIME_TYPE, USDZ_EXTENSION } from "../export/usdz";
11
11
  export { resolveShapeSource, executeExportShapeScriptUsdz, EXPORT_USDZ_TOOL_NAME, EXPORT_USDZ_DESCRIPTION, EXPORT_USDZ_PROMPT, EXPORT_USDZ_SCHEMA, EXPORT_USDZ_TOOL_TIMEOUT_MS, } from "../export/tool";
12
12
  export type { ExportUsdzResult } from "../export/tool";
13
- export { executePublishShapeScript, shapePostFrom, shapePostUrl, normalizeKeywords as normalizeShapeKeywords, PUBLISH_TOOL_NAME, PUBLISH_DESCRIPTION, PUBLISH_PROMPT, PUBLISH_SCHEMA, SHAPE_GALLERY_URL, SHAPE_POST_KEYS, SHAPE_POST_LIMITS, NOT_CONNECTED_MESSAGE, } from "./publish";
13
+ export { executePublishShapeScript, shapePostFrom, shapePostUrl, normalizeKeywords as normalizeShapeKeywords, PUBLISH_TOOL_NAME, PUBLISH_DESCRIPTION, PUBLISH_PROMPT, PUBLISH_SCHEMA, SHAPE_GALLERY_URL, SHAPE_POST_KEYS, SHAPE_POST_LIMITS, SHAPE_SCRIPT_CONTENT_TYPE, SHAPE_OBJECT_CACHE_CONTROL, requireScriptBytes, NOT_CONNECTED_MESSAGE, } from "./publish";
14
14
  export type { PublishShapeScriptContext, PublishShapeResult, ShapeGalleryWriter, ShapePostDoc } from "./publish";
15
15
  export { samples } from "./samples";
16
16
  export { parseShapeScript } from "../shapescript/parser";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,sBAAsB,EACtB,sBAAsB,EACtB,wBAAwB,EACxB,gCAAgC,EAChC,6BAA6B,EAC7B,iCAAiC,EACjC,qBAAqB,GACtB,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC1D,OAAO,EAAE,UAAU,EAAE,kBAAkB,EAAE,yBAAyB,EAAE,MAAM,UAAU,CAAC;AACrF,YAAY,EAAE,yBAAyB,EAAE,MAAM,UAAU,CAAC;AAC1D,OAAO,EAAE,0BAA0B,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACrE,YAAY,EAAE,0BAA0B,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC3E,OAAO,EAAE,yBAAyB,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AACjG,YAAY,EAAE,aAAa,EAAE,aAAa,EAAE,uBAAuB,EAAE,yBAAyB,EAAE,MAAM,YAAY,CAAC;AACnH,OAAO,EAAE,sBAAsB,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAIlJ,OAAO,EAAE,WAAW,EAAE,iBAAiB,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAChG,OAAO,EACL,kBAAkB,EAClB,4BAA4B,EAC5B,qBAAqB,EACrB,uBAAuB,EACvB,kBAAkB,EAClB,kBAAkB,EAClB,2BAA2B,GAC5B,MAAM,gBAAgB,CAAC;AACxB,YAAY,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AACvD,OAAO,EACL,yBAAyB,EACzB,aAAa,EACb,YAAY,EACZ,iBAAiB,IAAI,sBAAsB,EAC3C,iBAAiB,EACjB,mBAAmB,EACnB,cAAc,EACd,cAAc,EACd,iBAAiB,EACjB,eAAe,EACf,iBAAiB,EACjB,qBAAqB,GACtB,MAAM,WAAW,CAAC;AACnB,YAAY,EAAE,yBAAyB,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACjH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACrE,YAAY,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AACrE,YAAY,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,sBAAsB,EACtB,sBAAsB,EACtB,wBAAwB,EACxB,gCAAgC,EAChC,6BAA6B,EAC7B,iCAAiC,EACjC,qBAAqB,GACtB,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC1D,OAAO,EAAE,UAAU,EAAE,kBAAkB,EAAE,yBAAyB,EAAE,MAAM,UAAU,CAAC;AACrF,YAAY,EAAE,yBAAyB,EAAE,MAAM,UAAU,CAAC;AAC1D,OAAO,EAAE,0BAA0B,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACrE,YAAY,EAAE,0BAA0B,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC3E,OAAO,EAAE,yBAAyB,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AACjG,YAAY,EAAE,aAAa,EAAE,aAAa,EAAE,uBAAuB,EAAE,yBAAyB,EAAE,MAAM,YAAY,CAAC;AACnH,OAAO,EAAE,sBAAsB,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAIlJ,OAAO,EAAE,WAAW,EAAE,iBAAiB,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAChG,OAAO,EACL,kBAAkB,EAClB,4BAA4B,EAC5B,qBAAqB,EACrB,uBAAuB,EACvB,kBAAkB,EAClB,kBAAkB,EAClB,2BAA2B,GAC5B,MAAM,gBAAgB,CAAC;AACxB,YAAY,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AACvD,OAAO,EACL,yBAAyB,EACzB,aAAa,EACb,YAAY,EACZ,iBAAiB,IAAI,sBAAsB,EAC3C,iBAAiB,EACjB,mBAAmB,EACnB,cAAc,EACd,cAAc,EACd,iBAAiB,EACjB,eAAe,EACf,iBAAiB,EACjB,yBAAyB,EACzB,0BAA0B,EAC1B,kBAAkB,EAClB,qBAAqB,GACtB,MAAM,WAAW,CAAC;AACnB,YAAY,EAAE,yBAAyB,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACjH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACrE,YAAY,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AACrE,YAAY,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC"}
@@ -7,9 +7,10 @@ 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
- /** 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;
10
+ /** In UTF-8 BYTES — the script is a Storage object and the gallery's Storage rule caps one
11
+ * at 10 MiB (`request.resource.size`); a script with Japanese comments is up to three bytes
12
+ * a character. This is the transport ceiling; what a phone can draw is the practical one. */
13
+ readonly scriptMax: number;
13
14
  readonly promptMax: 4000;
14
15
  readonly authorNameMax: 80;
15
16
  readonly keywordsMax: 10;
@@ -59,13 +60,14 @@ export declare const PUBLISH_SCHEMA: {
59
60
  /** The document a post is, minus the two server-stamped times the host adds
60
61
  * (`createdAt` / `updatedAt` must be `serverTimestamp()` — the rules refuse
61
62
  * anything else). Every key present with a value: the rules pin the set and
62
- * Firestore rejects `undefined`. */
63
+ * Firestore rejects `undefined`. The script is `scriptId`, the Storage object
64
+ * `uploadScript` returned — never the text. */
63
65
  export interface ShapePostDoc {
64
66
  uid: string;
65
67
  authorName: string;
66
68
  title: string;
67
69
  description: string;
68
- script: string;
70
+ scriptId: string;
69
71
  source: "prompt";
70
72
  prompt: string;
71
73
  photoIds: string[];
@@ -75,7 +77,7 @@ export interface ShapePostDoc {
75
77
  published: boolean;
76
78
  }
77
79
  /** The key set mulmoserver's rules accept, in the rules' own order. */
78
- export declare const SHAPE_POST_KEYS: readonly ["uid", "authorName", "title", "description", "script", "source", "prompt", "photoIds", "thumbnailId", "forkedFrom", "keywords", "published"];
80
+ export declare const SHAPE_POST_KEYS: readonly ["uid", "authorName", "title", "description", "scriptId", "source", "prompt", "photoIds", "thumbnailId", "forkedFrom", "keywords", "published"];
79
81
  /** What a host supplies: who is posting, and the writes, over its own
80
82
  * signed-in session — the Firestore document and the Storage object the
81
83
  * gallery card shows. */
@@ -90,7 +92,10 @@ export interface ShapeGalleryWriter {
90
92
  createPost: (id: string, doc: ShapePostDoc) => Promise<void>;
91
93
  /** Store a PNG under the post and return the object id the document carries. */
92
94
  uploadThumbnail: (id: string, png: Uint8Array) => Promise<string>;
93
- /** Remove an object under the post the thumbnail of a post that was never written. */
95
+ /** Store the ShapeScript source under the post as `SHAPE_SCRIPT_CONTENT_TYPE` and return
96
+ * the object id the document carries as `scriptId`. */
97
+ uploadScript: (id: string, script: string) => Promise<string>;
98
+ /** Remove an object under the post — the thumbnail or script of a post that was never written. */
94
99
  deleteObject: (id: string, objectId: string) => Promise<void>;
95
100
  }
96
101
  export interface PublishShapeScriptContext extends ShapeScriptDispatchContext {
@@ -115,6 +120,11 @@ export interface PublishShapeResult {
115
120
  /** Whether a thumbnail was attached. */
116
121
  thumbnail: boolean;
117
122
  }
123
+ /** What a host uploads the script as; the gallery's Storage rule admits `text/plain.*`. */
124
+ export declare const SHAPE_SCRIPT_CONTENT_TYPE = "text/plain; charset=utf-8";
125
+ /** The header a host puts on every object it uploads under a post. Each has a random id and
126
+ * is never rewritten, so a browser — and the gallery's CDN, when it has one — may keep it. */
127
+ export declare const SHAPE_OBJECT_CACHE_CONTROL = "public, max-age=31536000, immutable";
118
128
  export declare const NOT_CONNECTED_MESSAGE = "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.";
119
129
  /** Keywords as the gallery stores them: trimmed, lowercased, deduplicated,
120
130
  * each cut to `keywordMax`, at most `keywordsMax`. The same rule as
@@ -122,12 +132,15 @@ export declare const NOT_CONNECTED_MESSAGE = "Not connected to the gallery: publ
122
132
  * here can never be two spellings of one word. A comma-separated string is
123
133
  * accepted too, since a model sometimes sends one. */
124
134
  export declare function normalizeKeywords(raw: unknown): string[];
135
+ /** The script's limit is in UTF-8 bytes, measured as the Storage rule measures it. */
136
+ export declare function requireScriptBytes(value: string): string;
125
137
  /** The document for one post, built field by field so nothing the caller
126
138
  * passed can reach Firestore uninvited. Throws on a limit the rules would
127
139
  * refuse, naming the field. */
128
140
  export declare function shapePostFrom(writer: Pick<ShapeGalleryWriter, "uid" | "authorName">, fields: {
129
141
  title: string;
130
- script: string;
142
+ /** The object id `uploadScript` returned. */
143
+ scriptId: string;
131
144
  description?: string | undefined;
132
145
  prompt?: string | undefined;
133
146
  keywords?: unknown;
@@ -140,8 +153,8 @@ export declare function shapePostUrl(id: string, siteUrl?: string): string;
140
153
  * Run one `publishShapeScript` call. Throws on a missing session, a missing or
141
154
  * invalid source, a limit the gallery would refuse, and on ShapeScript errors
142
155
  * — the host's error path reports those to the model as it does for
143
- * `renderShapeScript`. Everything that can be refused is checked BEFORE the
144
- * thumbnail is uploaded, so a refusal writes nothing.
156
+ * `renderShapeScript`. Everything that can be refused is checked BEFORE
157
+ * anything is uploaded, so a refusal writes nothing.
145
158
  */
146
159
  export declare function executePublishShapeScript(context: PublishShapeScriptContext, args: Record<string, unknown>): Promise<PublishShapeResult>;
147
160
  //# sourceMappingURL=publish.d.ts.map
@@ -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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"}
@@ -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: 9e5,
57
+ scriptMax: 10485760,
58
58
  promptMax: 4e3,
59
59
  authorNameMax: 80,
60
60
  keywordsMax: 10,
@@ -98,7 +98,7 @@ var g = "publishShapeScript", _ = "https://server.mulmocast.com", v = {
98
98
  "authorName",
99
99
  "title",
100
100
  "description",
101
- "script",
101
+ "scriptId",
102
102
  "source",
103
103
  "prompt",
104
104
  "photoIds",
@@ -106,87 +106,89 @@ var g = "publishShapeScript", _ = "https://server.mulmocast.com", v = {
106
106
  "forkedFrom",
107
107
  "keywords",
108
108
  "published"
109
- ], C = "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.", w = (e) => typeof e == "string" && e.trim() !== "" ? e : void 0, T = (e) => typeof e == "string" ? e.trim().toLowerCase().slice(0, v.keywordMax) : "";
110
- function E(e) {
111
- let t = (Array.isArray(e) ? e : typeof e == "string" ? e.split(",") : []).map(T).filter((e) => e !== "");
109
+ ], C = "text/plain; charset=utf-8", w = "public, max-age=31536000, immutable", T = "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.", E = (e) => typeof e == "string" && e.trim() !== "" ? e : void 0, D = (e) => typeof e == "string" ? e.trim().toLowerCase().slice(0, v.keywordMax) : "";
110
+ function O(e) {
111
+ let t = (Array.isArray(e) ? e : typeof e == "string" ? e.split(",") : []).map(D).filter((e) => e !== "");
112
112
  return [...new Set(t)].slice(0, v.keywordsMax);
113
113
  }
114
- function D(e, t, n, r = 0) {
114
+ function k(e, t, n, r = 0) {
115
115
  if (t.length < r) throw Error(`\`${e}\` is required`);
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) {
119
+ function A(e) {
120
120
  if (e.length < 1) throw Error("`script` is required");
121
121
  let t = new TextEncoder().encode(e).length;
122
122
  if (t > v.scriptMax) throw Error(`\`script\` is too long (${t} bytes; the gallery allows ${v.scriptMax})`);
123
123
  return e;
124
124
  }
125
- function k(e, t) {
125
+ function j(e, t) {
126
126
  return {
127
127
  uid: e.uid,
128
128
  authorName: e.authorName.slice(0, v.authorNameMax),
129
- title: D("title", t.title.trim(), v.titleMax, 1),
130
- description: D("description", t.description ?? "", v.descriptionMax),
131
- script: O(t.script),
129
+ title: k("title", t.title.trim(), v.titleMax, 1),
130
+ description: k("description", t.description ?? "", v.descriptionMax),
131
+ scriptId: t.scriptId,
132
132
  source: "prompt",
133
- prompt: D("prompt", t.prompt ?? "", v.promptMax),
133
+ prompt: k("prompt", t.prompt ?? "", v.promptMax),
134
134
  photoIds: [],
135
135
  thumbnailId: t.thumbnailId ?? "",
136
136
  forkedFrom: null,
137
- keywords: E(t.keywords),
137
+ keywords: O(t.keywords),
138
138
  published: t.published !== !1
139
139
  };
140
140
  }
141
- function A(e, t = _) {
141
+ function M(e, t = _) {
142
142
  return `${t.endsWith("/") ? t.slice(0, -1) : t}/shapes/${e}`;
143
143
  }
144
- function j(e) {
144
+ function N(e) {
145
145
  r(i(a(e)));
146
146
  }
147
- var M = (e) => e instanceof Error ? e.message : String(e);
148
- async function N(e, t, n, r) {
147
+ var P = (e) => e instanceof Error ? e.message : String(e);
148
+ async function F(e, t, n, r) {
149
149
  try {
150
150
  let i = await e.renderThumbnail(r);
151
151
  return i ? await t.uploadThumbnail(n, i) : "";
152
152
  } catch (t) {
153
- return e.onWarning?.(`thumbnail skipped: ${M(t)}`), "";
153
+ return e.onWarning?.(`thumbnail skipped: ${P(t)}`), "";
154
154
  }
155
155
  }
156
- async function P(e, t, n, r) {
156
+ async function I(e, t, n, r) {
157
157
  try {
158
158
  await t.createPost(n, r);
159
159
  } catch (i) {
160
- throw r.thumbnailId && await t.deleteObject(n, r.thumbnailId).catch((t) => e.onWarning?.(`orphaned thumbnail ${r.thumbnailId}: ${M(t)}`)), i;
160
+ let a = [r.scriptId, r.thumbnailId].filter((e) => e !== "");
161
+ throw await Promise.all(a.map((r) => t.deleteObject(n, r).catch((t) => e.onWarning?.(`orphaned object ${r}: ${P(t)}`)))), i;
161
162
  }
162
163
  }
163
- var F = () => globalThis.crypto.randomUUID();
164
- async function I(e, t) {
164
+ var L = () => globalThis.crypto.randomUUID();
165
+ async function R(e, t) {
165
166
  let n = e.gallery;
166
- if (!n) throw Error(C);
167
- let r = w(t.title);
167
+ if (!n) throw Error(T);
168
+ let r = E(t.title);
168
169
  if (!r) throw Error("`title` is required");
169
170
  let { script: i } = await m(e, t);
170
- j(i);
171
- let a = k(n, {
171
+ A(i), N(i);
172
+ let a = j(n, {
172
173
  title: r,
173
- script: i,
174
- description: w(t.description),
175
- prompt: w(t.prompt),
174
+ scriptId: "",
175
+ description: E(t.description),
176
+ prompt: E(t.prompt),
176
177
  keywords: t.keywords,
177
178
  published: t.published !== !1
178
- }), o = F(), s = await N(e, n, o, i), c = {
179
+ }), o = L(), s = await n.uploadScript(o, i), c = await F(e, n, o, i), l = {
179
180
  ...a,
180
- thumbnailId: s
181
+ thumbnailId: c,
182
+ scriptId: s
181
183
  };
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.";
184
+ await I(e, n, o, l);
185
+ let u = M(o, n.siteUrl), d = l.published ? "Published" : "Saved as a draft (only the user can see it, under My models)", f = c ? "" : " No thumbnail could be attached; the gallery shows a placeholder until the user edits the post.";
184
186
  return {
185
- message: `${u}: "${c.title}" is at ${l}.${d}`,
187
+ message: `${d}: "${l.title}" is at ${u}.${f}`,
186
188
  id: o,
187
- url: l,
188
- thumbnail: s !== ""
189
+ url: u,
190
+ thumbnail: c !== ""
189
191
  };
190
192
  }
191
193
  //#endregion
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 };
194
+ export { m as S, u as _, g as a, c as b, S as c, R as d, O as f, l as g, M as h, x as i, v as l, j as m, y as n, _ as o, A as p, b as r, w as s, T as t, C as u, d as v, h as x, s as y };
@@ -0,0 +1 @@
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:10485760,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`,`scriptId`,`source`,`prompt`,`photoIds`,`thumbnailId`,`forkedFrom`,`keywords`,`published`],v=`text/plain; charset=utf-8`,y=`public, max-age=31536000, immutable`,b=`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.`,x=e=>typeof e==`string`&&e.trim()!==``?e:void 0,S=e=>typeof e==`string`?e.trim().toLowerCase().slice(0,p.keywordMax):``;function C(e){let t=(Array.isArray(e)?e:typeof e==`string`?e.split(`,`):[]).map(S).filter(e=>e!==``);return[...new Set(t)].slice(0,p.keywordsMax)}function w(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 T(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 E(e,t){return{uid:e.uid,authorName:e.authorName.slice(0,p.authorNameMax),title:w(`title`,t.title.trim(),p.titleMax,1),description:w(`description`,t.description??``,p.descriptionMax),scriptId:t.scriptId,source:`prompt`,prompt:w(`prompt`,t.prompt??``,p.promptMax),photoIds:[],thumbnailId:t.thumbnailId??``,forkedFrom:null,keywords:C(t.keywords),published:t.published!==!1}}function D(e,t=f){return`${t.endsWith(`/`)?t.slice(0,-1):t}/shapes/${e}`}function O(e){t.a(t.r(t.s(e)))}var k=e=>e instanceof Error?e.message:String(e);async function A(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: ${k(t)}`),``}}async function j(e,t,n,r){try{await t.createPost(n,r)}catch(i){let a=[r.scriptId,r.thumbnailId].filter(e=>e!==``);throw await Promise.all(a.map(r=>t.deleteObject(n,r).catch(t=>e.onWarning?.(`orphaned object ${r}: ${k(t)}`)))),i}}var M=()=>globalThis.crypto.randomUUID();async function N(e,t){let n=e.gallery;if(!n)throw Error(b);let r=x(t.title);if(!r)throw Error("`title` is required");let{script:i}=await l(e,t);T(i),O(i);let a=E(n,{title:r,scriptId:``,description:x(t.description),prompt:x(t.prompt),keywords:t.keywords,published:t.published!==!1}),o=M(),s=await n.uploadScript(o,i),c=await A(e,n,o,i),u={...a,thumbnailId:c,scriptId:s};await j(e,n,o,u);let d=D(o,n.siteUrl),f=u.published?`Published`:`Saved as a draft (only the user can see it, under My models)`,p=c?``:` No thumbnail could be attached; the gallery shows a placeholder until the user edits the post.`;return{message:`${f}: "${u.title}" is at ${d}.${p}`,id:o,url:d,thumbnail:c!==``}}Object.defineProperty(exports,"S",{enumerable:!0,get:function(){return l}}),Object.defineProperty(exports,"_",{enumerable:!0,get:function(){return a}}),Object.defineProperty(exports,"a",{enumerable:!0,get:function(){return d}}),Object.defineProperty(exports,"b",{enumerable:!0,get:function(){return r}}),Object.defineProperty(exports,"c",{enumerable:!0,get:function(){return _}}),Object.defineProperty(exports,"d",{enumerable:!0,get:function(){return N}}),Object.defineProperty(exports,"f",{enumerable:!0,get:function(){return C}}),Object.defineProperty(exports,"g",{enumerable:!0,get:function(){return i}}),Object.defineProperty(exports,"h",{enumerable:!0,get:function(){return D}}),Object.defineProperty(exports,"i",{enumerable:!0,get:function(){return g}}),Object.defineProperty(exports,"l",{enumerable:!0,get:function(){return p}}),Object.defineProperty(exports,"m",{enumerable:!0,get:function(){return E}}),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 T}}),Object.defineProperty(exports,"r",{enumerable:!0,get:function(){return h}}),Object.defineProperty(exports,"s",{enumerable:!0,get:function(){return y}}),Object.defineProperty(exports,"t",{enumerable:!0,get:function(){return b}}),Object.defineProperty(exports,"u",{enumerable:!0,get:function(){return v}}),Object.defineProperty(exports,"v",{enumerable:!0,get:function(){return o}}),Object.defineProperty(exports,"x",{enumerable:!0,get:function(){return u}}),Object.defineProperty(exports,"y",{enumerable:!0,get:function(){return n}});
package/dist/core.cjs CHANGED
@@ -1 +1 @@
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._;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./samples-BO-oAFPZ.cjs"),t=require("./toThreeJS-CDRtoJt7.cjs"),n=require("./core-Z6twLrfC.cjs");exports.EXPORT_USDZ_DESCRIPTION=n.g,exports.EXPORT_USDZ_PROMPT=n._,exports.EXPORT_USDZ_SCHEMA=n.v,exports.EXPORT_USDZ_TOOL_NAME=n.y,exports.EXPORT_USDZ_TOOL_TIMEOUT_MS=n.b,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_OBJECT_CACHE_CONTROL=n.s,exports.SHAPE_POST_KEYS=n.c,exports.SHAPE_POST_LIMITS=n.l,exports.SHAPE_SCRIPT_CONTENT_TYPE=n.u,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.x,exports.executePresentShapeScript=e.o,exports.executePublishShapeScript=n.d,exports.executeShapeScriptDispatch=e.l,exports.isPresentableShapePath=e.f,exports.isShapeArtifactPath=e.p,exports.isShapeScriptDispatchArgs=t.Vn,exports.locateShape=e.u,exports.normalizeShapeKeywords=n.f,exports.parseShapeScript=t.s,exports.pluginCore=e.s,exports.presentShapeScript=e.c,exports.readLoadShapeResult=t.Hn,exports.readSaveShapeResult=t.Un,exports.requireScriptBytes=n.p,exports.resolveShapeSource=n.S,exports.samples=e.t,exports.sceneInfoOf=t.i,exports.sceneToUsdz=e.i,exports.shapeArtifactPath=e.m,exports.shapePostFrom=n.m,exports.shapePostUrl=n.h,exports.shapeScriptToUsdz=e.a,exports.toArtifactsRelative=e.g,exports.usdzArtifactPath=e._;
package/dist/core.js CHANGED
@@ -1,4 +1,4 @@
1
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
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
- 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 };
3
+ import { S as w, _ as T, a as E, b as D, c as O, d as k, f as A, g as j, h as M, i as N, l as P, m as F, n as I, o as L, p as R, r as z, s as B, t as V, u as H, v as U, x as W, y as G } from "./core-7JKG8RwN.js";
4
+ export { j as EXPORT_USDZ_DESCRIPTION, T as EXPORT_USDZ_PROMPT, U as EXPORT_USDZ_SCHEMA, G as EXPORT_USDZ_TOOL_NAME, D as EXPORT_USDZ_TOOL_TIMEOUT_MS, V as NOT_CONNECTED_MESSAGE, I as PUBLISH_DESCRIPTION, z as PUBLISH_PROMPT, N as PUBLISH_SCHEMA, E as PUBLISH_TOOL_NAME, r as SHAPE_EXTENSIONS, L as SHAPE_GALLERY_URL, B as SHAPE_OBJECT_CACHE_CONTROL, O as SHAPE_POST_KEYS, P as SHAPE_POST_LIMITS, H as SHAPE_SCRIPT_CONTENT_TYPE, g as TOOL_DEFINITION, _ as TOOL_NAME, l as USDZ_EXTENSION, f as USDZ_MIME_TYPE, S as astToThreeJS, W as executeExportShapeScriptUsdz, u as executePresentShapeScript, k as executePublishShapeScript, s as executeShapeScriptDispatch, i as isPresentableShapePath, d as isShapeArtifactPath, b as isShapeScriptDispatchArgs, h as locateShape, A as normalizeShapeKeywords, C as parseShapeScript, p as pluginCore, n as presentShapeScript, v as readLoadShapeResult, y as readSaveShapeResult, R as requireScriptBytes, w as resolveShapeSource, m as samples, x as sceneInfoOf, o as sceneToUsdz, c as shapeArtifactPath, F as shapePostFrom, M 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-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._;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./samples-BO-oAFPZ.cjs"),t=require("./toThreeJS-CDRtoJt7.cjs"),n=require("./core-Z6twLrfC.cjs");exports.EXPORT_USDZ_DESCRIPTION=n.g,exports.EXPORT_USDZ_PROMPT=n._,exports.EXPORT_USDZ_SCHEMA=n.v,exports.EXPORT_USDZ_TOOL_NAME=n.y,exports.EXPORT_USDZ_TOOL_TIMEOUT_MS=n.b,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_OBJECT_CACHE_CONTROL=n.s,exports.SHAPE_POST_KEYS=n.c,exports.SHAPE_POST_LIMITS=n.l,exports.SHAPE_SCRIPT_CONTENT_TYPE=n.u,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.x,exports.executePresentShapeScript=e.o,exports.executePublishShapeScript=n.d,exports.executeShapeScriptDispatch=e.l,exports.isPresentableShapePath=e.f,exports.isShapeArtifactPath=e.p,exports.isShapeScriptDispatchArgs=t.Vn,exports.locateShape=e.u,exports.normalizeShapeKeywords=n.f,exports.parseShapeScript=t.s,exports.pluginCore=e.s,exports.presentShapeScript=e.c,exports.readLoadShapeResult=t.Hn,exports.readSaveShapeResult=t.Un,exports.requireScriptBytes=n.p,exports.resolveShapeSource=n.S,exports.samples=e.t,exports.sceneInfoOf=t.i,exports.sceneToUsdz=e.i,exports.shapeArtifactPath=e.m,exports.shapePostFrom=n.m,exports.shapePostUrl=n.h,exports.shapeScriptToUsdz=e.a,exports.toArtifactsRelative=e.g,exports.usdzArtifactPath=e._;
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
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
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
- 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 };
3
+ import { S as w, _ as T, a as E, b as D, c as O, d as k, f as A, g as j, h as M, i as N, l as P, m as F, n as I, o as L, p as R, r as z, s as B, t as V, u as H, v as U, x as W, y as G } from "./core-7JKG8RwN.js";
4
+ export { j as EXPORT_USDZ_DESCRIPTION, T as EXPORT_USDZ_PROMPT, U as EXPORT_USDZ_SCHEMA, G as EXPORT_USDZ_TOOL_NAME, D as EXPORT_USDZ_TOOL_TIMEOUT_MS, V as NOT_CONNECTED_MESSAGE, I as PUBLISH_DESCRIPTION, z as PUBLISH_PROMPT, N as PUBLISH_SCHEMA, E as PUBLISH_TOOL_NAME, r as SHAPE_EXTENSIONS, L as SHAPE_GALLERY_URL, B as SHAPE_OBJECT_CACHE_CONTROL, O as SHAPE_POST_KEYS, P as SHAPE_POST_LIMITS, H as SHAPE_SCRIPT_CONTENT_TYPE, g as TOOL_DEFINITION, _ as TOOL_NAME, l as USDZ_EXTENSION, f as USDZ_MIME_TYPE, S as astToThreeJS, W as executeExportShapeScriptUsdz, u as executePresentShapeScript, k as executePublishShapeScript, s as executeShapeScriptDispatch, i as isPresentableShapePath, d as isShapeArtifactPath, b as isShapeScriptDispatchArgs, h as locateShape, A as normalizeShapeKeywords, C as parseShapeScript, p as pluginCore, n as presentShapeScript, v as readLoadShapeResult, y as readSaveShapeResult, R as requireScriptBytes, w as resolveShapeSource, m as samples, x as sceneInfoOf, o as sceneToUsdz, c as shapeArtifactPath, F as shapePostFrom, M as shapePostUrl, t as shapeScriptToUsdz, a as toArtifactsRelative, e as usdzArtifactPath };
@@ -2,7 +2,7 @@ export { renderShapeScriptSheet, RenderUnavailableError, CHROMIUM_HINT, RENDER_T
2
2
  export type { RenderShapeScriptOptions } from "./renderer";
3
3
  export { buildRenderPage, gridFor } from "./page";
4
4
  export type { ViewAngle, RenderPageOptions } from "./page";
5
- export { executeRenderShapeScript, viewAngles, RENDER_SHAPE_SCRIPT_TOOL_NAME, RENDER_SHAPE_SCRIPT_DESCRIPTION, RENDER_SHAPE_SCRIPT_PROMPT, RENDER_SHAPE_SCRIPT_SCHEMA, RENDER_TOOL_TIMEOUT_MS, renderOptionsFrom, savedMessage, } from "./tool";
5
+ export { executeRenderShapeScript, viewAngles, RENDER_SHAPE_SCRIPT_TOOL_NAME, RENDER_SHAPE_SCRIPT_DESCRIPTION, RENDER_SHAPE_SCRIPT_PROMPT, RENDER_SHAPE_SCRIPT_SCHEMA, RENDER_TOOL_TIMEOUT_MS, PUBLISH_TOOL_TIMEOUT_MS, renderOptionsFrom, savedMessage, } from "./tool";
6
6
  export type { RenderToolDeps, RenderToolResult } from "./tool";
7
7
  export { renderShapeThumbnail } from "./thumbnail";
8
8
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/render/index.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,sBAAsB,EAAE,sBAAsB,EAAE,aAAa,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AACnJ,YAAY,EAAE,wBAAwB,EAAE,MAAM,YAAY,CAAC;AAC3D,OAAO,EAAE,eAAe,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAClD,YAAY,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,QAAQ,CAAC;AAC3D,OAAO,EACL,wBAAwB,EACxB,UAAU,EACV,6BAA6B,EAC7B,+BAA+B,EAC/B,0BAA0B,EAC1B,0BAA0B,EAC1B,sBAAsB,EACtB,iBAAiB,EACjB,YAAY,GACb,MAAM,QAAQ,CAAC;AAChB,YAAY,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,QAAQ,CAAC;AAC/D,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/render/index.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,sBAAsB,EAAE,sBAAsB,EAAE,aAAa,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AACnJ,YAAY,EAAE,wBAAwB,EAAE,MAAM,YAAY,CAAC;AAC3D,OAAO,EAAE,eAAe,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAClD,YAAY,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,QAAQ,CAAC;AAC3D,OAAO,EACL,wBAAwB,EACxB,UAAU,EACV,6BAA6B,EAC7B,+BAA+B,EAC/B,0BAA0B,EAC1B,0BAA0B,EAC1B,sBAAsB,EACtB,uBAAuB,EACvB,iBAAiB,EACjB,YAAY,GACb,MAAM,QAAQ,CAAC;AAChB,YAAY,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,QAAQ,CAAC;AAC/D,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC"}
@@ -4,6 +4,12 @@ import type { ViewAngle } from "./page";
4
4
  * the scene and writing the PNG. A transport sized to the render alone aborts a
5
5
  * call that was about to succeed. */
6
6
  export declare const RENDER_TOOL_TIMEOUT_MS: number;
7
+ /** Milliseconds a host must allow `publishShapeScript`: the thumbnail render
8
+ * above, plus the two Storage uploads — the script may be 10 MiB on a slow
9
+ * link. A transport sized to the render alone aborts the caller while the
10
+ * uploads and the document write go on, so the post lands after the user was
11
+ * told it failed. */
12
+ export declare const PUBLISH_TOOL_TIMEOUT_MS: number;
7
13
  export declare const RENDER_SHAPE_SCRIPT_TOOL_NAME = "renderShapeScript";
8
14
  export declare const RENDER_SHAPE_SCRIPT_DESCRIPTION = "Render a ShapeScript model to a PNG image and save it, so you can LOOK at the model you wrote and check it before showing it to the user. Returns the image path \u2014 read that file to see the result. By default it renders four camera angles onto one sheet, because a single view cannot settle what is in front of what. Takes the same source as presentShapeScript: inline `script`, or `path` to a saved .shape file.";
9
15
  export declare const RENDER_SHAPE_SCRIPT_PROMPT = "Use renderShapeScript to CHECK a 3D model you wrote before presenting it \u2014 it saves a PNG and returns the path, which you then read to see what the model actually looks like. Fix what you see and re-render. Rendering needs a local headless browser; if it reports one is missing, say so and continue with presentShapeScript rather than retrying.";
@@ -1 +1 @@
1
- {"version":3,"file":"tool.d.ts","sourceRoot":"","sources":["../../src/render/tool.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AAcxC;;;sCAGsC;AACtC,eAAO,MAAM,sBAAsB,QAA4B,CAAC;AAEhE,eAAO,MAAM,6BAA6B,sBAAsB,CAAC;AAEjE,eAAO,MAAM,+BAA+B,qaACmX,CAAC;AAEha,eAAO,MAAM,0BAA0B,kWACqT,CAAC;AAE7V;2DAC2D;AAC3D,eAAO,MAAM,0BAA0B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cA2CrB,MAAM,EAAE;CACzB,CAAC;AAcF;;;;;;;GAOG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAG,SAAS,EAAE,CAa3F;AAED,2EAA2E;AAC3E,MAAM,WAAW,cAAc;IAC7B;;qBAEiB;IACjB,SAAS,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IAC7C;;6CAEyC;IACzC,SAAS,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IAC/C;;yBAEqB;IACrB,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACvC;AAWD;;;;;;;;;2CAS2C;AAC3C,MAAM,WAAW,gBAAgB;IAC/B,2EAA2E;IAC3E,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED;;;;;;GAMG;AACH;2EAC2E;AAC3E,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,SAAS,EAAE,EAAE,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI;0BAAf,MAAM,KAAK,IAAI;;;;;;;EAUlJ;AAED;;gEAEgE;AAChE,wBAAgB,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,SAAS,EAAE,GAAG,MAAM,CAInF;AAED,wBAAsB,wBAAwB,CAAC,IAAI,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAiB7H"}
1
+ {"version":3,"file":"tool.d.ts","sourceRoot":"","sources":["../../src/render/tool.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AAcxC;;;sCAGsC;AACtC,eAAO,MAAM,sBAAsB,QAA4B,CAAC;AAEhE;;;;sBAIsB;AACtB,eAAO,MAAM,uBAAuB,QAAkC,CAAC;AAEvE,eAAO,MAAM,6BAA6B,sBAAsB,CAAC;AAEjE,eAAO,MAAM,+BAA+B,qaACmX,CAAC;AAEha,eAAO,MAAM,0BAA0B,kWACqT,CAAC;AAE7V;2DAC2D;AAC3D,eAAO,MAAM,0BAA0B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cA2CrB,MAAM,EAAE;CACzB,CAAC;AAcF;;;;;;;GAOG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAG,SAAS,EAAE,CAa3F;AAED,2EAA2E;AAC3E,MAAM,WAAW,cAAc;IAC7B;;qBAEiB;IACjB,SAAS,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IAC7C;;6CAEyC;IACzC,SAAS,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IAC/C;;yBAEqB;IACrB,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACvC;AAWD;;;;;;;;;2CAS2C;AAC3C,MAAM,WAAW,gBAAgB;IAC/B,2EAA2E;IAC3E,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED;;;;;;GAMG;AACH;2EAC2E;AAC3E,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,SAAS,EAAE,EAAE,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI;0BAAf,MAAM,KAAK,IAAI;;;;;;;EAUlJ;AAED;;gEAEgE;AAChE,wBAAgB,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,SAAS,EAAE,GAAG,MAAM,CAInF;AAED,wBAAsB,wBAAwB,CAAC,IAAI,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAiB7H"}
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-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)};
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 m(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};
@@ -40,7 +40,7 @@ scene.add(headlight, fill, new AmbientLight(0xffffff, 0.9));
40
40
  const floor = new GridHelper(radius * 4, 12, 0xc0c0c0, 0xe4e4e4);
41
41
  floor.position.y = bounds.min.y;
42
42
  scene.add(floor);
43
- `}function m(){return`
43
+ `}function h(){return`
44
44
  const aspect = config.width / config.height;
45
45
  const distance = (radius * 3.2) / Math.max(config.zoom, 0.01);
46
46
 
@@ -77,10 +77,10 @@ config.views.forEach((angle, index) => {
77
77
  });
78
78
 
79
79
  renderer.dispose();
80
- window.__shapeSheet = sheet.toDataURL("image/png");`}function h(e){let{threeUrl:t,sceneJson:n,views:r,width:i,height:a,zoom:o,projection:s}=e;return`<!doctype html>
80
+ window.__shapeSheet = sheet.toDataURL("image/png");`}function g(e){let{threeUrl:t,sceneJson:n,views:r,width:i,height:a,zoom:o,projection:s}=e;return`<!doctype html>
81
81
  <meta charset="utf-8">
82
82
  <style>html,body{margin:0;background:#ffffff}</style>
83
83
  <canvas id="sheet"></canvas>
84
84
  <script type="module">
85
- ${`${ee(t,JSON.stringify({views:r,width:i,height:a,zoom:o,projection:s,scene:n}),JSON.stringify(p(r.length)))}\n${m()}`}
86
- <\/script>`}var g=1e3;function _(e){return e instanceof Error?e.message:String(e)}var v=60*g,y=30*g,b=9e4,x="renderShapeScript needs Puppeteer's headless Chromium, which this host does not have. Run `npx puppeteer browsers install chrome`, then retry. Everything else, including presentShapeScript, works without it.",S=class extends Error{};function C(e,t){try{e?.(t)}catch{}}function w(){let e={}.url;if(typeof e==`string`&&e.length>0)return e;if(typeof __filename==`string`)return(0,d.pathToFileURL)(__filename).href;throw Error(`shapescript render: cannot locate this module to resolve three from`)}var T=(0,u.createRequire)(w());function E(e){return c.Bn(e)&&typeof e.launch==`function`}async function D(){try{let e=await import(`puppeteer`);return E(e)?e:c.Bn(e)&&E(e.default)?e.default:null}catch{return null}}function O(){try{return(0,u.createRequire)(T.resolve(`@mulmoclaude/shapescript-plugin/package.json`))}catch{return T}}function te(){let e=O().resolve(`three`);return e.endsWith(`three.cjs`)?e.replace(/three\.cjs$/,`three.module.js`):e}var k=`https://shapescript.invalid`,A=`${k}/render.html`,j=`./three.module.js`;async function M(e,t,n){let r;try{r=new URL(e)}catch{return null}if(r.origin!==k)return null;let i=f.default.posix.basename(r.pathname);return i===`render.html`?{contentType:`text/html; charset=utf-8`,body:t}:/^three[\w.-]*\.js$/.test(i)?{contentType:`text/javascript; charset=utf-8`,body:await(0,l.readFile)(f.default.join(n,i),`utf-8`)}:null}async function N(e,t){let n=f.default.dirname(te());await e.setRequestInterception(!0),e.on(`request`,e=>{(async()=>{try{let r=await M(e.url(),t,n);await(r?e.respond({status:200,...r}):e.abort())}catch{}})()})}async function P(e){let t=await D();if(!t)throw new S(x);let n=c.r(c.s(e.script)).toJSON(),r=h({...e,threeUrl:j,sceneJson:n}),i;try{i=await t.launch({headless:!0,timeout:y,args:[`--enable-unsafe-swiftshader`,`--use-gl=swiftshader`]})}catch(e){throw new S(`${x} (launch failed: ${_(e)})`)}try{let e=await i.newPage();await e.setViewport({width:800,height:600});let t=[];e.on(`pageerror`,e=>t.push(e.message)),await N(e,r),await e.goto(A,{waitUntil:`load`});try{await e.waitForFunction(`typeof window.__shapeSheet === 'string'`,{timeout:v})}catch(e){let n=t.length>0?`the render page failed: ${t.join(`; `)}`:_(e);throw Error(n,{cause:e})}let n=await e.evaluate(`window.__shapeSheet`);if(typeof n!=`string`||!n.startsWith(`data:image/png;base64,`))throw Error(`the render page produced no image`);return n.slice(22)}finally{await i.close().catch(t=>C(e.onWarning,`chromium close failed: ${_(t)}`))}}var F=30,I=25,ne=1,L=480,R=900,z=160,B=85,V=b+3e4,H=`renderShapeScript`,U="Render a ShapeScript model to a PNG image and save it, so you can LOOK at the model you wrote and check it before showing it to the user. Returns the image path — read that file to see the result. By default it renders four camera angles onto one sheet, because a single view cannot settle what is in front of what. Takes the same source as presentShapeScript: inline `script`, or `path` to a saved .shape file.",W=`Use renderShapeScript to CHECK a 3D model you wrote before presenting it — it saves a PNG and returns the path, which you then read to see what the model actually looks like. Fix what you see and re-render. Rendering needs a local headless browser; if it reports one is missing, say so and continue with presentShapeScript rather than retrying.`,G={type:`object`,properties:{script:{type:`string`,description:"ShapeScript source to render. Provide either this or `path`, not both."},path:{type:`string`,description:`Path to an existing .shape file to render (e.g. one presentShapeScript saved under artifacts/shapes/).`},azimuth:{type:`number`,description:`Camera rotation around the model in degrees, 0 = looking from +Z. Default ${F}. In the default four-view sheet this is the FIRST view's angle; the others are offset from it.`},elevation:{type:`number`,description:`Camera height in degrees above the horizon, 90 = straight down. Default ${I}. Avoid 0 and 90 for the main view — an axis-aligned shot flattens depth.`},zoom:{type:`number`,description:`Multiplier on the automatic framing, which fits the whole model. 1 = fit (default), 2 = twice as close, 0.5 = further out. Prefer this over guessing a camera distance: it means the same thing at any model scale.`},views:{type:`string`,enum:[`quad`,`single`],description:"`quad` (default) renders four angles on one sheet — use it to judge shape and layout. `single` renders only `azimuth`/`elevation`, for a close look at one detail."},projection:{type:`string`,enum:[`perspective`,`orthographic`],description:"`perspective` (default) looks natural; `orthographic` keeps parallel edges parallel, which is better for comparing proportions."},width:{type:`number`,description:`Pixel width of ONE view. Default ${L}, clamped to ${z}–${R}.`},height:{type:`number`,description:`Pixel height of ONE view. Default ${L}, clamped to ${z}–${R}.`}},required:[]};function K(e,t){return typeof e!=`number`||!Number.isFinite(e)?t:Math.min(R,Math.max(z,Math.round(e)))}function q(e,t){return typeof e==`number`&&Number.isFinite(e)?e:t}var J=e=>`${Math.round(e)}°`;function Y(e,t,n){let r=(e,t,n)=>({azimuth:e,elevation:t,label:`${n} — az ${J(e)}, el ${J(t)}`});return n?[r(e,t,`view`)]:[r(e,t,`front-right`),r(e+90,t,`back-right`),r(e+180,t,`back-left`),r(e,B,`top`)]}async function X(e,t){let n=typeof t.script==`string`&&t.script.trim()!==``?t.script:void 0,r=typeof t.path==`string`&&t.path.trim()!==``?t.path:void 0;if(n&&r)throw Error("Provide either `script` or `path`, not both");if(n)return n;if(r)return e.readShape(r);throw Error("Provide either `script` (inline source) or `path` (an existing .shape file)")}function Z(e,t,n,r){return{script:t,views:n,width:K(e.width,L),height:K(e.height,L),zoom:Math.max(q(e.zoom,ne),.01),projection:e.projection===`orthographic`?`orthographic`:`perspective`,...r?{onWarning:r}:{}}}function Q(e,t){let n=t.map(e=>e.label).join(`; `);return`Saved render to ${e} (${t.length===1?`1 view`:`${t.length} views`}: ${n}). Read that file to see the model.`}async function re(e,t){let n=await X(e,t),r=Y(q(t.azimuth,F),q(t.elevation,I),t.views===`single`);try{let i=await P(Z(t,n,r,e.onWarning));return{message:Q(await e.saveImage(i),r),rendered:!0}}catch(t){if(t instanceof S)return C(e.onWarning,`renderShapeScript: unavailable — ${t.message}`),{message:t.message,rendered:!1};throw t}}var $=640,ie=480,ae=30,oe=25;async function se(e,t){try{let n=await P({script:e,views:[{azimuth:ae,elevation:oe,label:``}],width:$,height:ie,zoom:1,projection:`perspective`,...t?{onWarning:t}:{}});return new Uint8Array(Buffer.from(n,`base64`))}catch(e){if(e instanceof S)return null;throw e}}exports.CHROMIUM_HINT=x,exports.LAUNCH_TIMEOUT_MS=y,exports.RENDER_BUDGET_MS=b,exports.RENDER_SHAPE_SCRIPT_DESCRIPTION=U,exports.RENDER_SHAPE_SCRIPT_PROMPT=W,exports.RENDER_SHAPE_SCRIPT_SCHEMA=G,exports.RENDER_SHAPE_SCRIPT_TOOL_NAME=H,exports.RENDER_TIMEOUT_MS=v,exports.RENDER_TOOL_TIMEOUT_MS=V,exports.RenderUnavailableError=S,exports.buildRenderPage=h,exports.executeRenderShapeScript=re,exports.gridFor=p,exports.renderOptionsFrom=Z,exports.renderShapeScriptSheet=P,exports.renderShapeThumbnail=se,exports.savedMessage=Q,exports.viewAngles=Y;
85
+ ${`${m(t,JSON.stringify({views:r,width:i,height:a,zoom:o,projection:s,scene:n}),JSON.stringify(p(r.length)))}\n${h()}`}
86
+ <\/script>`}var _=1e3;function v(e){return e instanceof Error?e.message:String(e)}var y=60*_,b=30*_,x=9e4,S="renderShapeScript needs Puppeteer's headless Chromium, which this host does not have. Run `npx puppeteer browsers install chrome`, then retry. Everything else, including presentShapeScript, works without it.",C=class extends Error{};function w(e,t){try{e?.(t)}catch{}}function T(){let e={}.url;if(typeof e==`string`&&e.length>0)return e;if(typeof __filename==`string`)return(0,d.pathToFileURL)(__filename).href;throw Error(`shapescript render: cannot locate this module to resolve three from`)}var E=(0,u.createRequire)(T());function D(e){return c.Bn(e)&&typeof e.launch==`function`}async function ee(){try{let e=await import(`puppeteer`);return D(e)?e:c.Bn(e)&&D(e.default)?e.default:null}catch{return null}}function O(){try{return(0,u.createRequire)(E.resolve(`@mulmoclaude/shapescript-plugin/package.json`))}catch{return E}}function k(){let e=O().resolve(`three`);return e.endsWith(`three.cjs`)?e.replace(/three\.cjs$/,`three.module.js`):e}var A=`https://shapescript.invalid`,j=`${A}/render.html`,M=`./three.module.js`;async function N(e,t,n){let r;try{r=new URL(e)}catch{return null}if(r.origin!==A)return null;let i=f.default.posix.basename(r.pathname);return i===`render.html`?{contentType:`text/html; charset=utf-8`,body:t}:/^three[\w.-]*\.js$/.test(i)?{contentType:`text/javascript; charset=utf-8`,body:await(0,l.readFile)(f.default.join(n,i),`utf-8`)}:null}async function P(e,t){let n=f.default.dirname(k());await e.setRequestInterception(!0),e.on(`request`,e=>{(async()=>{try{let r=await N(e.url(),t,n);await(r?e.respond({status:200,...r}):e.abort())}catch{}})()})}async function F(e){let t=await ee();if(!t)throw new C(S);let n=c.r(c.s(e.script)).toJSON(),r=g({...e,threeUrl:M,sceneJson:n}),i;try{i=await t.launch({headless:!0,timeout:b,args:[`--enable-unsafe-swiftshader`,`--use-gl=swiftshader`]})}catch(e){throw new C(`${S} (launch failed: ${v(e)})`)}try{let e=await i.newPage();await e.setViewport({width:800,height:600});let t=[];e.on(`pageerror`,e=>t.push(e.message)),await P(e,r),await e.goto(j,{waitUntil:`load`});try{await e.waitForFunction(`typeof window.__shapeSheet === 'string'`,{timeout:y})}catch(e){let n=t.length>0?`the render page failed: ${t.join(`; `)}`:v(e);throw Error(n,{cause:e})}let n=await e.evaluate(`window.__shapeSheet`);if(typeof n!=`string`||!n.startsWith(`data:image/png;base64,`))throw Error(`the render page produced no image`);return n.slice(22)}finally{await i.close().catch(t=>w(e.onWarning,`chromium close failed: ${v(t)}`))}}var I=30,L=25,te=1,R=480,z=900,B=160,V=85,H=x+3e4,U=H+6e4,W=`renderShapeScript`,G="Render a ShapeScript model to a PNG image and save it, so you can LOOK at the model you wrote and check it before showing it to the user. Returns the image path — read that file to see the result. By default it renders four camera angles onto one sheet, because a single view cannot settle what is in front of what. Takes the same source as presentShapeScript: inline `script`, or `path` to a saved .shape file.",K=`Use renderShapeScript to CHECK a 3D model you wrote before presenting it — it saves a PNG and returns the path, which you then read to see what the model actually looks like. Fix what you see and re-render. Rendering needs a local headless browser; if it reports one is missing, say so and continue with presentShapeScript rather than retrying.`,q={type:`object`,properties:{script:{type:`string`,description:"ShapeScript source to render. Provide either this or `path`, not both."},path:{type:`string`,description:`Path to an existing .shape file to render (e.g. one presentShapeScript saved under artifacts/shapes/).`},azimuth:{type:`number`,description:`Camera rotation around the model in degrees, 0 = looking from +Z. Default ${I}. In the default four-view sheet this is the FIRST view's angle; the others are offset from it.`},elevation:{type:`number`,description:`Camera height in degrees above the horizon, 90 = straight down. Default ${L}. Avoid 0 and 90 for the main view — an axis-aligned shot flattens depth.`},zoom:{type:`number`,description:`Multiplier on the automatic framing, which fits the whole model. 1 = fit (default), 2 = twice as close, 0.5 = further out. Prefer this over guessing a camera distance: it means the same thing at any model scale.`},views:{type:`string`,enum:[`quad`,`single`],description:"`quad` (default) renders four angles on one sheet — use it to judge shape and layout. `single` renders only `azimuth`/`elevation`, for a close look at one detail."},projection:{type:`string`,enum:[`perspective`,`orthographic`],description:"`perspective` (default) looks natural; `orthographic` keeps parallel edges parallel, which is better for comparing proportions."},width:{type:`number`,description:`Pixel width of ONE view. Default ${R}, clamped to ${B}–${z}.`},height:{type:`number`,description:`Pixel height of ONE view. Default ${R}, clamped to ${B}–${z}.`}},required:[]};function J(e,t){return typeof e!=`number`||!Number.isFinite(e)?t:Math.min(z,Math.max(B,Math.round(e)))}function Y(e,t){return typeof e==`number`&&Number.isFinite(e)?e:t}var X=e=>`${Math.round(e)}°`;function Z(e,t,n){let r=(e,t,n)=>({azimuth:e,elevation:t,label:`${n} — az ${X(e)}, el ${X(t)}`});return n?[r(e,t,`view`)]:[r(e,t,`front-right`),r(e+90,t,`back-right`),r(e+180,t,`back-left`),r(e,V,`top`)]}async function ne(e,t){let n=typeof t.script==`string`&&t.script.trim()!==``?t.script:void 0,r=typeof t.path==`string`&&t.path.trim()!==``?t.path:void 0;if(n&&r)throw Error("Provide either `script` or `path`, not both");if(n)return n;if(r)return e.readShape(r);throw Error("Provide either `script` (inline source) or `path` (an existing .shape file)")}function Q(e,t,n,r){return{script:t,views:n,width:J(e.width,R),height:J(e.height,R),zoom:Math.max(Y(e.zoom,te),.01),projection:e.projection===`orthographic`?`orthographic`:`perspective`,...r?{onWarning:r}:{}}}function $(e,t){let n=t.map(e=>e.label).join(`; `);return`Saved render to ${e} (${t.length===1?`1 view`:`${t.length} views`}: ${n}). Read that file to see the model.`}async function re(e,t){let n=await ne(e,t),r=Z(Y(t.azimuth,I),Y(t.elevation,L),t.views===`single`);try{let i=await F(Q(t,n,r,e.onWarning));return{message:$(await e.saveImage(i),r),rendered:!0}}catch(t){if(t instanceof C)return w(e.onWarning,`renderShapeScript: unavailable — ${t.message}`),{message:t.message,rendered:!1};throw t}}var ie=640,ae=480,oe=30,se=25;async function ce(e,t){try{let n=await F({script:e,views:[{azimuth:oe,elevation:se,label:``}],width:ie,height:ae,zoom:1,projection:`perspective`,...t?{onWarning:t}:{}});return new Uint8Array(Buffer.from(n,`base64`))}catch(e){if(e instanceof C)return null;throw e}}exports.CHROMIUM_HINT=S,exports.LAUNCH_TIMEOUT_MS=b,exports.PUBLISH_TOOL_TIMEOUT_MS=U,exports.RENDER_BUDGET_MS=x,exports.RENDER_SHAPE_SCRIPT_DESCRIPTION=G,exports.RENDER_SHAPE_SCRIPT_PROMPT=K,exports.RENDER_SHAPE_SCRIPT_SCHEMA=q,exports.RENDER_SHAPE_SCRIPT_TOOL_NAME=W,exports.RENDER_TIMEOUT_MS=y,exports.RENDER_TOOL_TIMEOUT_MS=H,exports.RenderUnavailableError=C,exports.buildRenderPage=g,exports.executeRenderShapeScript=re,exports.gridFor=p,exports.renderOptionsFrom=Q,exports.renderShapeScriptSheet=F,exports.renderShapeThumbnail=ce,exports.savedMessage=$,exports.viewAngles=Z;
package/dist/render.js CHANGED
@@ -189,7 +189,7 @@ async function A(e) {
189
189
  }
190
190
  //#endregion
191
191
  //#region src/render/tool.ts
192
- var j = 30, M = 25, N = 1, P = 480, F = 900, I = 160, L = 85, R = h + 3e4, z = "renderShapeScript", B = "Render a ShapeScript model to a PNG image and save it, so you can LOOK at the model you wrote and check it before showing it to the user. Returns the image path — read that file to see the result. By default it renders four camera angles onto one sheet, because a single view cannot settle what is in front of what. Takes the same source as presentShapeScript: inline `script`, or `path` to a saved .shape file.", V = "Use renderShapeScript to CHECK a 3D model you wrote before presenting it — it saves a PNG and returns the path, which you then read to see what the model actually looks like. Fix what you see and re-render. Rendering needs a local headless browser; if it reports one is missing, say so and continue with presentShapeScript rather than retrying.", H = {
192
+ var j = 30, M = 25, N = 1, P = 480, F = 900, I = 160, L = 85, R = h + 3e4, z = R + 6e4, B = "renderShapeScript", V = "Render a ShapeScript model to a PNG image and save it, so you can LOOK at the model you wrote and check it before showing it to the user. Returns the image path — read that file to see the result. By default it renders four camera angles onto one sheet, because a single view cannot settle what is in front of what. Takes the same source as presentShapeScript: inline `script`, or `path` to a saved .shape file.", H = "Use renderShapeScript to CHECK a 3D model you wrote before presenting it — it saves a PNG and returns the path, which you then read to see what the model actually looks like. Fix what you see and re-render. Rendering needs a local headless browser; if it reports one is missing, say so and continue with presentShapeScript rather than retrying.", U = {
193
193
  type: "object",
194
194
  properties: {
195
195
  script: {
@@ -233,18 +233,18 @@ var j = 30, M = 25, N = 1, P = 480, F = 900, I = 160, L = 85, R = h + 3e4, z = "
233
233
  },
234
234
  required: []
235
235
  };
236
- function U(e, t) {
236
+ function W(e, t) {
237
237
  return typeof e != "number" || !Number.isFinite(e) ? t : Math.min(F, Math.max(I, Math.round(e)));
238
238
  }
239
- function W(e, t) {
239
+ function G(e, t) {
240
240
  return typeof e == "number" && Number.isFinite(e) ? e : t;
241
241
  }
242
- var G = (e) => `${Math.round(e)}°`;
243
- function K(e, t, n) {
242
+ var K = (e) => `${Math.round(e)}°`;
243
+ function q(e, t, n) {
244
244
  let r = (e, t, n) => ({
245
245
  azimuth: e,
246
246
  elevation: t,
247
- label: `${n} — az ${G(e)}, el ${G(t)}`
247
+ label: `${n} — az ${K(e)}, el ${K(t)}`
248
248
  });
249
249
  return n ? [r(e, t, "view")] : [
250
250
  r(e, t, "front-right"),
@@ -253,34 +253,34 @@ function K(e, t, n) {
253
253
  r(e, L, "top")
254
254
  ];
255
255
  }
256
- async function q(e, t) {
256
+ async function J(e, t) {
257
257
  let n = typeof t.script == "string" && t.script.trim() !== "" ? t.script : void 0, r = typeof t.path == "string" && t.path.trim() !== "" ? t.path : void 0;
258
258
  if (n && r) throw Error("Provide either `script` or `path`, not both");
259
259
  if (n) return n;
260
260
  if (r) return e.readShape(r);
261
261
  throw Error("Provide either `script` (inline source) or `path` (an existing .shape file)");
262
262
  }
263
- function J(e, t, n, r) {
263
+ function Y(e, t, n, r) {
264
264
  return {
265
265
  script: t,
266
266
  views: n,
267
- width: U(e.width, P),
268
- height: U(e.height, P),
269
- zoom: Math.max(W(e.zoom, N), .01),
267
+ width: W(e.width, P),
268
+ height: W(e.height, P),
269
+ zoom: Math.max(G(e.zoom, N), .01),
270
270
  projection: e.projection === "orthographic" ? "orthographic" : "perspective",
271
271
  ...r ? { onWarning: r } : {}
272
272
  };
273
273
  }
274
- function Y(e, t) {
274
+ function X(e, t) {
275
275
  let n = t.map((e) => e.label).join("; ");
276
276
  return `Saved render to ${e} (${t.length === 1 ? "1 view" : `${t.length} views`}: ${n}). Read that file to see the model.`;
277
277
  }
278
- async function X(e, t) {
279
- let n = await q(e, t), r = K(W(t.azimuth, j), W(t.elevation, M), t.views === "single");
278
+ async function Z(e, t) {
279
+ let n = await J(e, t), r = q(G(t.azimuth, j), G(t.elevation, M), t.views === "single");
280
280
  try {
281
- let i = await A(J(t, n, r, e.onWarning));
281
+ let i = await A(Y(t, n, r, e.onWarning));
282
282
  return {
283
- message: Y(await e.saveImage(i), r),
283
+ message: X(await e.saveImage(i), r),
284
284
  rendered: !0
285
285
  };
286
286
  } catch (t) {
@@ -293,18 +293,18 @@ async function X(e, t) {
293
293
  }
294
294
  //#endregion
295
295
  //#region src/render/thumbnail.ts
296
- var Z = 640, Q = 480, $ = 30, ee = 25;
297
- async function te(e, t) {
296
+ var Q = 640, $ = 480, ee = 30, te = 25;
297
+ async function ne(e, t) {
298
298
  try {
299
299
  let n = await A({
300
300
  script: e,
301
301
  views: [{
302
- azimuth: $,
303
- elevation: ee,
302
+ azimuth: ee,
303
+ elevation: te,
304
304
  label: ""
305
305
  }],
306
- width: Z,
307
- height: Q,
306
+ width: Q,
307
+ height: $,
308
308
  zoom: 1,
309
309
  projection: "perspective",
310
310
  ...t ? { onWarning: t } : {}
@@ -316,4 +316,4 @@ async function te(e, t) {
316
316
  }
317
317
  }
318
318
  //#endregion
319
- export { g as CHROMIUM_HINT, m as LAUNCH_TIMEOUT_MS, h as RENDER_BUDGET_MS, B as RENDER_SHAPE_SCRIPT_DESCRIPTION, V as RENDER_SHAPE_SCRIPT_PROMPT, H as RENDER_SHAPE_SCRIPT_SCHEMA, z as RENDER_SHAPE_SCRIPT_TOOL_NAME, p as RENDER_TIMEOUT_MS, R as RENDER_TOOL_TIMEOUT_MS, _ as RenderUnavailableError, u as buildRenderPage, X as executeRenderShapeScript, s as gridFor, J as renderOptionsFrom, A as renderShapeScriptSheet, te as renderShapeThumbnail, Y as savedMessage, K as viewAngles };
319
+ export { g as CHROMIUM_HINT, m as LAUNCH_TIMEOUT_MS, z as PUBLISH_TOOL_TIMEOUT_MS, h as RENDER_BUDGET_MS, V as RENDER_SHAPE_SCRIPT_DESCRIPTION, H as RENDER_SHAPE_SCRIPT_PROMPT, U as RENDER_SHAPE_SCRIPT_SCHEMA, B as RENDER_SHAPE_SCRIPT_TOOL_NAME, p as RENDER_TIMEOUT_MS, R as RENDER_TOOL_TIMEOUT_MS, _ as RenderUnavailableError, u as buildRenderPage, Z as executeRenderShapeScript, s as gridFor, Y as renderOptionsFrom, A as renderShapeScriptSheet, ne as renderShapeThumbnail, X as savedMessage, q as viewAngles };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mulmoclaude/shapescript-plugin",
3
- "version": "2.8.0",
3
+ "version": "3.0.0",
4
4
  "description": "presentShapeScript — interactive 3D visualizations authored in the ShapeScript language (parser + Three.js renderer). Core (tool definition + execute) on `.`, Vue View/Preview on `./vue`.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1 +0,0 @@
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}});