gum-jsx 1.6.3 → 1.6.4

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.
@@ -0,0 +1,96 @@
1
+ // get coefficient bounds
2
+ const maxCoeff = 2
3
+ const coeffs = range(-maxCoeff, maxCoeff + 1)
4
+ const gridLocs = range(-4*maxCoeff, 4*maxCoeff + 1)
5
+ const deltaCoeffs = range(-1, 2)
6
+
7
+ // get bounding box for plotting
8
+ const bound0 = maxCoeff * (1 + sqrt(3))
9
+ const bound = bound0 * 1.1
10
+
11
+ // define basis vectors
12
+ const I = [0, 1]
13
+ const omega = [cos(2*pi/3), sin(2*pi/3)]
14
+ const iomega = mulc(I, omega)
15
+ const basis = [[1, 0], I, omega, iomega]
16
+
17
+ // create linear combination
18
+ function lincomb([a, b, c, d]) {
19
+ return addc(
20
+ addc(mulc(a, basis[0]), mulc(b, basis[1])),
21
+ addc(mulc(c, basis[2]), mulc(d, basis[3])),
22
+ )
23
+ }
24
+
25
+ // check if delta is a unit delta
26
+ function isUnitDelta([a, b, c, d]) {
27
+ return b*c == a*d &&
28
+ a*a + b*b + c*c + d*d - a*c - b*d == 1
29
+ }
30
+
31
+ // check if delta is positive (avoid double counting)
32
+ function positive([a, b, c, d]) {
33
+ return a > 0 ||
34
+ (a == 0 && b > 0) ||
35
+ (a == 0 && b == 0 && c > 0) ||
36
+ (a == 0 && b == 0 && c == 0 && d > 0)
37
+ }
38
+
39
+ // create node from coefficients
40
+ function sample(coef) {
41
+ return { coef, pos: lincomb(coef) }
42
+ }
43
+
44
+ // create list of nodes
45
+ const nodes = coeffs.flatMap(a =>
46
+ coeffs.flatMap(b =>
47
+ coeffs.flatMap(c =>
48
+ coeffs.map(d => sample([a, b, c, d]))
49
+ )
50
+ )
51
+ )
52
+
53
+ // make node map for quick lookup
54
+ const key = v => v.join(',')
55
+ const nodeMap = new Map(nodes.map(n => [key(n.coef), n]))
56
+
57
+ // define edge deltas
58
+ const edgeDeltas = deltaCoeffs.flatMap(a =>
59
+ deltaCoeffs.flatMap(b =>
60
+ deltaCoeffs.flatMap(c =>
61
+ deltaCoeffs.map(d => [a, b, c, d])
62
+ )
63
+ )
64
+ ).filter(isUnitDelta).filter(positive)
65
+
66
+ // build displayed edges
67
+ const edges = nodes.flatMap(n => edgeDeltas
68
+ .map(d => nodeMap.get(key(addn(n.coef, d))))
69
+ .filter(m => m != null)
70
+ .map(m => [n.pos, m.pos])
71
+ )
72
+
73
+ // get resulting sizes
74
+ const n = nodes.length
75
+ const m = edges.length
76
+
77
+ // get approximate scaling
78
+ const delta = log(m) / log(n)
79
+ const delta1 = rounder(delta, 2)
80
+
81
+ // prepare data for plotting
82
+ const samples = nodes.map(n => n.pos)
83
+ const title = <Latex>{"\\mathbb{Q}(i, \\zeta_3)"}</Latex>
84
+
85
+ // plot the data
86
+ return <TitleBox border={2} rounded={0.02} clip margin title={title} title-size={0.075}>
87
+ <Graph aspect={1} coord={[-bound, -bound, bound, bound]}>
88
+ <Mesh2D locs={gridLocs} opacity={0.15} />
89
+ <Segments edges={edges} stroke={blue} opacity={0.75} />
90
+ <Points points={samples} point-size={0.075} fill={yellow} stroke-opacity={0.5} />
91
+ </Graph>
92
+ <Group rect={[0.025, 0.925, 0.975, 0.975]}>
93
+ <Latex align="left">{`n = ${n}`}</Latex>
94
+ <Latex align="right">{`\\\\nu = ${m} \\\\approx n^{${delta1}} `}</Latex>
95
+ </Group>
96
+ </TitleBox>
@@ -0,0 +1,7 @@
1
+ # Unit Distance
2
+
3
+ This example turns an algebraic point set into a unit-distance graph. The points are generated as integer linear combinations of the complex basis `1`, `i`, `\zeta_3`, and `i\zeta_3`, where `\zeta_3 = e^{2\pi i/3}`. After mapping those combinations into the complex plane, the figure draws every edge whose coefficient difference has complex norm one.
4
+
5
+ The important part is that unit distances are detected before the coordinates become pixels. The `isUnitDelta` helper checks an exact quadratic condition on the coefficient vector, which avoids fragile floating-point distance comparisons between plotted points. A `Map` from coefficient keys to nodes then makes it cheap to look up whether the other endpoint of each unit step is present in the finite sample.
6
+
7
+ The rendering is also intentionally batched. [Points](/docs/Points) handles the point cloud, while `Segments` draws the unit edges as a single SVG path instead of creating a separate [Line](/docs/Line) element for every edge. That keeps the example responsive even though the graph has many repeated local hexagonal patterns.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gum-jsx",
3
- "version": "1.6.3",
3
+ "version": "1.6.4",
4
4
  "description": "Language for vector graphics generation.",
