gum-jsx 1.1.4 → 1.2.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.
- package/index.d.ts +0 -36
- package/package.json +4 -9
- package/src/cli.js +4 -16
- package/src/server.js +3 -56
- package/src/test.js +3 -4
- package/src/dynamic.js +0 -136
- package/src/render.js +0 -146
package/index.d.ts
CHANGED
|
@@ -1219,42 +1219,6 @@ declare module 'gum-jsx/eval' {
|
|
|
1219
1219
|
export function evaluateGum(code: string, options?: EvaluateOptions): Svg;
|
|
1220
1220
|
}
|
|
1221
1221
|
|
|
1222
|
-
// =============================================================================
|
|
1223
|
-
// Rendering (from render.js)
|
|
1224
|
-
// =============================================================================
|
|
1225
|
-
|
|
1226
|
-
declare module 'gum-jsx/render' {
|
|
1227
|
-
/** A point in 2D space [x, y] */
|
|
1228
|
-
export type point = [number, number];
|
|
1229
|
-
|
|
1230
|
-
export interface RenderOptions {
|
|
1231
|
-
size?: number | point;
|
|
1232
|
-
background?: string;
|
|
1233
|
-
}
|
|
1234
|
-
|
|
1235
|
-
/** Render SVG to PNG (returns Buffer in Node, Blob in browser) */
|
|
1236
|
-
export function renderPng(svg: string, options?: RenderOptions): Promise<Buffer | Blob>;
|
|
1237
|
-
|
|
1238
|
-
/** Node.js renderer class */
|
|
1239
|
-
export class NodeRender {
|
|
1240
|
-
fonts: string[];
|
|
1241
|
-
Resvg: any;
|
|
1242
|
-
|
|
1243
|
-
init(): Promise<void>;
|
|
1244
|
-
renderPng(svg: string, options?: RenderOptions): Buffer;
|
|
1245
|
-
}
|
|
1246
|
-
|
|
1247
|
-
/** Browser renderer class */
|
|
1248
|
-
export class BrowserRender {
|
|
1249
|
-
canvas: HTMLCanvasElement;
|
|
1250
|
-
ctx: CanvasRenderingContext2D;
|
|
1251
|
-
|
|
1252
|
-
init(): Promise<void>;
|
|
1253
|
-
makeCanvas(size?: point, options?: { dpr?: number | null }): { canvas: HTMLCanvasElement; ctx: CanvasRenderingContext2D };
|
|
1254
|
-
renderPng(svg: string, options?: RenderOptions): Promise<Blob>;
|
|
1255
|
-
}
|
|
1256
|
-
}
|
|
1257
|
-
|
|
1258
1222
|
// =============================================================================
|
|
1259
1223
|
// Error Types (from error.js)
|
|
1260
1224
|
// =============================================================================
|
package/package.json
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gum-jsx",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"description": "Language for vector graphics generation.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"author": "Douglas Hanley",
|
|
7
|
-
"homepage": "https://github.com/CompendiumLabs/gum.
|
|
7
|
+
"homepage": "https://github.com/CompendiumLabs/gum.jsx",
|
|
8
8
|
"repository": {
|
|
9
9
|
"type": "git",
|
|
10
|
-
"url": "git+https://github.com/CompendiumLabs/gum.
|
|
10
|
+
"url": "git+https://github.com/CompendiumLabs/gum.jsx"
|
|
11
11
|
},
|
|
12
12
|
"license": "MIT",
|
|
13
13
|
"files": [
|
|
@@ -21,7 +21,6 @@
|
|
|
21
21
|
},
|
|
22
22
|
"./error": "./src/error.js",
|
|
23
23
|
"./eval": "./src/eval.js",
|
|
24
|
-
"./render": "./src/render.js",
|
|
25
24
|
"./docs/*": "./src/docs/*",
|
|
26
25
|
"./fonts/*": "./src/fonts/*"
|
|
27
26
|
},
|
|
@@ -43,12 +42,8 @@
|
|
|
43
42
|
},
|
|
44
43
|
"optionalDependencies": {
|
|
45
44
|
"@mathjax/src": "^4.1.0",
|
|
46
|
-
"@modelcontextprotocol/sdk": "^1.25.2",
|
|
47
|
-
"@resvg/resvg-js": "^2.6.2",
|
|
48
45
|
"commander": "^14.0.2",
|
|
49
46
|
"express": "^5.2.1",
|
|
50
|
-
"
|
|
51
|
-
"mathjax": "^4.1.0",
|
|
52
|
-
"zod": "^4.3.5"
|
|
47
|
+
"mathjax": "^4.1.0"
|
|
53
48
|
}
|
|
54
49
|
}
|
package/src/cli.js
CHANGED
|
@@ -3,32 +3,20 @@
|
|
|
3
3
|
import { program } from 'commander'
|
|
4
4
|
import { waitForStdin } from './node.js'
|
|
5
5
|
import { evaluateGum } from './eval.js'
|
|
6
|
-
import { renderPng } from './render.js'
|
|
7
6
|
|
|
8
7
|
// get options from commander
|
|
9
8
|
program
|
|
10
9
|
.option('-s, --size <size>', 'size of the image', (value) => parseInt(value), 500)
|
|
11
|
-
.option('-x, --pixels <pixels>', 'svg pixel coords', (value) => parseInt(value), 500)
|
|
12
|
-
.option('-f, --format <format>', 'format of the image', 'svg')
|
|
13
10
|
.option('-t, --theme <theme>', 'theme to use', 'dark')
|
|
14
|
-
.option('-b, --background <color>', 'background color', null)
|
|
15
11
|
.parse()
|
|
16
|
-
const { size,
|
|
12
|
+
const { size, theme } = program.opts()
|
|
17
13
|
|
|
18
14
|
// wait for stdin
|
|
19
15
|
const code = await waitForStdin()
|
|
20
16
|
|
|
21
17
|
// evaluate gum with size
|
|
22
|
-
const elem = evaluateGum(code, { size
|
|
18
|
+
const elem = evaluateGum(code, { size, theme })
|
|
23
19
|
const svg = elem.svg()
|
|
24
20
|
|
|
25
|
-
// output svg
|
|
26
|
-
|
|
27
|
-
const png = renderPng(svg, { size, background })
|
|
28
|
-
process.stdout.write(png)
|
|
29
|
-
} else if (format == 'svg') {
|
|
30
|
-
process.stdout.write(svg)
|
|
31
|
-
} else {
|
|
32
|
-
console.error(`Invalid format: ${format}`)
|
|
33
|
-
process.exit(1)
|
|
34
|
-
}
|
|
21
|
+
// output svg
|
|
22
|
+
process.stdout.write(svg)
|
package/src/server.js
CHANGED
|
@@ -3,25 +3,8 @@
|
|
|
3
3
|
import express from 'express'
|
|
4
4
|
import { program } from 'commander'
|
|
5
5
|
import { evaluateGum } from './eval.js'
|
|
6
|
-
import { canvas } from './canvas.js'
|
|
7
6
|
import { ErrorNoCode, ErrorNoReturn, ErrorNoElement } from './eval.js'
|
|
8
7
|
|
|
9
|
-
class ErrorGenerate extends Error {
|
|
10
|
-
constructor(error) {
|
|
11
|
-
super(error.message)
|
|
12
|
-
this.name = 'ErrorGenerate'
|
|
13
|
-
this.error = error
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
class ErrorRender extends Error {
|
|
18
|
-
constructor(error) {
|
|
19
|
-
super(error.message)
|
|
20
|
-
this.name = 'ErrorRender'
|
|
21
|
-
this.error = error
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
|
|
25
8
|
function parseError(error) {
|
|
26
9
|
if (error instanceof ErrorNoCode) {
|
|
27
10
|
return 'ERR_NOCODE: No code provided'
|
|
@@ -59,21 +42,17 @@ app.get('/', (req, res) => {
|
|
|
59
42
|
})
|
|
60
43
|
|
|
61
44
|
// eval gum jsx to svg
|
|
62
|
-
app.post('/
|
|
45
|
+
app.post('/', (req, res) => {
|
|
63
46
|
// get params
|
|
64
47
|
const code = req.body
|
|
65
|
-
const size0 = parseInt(req.query.size ??
|
|
48
|
+
const size0 = parseInt(req.query.size ?? 500)
|
|
66
49
|
const theme = req.query.theme ?? 'light'
|
|
67
50
|
|
|
68
51
|
// evaluate code and return svg
|
|
69
52
|
let svg
|
|
70
53
|
try {
|
|
71
54
|
const elem = evaluateGum(code, { size: size0, theme })
|
|
72
|
-
|
|
73
|
-
svg = elem.svg()
|
|
74
|
-
} catch (err) {
|
|
75
|
-
throw new ErrorGenerate(err)
|
|
76
|
-
}
|
|
55
|
+
svg = elem.svg()
|
|
77
56
|
} catch (error) {
|
|
78
57
|
const message = parseError(error)
|
|
79
58
|
return res.status(500).send(message)
|
|
@@ -84,38 +63,6 @@ app.post('/evaluate', (req, res) => {
|
|
|
84
63
|
res.send(svg)
|
|
85
64
|
})
|
|
86
65
|
|
|
87
|
-
// render gum jsx to png
|
|
88
|
-
app.post('/render', async (req, res) => {
|
|
89
|
-
// get params
|
|
90
|
-
const code = req.body
|
|
91
|
-
const size0 = parseInt(req.query.size ?? 750)
|
|
92
|
-
const theme = req.query.theme ?? 'light'
|
|
93
|
-
|
|
94
|
-
// evaluate code and render to png
|
|
95
|
-
let png, svg
|
|
96
|
-
try {
|
|
97
|
-
const elem = evaluateGum(code, { size: size0, theme })
|
|
98
|
-
try {
|
|
99
|
-
svg = elem.svg()
|
|
100
|
-
} catch (err) {
|
|
101
|
-
throw new ErrorGenerate(err)
|
|
102
|
-
}
|
|
103
|
-
try {
|
|
104
|
-
const { size } = elem
|
|
105
|
-
png = await canvas.renderPng(svg, { size })
|
|
106
|
-
} catch (err) {
|
|
107
|
-
throw new ErrorRender(err)
|
|
108
|
-
}
|
|
109
|
-
} catch (error) {
|
|
110
|
-
const message = parseError(error)
|
|
111
|
-
return res.status(500).send(message)
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
// send png
|
|
115
|
-
res.setHeader('Content-Type', 'image/png')
|
|
116
|
-
res.send(png)
|
|
117
|
-
})
|
|
118
|
-
|
|
119
66
|
// start server
|
|
120
67
|
app.listen(port, host, () => {
|
|
121
68
|
// console.log(`Server running on http://${host}:${port}`)
|
package/src/test.js
CHANGED
|
@@ -3,15 +3,14 @@
|
|
|
3
3
|
import { program } from 'commander'
|
|
4
4
|
|
|
5
5
|
import { waitForStdin } from './node.js'
|
|
6
|
-
import {
|
|
7
|
-
import { textSizer, splitWords
|
|
6
|
+
import { setTheme } from './defaults.js'
|
|
7
|
+
import { textSizer, splitWords } from './text.js'
|
|
8
8
|
import { evaluateGum } from './eval.js'
|
|
9
9
|
|
|
10
10
|
// evaluate command
|
|
11
11
|
async function cmdEvaluate({ debug }) {
|
|
12
12
|
const code = await waitForStdin()
|
|
13
|
-
|
|
14
|
-
const elem = evaluateGum(code, { debug, size: 1000 })
|
|
13
|
+
const elem = evaluateGum(code, { debug, theme: 'dark', size: 1000 })
|
|
15
14
|
const svg = elem.svg()
|
|
16
15
|
console.log(svg)
|
|
17
16
|
}
|
package/src/dynamic.js
DELETED
|
@@ -1,136 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
** Interactive
|
|
3
|
-
**/
|
|
4
|
-
|
|
5
|
-
class Interactive {
|
|
6
|
-
constructor(vars, func) {
|
|
7
|
-
this.func = func;
|
|
8
|
-
this.vars = vars;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
element() {
|
|
12
|
-
let vals = map_object(this.vars, v => v.value);
|
|
13
|
-
return this.func(vals);
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
class Variable {
|
|
18
|
-
constructor(init, args) {
|
|
19
|
-
args = args ?? {};
|
|
20
|
-
this.value = init;
|
|
21
|
-
this.attr = filter_object(args, v => v != null);
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
update(val) {
|
|
25
|
-
this.value = val;
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
class Slider extends Variable {
|
|
30
|
-
constructor(init, args) {
|
|
31
|
-
let {min, max, step, ...attr} = args ?? {};
|
|
32
|
-
min = min ?? 0;
|
|
33
|
-
max = max ?? 100;
|
|
34
|
-
step = step ?? 1;
|
|
35
|
-
|
|
36
|
-
let attr1 = {min, max, step, ...attr};
|
|
37
|
-
super(init, attr1);
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
class Toggle extends Variable {
|
|
42
|
-
constructor(init, args) {
|
|
43
|
-
init = init ?? true;
|
|
44
|
-
super(init, args);
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
class List extends Variable {
|
|
49
|
-
constructor(init, args) {
|
|
50
|
-
let {choices, ...attr} = args ?? {};
|
|
51
|
-
choices = choices ?? {};
|
|
52
|
-
|
|
53
|
-
if (is_array(choices)) {
|
|
54
|
-
choices = Object.fromEntries(choices.map(v => [v, v]));
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
let attr1 = {choices, ...attr};
|
|
58
|
-
super(init, attr1);
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
/**
|
|
63
|
-
** Animation
|
|
64
|
-
**/
|
|
65
|
-
|
|
66
|
-
class Transition {
|
|
67
|
-
constructor(args) {
|
|
68
|
-
let {tlim} = args ?? {};
|
|
69
|
-
this.tlim = tlim ?? [null, null];
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
frac(t, tlimf) {
|
|
73
|
-
let [t0, t1] = this.tlim;
|
|
74
|
-
let [t0f, t1f] = tlimf;
|
|
75
|
-
t0 = t0 ?? t0f;
|
|
76
|
-
t1 = t1 ?? t1f;
|
|
77
|
-
let f = (t - t0) / (t1 - t0);
|
|
78
|
-
return max(0, min(1, f));
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
class Continuous extends Transition {
|
|
83
|
-
constructor(lim, args) {
|
|
84
|
-
super(args);
|
|
85
|
-
this.lim = lim;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
value(t, tlimf) {
|
|
89
|
-
let f = this.frac(t, tlimf);
|
|
90
|
-
let [lo, hi] = this.lim;
|
|
91
|
-
return lo + (hi - lo) * f;
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
class Discrete extends Transition {
|
|
96
|
-
constructor(vals, args) {
|
|
97
|
-
super(args);
|
|
98
|
-
this.vals = vals;
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
value(t, tlimf) {
|
|
102
|
-
let f = this.frac(t, tlimf);
|
|
103
|
-
let i0 = floor(f * this.vals.length);
|
|
104
|
-
let i = min(i0, this.vals.length - 1);
|
|
105
|
-
return this.vals[i];
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
class Animation {
|
|
110
|
-
constructor(vars, func, args) {
|
|
111
|
-
let {tlim, N} = args ?? {};
|
|
112
|
-
tlim = tlim ?? [0, 1];
|
|
113
|
-
N = N ?? 10;
|
|
114
|
-
|
|
115
|
-
// total frames
|
|
116
|
-
let [t0f, t1f] = tlim;
|
|
117
|
-
let time = linspace(t0f, t1f, N);
|
|
118
|
-
|
|
119
|
-
// animation state
|
|
120
|
-
this.frames = time.map(t => {
|
|
121
|
-
let vals = map_object(vars, v => v.value(t, tlim));
|
|
122
|
-
return func(vals);
|
|
123
|
-
});
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
frame(i) {
|
|
127
|
-
let frame = this.frames[i];
|
|
128
|
-
return renderElem(frame);
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
*animate() {
|
|
132
|
-
for (let i = 0; i < this.frames.length; i++) {
|
|
133
|
-
yield this.frame(i);
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
}
|
package/src/render.js
DELETED
|
@@ -1,146 +0,0 @@
|
|
|
1
|
-
// png rendering
|
|
2
|
-
|
|
3
|
-
import { CONSTANTS as C } from './defaults.js'
|
|
4
|
-
import { getFontPaths } from './text.js'
|
|
5
|
-
import { ensure_vector } from './utils.js'
|
|
6
|
-
|
|
7
|
-
//
|
|
8
|
-
// constants
|
|
9
|
-
//
|
|
10
|
-
|
|
11
|
-
const DEFAULT_SIZE = [500, 500]
|
|
12
|
-
|
|
13
|
-
//
|
|
14
|
-
// node render
|
|
15
|
-
//
|
|
16
|
-
|
|
17
|
-
class NodeRender {
|
|
18
|
-
async init() {
|
|
19
|
-
const { sans, mono, moji } = await getFontPaths()
|
|
20
|
-
this.fonts = [ sans, mono, moji ]
|
|
21
|
-
try {
|
|
22
|
-
const { Resvg } = await import(/* @vite-ignore */ '@resvg/resvg-js')
|
|
23
|
-
this.Resvg = Resvg
|
|
24
|
-
} catch {
|
|
25
|
-
this.Resvg = null
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
renderPng(svg, { size = DEFAULT_SIZE, background = 'white' }) {
|
|
30
|
-
const [ width, height ] = ensure_vector(size, 2)
|
|
31
|
-
|
|
32
|
-
const fontsArgs = {
|
|
33
|
-
fontFiles: this.fonts,
|
|
34
|
-
loadSystemFonts: false,
|
|
35
|
-
defaultFontFamily: C.sans,
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
const opts = {
|
|
39
|
-
background,
|
|
40
|
-
fitTo: {
|
|
41
|
-
mode: 'width',
|
|
42
|
-
value: width,
|
|
43
|
-
},
|
|
44
|
-
font: fontsArgs,
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
const resvg = new this.Resvg(svg, opts)
|
|
48
|
-
const data = resvg.render()
|
|
49
|
-
return data.asPng()
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
//
|
|
54
|
-
// browser render
|
|
55
|
-
//
|
|
56
|
-
|
|
57
|
-
function loadImage(url) {
|
|
58
|
-
return new Promise((resolve, reject) => {
|
|
59
|
-
const img = new Image()
|
|
60
|
-
img.onload = () => resolve(img)
|
|
61
|
-
img.onerror = () => reject(new Error('Failed to load image'))
|
|
62
|
-
img.src = url
|
|
63
|
-
})
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
function canvasToBlob(canvas) {
|
|
67
|
-
return new Promise((resolve, reject) => {
|
|
68
|
-
canvas.toBlob((blob) => {
|
|
69
|
-
if (blob) {
|
|
70
|
-
resolve(blob)
|
|
71
|
-
} else {
|
|
72
|
-
reject(new Error('Failed to convert canvas to blob'))
|
|
73
|
-
}
|
|
74
|
-
})
|
|
75
|
-
})
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
class BrowserRender {
|
|
79
|
-
async init() {
|
|
80
|
-
const { canvas, ctx } = this.makeCanvas()
|
|
81
|
-
this.canvas = canvas
|
|
82
|
-
this.ctx = ctx
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
makeCanvas(size = DEFAULT_SIZE, { dpr: dpr0 = null } = {}) {
|
|
86
|
-
const dpr = dpr0 ?? window.devicePixelRatio ?? 1
|
|
87
|
-
const [ width, height ] = size
|
|
88
|
-
|
|
89
|
-
// make canvas and ensize
|
|
90
|
-
const canvas = document.createElement('canvas')
|
|
91
|
-
canvas.width = Math.round(width * dpr)
|
|
92
|
-
canvas.height = Math.round(height * dpr)
|
|
93
|
-
canvas.style.width = `${Math.round(width)}px`
|
|
94
|
-
canvas.style.height = `${Math.round(height)}px`
|
|
95
|
-
|
|
96
|
-
// make context and scale
|
|
97
|
-
const ctx = canvas.getContext('2d')
|
|
98
|
-
ctx.scale(dpr, dpr)
|
|
99
|
-
|
|
100
|
-
// return canvas and context
|
|
101
|
-
return { canvas, ctx }
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
async renderPng(svg, { size = DEFAULT_SIZE, background = 'white' } = {}) {
|
|
105
|
-
const [ width, height ] = size
|
|
106
|
-
|
|
107
|
-
// make canvas and context
|
|
108
|
-
const { canvas, ctx } = this.makeCanvas(size)
|
|
109
|
-
const { canvas: exportCanvas, ctx: exportCtx } = this.makeCanvas(size, { dpr: 1 })
|
|
110
|
-
|
|
111
|
-
// load svg image
|
|
112
|
-
const svgBlob = new Blob([ svg ], { type: 'image/svg+xml' })
|
|
113
|
-
const svgUrl = URL.createObjectURL(svgBlob)
|
|
114
|
-
const svgImg = await loadImage(svgUrl)
|
|
115
|
-
|
|
116
|
-
// fill background
|
|
117
|
-
if (background != null) {
|
|
118
|
-
ctx.fillStyle = background
|
|
119
|
-
ctx.fillRect(0, 0, width, height)
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
// draw svg and export canvas
|
|
123
|
-
ctx.drawImage(svgImg, 0, 0, width, height)
|
|
124
|
-
exportCtx.drawImage(canvas, 0, 0, width, height)
|
|
125
|
-
|
|
126
|
-
// convert export canvas to blob
|
|
127
|
-
const pngBlob = await canvasToBlob(exportCanvas)
|
|
128
|
-
URL.revokeObjectURL(svgUrl)
|
|
129
|
-
|
|
130
|
-
// return png blob
|
|
131
|
-
return pngBlob
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
//
|
|
136
|
-
// exports
|
|
137
|
-
//
|
|
138
|
-
|
|
139
|
-
// set up renderer
|
|
140
|
-
const render = (typeof window == 'undefined') ? new NodeRender() : new BrowserRender()
|
|
141
|
-
await render.init()
|
|
142
|
-
function renderPng(svg, args) {
|
|
143
|
-
return render.renderPng(svg, args)
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
export { renderPng, NodeRender, BrowserRender }
|