sketchmark 2.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.
Files changed (64) hide show
  1. package/README.md +188 -0
  2. package/bin/sketchmark.cjs +2008 -0
  3. package/dist/src/builders/index.d.ts +74 -0
  4. package/dist/src/builders/index.js +230 -0
  5. package/dist/src/compounds.d.ts +13 -0
  6. package/dist/src/compounds.js +118 -0
  7. package/dist/src/deck.d.ts +4 -0
  8. package/dist/src/deck.js +91 -0
  9. package/dist/src/diagnostics.d.ts +5 -0
  10. package/dist/src/diagnostics.js +113 -0
  11. package/dist/src/export/index.d.ts +8 -0
  12. package/dist/src/export/index.js +15 -0
  13. package/dist/src/index.d.ts +19 -0
  14. package/dist/src/index.js +35 -0
  15. package/dist/src/kernel.d.ts +8 -0
  16. package/dist/src/kernel.js +68 -0
  17. package/dist/src/normalize.d.ts +6 -0
  18. package/dist/src/normalize.js +191 -0
  19. package/dist/src/patch.d.ts +5 -0
  20. package/dist/src/patch.js +72 -0
  21. package/dist/src/path-sampling.d.ts +3 -0
  22. package/dist/src/path-sampling.js +275 -0
  23. package/dist/src/player/index.d.ts +68 -0
  24. package/dist/src/player/index.js +600 -0
  25. package/dist/src/project.d.ts +11 -0
  26. package/dist/src/project.js +107 -0
  27. package/dist/src/render/html.d.ts +2 -0
  28. package/dist/src/render/html.js +13 -0
  29. package/dist/src/render/raw-three.d.ts +7 -0
  30. package/dist/src/render/raw-three.js +17 -0
  31. package/dist/src/render/svg.d.ts +3 -0
  32. package/dist/src/render/svg.js +277 -0
  33. package/dist/src/render/three-html.d.ts +2 -0
  34. package/dist/src/render/three-html.js +303 -0
  35. package/dist/src/render/three-preview-svg.d.ts +3 -0
  36. package/dist/src/render/three-preview-svg.js +102 -0
  37. package/dist/src/scenes.d.ts +4 -0
  38. package/dist/src/scenes.js +25 -0
  39. package/dist/src/schema.d.ts +2 -0
  40. package/dist/src/schema.js +403 -0
  41. package/dist/src/sequences.d.ts +43 -0
  42. package/dist/src/sequences.js +109 -0
  43. package/dist/src/shapes/builtins.d.ts +2 -0
  44. package/dist/src/shapes/builtins.js +429 -0
  45. package/dist/src/shapes/common.d.ts +9 -0
  46. package/dist/src/shapes/common.js +75 -0
  47. package/dist/src/shapes/geometry.d.ts +22 -0
  48. package/dist/src/shapes/geometry.js +166 -0
  49. package/dist/src/shapes/index.d.ts +2 -0
  50. package/dist/src/shapes/index.js +18 -0
  51. package/dist/src/shapes/registry.d.ts +9 -0
  52. package/dist/src/shapes/registry.js +35 -0
  53. package/dist/src/shapes/types.d.ts +34 -0
  54. package/dist/src/shapes/types.js +2 -0
  55. package/dist/src/types.d.ts +439 -0
  56. package/dist/src/types.js +2 -0
  57. package/dist/src/utils.d.ts +25 -0
  58. package/dist/src/utils.js +157 -0
  59. package/dist/src/validate.d.ts +2 -0
  60. package/dist/src/validate.js +434 -0
  61. package/dist/tests/run.d.ts +1 -0
  62. package/dist/tests/run.js +651 -0
  63. package/package.json +52 -0
  64. package/schema/visual.schema.json +930 -0