5
5
  "type": "module",
6
6
  "author": "Douglas Hanley",
@@ -126,6 +126,31 @@ class CoordLine extends Line {
126
126
  }
127
127
  }
128
128
 
129
+ interface SegmentsArgs extends ElementArgs {
130
+ edges?: [Point, Point][]
131
+ }
132
+
133
+ class Segments extends Element {
134
+ edges: [Point, Point][]
135
+
136
+ constructor(args: SegmentsArgs = {}) {
137
+ const { edges = [], ...attr } = args
138
+ super({ tag: 'path', unary: true, ...attr })
139
+ this.args = args
140
+ this.edges = edges
141
+ }
142
+
143
+ props(ctx: Context): Attrs {
144
+ const attr = super.props(ctx)
145
+ const d = this.edges.map(([e0, e1]) => {
146
+ const [p0, p1] = ctx.mapPoint(e0)
147
+ const [q0, q1] = ctx.mapPoint(e1)
148
+ return `M ${rounder(p0, ctx.prec)},${rounder(p1, ctx.prec)} L ${rounder(q0, ctx.prec)},${rounder(q1, ctx.prec)}`
149
+ }).join(' ')
150
+ return { d, ...attr }
151
+ }
152
+ }
153
+
129
154
  //
130
155
  // shape classes
131
156
  //
