@thi.ng/geom-voronoi 2.3.33 → 2.3.35

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 (3) hide show
  1. package/CHANGELOG.md +1 -1
  2. package/index.js +296 -296
  3. package/package.json +16 -14
package/CHANGELOG.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Change Log
2
2
 
3
- - **Last updated**: 2023-12-03T12:13:31Z
3
+ - **Last updated**: 2023-12-11T10:07:09Z
4
4
  - **Generator**: [thi.ng/monopub](https://thi.ng/monopub)
5
5
 
6
6
  All notable changes to this project will be documented in this file.
package/index.js CHANGED
@@ -2,315 +2,315 @@ import { defBitField } from "@thi.ng/bitfield/bitfield";
2
2
  import { isNumber } from "@thi.ng/checks/is-number";
3
3
  import { liangBarsky2 } from "@thi.ng/geom-clip-line/liang-barsky";
4
4
  import { sutherlandHodgeman } from "@thi.ng/geom-clip-poly";
5
- import { pointInCircumCircle, pointInPolygon2, pointInSegment, } from "@thi.ng/geom-isec/point";
5
+ import {
6
+ pointInCircumCircle,
7
+ pointInPolygon2,
8
+ pointInSegment
9
+ } from "@thi.ng/geom-isec/point";
6
10
  import { centroid } from "@thi.ng/geom-poly-utils/centroid";
7
11
  import { circumCenter2 } from "@thi.ng/geom-poly-utils/circumcenter";
8
12
  import { EPS } from "@thi.ng/math/api";
9
13
  import { defEdge } from "@thi.ng/quad-edge";
10
- import { ZERO2, } from "@thi.ng/vectors/api";
14
+ import {
15
+ ZERO2
16
+ } from "@thi.ng/vectors/api";
11
17
  import { eqDelta2 } from "@thi.ng/vectors/eqdelta";
12
18
  import { signedArea2 } from "@thi.ng/vectors/signed-area";
13
- export class DVMesh {
14
- first;
15
- nextEID;
16
- nextVID;
17
- constructor(pts, size = 1e5) {
18
- const a = { pos: [0, -size], id: 0 };
19
- const b = { pos: [size, size], id: 1 };
20
- const c = { pos: [-size, size], id: 2 };
21
- const eab = defEdge(0, a, b);
22
- const ebc = defEdge(4, b, c);
23
- const eca = defEdge(8, c, a);
24
- eab.sym.splice(ebc);
25
- ebc.sym.splice(eca);
26
- eca.sym.splice(eab);
27
- this.first = eab;
28
- this.nextEID = 12;
29
- this.nextVID = 3;
30
- if (pts && pts.length) {
31
- isNumber(pts[0][0])
32
- ? this.addKeys(pts)
33
- : this.addAll(pts);
34
- }
35
- else {
36
- this.computeDual();
37
- }
38
- }
39
- /**
40
- * Adds a single new point `p` w/ optional value `val` to the mesh, unless
41
- * there already is another point existing within radius `eps`. If `update`
42
- * is true (default), the mesh dual will be automatically updated using
43
- * {@link DVMesh.computeDual}.
44
- *
45
- * @remarks
46
- * If adding multiple points, ensure `computeDual` will only be called
47
- * for/after the last point insertion to avoid computational overhead.
48
- *
49
- * @param p -
50
- * @param val -
51
- * @param eps -
52
- * @param update -
53
- */
54
- add(p, val, eps = EPS, update = true) {
55
- let [e, exists] = this.locate(p, eps);
56
- if (exists)
57
- return false;
58
- if (pointInSegment(p, e.origin.pos, e.dest.pos)) {
59
- e = e.oprev;
60
- e.onext.remove();
61
- }
62
- let base = defEdge(this.nextEID, e.origin, {
63
- pos: p,
64
- id: this.nextVID++,
65
- val,
66
- });
67
- base.splice(e);
68
- this.nextEID += 4;
69
- const first = base;
70
- do {
71
- base = e.connect(base.sym, this.nextEID);
72
- e = base.oprev;
73
- this.nextEID += 4;
74
- } while (e.lnext !== first);
75
- // enforce delaunay constraints
76
- do {
77
- const t = e.oprev;
78
- if (isRightOf(t.dest.pos, e) &&
79
- pointInCircumCircle(e.origin.pos, t.dest.pos, e.dest.pos, p)) {
80
- e.swap();
81
- e = e.oprev;
82
- }
83
- else if (e.onext !== first) {
84
- e = e.onext.lprev;
85
- }
86
- else {
87
- break;
88
- }
89
- } while (true);
90
- update && this.computeDual();
91
- return true;
19
+ class DVMesh {
20
+ first;
21
+ nextEID;
22
+ nextVID;
23
+ constructor(pts, size = 1e5) {
24
+ const a = { pos: [0, -size], id: 0 };
25
+ const b = { pos: [size, size], id: 1 };
26
+ const c = { pos: [-size, size], id: 2 };
27
+ const eab = defEdge(0, a, b);
28
+ const ebc = defEdge(4, b, c);
29
+ const eca = defEdge(8, c, a);
30
+ eab.sym.splice(ebc);
31
+ ebc.sym.splice(eca);
32
+ eca.sym.splice(eab);
33
+ this.first = eab;
34
+ this.nextEID = 12;
35
+ this.nextVID = 3;
36
+ if (pts && pts.length) {
37
+ isNumber(pts[0][0]) ? this.addKeys(pts) : this.addAll(pts);
38
+ } else {
39
+ this.computeDual();
92
40
  }
93
- addKeys(pts, eps) {
94
- for (let p of pts) {
95
- this.add(p, undefined, eps, false);
96
- }
97
- this.computeDual();
41
+ }
42
+ /**
43
+ * Adds a single new point `p` w/ optional value `val` to the mesh, unless
44
+ * there already is another point existing within radius `eps`. If `update`
45
+ * is true (default), the mesh dual will be automatically updated using
46
+ * {@link DVMesh.computeDual}.
47
+ *
48
+ * @remarks
49
+ * If adding multiple points, ensure `computeDual` will only be called
50
+ * for/after the last point insertion to avoid computational overhead.
51
+ *
52
+ * @param p -
53
+ * @param val -
54
+ * @param eps -
55
+ * @param update -
56
+ */
57
+ add(p, val, eps = EPS, update = true) {
58
+ let [e, exists] = this.locate(p, eps);
59
+ if (exists)
60
+ return false;
61
+ if (pointInSegment(p, e.origin.pos, e.dest.pos)) {
62
+ e = e.oprev;
63
+ e.onext.remove();
98
64
  }
99
- addAll(pairs, eps) {
100
- for (let p of pairs) {
101
- this.add(p[0], p[1], eps, false);
102
- }
103
- this.computeDual();
65
+ let base = defEdge(this.nextEID, e.origin, {
66
+ pos: p,
67
+ id: this.nextVID++,
68
+ val
69
+ });
70
+ base.splice(e);
71
+ this.nextEID += 4;
72
+ const first = base;
73
+ do {
74
+ base = e.connect(base.sym, this.nextEID);
75
+ e = base.oprev;
76
+ this.nextEID += 4;
77
+ } while (e.lnext !== first);
78
+ do {
79
+ const t = e.oprev;
80
+ if (isRightOf(t.dest.pos, e) && pointInCircumCircle(e.origin.pos, t.dest.pos, e.dest.pos, p)) {
81
+ e.swap();
82
+ e = e.oprev;
83
+ } else if (e.onext !== first) {
84
+ e = e.onext.lprev;
85
+ } else {
86
+ break;
87
+ }
88
+ } while (true);
89
+ update && this.computeDual();
90
+ return true;
91
+ }
92
+ addKeys(pts, eps) {
93
+ for (let p of pts) {
94
+ this.add(p, void 0, eps, false);
104
95
  }
105
- /**
106
- * Returns tuple of the edge related to `p` and a boolean to indicate if
107
- * `p` already exists in this triangulation (true if already present).
108
- *
109
- * @param p - query point
110
- */
111
- locate(p, eps = EPS) {
112
- let e = this.first;
113
- while (true) {
114
- if (eqDelta2(p, e.origin.pos, eps) ||
115
- eqDelta2(p, e.dest.pos, eps)) {
116
- return [e, true];
117
- }
118
- else if (isRightOf(p, e)) {
119
- e = e.sym;
120
- }
121
- else if (!isRightOf(p, e.onext)) {
122
- e = e.onext;
123
- }
124
- else if (!isRightOf(p, e.dprev)) {
125
- e = e.dprev;
126
- }
127
- else {
128
- return [e, false];
129
- }
130
- }
96
+ this.computeDual();
97
+ }
98
+ addAll(pairs, eps) {
99
+ for (let p of pairs) {
100
+ this.add(p[0], p[1], eps, false);
131
101
  }
132
- /**
133
- * Syncronize / update / add dual faces (i.e. Voronoi) for current
134
- * primary mesh (i.e. Delaunay).
135
- */
136
- computeDual() {
137
- const work = [this.first.rot];
138
- const visitedEdges = {};
139
- const visitedVerts = {};
140
- while (work.length) {
141
- const e = work.pop();
142
- if (visitedEdges[e.id])
143
- continue;
144
- visitedEdges[e.id] = true;
145
- if (!e.origin || !visitedVerts[e.origin.id]) {
146
- let t = e.rot;
147
- const a = t.origin.pos;
148
- let isBoundary = t.origin.id < 3;
149
- t = t.lnext;
150
- const b = t.origin.pos;
151
- isBoundary = isBoundary && t.origin.id < 3;
152
- t = t.lnext;
153
- const c = t.origin.pos;
154
- isBoundary = isBoundary && t.origin.id < 3;
155
- const id = this.nextVID++;
156
- e.origin = {
157
- pos: !isBoundary ? circumCenter2(a, b, c) : ZERO2,
158
- id,
159
- };
160
- visitedVerts[id] = true;
161
- }
162
- work.push(e.sym, e.onext, e.lnext);
163
- }
102
+ this.computeDual();
103
+ }
104
+ /**
105
+ * Returns tuple of the edge related to `p` and a boolean to indicate if
106
+ * `p` already exists in this triangulation (true if already present).
107
+ *
108
+ * @param p - query point
109
+ */
110
+ locate(p, eps = EPS) {
111
+ let e = this.first;
112
+ while (true) {
113
+ if (eqDelta2(p, e.origin.pos, eps) || eqDelta2(p, e.dest.pos, eps)) {
114
+ return [e, true];
115
+ } else if (isRightOf(p, e)) {
116
+ e = e.sym;
117
+ } else if (!isRightOf(p, e.onext)) {
118
+ e = e.onext;
119
+ } else if (!isRightOf(p, e.dprev)) {
120
+ e = e.dprev;
121
+ } else {
122
+ return [e, false];
123
+ }
164
124
  }
165
- delaunay(bounds) {
166
- const cells = [];
167
- const usedEdges = defBitField(this.nextEID);
168
- const bc = bounds && centroid(bounds);
169
- this.traverse((eab) => {
170
- if (!usedEdges.at(eab.id)) {
171
- const ebc = eab.lnext;
172
- const eca = ebc.lnext;
173
- const va = eab.origin.pos;
174
- const vb = ebc.origin.pos;
175
- const vc = eca.origin.pos;
176
- let verts = [va, vb, vc];
177
- if (bounds &&
178
- !(pointInPolygon2(va, bounds) &&
179
- pointInPolygon2(vb, bounds) &&
180
- pointInPolygon2(vc, bounds))) {
181
- verts = sutherlandHodgeman(verts, bounds, bc);
182
- if (verts.length > 2) {
183
- cells.push(verts);
184
- }
185
- }
186
- else {
187
- cells.push(verts);
188
- }
189
- usedEdges.setAt(eab.id);
190
- usedEdges.setAt(ebc.id);
191
- usedEdges.setAt(eca.id);
192
- }
193
- });
194
- return cells;
125
+ }
126
+ /**
127
+ * Syncronize / update / add dual faces (i.e. Voronoi) for current
128
+ * primary mesh (i.e. Delaunay).
129
+ */
130
+ computeDual() {
131
+ const work = [this.first.rot];
132
+ const visitedEdges = {};
133
+ const visitedVerts = {};
134
+ while (work.length) {
135
+ const e = work.pop();
136
+ if (visitedEdges[e.id])
137
+ continue;
138
+ visitedEdges[e.id] = true;
139
+ if (!e.origin || !visitedVerts[e.origin.id]) {
140
+ let t = e.rot;
141
+ const a = t.origin.pos;
142
+ let isBoundary = t.origin.id < 3;
143
+ t = t.lnext;
144
+ const b = t.origin.pos;
145
+ isBoundary = isBoundary && t.origin.id < 3;
146
+ t = t.lnext;
147
+ const c = t.origin.pos;
148
+ isBoundary = isBoundary && t.origin.id < 3;
149
+ const id = this.nextVID++;
150
+ e.origin = {
151
+ pos: !isBoundary ? circumCenter2(a, b, c) : ZERO2,
152
+ id
153
+ };
154
+ visitedVerts[id] = true;
155
+ }
156
+ work.push(e.sym, e.onext, e.lnext);
195
157
  }
196
- /**
197
- * Advanced use only. Returns Delaunay triangles as arrays of raw
198
- * [thi.ng/quad-edge
199
- * Edges](https://docs.thi.ng/umbrella/quad-edge/classes/Edge.html).
200
- *
201
- * @remarks
202
- * The actual vertex position associated with each edge can be obtained via
203
- * `e.origin.pos`. Each edge (and each associated {@link Vertex}) also has a
204
- * unique ID, accessible via `e.id` and `e.origin.id`.
205
- */
206
- delaunayQE() {
207
- const cells = [];
208
- const usedEdges = defBitField(this.nextEID);
209
- this.traverse((eab) => {
210
- if (!usedEdges.at(eab.id)) {
211
- const ebc = eab.lnext;
212
- const eca = ebc.lnext;
213
- cells.push([eab, ebc, eca]);
214
- usedEdges.setAt(eab.id);
215
- usedEdges.setAt(ebc.id);
216
- usedEdges.setAt(eca.id);
217
- }
218
- });
219
- return cells;
220
- }
221
- voronoi(bounds) {
222
- const cells = [];
223
- const bc = bounds && centroid(bounds);
224
- this.traverse(bounds
225
- ? (e) => {
226
- const first = (e = e.rot);
227
- let verts = [];
228
- let needsClip = false;
229
- let p;
230
- do {
231
- p = e.origin.pos;
232
- verts.push(p);
233
- needsClip =
234
- needsClip || !pointInPolygon2(p, bounds);
235
- } while ((e = e.lnext) !== first);
236
- if (needsClip) {
237
- verts = sutherlandHodgeman(verts, bounds, bc);
238
- if (verts.length < 3)
239
- return;
240
- }
241
- cells.push(verts);
242
- }
243
- : (e) => {
244
- const first = (e = e.rot);
245
- const verts = [];
246
- do {
247
- verts.push(e.origin.pos);
248
- } while ((e = e.lnext) !== first);
249
- cells.push(verts);
250
- }, false);
251
- return cells;
252
- }
253
- /**
254
- * Advanced use only. Returns Voronoi cells as arrays of raw
255
- * [thi.ng/quad-edge
256
- * Edges](https://docs.thi.ng/umbrella/quad-edge/classes/Edge.html).
257
- *
258
- * @remarks
259
- * The actual vertex position associated with each edge can be obtained via
260
- * `e.origin.pos`. Each edge (and each associated {@link Vertex}) also has a
261
- * unique ID, accessible via `e.id` and `e.origin.id`.
262
- */
263
- voronoiQE() {
264
- const cells = [];
265
- this.traverse((e) => {
266
- const first = (e = e.rot);
267
- const cell = [];
268
- do {
269
- cell.push(e);
270
- } while ((e = e.lnext) !== first);
271
- cells.push(cell);
272
- }, false);
273
- return cells;
274
- }
275
- edges(voronoi = false, boundsMinMax) {
276
- const edges = [];
277
- this.traverse((e, visitedEdges) => {
278
- if (visitedEdges.at(e.sym.id))
279
- return;
280
- if (e.origin.id > 2 && e.dest.id > 2) {
281
- const a = e.origin.pos;
282
- const b = e.dest.pos;
283
- if (boundsMinMax) {
284
- const clip = liangBarsky2(a, b, boundsMinMax[0], boundsMinMax[1]);
285
- clip && edges.push([clip[0], clip[1]]);
286
- }
287
- else {
288
- edges.push([a, b]);
289
- }
290
- }
291
- visitedEdges.setAt(e.id);
292
- }, true, voronoi ? this.first.rot : this.first);
293
- return edges;
294
- }
295
- traverse(proc, edges = true, e = this.first) {
296
- const work = [e];
297
- const visitedEdges = defBitField(this.nextEID);
298
- const visitedVerts = defBitField(this.nextVID);
299
- while (work.length) {
300
- e = work.pop();
301
- if (visitedEdges.at(e.id))
302
- continue;
303
- visitedEdges.setAt(e.id);
304
- const eoID = e.origin.id;
305
- if (eoID > 2 && e.rot.origin.id > 2) {
306
- if (edges || !visitedVerts.at(eoID)) {
307
- visitedVerts.setAt(eoID);
308
- proc(e, visitedEdges, visitedVerts);
309
- }
310
- }
311
- work.push(e.sym, e.onext, e.lnext);
158
+ }
159
+ delaunay(bounds) {
160
+ const cells = [];
161
+ const usedEdges = defBitField(this.nextEID);
162
+ const bc = bounds && centroid(bounds);
163
+ this.traverse((eab) => {
164
+ if (!usedEdges.at(eab.id)) {
165
+ const ebc = eab.lnext;
166
+ const eca = ebc.lnext;
167
+ const va = eab.origin.pos;
168
+ const vb = ebc.origin.pos;
169
+ const vc = eca.origin.pos;
170
+ let verts = [va, vb, vc];
171
+ if (bounds && !(pointInPolygon2(va, bounds) && pointInPolygon2(vb, bounds) && pointInPolygon2(vc, bounds))) {
172
+ verts = sutherlandHodgeman(verts, bounds, bc);
173
+ if (verts.length > 2) {
174
+ cells.push(verts);
175
+ }
176
+ } else {
177
+ cells.push(verts);
178
+ }
179
+ usedEdges.setAt(eab.id);
180
+ usedEdges.setAt(ebc.id);
181
+ usedEdges.setAt(eca.id);
182
+ }
183
+ });
184
+ return cells;
185
+ }
186
+ /**
187
+ * Advanced use only. Returns Delaunay triangles as arrays of raw
188
+ * [thi.ng/quad-edge
189
+ * Edges](https://docs.thi.ng/umbrella/quad-edge/classes/Edge.html).
190
+ *
191
+ * @remarks
192
+ * The actual vertex position associated with each edge can be obtained via
193
+ * `e.origin.pos`. Each edge (and each associated {@link Vertex}) also has a
194
+ * unique ID, accessible via `e.id` and `e.origin.id`.
195
+ */
196
+ delaunayQE() {
197
+ const cells = [];
198
+ const usedEdges = defBitField(this.nextEID);
199
+ this.traverse((eab) => {
200
+ if (!usedEdges.at(eab.id)) {
201
+ const ebc = eab.lnext;
202
+ const eca = ebc.lnext;
203
+ cells.push([eab, ebc, eca]);
204
+ usedEdges.setAt(eab.id);
205
+ usedEdges.setAt(ebc.id);
206
+ usedEdges.setAt(eca.id);
207
+ }
208
+ });
209
+ return cells;
210
+ }
211
+ voronoi(bounds) {
212
+ const cells = [];
213
+ const bc = bounds && centroid(bounds);
214
+ this.traverse(
215
+ bounds ? (e) => {
216
+ const first = e = e.rot;
217
+ let verts = [];
218
+ let needsClip = false;
219
+ let p;
220
+ do {
221
+ p = e.origin.pos;
222
+ verts.push(p);
223
+ needsClip = needsClip || !pointInPolygon2(p, bounds);
224
+ } while ((e = e.lnext) !== first);
225
+ if (needsClip) {
226
+ verts = sutherlandHodgeman(verts, bounds, bc);
227
+ if (verts.length < 3)
228
+ return;
229
+ }
230
+ cells.push(verts);
231
+ } : (e) => {
232
+ const first = e = e.rot;
233
+ const verts = [];
234
+ do {
235
+ verts.push(e.origin.pos);
236
+ } while ((e = e.lnext) !== first);
237
+ cells.push(verts);
238
+ },
239
+ false
240
+ );
241
+ return cells;
242
+ }
243
+ /**
244
+ * Advanced use only. Returns Voronoi cells as arrays of raw
245
+ * [thi.ng/quad-edge
246
+ * Edges](https://docs.thi.ng/umbrella/quad-edge/classes/Edge.html).
247
+ *
248
+ * @remarks
249
+ * The actual vertex position associated with each edge can be obtained via
250
+ * `e.origin.pos`. Each edge (and each associated {@link Vertex}) also has a
251
+ * unique ID, accessible via `e.id` and `e.origin.id`.
252
+ */
253
+ voronoiQE() {
254
+ const cells = [];
255
+ this.traverse((e) => {
256
+ const first = e = e.rot;
257
+ const cell = [];
258
+ do {
259
+ cell.push(e);
260
+ } while ((e = e.lnext) !== first);
261
+ cells.push(cell);
262
+ }, false);
263
+ return cells;
264
+ }
265
+ edges(voronoi = false, boundsMinMax) {
266
+ const edges = [];
267
+ this.traverse(
268
+ (e, visitedEdges) => {
269
+ if (visitedEdges.at(e.sym.id))
270
+ return;
271
+ if (e.origin.id > 2 && e.dest.id > 2) {
272
+ const a = e.origin.pos;
273
+ const b = e.dest.pos;
274
+ if (boundsMinMax) {
275
+ const clip = liangBarsky2(
276
+ a,
277
+ b,
278
+ boundsMinMax[0],
279
+ boundsMinMax[1]
280
+ );
281
+ clip && edges.push([clip[0], clip[1]]);
282
+ } else {
283
+ edges.push([a, b]);
284
+ }
285
+ }
286
+ visitedEdges.setAt(e.id);
287
+ },
288
+ true,
289
+ voronoi ? this.first.rot : this.first
290
+ );
291
+ return edges;
292
+ }
293
+ traverse(proc, edges = true, e = this.first) {
294
+ const work = [e];
295
+ const visitedEdges = defBitField(this.nextEID);
296
+ const visitedVerts = defBitField(this.nextVID);
297
+ while (work.length) {
298
+ e = work.pop();
299
+ if (visitedEdges.at(e.id))
300
+ continue;
301
+ visitedEdges.setAt(e.id);
302
+ const eoID = e.origin.id;
303
+ if (eoID > 2 && e.rot.origin.id > 2) {
304
+ if (edges || !visitedVerts.at(eoID)) {
305
+ visitedVerts.setAt(eoID);
306
+ proc(e, visitedEdges, visitedVerts);
312
307
  }
308
+ }
309
+ work.push(e.sym, e.onext, e.lnext);
313
310
  }
311
+ }
314
312
  }
315
- /** @internal */
316
313
  const isRightOf = (p, e) => signedArea2(p, e.dest.pos, e.origin.pos) > 0;
314
+ export {
315
+ DVMesh
316
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thi.ng/geom-voronoi",
3
- "version": "2.3.33",
3
+ "version": "2.3.35",
4
4
  "description": "Fast, incremental 2D Delaunay & Voronoi mesh implementation",
5
5
  "type": "module",
6
6
  "module": "./index.js",
@@ -24,7 +24,9 @@
24
24
  "author": "Karsten Schmidt (https://thi.ng)",
25
25
  "license": "Apache-2.0",
26
26
  "scripts": {
27
- "build": "yarn clean && tsc --declaration",
27
+ "build": "yarn build:esbuild && yarn build:decl",
28
+ "build:decl": "tsc --declaration --emitDeclarationOnly",
29
+ "build:esbuild": "esbuild --format=esm --platform=neutral --target=es2022 --tsconfig=tsconfig.json --outdir=. src/**/*.ts",
28
30
  "clean": "rimraf --glob '*.js' '*.d.ts' '*.map' doc",
29
31
  "doc": "typedoc --excludePrivate --excludeInternal --out doc src/index.ts",
30
32
  "doc:ae": "mkdir -p .ae/doc .ae/temp && api-extractor run --local --verbose",
@@ -33,20 +35,20 @@
33
35
  "test": "bun test"
34
36
  },
35
37
  "dependencies": {
36
- "@thi.ng/api": "^8.9.10",
37
- "@thi.ng/bitfield": "^2.3.8",
38
- "@thi.ng/checks": "^3.4.10",
39
- "@thi.ng/geom-clip-line": "^2.3.48",
40
- "@thi.ng/geom-clip-poly": "^2.1.90",
41
- "@thi.ng/geom-isec": "^2.1.90",
42
- "@thi.ng/geom-poly-utils": "^2.3.74",
43
- "@thi.ng/math": "^5.7.5",
44
- "@thi.ng/quad-edge": "^3.1.41",
45
- "@thi.ng/vectors": "^7.8.7"
38
+ "@thi.ng/api": "^8.9.12",
39
+ "@thi.ng/bitfield": "^2.3.10",
40
+ "@thi.ng/checks": "^3.4.12",
41
+ "@thi.ng/geom-clip-line": "^2.3.50",
42
+ "@thi.ng/geom-clip-poly": "^2.1.92",
43
+ "@thi.ng/geom-isec": "^2.1.92",
44
+ "@thi.ng/geom-poly-utils": "^2.3.76",
45
+ "@thi.ng/math": "^5.7.7",
46
+ "@thi.ng/quad-edge": "^3.1.43",
47
+ "@thi.ng/vectors": "^7.8.9"
46
48
  },
47
49
  "devDependencies": {
48
50
  "@microsoft/api-extractor": "^7.38.3",
49
- "@thi.ng/testament": "^0.4.3",
51
+ "esbuild": "^0.19.8",
50
52
  "rimraf": "^5.0.5",
51
53
  "tools": "^0.0.1",
52
54
  "typedoc": "^0.25.4",
@@ -90,5 +92,5 @@
90
92
  ],
91
93
  "year": 2016
92
94
  },
93
- "gitHead": "04d1de79f256d7a53c6b5fd157b37f49bc88e11d\n"
95
+ "gitHead": "5e7bafedfc3d53bc131469a28de31dd8e5b4a3ff\n"
94
96
  }