@@ -0,0 +1,403 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.generateVisualSchema = generateVisualSchema;
4
+ const shapes_1 = require("./shapes");
5
+ function generateVisualSchema() {
6
+ const shapeDefinitions = (0, shapes_1.registeredAuthoringShapeDefinitions)();
7
+ const elementProperties = {
8
+ id: { type: "string" },
9
+ type: { enum: shapeDefinitions.map((definition) => definition.type) },
10
+ opacity: { type: "number" },
11
+ fill: { $ref: "#/$defs/paint" },
12
+ stroke: { $ref: "#/$defs/paint" },
13
+ strokeWidth: { type: "number" },
14
+ dashArray: { type: "array", items: { type: "number" } },
15
+ strokeCap: { enum: ["butt", "round", "square"] },
16
+ strokeJoin: { enum: ["miter", "round", "bevel"] },
17
+ miterLimit: { type: "number" },
18
+ dashOffset: { type: "number" },
19
+ drawStart: { type: "number" },
20
+ drawEnd: { type: "number" },
21
+ effects: { $ref: "#/$defs/effects" },
22
+ blendMode: { type: "string" },
23
+ rotation: { type: "number" },
24
+ scale: { type: "number" },
25
+ scaleX: { type: "number" },
26
+ scaleY: { type: "number" },
27
+ origin: { oneOf: [{ type: "string" }, { $ref: "#/$defs/point2" }] },
28
+ clip: { $ref: "#/$defs/clipShape" },
29
+ mask: { $ref: "#/$defs/clipShape" },
30
+ animate: { type: "object", additionalProperties: { $ref: "#/$defs/animationValue" } },
31
+ metadata: { type: "object", additionalProperties: true },
32
+ align: { enum: ["left", "center", "right"] },
33
+ valign: { enum: ["top", "middle", "bottom"] },
34
+ fontSize: { type: "number" },
35
+ fontFamily: { type: "string" },
36
+ weight: { oneOf: [{ type: "number" }, { type: "string" }] },
37
+ fontStyle: { type: "string" },
38
+ lineHeight: { type: "number" },
39
+ letterSpacing: { type: "number" },
40
+ maxWidth: { type: "number" },
41
+ wrap: { type: "boolean" },
42
+ label: { type: "string" },
43
+ labelX: { type: "number" },
44
+ labelY: { type: "number" },
45
+ progress: { oneOf: [{ type: "number" }, { $ref: "#/$defs/animationValue" }] },
46
+ follow: { type: "string" },
47
+ rotationX: { type: "number" },
48
+ rotationY: { type: "number" },
49
+ rotationZ: { type: "number" },
50
+ scaleZ: { type: "number" }
51
+ };
52
+ for (const definition of shapeDefinitions) {
53
+ for (const [key, value] of Object.entries(definition.schema?.properties ?? {})) {
54
+ elementProperties[key] = mergeSchemaProperty(elementProperties[key], value);
55
+ }
56
+ }
57
+ return {
58
+ $schema: "https://json-schema.org/draft/2020-12/schema",
59
+ $id: "https://sketchmark.dev/schema/visual.schema.json",
60
+ title: "Sketchmark Primitive Visual Document",
61
+ type: "object",
62
+ required: ["version", "canvas"],
63
+ additionalProperties: true,
64
+ properties: {
65
+ version: { const: 1 },
66
+ canvas: {
67
+ type: "object",
68
+ required: ["width", "height"],
69
+ additionalProperties: true,
70
+ properties: {
71
+ width: { type: "number" },
72
+ height: { type: "number" },
73
+ background: { type: "string" },
74
+ duration: { type: "number" },
75
+ fps: { type: "number" },
76
+ space: { enum: ["2d", "3d"] },
77
+ renderer: { enum: ["svg", "three"] }
78
+ }
79
+ },
80
+ elements: {
81
+ type: "array",
82
+ items: { $ref: "#/$defs/element" }
83
+ },
84
+ imports: {
85
+ type: "object",
86
+ additionalProperties: { type: "string" }
87
+ },
88
+ assets: {
89
+ type: "object",
90
+ additionalProperties: { type: "string" }
91
+ },
92
+ exports: {
93
+ type: "object",
94
+ additionalProperties: {
95
+ type: "object",
96
+ properties: {
97
+ format: { enum: ["svg", "html", "png", "jpg", "mp4", "webm", "pdf", "pptx"] },
98
+ sequence: { type: "string" },
99
+ scene: { type: "string" }
100
+ },
101
+ additionalProperties: true
102
+ }
103
+ },
104
+ scenes: {
105
+ type: "object",
106
+ additionalProperties: {
107
+ type: "object",
108
+ required: ["elements"],
109
+ properties: {
110
+ canvas: { type: "object" },
111
+ elements: {
112
+ type: "array",
113
+ items: { $ref: "#/$defs/element" }
114
+ },
115
+ steps: {
116
+ type: "array",
117
+ items: { $ref: "#/$defs/deckStep" }
118
+ }
119
+ },
120
+ additionalProperties: true
121
+ }
122
+ },
123
+ sequences: {
124
+ type: "object",
125
+ additionalProperties: {
126
+ type: "object",
127
+ required: ["id", "clips"],
128
+ properties: {
129
+ id: { type: "string" },
130
+ clips: {
131
+ type: "array",
132
+ items: { $ref: "#/$defs/clip" }
133
+ }
134
+ },
135
+ additionalProperties: true
136
+ }
137
+ }
138
+ },
139
+ $defs: {
140
+ point2: {
141
+ type: "array",
142
+ minItems: 2,
143
+ maxItems: 2,
144
+ items: { type: "number" }
145
+ },
146
+ point3: {
147
+ type: "array",
148
+ minItems: 3,
149
+ maxItems: 3,
150
+ items: { type: "number" }
151
+ },
152
+ endpoint: {
153
+ oneOf: [{ $ref: "#/$defs/point2" }, { type: "string" }]
154
+ },
155
+ paint: paintSchema(),
156
+ imageFit: {
157
+ enum: ["fill", "contain", "cover"]
158
+ },
159
+ gradientStops: gradientStopsSchema(),
160
+ effects: effectsSchema(),
161
+ clipShape: clipShapeSchema(),
162
+ imageSource: {
163
+ type: "object",
164
+ required: ["x", "y", "width", "height", "imageWidth", "imageHeight"],
165
+ properties: {
166
+ x: { type: "number" },
167
+ y: { type: "number" },
168
+ width: { type: "number" },
169
+ height: { type: "number" },
170
+ imageWidth: { type: "number" },
171
+ imageHeight: { type: "number" }
172
+ },
173
+ additionalProperties: true
174
+ },
175
+ animationValue: {
176
+ type: "object",
177
+ additionalProperties: true,
178
+ properties: {
179
+ from: { oneOf: [{ type: "number" }, { type: "string" }] },
180
+ to: { oneOf: [{ type: "number" }, { type: "string" }] },
181
+ duration: { type: "number" },
182
+ delay: { type: "number" },
183
+ ease: { type: "string" },
184
+ keyframes: {
185
+ type: "array",
186
+ items: {
187
+ type: "array",
188
+ minItems: 2,
189
+ maxItems: 2,
190
+ prefixItems: [{ type: "number" }, { oneOf: [{ type: "number" }, { type: "string" }] }]
191
+ }
192
+ }
193
+ }
194
+ },
195
+ clip: {
196
+ type: "object",
197
+ required: ["scene", "duration"],
198
+ properties: {
199
+ scene: { type: "string" },
200
+ duration: { type: "number" },
201
+ transition: {
202
+ oneOf: [
203
+ { enum: ["cut", "fade"] },
204
+ {
205
+ type: "object",
206
+ required: ["type"],
207
+ properties: {
208
+ type: { enum: ["cut", "fade"] },
209
+ duration: { type: "number" }
210
+ },
211
+ additionalProperties: true
212
+ }
213
+ ]
214
+ }
215
+ },
216
+ additionalProperties: true
217
+ },
218
+ deckStep: {
219
+ type: "object",
220
+ required: ["id"],
221
+ properties: {
222
+ id: { type: "string" },
223
+ show: { type: "array", items: { type: "string" } },
224
+ hide: { type: "array", items: { type: "string" } },
225
+ duration: { type: "number" }
226
+ },
227
+ additionalProperties: true
228
+ },
229
+ element: {
230
+ type: "object",
231
+ required: ["type"],
232
+ additionalProperties: true,
233
+ properties: elementProperties
234
+ }
235
+ }
236
+ };
237
+ }
238
+ function mergeSchemaProperty(existing, incoming) {
239
+ if (existing === undefined)
240
+ return incoming;
241
+ if (schemaKey(existing) === schemaKey(incoming))
242
+ return existing;
243
+ const items = schemaAlternatives(existing);
244
+ const incomingItems = schemaAlternatives(incoming);
245
+ for (const item of incomingItems) {
246
+ if (!items.some((existingItem) => schemaKey(existingItem) === schemaKey(item)))
247
+ items.push(item);
248
+ }
249
+ return { oneOf: items };
250
+ }
251
+ function schemaAlternatives(value) {
252
+ if (value && typeof value === "object" && Array.isArray(value.oneOf)) {
253
+ return [...(value.oneOf)];
254
+ }
255
+ return [value];
256
+ }
257
+ function schemaKey(value) {
258
+ return JSON.stringify(sortJson(value));
259
+ }
260
+ function sortJson(value) {
261
+ if (Array.isArray(value))
262
+ return value.map(sortJson);
263
+ if (!value || typeof value !== "object")
264
+ return value;
265
+ return Object.fromEntries(Object.entries(value).sort(([left], [right]) => left.localeCompare(right)).map(([key, item]) => [key, sortJson(item)]));
266
+ }
267
+ function paintSchema() {
268
+ return {
269
+ oneOf: [
270
+ { type: "string" },
271
+ {
272
+ type: "object",
273
+ required: ["type", "from", "to", "stops"],
274
+ properties: {
275
+ type: { const: "linearGradient" },
276
+ from: { $ref: "#/$defs/point2" },
277
+ to: { $ref: "#/$defs/point2" },
278
+ stops: { $ref: "#/$defs/gradientStops" }
279
+ },
280
+ additionalProperties: true
281
+ },
282
+ {
283
+ type: "object",
284
+ required: ["type", "center", "radius", "stops"],
285
+ properties: {
286
+ type: { const: "radialGradient" },
287
+ center: { $ref: "#/$defs/point2" },
288
+ radius: { type: "number" },
289
+ focus: { $ref: "#/$defs/point2" },
290
+ stops: { $ref: "#/$defs/gradientStops" }
291
+ },
292
+ additionalProperties: true
293
+ },
294
+ {
295
+ type: "object",
296
+ required: ["type", "src", "width", "height"],
297
+ properties: {
298
+ type: { const: "pattern" },
299
+ src: { type: "string" },
300
+ x: { type: "number" },
301
+ y: { type: "number" },
302
+ width: { type: "number" },
303
+ height: { type: "number" },
304
+ fit: { $ref: "#/$defs/imageFit" },
305
+ opacity: { type: "number" }
306
+ },
307
+ additionalProperties: true
308
+ }
309
+ ]
310
+ };
311
+ }
312
+ function gradientStopsSchema() {
313
+ return {
314
+ type: "array",
315
+ minItems: 2,
316
+ items: {
317
+ oneOf: [
318
+ {
319
+ type: "array",
320
+ minItems: 2,
321
+ maxItems: 2,
322
+ prefixItems: [{ type: "number" }, { type: "string" }]
323
+ },
324
+ {
325
+ type: "object",
326
+ required: ["offset", "color"],
327
+ properties: {
328
+ offset: { type: "number" },
329
+ color: { type: "string" }
330
+ },
331
+ additionalProperties: true
332
+ }
333
+ ]
334
+ }
335
+ };
336
+ }
337
+ function effectsSchema() {
338
+ return {
339
+ type: "object",
340
+ properties: {
341
+ blur: { type: "number" },
342
+ brightness: { type: "number" },
343
+ contrast: { type: "number" },
344
+ saturate: { type: "number" },
345
+ hueRotate: { type: "number" },
346
+ shadow: {
347
+ type: "object",
348
+ required: ["dx", "dy", "blur", "color"],
349
+ properties: {
350
+ dx: { type: "number" },
351
+ dy: { type: "number" },
352
+ blur: { type: "number" },
353
+ color: { type: "string" },
354
+ opacity: { type: "number" }
355
+ },
356
+ additionalProperties: true
357
+ }
358
+ },
359
+ additionalProperties: true
360
+ };
361
+ }
362
+ function clipShapeSchema() {
363
+ return {
364
+ oneOf: [
365
+ {
366
+ type: "object",
367
+ required: ["type", "x", "y", "width", "height"],
368
+ properties: {
369
+ type: { const: "rect" },
370
+ x: { type: "number" },
371
+ y: { type: "number" },
372
+ width: { type: "number" },
373
+ height: { type: "number" },
374
+ radius: { type: "number" },
375
+ opacity: { type: "number" }
376
+ },
377
+ additionalProperties: true
378
+ },
379
+ {
380
+ type: "object",
381
+ required: ["type", "cx", "cy", "radius"],
382
+ properties: {
383
+ type: { const: "circle" },
384
+ cx: { type: "number" },
385
+ cy: { type: "number" },
386
+ radius: { type: "number" },
387
+ opacity: { type: "number" }
388
+ },
389
+ additionalProperties: true
390
+ },
391
+ {
392
+ type: "object",
393
+ required: ["type", "d"],
394
+ properties: {
395
+ type: { const: "path" },
396
+ d: { type: "string" },
397
+ opacity: { type: "number" }
398
+ },
399
+ additionalProperties: true
400
+ }
401
+ ]
402
+ };
403
+ }
@@ -0,0 +1,43 @@
1
+ import type { ResolvedVisualDocument, VisualDocument } from "./types";
2
+ export interface CompiledVisualSequence {
3
+ id: string;
4
+ duration: number;
5
+ clips: Array<{
6
+ scene: string;
7
+ start: number;
8
+ duration: number;
9
+ transition: NormalizedTransition;
10
+ }>;
11
+ }
12
+ export interface SequenceFrame {
13
+ document: VisualDocument;
14
+ scene: string;
15
+ localTime: number;
16
+ globalTime: number;
17
+ transition?: {
18
+ type: "fade";
19
+ fromScene: string;
20
+ toScene: string;
21
+ progress: number;
22
+ duration: number;
23
+ };
24
+ }
25
+ export interface ResolvedSequenceFrame extends Omit<SequenceFrame, "document"> {
26
+ document: ResolvedVisualDocument;
27
+ }
28
+ export interface SequenceTimelineFrame {
29
+ index: number;
30
+ time: number;
31
+ scene: string;
32
+ localTime: number;
33
+ transition?: SequenceFrame["transition"];
34
+ }
35
+ export interface NormalizedTransition {
36
+ type: "cut" | "fade";
37
+ duration: number;
38
+ }
39
+ export declare function compileVisualSequence(document: VisualDocument, sequenceId: string): CompiledVisualSequence;
40
+ export declare function defaultSequenceId(document: VisualDocument): string | undefined;
41
+ export declare function documentForSequenceTime(document: VisualDocument, sequenceId: string, time: number): SequenceFrame;
42
+ export declare function resolvedFrameForSequenceTime(document: VisualDocument, sequenceId: string, time: number): ResolvedSequenceFrame;
43
+ export declare function sequenceTimeline(document: VisualDocument, sequenceId: string, fps: number): SequenceTimelineFrame[];
@@ -0,0 +1,109 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.compileVisualSequence = compileVisualSequence;
4
+ exports.defaultSequenceId = defaultSequenceId;
5
+ exports.documentForSequenceTime = documentForSequenceTime;
6
+ exports.resolvedFrameForSequenceTime = resolvedFrameForSequenceTime;
7
+ exports.sequenceTimeline = sequenceTimeline;
8
+ const scenes_1 = require("./scenes");
9
+ const normalize_1 = require("./normalize");
10
+ const utils_1 = require("./utils");
11
+ function compileVisualSequence(document, sequenceId) {
12
+ const sequence = document.sequences?.[sequenceId];
13
+ if (!sequence)
14
+ throw new Error(`Unknown sequence '${sequenceId}'.`);
15
+ let cursor = 0;
16
+ const clips = sequence.clips.map((clip) => {
17
+ if (!document.scenes?.[clip.scene])
18
+ throw new Error(`Unknown scene '${clip.scene}' in sequence '${sequenceId}'.`);
19
+ const item = { scene: clip.scene, start: cursor, duration: clip.duration, transition: normalizeTransition(clip.transition) };
20
+ cursor += clip.duration;
21
+ return item;
22
+ });
23
+ return { id: sequenceId, duration: cursor, clips };
24
+ }
25
+ function defaultSequenceId(document) {
26
+ return Object.keys(document.sequences ?? {})[0];
27
+ }
28
+ function documentForSequenceTime(document, sequenceId, time) {
29
+ const sequence = compileVisualSequence(document, sequenceId);
30
+ const clamped = Math.max(0, Math.min(sequence.duration || 0, time));
31
+ const clipIndex = sequence.clips.findIndex((item) => clamped >= item.start && clamped < item.start + item.duration);
32
+ const index = clipIndex === -1 ? sequence.clips.length - 1 : clipIndex;
33
+ const clip = sequence.clips[index];
34
+ if (!clip)
35
+ throw new Error(`Sequence '${sequenceId}' has no clips.`);
36
+ const localTime = Math.max(0, clamped - clip.start);
37
+ const previous = index > 0 ? sequence.clips[index - 1] : undefined;
38
+ if (previous && clip.transition.type === "fade" && clip.transition.duration > 0 && localTime < clip.transition.duration) {
39
+ const progress = Math.max(0, Math.min(1, localTime / clip.transition.duration));
40
+ return {
41
+ document: fadeDocuments((0, scenes_1.documentForScene)(document, previous.scene), (0, scenes_1.documentForScene)(document, clip.scene), progress),
42
+ scene: clip.scene,
43
+ localTime,
44
+ globalTime: clamped,
45
+ transition: { type: "fade", fromScene: previous.scene, toScene: clip.scene, progress, duration: clip.transition.duration }
46
+ };
47
+ }
48
+ return {
49
+ document: (0, scenes_1.documentForScene)(document, clip.scene),
50
+ scene: clip.scene,
51
+ localTime,
52
+ globalTime: clamped
53
+ };
54
+ }
55
+ function resolvedFrameForSequenceTime(document, sequenceId, time) {
56
+ const frame = documentForSequenceTime(document, sequenceId, time);
57
+ return {
58
+ ...frame,
59
+ document: (0, normalize_1.resolveVisualFrame)(frame.document, frame.localTime)
60
+ };
61
+ }
62
+ function sequenceTimeline(document, sequenceId, fps) {
63
+ const sequence = compileVisualSequence(document, sequenceId);
64
+ const safeFps = Math.max(1, Math.round(fps));
65
+ const frameCount = Math.max(1, Math.ceil(sequence.duration * safeFps));
66
+ const frames = [];
67
+ for (let index = 0; index < frameCount; index += 1) {
68
+ const time = index / safeFps;
69
+ const frame = documentForSequenceTime(document, sequenceId, time);
70
+ frames.push({
71
+ index,
72
+ time,
73
+ scene: frame.scene,
74
+ localTime: frame.localTime,
75
+ ...(frame.transition ? { transition: frame.transition } : {})
76
+ });
77
+ }
78
+ return frames;
79
+ }
80
+ function normalizeTransition(transition) {
81
+ if (!transition || transition === "cut")
82
+ return { type: "cut", duration: 0 };
83
+ if (transition === "fade")
84
+ return { type: "fade", duration: 0.4 };
85
+ return { type: transition.type, duration: Math.max(0, Number(transition.duration ?? (transition.type === "fade" ? 0.4 : 0))) };
86
+ }
87
+ function fadeDocuments(from, to, progress) {
88
+ const resolvedFrom = (0, normalize_1.normalizeVisualDocument)(from);
89
+ const resolvedTo = (0, normalize_1.normalizeVisualDocument)(to);
90
+ return {
91
+ ...to,
92
+ elements: [
93
+ ...withOpacity(resolvedFrom.elements ?? [], 1 - progress, "fade_from"),
94
+ ...withOpacity(resolvedTo.elements ?? [], progress, "fade_to")
95
+ ]
96
+ };
97
+ }
98
+ function withOpacity(elements, multiplier, prefix) {
99
+ return elements.map((element) => {
100
+ const next = (0, utils_1.clone)(element);
101
+ if (next.id)
102
+ next.id = `${prefix}_${next.id}`;
103
+ next.opacity = Number(next.opacity ?? 1) * multiplier;
104
+ if (next.type === "group" && Array.isArray(next.children)) {
105
+ next.children = withOpacity(next.children, multiplier, prefix);
106
+ }
107
+ return next;
108
+ });
109
+ }
@@ -0,0 +1,2 @@
1
+ import type { ShapeDefinition } from "./types";
2
+ export declare const builtInShapeLowerers: ShapeDefinition[];