@@ -835,5 +860,5 @@ class Arrow extends Group {
835
860
  // exports
836
861
  //
837
862
 
838
- export { Line, UnitLine, VLine, HLine, CoordLine, Square, Ellipse, Arc, Circle, Dot, Ray, Pointstring, Shape, Triangle, Fill, VFill, HFill, Path, Command, MoveCmd, LineCmd, ArcCmd, CornerCmd, RoundedCornerCmd, CubicSplineCmd, Spline, RoundedRect, RoundedLine, ArrowHead, Arrow }
839
- export type { LineArgs, UnitLineArgs, CoordLineArgs, ArcArgs, DotArgs, RayArgs, SplineArgs, RoundedRectArgs, RoundedLineArgs, ArrowHeadArgs, ArrowArgs, CubicSplineCmdArgs, FillArgs }
863
+ export { Line, UnitLine, VLine, HLine, CoordLine, Segments, Square, Ellipse, Arc, Circle, Dot, Ray, Pointstring, Shape, Triangle, Fill, VFill, HFill, Path, Command, MoveCmd, LineCmd, ArcCmd, CornerCmd, RoundedCornerCmd, CubicSplineCmd, Spline, RoundedRect, RoundedLine, ArrowHead, Arrow }
864
+ export type { LineArgs, UnitLineArgs, CoordLineArgs, SegmentsArgs, ArcArgs, DotArgs, RayArgs, SplineArgs, RoundedRectArgs, RoundedLineArgs, ArrowHeadArgs, ArrowArgs, CubicSplineCmdArgs, FillArgs }
package/src/elems/math.ts CHANGED
@@ -50,6 +50,10 @@ const SYMBOL_MODE_FONT: Record<SymbolMode, FontFamily> = {
50
50
  text: 'KaTeX_Main',
51
51
  }
52
52
 
53
+ const TEX_FONT_FAMILY: Record<string, FontFamily | undefined> = {
54
+ mathbb: 'KaTeX_AMS',
55
+ }
56
+
53
57
  //
54
58
  // constants
55
59
  //
@@ -1130,6 +1134,11 @@ function convert_tree(tree: Tree | TreeNode | null, attr: Attrs = {}): WithMath
1130
1134
  } else if (type == 'text') {
1131
1135
  const { body } = tree
1132
1136
  return convert_tree(body, attr)
1137
+ } else if (type == 'font') {
1138
+ const { font, body } = tree
1139
+ const font_family = TEX_FONT_FAMILY[font]
1140
+ const font_attr = font_family == null ? {} : { font_family }
1141
+ return convert_tree(body, { ...attr, ...font_attr })
1133
1142
  } else if (type == 'accent') {
1134
1143
  const { label, base: base0 } = tree
1135
1144
  const base = convert_tree(base0, attr)
package/src/gum.ts CHANGED
@@ -5,13 +5,13 @@ import './types/linebreak.d.ts'
5
5
  import './types/katex.d.ts'
6
6
 
7
7
  import { setTheme } from './lib/theme'
8
- import { sans, mono, moji, cmoji, light, regular, bold, none, black, white, gray, blue, red, green, yellow, purple, lightgray, darkgray, e, pi, phi, r2d, d2r } from './lib/const'
9
- import { is_scalar, is_string, is_boolean, is_object, is_function, is_array, zip, reshape, split, concat, slice, sum, prod, mean, cumsum, norm, range, linspace, enumerate, repeat, meshgrid, lingrid, exp, log, log10, sin, cos, tan, abs, pow, sqrt, sign, floor, ceil, round, atan, atan2, minimum, maximum, min, max, clamp, rescale, sigmoid, logit, smoothstep, setSeed, random, uniform, normal, integer, interp, palette, polar, polard, rounder, add2, sub2, mul2, div2, normalize } from './lib/utils'
8
+ import { sans, mono, moji, cmoji, light, regular, bold, none, black, white, gray, blue, red, green, yellow, purple, lightgray, darkgray, slate, e, pi, phi, r2d, d2r } from './lib/const'
9
+ import { is_scalar, is_string, is_boolean, is_object, is_function, is_array, zip, reshape, split, concat, slice, sum, prod, mean, cumsum, norm, range, linspace, enumerate, repeat, meshgrid, lingrid, exp, log, log10, sin, cos, tan, abs, pow, sqrt, sign, floor, ceil, round, atan, atan2, minimum, maximum, min, max, clamp, rescale, normalize, sigmoid, logit, smoothstep, setSeed, random, uniform, normal, integer, interp, palette, polar, polard, rounder, add2, sub2, mul2, div2, addn, subn, muln, divn, addc, subc, mulc, divc, conjc, normc, argc } from './lib/utils'
10
10
  import { registerFont } from './fonts/fonts'
11
11
 
12
12
  import { Context, Element, Group, Svg, Rectangle, Spacer, is_element, type ElementArgs } from './elems/core'
13
13
  import { Box, Frame, Stack, VStack, HStack, HWrap, Grid, Points, Anchor, Attach, Absolute } from './elems/layout'
14
- import { Line, UnitLine, VLine, HLine, Square, Ellipse, Arc, Circle, Dot, Ray, Shape, Triangle, Fill, VFill, HFill, Path, Command, MoveCmd, LineCmd, ArcCmd, CornerCmd, RoundedCornerCmd, CubicSplineCmd, Spline, RoundedRect, RoundedLine, ArrowHead, Arrow } from './elems/geometry'
14
+ import { Line, UnitLine, VLine, HLine, CoordLine, Segments, Square, Ellipse, Arc, Circle, Dot, Ray, Shape, Triangle, Fill, VFill, HFill, Path, Command, MoveCmd, LineCmd, ArcCmd, CornerCmd, RoundedCornerCmd, CubicSplineCmd, Spline, RoundedRect, RoundedLine, ArrowHead, Arrow } from './elems/geometry'
15
15
  import { spline1d, spline2d } from './lib/interp'
16
16
  import { Span, TextLine, Text, TextBox, TextFrame, TextStack, Bold, Italic } from './elems/text'
17
17
  import { Node, Edge, Network } from './elems/network'
@@ -27,11 +27,11 @@ const Rect = Rectangle
27
27
  type ElementConstructor = new (args: ElementArgs) => Element
28
28
 
29
29
  const CONST = {
30
- e, pi, phi, r2d, d2r, none, white, black, blue, red, green, yellow, purple, gray, lightgray, darkgray, sans, mono, moji, cmoji, light, regular, bold,
30
+ e, pi, phi, r2d, d2r, none, white, black, blue, red, green, yellow, purple, gray, lightgray, darkgray, slate, sans, mono, moji, cmoji, light, regular, bold,
31
31
  }
32
32
 
33
33
  const UTILS = {
34
- range, linspace, enumerate, repeat, meshgrid, lingrid, zip, reshape, split, concat, slice, sum, prod, mean, cumsum, min, max, minimum, maximum, norm, clamp, rescale, normalize, exp, log, log10, sin, cos, tan, abs, pow, sqrt, sign, floor, ceil, round, atan, atan2, sigmoid, logit, smoothstep, polar, polard, rounder, interp, palette, add2, sub2, mul2, div2, spline1d, spline2d,
34
+ range, linspace, enumerate, repeat, meshgrid, lingrid, zip, reshape, split, concat, slice, sum, prod, mean, cumsum, min, max, minimum, maximum, norm, clamp, rescale, normalize, exp, log, log10, sin, cos, tan, abs, pow, sqrt, sign, floor, ceil, round, atan, atan2, sigmoid, logit, smoothstep, polar, polard, rounder, interp, palette, add2, sub2, mul2, div2, addn, subn, muln, divn, addc, subc, mulc, divc, conjc, normc, argc, spline1d, spline2d,
35
35
  }
36
36
 
37
37
  const RAND = {
@@ -39,7 +39,7 @@ const RAND = {
39
39
  }
40
40
 
41
41
  const ELEMS: Record<string, ElementConstructor> = {
42
- Element, Group, Svg, Box, Frame, Stack, VStack, HStack, HWrap, Grid, Points, Anchor, Attach, Absolute, Spacer, Ray, Line, UnitLine, HLine, VLine, Rectangle, Rect, RoundedRect, RoundedLine, Square, Ellipse, Arc, Circle, Dot, Shape, Path, Spline, Triangle, Fill, VFill, HFill, Arrow, Field, Span, TextLine, Text, TextBox, TextFrame, TextStack, Bold, Italic, LabelBox, TitleBox, TitleFrame, ArrowHead, Node, Edge, Network, SymPoints, SymLine, SymSpline, SymShape, SymFill, SymField, Bar, VBar, HBar, Bars, VBars, HBars, Scale, VScale, HScale, Label, HLabel, VLabel, Labels, HLabels, VLabels, Axis, HAxis, VAxis, OuterLabel, Mesh, HMesh, VMesh, Mesh2D, Graph, Plot, BarPlot, Legend, Slide, Latex, Tex, MathSpan, MathSymbol, MathSpacer, MathRow, MathCol, MathBox, MathRule, MathText, SupSub, Frac, Sqrt, Accent, Bracket, PngImage, SvgImage
42
+ Element, Group, Svg, Box, Frame, Stack, VStack, HStack, HWrap, Grid, Points, Anchor, Attach, Absolute, Spacer, Ray, Line, UnitLine, HLine, VLine, CoordLine, Segments, Rectangle, Rect, RoundedRect, RoundedLine, Square, Ellipse, Arc, Circle, Dot, Shape, Path, Spline, Triangle, Fill, VFill, HFill, Arrow, Field, Span, TextLine, Text, TextBox, TextFrame, TextStack, Bold, Italic, LabelBox, TitleBox, TitleFrame, ArrowHead, Node, Edge, Network, SymPoints, SymLine, SymSpline, SymShape, SymFill, SymField, Bar, VBar, HBar, Bars, VBars, HBars, Scale, VScale, HScale, Label, HLabel, VLabel, Labels, HLabels, VLabels, Axis, HAxis, VAxis, OuterLabel, Mesh, HMesh, VMesh, Mesh2D, Graph, Plot, BarPlot, Legend, Slide, Latex, Tex, MathSpan, MathSymbol, MathSpacer, MathRow, MathCol, MathBox, MathRule, MathText, SupSub, Frac, Sqrt, Accent, Bracket, PngImage, SvgImage
43
43
  }
44
44
 
45
45
  const CONTEXT = { ...CONST, ...UTILS, ...RAND, ...ELEMS }
@@ -48,10 +48,10 @@ export {
48
48
  ELEMS, CONTEXT, Context,
49
49
  setTheme, registerFont, calcPngAspect, parseTable,
50
50
  is_string, is_boolean, is_array, is_object, is_function, is_element, is_scalar,
51
- e, pi, phi, r2d, d2r, none, white, black, blue, red, green, yellow, purple, gray, lightgray, darkgray, sans, mono, moji, cmoji, light, regular, bold,
52
- range, linspace, enumerate, repeat, meshgrid, lingrid, zip, reshape, split, concat, slice, sum, prod, mean, cumsum, min, max, minimum, maximum, norm, clamp, rescale, normalize, exp, log, log10, sin, cos, tan, abs, pow, sqrt, sign, floor, ceil, round, atan, atan2, sigmoid, logit, smoothstep, polar, polard, rounder, interp, palette, add2, sub2, mul2, div2, spline1d, spline2d,
51
+ e, pi, phi, r2d, d2r, none, white, black, blue, red, green, yellow, purple, gray, lightgray, darkgray, slate, sans, mono, moji, cmoji, light, regular, bold,
52
+ range, linspace, enumerate, repeat, meshgrid, lingrid, zip, reshape, split, concat, slice, sum, prod, mean, cumsum, min, max, minimum, maximum, norm, clamp, rescale, normalize, exp, log, log10, sin, cos, tan, abs, pow, sqrt, sign, floor, ceil, round, atan, atan2, sigmoid, logit, smoothstep, polar, polard, rounder, interp, palette, add2, sub2, mul2, div2, addn, subn, muln, divn, addc, subc, mulc, divc, conjc, normc, argc, spline1d, spline2d,
53
53
  setSeed, random, uniform, normal, integer,
54
- Element, Group, Svg, Box, Frame, Stack, HWrap, VStack, HStack, Grid, Points, Anchor, Attach, Absolute, Spacer, Ray, Line, UnitLine, HLine, VLine, Rectangle, Rect, RoundedRect, RoundedLine, Square, Ellipse, Arc, Circle, Dot, Shape, Path, Spline, Triangle, Fill, Arrow, Field, Span, TextLine, Text, TextBox, TextFrame, TextStack, Bold, Italic, LabelBox, TitleBox, TitleFrame, ArrowHead, Node, Edge, Network, SymPoints, SymLine, SymSpline, SymShape, SymFill, SymField, Bar, VBar, HBar, Bars, VBars, HBars, Scale, VScale, HScale, Label, HLabel, VLabel, Labels, HLabels, VLabels, Axis, HAxis, VAxis, OuterLabel, Mesh, HMesh, VMesh, Mesh2D, Graph, Plot, BarPlot, Legend, Slide, Latex, MathSpan, MathSymbol, MathSpacer, MathRow, MathCol, MathBox, MathRule, MathText, SupSub, Frac, Sqrt, Accent, Bracket, PngImage, SvgImage,
54
+ Element, Group, Svg, Box, Frame, Stack, HWrap, VStack, HStack, Grid, Points, Anchor, Attach, Absolute, Spacer, Ray, Line, UnitLine, HLine, VLine, CoordLine, Segments, Rectangle, Rect, RoundedRect, RoundedLine, Square, Ellipse, Arc, Circle, Dot, Shape, Path, Spline, Triangle, Fill, Arrow, Field, Span, TextLine, Text, TextBox, TextFrame, TextStack, Bold, Italic, LabelBox, TitleBox, TitleFrame, ArrowHead, Node, Edge, Network, SymPoints, SymLine, SymSpline, SymShape, SymFill, SymField, Bar, VBar, HBar, Bars, VBars, HBars, Scale, VScale, HScale, Label, HLabel, VLabel, Labels, HLabels, VLabels, Axis, HAxis, VAxis, OuterLabel, Mesh, HMesh, VMesh, Mesh2D, Graph, Plot, BarPlot, Legend, Slide, Latex, MathSpan, MathSymbol, MathSpacer, MathRow, MathCol, MathBox, MathRule, MathText, SupSub, Frac, Sqrt, Accent, Bracket, PngImage, SvgImage,
55
55
  Command, MoveCmd, LineCmd, ArcCmd, CornerCmd, RoundedCornerCmd, CubicSplineCmd,
56
56
  }
57
57
 
package/src/lib/const.ts CHANGED
@@ -32,6 +32,7 @@ const yellow = '#ffb300'
32
32
  const purple = '#9c27b0'
33
33
  const lightgray = '#f6f6f6'
34
34
  const darkgray = '#888888'
35
+ const slate = '#1e252e'
35
36
 
36
37
  // math
37
38
  const e = Math.E
@@ -55,4 +56,4 @@ const DEFAULTS = {
55
56
  calc_size: 16,
56
57
  }
57
58
 
58
- export { DEFAULTS, svgns, htmlns, sans, mono, moji, cmoji, light, regular, bold, vtext, none, black, white, gray, blue, red, green, yellow, purple, lightgray, darkgray, e, pi, phi, r2d, d2r }
59
+ export { DEFAULTS, svgns, htmlns, sans, mono, moji, cmoji, light, regular, bold, vtext, none, black, white, gray, blue, red, green, yellow, purple, lightgray, darkgray, slate, e, pi, phi, r2d, d2r }
package/src/lib/parse.ts CHANGED
@@ -291,8 +291,14 @@ const handlers: Record<string, (node: ASTNode) => any> = {
291
291
  return body.map(walkTree).join('\n')
292
292
  },
293
293
  MethodDefinition(node) {
294
- const { key, value } = node
295
- return `${walkTree(key)}${walkTree(value)}`
294
+ const { key, value, computed, static: isStatic, kind } = node
295
+ const prefix = isStatic ? 'static ' : ''
296
+ const name = computed ? `[${walkTree(key)}]` : walkTree(key)
297
+ const params = value.params.map(walkTree).join(', ')
298
+ const body = walkTree(value.body)
299
+ if (kind == 'get') return `${prefix}get ${name}() ${body}`
300
+ if (kind == 'set') return `${prefix}set ${name}(${params}) ${body}`
301
+ return `${prefix}${name}(${params}) ${body}`
296
302
  },
297
303
  JSXIdentifier(node) {
298
304
  return node.name
package/src/lib/types.ts CHANGED
@@ -7,7 +7,9 @@ type Limit = [number, number]
7
7
  type Size = [number, number]
8
8
  type Grad = [number, number]
9
9
  type Polar = [number | Size, number]
10
- type Pair = Point | Size | Limit | Grad
10
+ type Complex = [number, number]
11
+ type Pair = Point | Size | Limit | Grad | Complex
12
+ type Vector = number[]
11
13
 
12
14
  // color
13
15
  type RGBA = [number, number, number, number]
@@ -72,4 +74,4 @@ interface CliArgs {
72
74
  }
73
75
 
74
76
 
75
- export type { Point, Rect, Limit, Size, Grad, Polar, Pair, RGBA, MNumber, MPoint, AlignValue, Align, Zone, Side, Side0, Orient, Angle, Direc, RoundedValue, Padding, Rounded, Attrs, Spec, ThemeName, OutputFormat, LoadFileData, LoadFile, CliArgs }
77
+ export type { Point, Rect, Limit, Size, Grad, Polar, Complex, Pair, Vector, RGBA, MNumber, MPoint, AlignValue, Align, Zone, Side, Side0, Orient, Angle, Direc, RoundedValue, Padding, Rounded, Attrs, Spec, ThemeName, OutputFormat, LoadFileData, LoadFile, CliArgs }
package/src/lib/utils.ts CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  import { DEFAULTS as D, d2r, r2d } from './const'
4
4
  import { setSeed, random, uniform, normal, integer } from './rng'
5
- import type { Point, Rect, Limit, RGBA, MNumber, MPoint, Orient, Side, Side0, Angle, Direc, Size, Pair, Grad, Polar, Attrs } from './types'
5
+ import type { Point, Rect, Limit, RGBA, MNumber, MPoint, Orient, Side, Side0, Direc, Size, Pair, Grad, Complex, Vector, Attrs } from './types'
6
6
 
7
7
  //
8
8
  // environment tests
@@ -461,6 +461,78 @@ function div2(p0: number | Pair, p1: number | Pair): Pair {
461
461
  return [ x0 / x1, y0 / y1 ]
462
462
  }
463
463
 
464
+ //
465
+ // vector arithmetic
466
+ //
467
+
468
+ function broadcast_op(op: (x: number, y: number) => number, v0: Vector, v1: Vector): Vector {
469
+ return zip(v0, v1).map(([ x0, x1 ]) => op(x0, x1))
470
+ }
471
+
472
+ function addn(v0: Vector, v1: Vector): Vector {
473
+ return broadcast_op((x, y) => x + y, v0, v1)
474
+ }
475
+
476
+ function subn(v0: Vector, v1: Vector): Vector {
477
+ return broadcast_op((x, y) => x - y, v0, v1)
478
+ }
479
+
480
+ function muln(v0: Vector, v1: Vector): Vector {
481
+ return broadcast_op((x, y) => x * y, v0, v1)
482
+ }
483
+
484
+ function divn(v0: Vector, v1: Vector): Vector {
485
+ return broadcast_op((x, y) => x / y, v0, v1)
486
+ }
487
+
488
+ //
489
+ // complex arithmetic
490
+ //
491
+
492
+ function ensure_complex(z: number | Complex): Complex {
493
+ return is_scalar(z) ? [ z, 0 ] as Complex : z
494
+ }
495
+
496
+ function addc(z: number | Complex, w: number | Complex): Complex {
497
+ const [ x, y ] = ensure_complex(z)
498
+ const [ u, v ] = ensure_complex(w)
499
+ return [ x + u, y + v ]
500
+ }
501
+
502
+ function subc(z: number | Complex, w: number | Complex): Complex {
503
+ const [ x, y ] = ensure_complex(z)
504
+ const [ u, v ] = ensure_complex(w)
505
+ return [ x - u, y - v ]
506
+ }
507
+
508
+ function mulc(z: number | Complex, w: number | Complex): Complex {
509
+ const [ x, y ] = ensure_complex(z)
510
+ const [ u, v ] = ensure_complex(w)
511
+ return [ x * u - y * v, x * v + y * u ]
512
+ }
513
+
514
+ function divc(z: number | Complex, w: number | Complex): Complex {
515
+ const [ x, y ] = ensure_complex(z)
516
+ const [ u, v ] = ensure_complex(w)
517
+ const denom = norm([ u, v ], 2)
518
+ return [ (x * u + y * v) / denom, (y * u - x * v) / denom ]
519
+ }
520
+
521
+ function conjc(z: number | Complex): Complex {
522
+ const [ x, y ] = ensure_complex(z)
523
+ return [ x, -y ]
524
+ }
525
+
526
+ function normc(z: number | Complex): number {
527
+ const [ x, y ] = ensure_complex(z)
528
+ return norm([ x, y ], 2)
529
+ }
530
+
531
+ function argc(z: number | Complex): number {
532
+ const [ x, y ] = ensure_complex(z)
533
+ return atan2(y, x)
534
+ }
535
+
464
536
  //
465
537
  // metaposition arithmetic
466
538
  //
@@ -913,4 +985,4 @@ function binary_search(arr: number[], t: number): number {
913
985
  // export
914
986
  //
915
987
 
916
- export { is_browser, is_boolean, is_scalar, is_string, is_number, is_object, is_function, is_array, is_singleton, is_point, ensure_vector, ensure_pair, ensure_singleton, ensure_function, check_singleton, check_array, check_string, gzip, zip, reshape, split, concat, squeeze, slice, intersperse, sum, prod, mean, all, any, cumsum, norm, normalize, range, linspace, enumerate, repeat, padvec, meshgrid, lingrid, map_object, filter_object, compress_whitespace, exp, log, log10, sin, cos, tan, cot, abs, pow, sqrt, sign, floor, ceil, round, atan, atan2, isNan, isInf, minimum, maximum, heaviside, heavisign, abs_min, abs_max, min, max, clamp, rescale, sigmoid, logit, smoothstep, identity, invert, setSeed, random, uniform, normal, integer, add2, sub2, mul2, div2, ensure_number, ensure_point, ensure_mnumber, ensure_mpoint, addm, subm, add2m, sub2m, make_mpoint, squeeze_mnumber, squeeze_mpoint, rect_size, rect_dims, rect_center, rect_radius, rect_aspect, rect_radial, norm_angle, split_limits, vector_angle, angle_direc, polar, polard, side_direc, unit_direc, norm_side, rgba_repr, interp, palette, detect_coords, resolve_limits, join_limits, invert_orient, aspect_invariant, flip_rect, radial_rect, box_rect, rect_box, cbox_rect, rect_cbox, merge_rects, merge_points, merge_limits, merge_values, expand_limits, expand_rect, upright_rect, upright_limits, rounder, remap_rect, resizer, rescaler, rotate_aspect, prefix_split, prefix_join, binary_search }
988
+ export { is_browser, is_boolean, is_scalar, is_string, is_number, is_object, is_function, is_array, is_singleton, is_point, ensure_vector, ensure_pair, ensure_singleton, ensure_function, check_singleton, check_array, check_string, gzip, zip, reshape, split, concat, squeeze, slice, intersperse, sum, prod, mean, all, any, cumsum, norm, normalize, range, linspace, enumerate, repeat, padvec, meshgrid, lingrid, map_object, filter_object, compress_whitespace, exp, log, log10, sin, cos, tan, cot, abs, pow, sqrt, sign, floor, ceil, round, atan, atan2, isNan, isInf, minimum, maximum, heaviside, heavisign, abs_min, abs_max, min, max, clamp, rescale, sigmoid, logit, smoothstep, identity, invert, setSeed, random, uniform, normal, integer, add2, sub2, mul2, div2, addn, subn, muln, divn, addc, subc, mulc, divc, conjc, normc, argc, ensure_number, ensure_point, ensure_mnumber, ensure_mpoint, addm, subm, add2m, sub2m, make_mpoint, squeeze_mnumber, squeeze_mpoint, rect_size, rect_dims, rect_center, rect_radius, rect_aspect, rect_radial, norm_angle, split_limits, vector_angle, angle_direc, polar, polard, side_direc, unit_direc, norm_side, rgba_repr, interp, palette, detect_coords, resolve_limits, join_limits, invert_orient, aspect_invariant, flip_rect, radial_rect, box_rect, rect_box, cbox_rect, rect_cbox, merge_rects, merge_points, merge_limits, merge_values, expand_limits, expand_rect, upright_rect, upright_limits, rounder, remap_rect, resizer, rescaler, rotate_aspect, prefix_split, prefix_join, binary_search }
@@ -53,6 +53,13 @@ declare module 'katex' {
53
53
  body: TreeNode[]
54
54
  }
55
55
 
56
+ export type TreeFont = {
57
+ type: 'font'
58
+ mode: SymbolMode
59
+ font: string
60
+ body: TreeNode
61
+ }
62
+
56
63
  export type TreeSupSub = {
57
64
  type: 'supsub'
58
65
  base: TreeNode | null
@@ -115,6 +122,7 @@ declare module 'katex' {
115
122
  | TreeOp
116
123
  | TreeKern
117
124
  | TreeText
125
+ | TreeFont
118
126
  | TreeStyling
119
127
  | TreeAccent
120
128
  | TreeSupSub