@dra2020/baseclient 1.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 (113) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +25 -0
  3. package/dist/all/all.d.ts +18 -0
  4. package/dist/baseclient.js +9567 -0
  5. package/dist/baseclient.js.map +1 -0
  6. package/dist/context/all.d.ts +1 -0
  7. package/dist/context/context.d.ts +13 -0
  8. package/dist/filterexpr/all.d.ts +1 -0
  9. package/dist/filterexpr/filterexpr.d.ts +64 -0
  10. package/dist/fsm/all.d.ts +1 -0
  11. package/dist/fsm/fsm.d.ts +118 -0
  12. package/dist/logabstract/all.d.ts +1 -0
  13. package/dist/logabstract/log.d.ts +26 -0
  14. package/dist/logclient/all.d.ts +1 -0
  15. package/dist/logclient/log.d.ts +6 -0
  16. package/dist/ot-editutil/all.d.ts +2 -0
  17. package/dist/ot-editutil/oteditutil.d.ts +14 -0
  18. package/dist/ot-editutil/otmaputil.d.ts +21 -0
  19. package/dist/ot-js/all.d.ts +9 -0
  20. package/dist/ot-js/otarray.d.ts +111 -0
  21. package/dist/ot-js/otclientengine.d.ts +38 -0
  22. package/dist/ot-js/otcomposite.d.ts +37 -0
  23. package/dist/ot-js/otcounter.d.ts +17 -0
  24. package/dist/ot-js/otengine.d.ts +22 -0
  25. package/dist/ot-js/otmap.d.ts +19 -0
  26. package/dist/ot-js/otserverengine.d.ts +38 -0
  27. package/dist/ot-js/otsession.d.ts +111 -0
  28. package/dist/ot-js/ottypes.d.ts +29 -0
  29. package/dist/poly/all.d.ts +15 -0
  30. package/dist/poly/blend.d.ts +1 -0
  31. package/dist/poly/boundbox.d.ts +16 -0
  32. package/dist/poly/cartesian.d.ts +5 -0
  33. package/dist/poly/graham-scan.d.ts +8 -0
  34. package/dist/poly/hash.d.ts +1 -0
  35. package/dist/poly/matrix.d.ts +24 -0
  36. package/dist/poly/minbound.d.ts +1 -0
  37. package/dist/poly/poly.d.ts +52 -0
  38. package/dist/poly/polybin.d.ts +5 -0
  39. package/dist/poly/polylabel.d.ts +7 -0
  40. package/dist/poly/polypack.d.ts +30 -0
  41. package/dist/poly/polyround.d.ts +1 -0
  42. package/dist/poly/polysimplify.d.ts +1 -0
  43. package/dist/poly/quad.d.ts +48 -0
  44. package/dist/poly/selfintersect.d.ts +1 -0
  45. package/dist/poly/shamos.d.ts +1 -0
  46. package/dist/poly/simplify.d.ts +2 -0
  47. package/dist/poly/topo.d.ts +46 -0
  48. package/dist/poly/union.d.ts +48 -0
  49. package/dist/util/all.d.ts +5 -0
  50. package/dist/util/bintrie.d.ts +93 -0
  51. package/dist/util/countedhash.d.ts +19 -0
  52. package/dist/util/gradient.d.ts +15 -0
  53. package/dist/util/indexedarray.d.ts +15 -0
  54. package/dist/util/util.d.ts +68 -0
  55. package/docs/context.md +2 -0
  56. package/docs/fsm.md +243 -0
  57. package/docs/logabstract.md +2 -0
  58. package/docs/logclient.md +2 -0
  59. package/docs/ot-editutil.md +2 -0
  60. package/docs/ot-js.md +95 -0
  61. package/docs/poly.md +103 -0
  62. package/docs/util.md +2 -0
  63. package/lib/all/all.ts +19 -0
  64. package/lib/context/all.ts +1 -0
  65. package/lib/context/context.ts +82 -0
  66. package/lib/filterexpr/all.ts +1 -0
  67. package/lib/filterexpr/filterexpr.ts +625 -0
  68. package/lib/fsm/all.ts +1 -0
  69. package/lib/fsm/fsm.ts +549 -0
  70. package/lib/logabstract/all.ts +1 -0
  71. package/lib/logabstract/log.ts +55 -0
  72. package/lib/logclient/all.ts +1 -0
  73. package/lib/logclient/log.ts +105 -0
  74. package/lib/ot-editutil/all.ts +2 -0
  75. package/lib/ot-editutil/oteditutil.ts +180 -0
  76. package/lib/ot-editutil/otmaputil.ts +209 -0
  77. package/lib/ot-js/all.ts +9 -0
  78. package/lib/ot-js/otarray.ts +1168 -0
  79. package/lib/ot-js/otclientengine.ts +327 -0
  80. package/lib/ot-js/otcomposite.ts +247 -0
  81. package/lib/ot-js/otcounter.ts +145 -0
  82. package/lib/ot-js/otengine.ts +71 -0
  83. package/lib/ot-js/otmap.ts +144 -0
  84. package/lib/ot-js/otserverengine.ts +329 -0
  85. package/lib/ot-js/otsession.ts +199 -0
  86. package/lib/ot-js/ottypes.ts +98 -0
  87. package/lib/poly/all.ts +15 -0
  88. package/lib/poly/blend.ts +27 -0
  89. package/lib/poly/boundbox.ts +102 -0
  90. package/lib/poly/cartesian.ts +130 -0
  91. package/lib/poly/graham-scan.ts +401 -0
  92. package/lib/poly/hash.ts +15 -0
  93. package/lib/poly/matrix.ts +309 -0
  94. package/lib/poly/minbound.ts +211 -0
  95. package/lib/poly/poly.ts +767 -0
  96. package/lib/poly/polybin.ts +218 -0
  97. package/lib/poly/polylabel.ts +204 -0
  98. package/lib/poly/polypack.ts +458 -0
  99. package/lib/poly/polyround.ts +30 -0
  100. package/lib/poly/polysimplify.ts +24 -0
  101. package/lib/poly/quad.ts +272 -0
  102. package/lib/poly/selfintersect.ts +87 -0
  103. package/lib/poly/shamos.ts +297 -0
  104. package/lib/poly/simplify.ts +119 -0
  105. package/lib/poly/topo.ts +525 -0
  106. package/lib/poly/union.ts +371 -0
  107. package/lib/util/all.ts +5 -0
  108. package/lib/util/bintrie.ts +603 -0
  109. package/lib/util/countedhash.ts +83 -0
  110. package/lib/util/gradient.ts +108 -0
  111. package/lib/util/indexedarray.ts +80 -0
  112. package/lib/util/util.ts +695 -0
  113. package/package.json +52 -0
@@ -0,0 +1,218 @@
1
+ import * as Util from '../util/all';
2
+ import * as PP from './polypack';
3
+ import * as T from './topo';
4
+
5
+ // Packed Buffer format:
6
+ //
7
+ // (strings are packed as UTF8 bytes, padded to 4 byte boundary)
8
+ //
9
+ // { 4 byte size (byte offset to packed coordinate buffer) }
10
+ // { 4 byte length: property name,
11
+ // 4 byte length: json string }*
12
+ // { 4 byte length: 'features' }
13
+ // { 4 byte length: length of 'features' array }
14
+ // { 4 byte length: property name,
15
+ // 4 byte length: json string }*
16
+ // { padding to 8 byte boundary }
17
+ // { packed buffer coordinates in polypack format (indexed by geometry.packed above) }
18
+ //
19
+
20
+ const MagicInt = 17;
21
+ const MagicFloat = 17.17;
22
+
23
+ function pad(n: number, pad: number): number
24
+ {
25
+ let mod = n % pad;
26
+ return mod ? pad - mod : 0;
27
+ }
28
+
29
+ function sizeOfString(coder: Util.Coder, s: string): number
30
+ {
31
+ let s8 = Util.s2u8(coder, s);
32
+ return 4 + s8.length + pad(s8.length, 4);
33
+ }
34
+
35
+ function packString(coder: Util.Coder, buf8: Uint8Array, buf32: Int32Array, offset: number, s: string): number
36
+ {
37
+ let s8 = Util.s2u8(coder, s);
38
+ buf32[offset >> 2] = s8.length;
39
+ offset += 4;
40
+ let i: number;
41
+ for (i = 0; i < s8.length; i++) buf8[offset++] = s8[i];
42
+ offset += pad(offset, 4);
43
+ return offset;
44
+ }
45
+
46
+ function unpackString(coder: Util.Coder, buf8: Uint8Array, buf32: Int32Array, offset: number): string
47
+ {
48
+ let size = buf32[offset >> 2];
49
+ let s = Util.u82s(coder, buf8, offset+4, size);
50
+ return s;
51
+ }
52
+
53
+ export function packCollection(coder: Util.Coder, col: any): ArrayBuffer
54
+ {
55
+ // Compute size
56
+ let pp = PP.featurePack(col) as PP.PolyPack;
57
+ let buffer: any = col.features.length ? col.features[0].geometry.packed.buffer : null; // to restore, below
58
+ let size = 16; // int endiness, offset to coordinates, float endiness
59
+ col.features.forEach((f: any) => { delete f.geometry.packed.buffer; }); // reconstructed when unpacking
60
+ let j = JSON.stringify(col);
61
+ size += sizeOfString(coder, j);
62
+ size += pad(size, 8);
63
+ let fullsize = size + pp.length * 8; // add space for coordinates
64
+
65
+ // Now pack it
66
+ let ab = new ArrayBuffer(fullsize);
67
+ let buf8 = new Uint8Array(ab);
68
+ let buf32 = new Int32Array(ab);
69
+ let buf64 = new Float64Array(ab);
70
+ let offset = 0;
71
+ buf32[0] = MagicInt;
72
+ offset += 4;
73
+ buf32[1] = size;
74
+ offset += 4;
75
+ buf64[1] = MagicFloat; // Note that buf64[0] has the two ints stored above
76
+ offset += 8;
77
+ offset = packString(coder, buf8, buf32, offset, j);
78
+ offset += pad(offset, 8);
79
+ if (offset != size)
80
+ throw 'Oops, packing error.';
81
+ let foff = offset >> 3;
82
+ let buf = pp.buffer as Float64Array;
83
+ for (let i: number = 0; i < pp.length; i++)
84
+ buf64[foff++] = buf[i];
85
+
86
+ // Now restore
87
+ col.features.forEach((f: any) => { f.geometry.packed.buffer = buffer; });
88
+ PP.featureUnpack(col);
89
+
90
+ return ab;
91
+ }
92
+
93
+ function reverse(buf8: Uint8Array, s: number, n: number): void
94
+ {
95
+ let e = s + n - 1;
96
+ while (s < e)
97
+ {
98
+ let t = buf8[s];
99
+ buf8[s] = buf8[e];
100
+ buf8[e] = t;
101
+ s++, e--;
102
+ }
103
+ }
104
+
105
+ function enforceEndianness(ab: ArrayBuffer): void
106
+ {
107
+ let buf8 = new Uint8Array(ab);
108
+ let buf32 = new Int32Array(ab);
109
+ let buf64 = new Float64Array(ab);
110
+ let reverseInts = false;
111
+ if (buf32[0] != MagicInt)
112
+ {
113
+ reverseInts = true;
114
+ reverse(buf8, 0, 4);
115
+ if (buf32[0] != MagicInt) throw 'unpackCollection: badly formatted buffer';
116
+ reverse(buf8, 4, 4); // size of non-floats
117
+ }
118
+ let reverseFloats = false;
119
+ if (buf64[1] != MagicFloat)
120
+ {
121
+ reverseFloats = true;
122
+ reverse(buf8, 8, 8);
123
+ if (buf64[1] != MagicFloat) throw 'unpackCollection: badly formatted buffer';
124
+ }
125
+ if (reverseInts)
126
+ reverse(buf8, 16, 4); // JSON string length
127
+ if (reverseFloats)
128
+ {
129
+ let s = buf32[1]; // Offset to floats
130
+ let e = ab.byteLength;
131
+ for (; s < e; s += 8)
132
+ reverse(buf8, s, 8);
133
+ }
134
+ }
135
+
136
+ export function unpackCollection(coder: Util.Coder, ab: ArrayBuffer): any
137
+ {
138
+ enforceEndianness(ab);
139
+ let col: any = {};
140
+ let buf8 = new Uint8Array(ab);
141
+ let buf32 = new Int32Array(ab);
142
+ let size = buf32[1];
143
+ let buf64 = new Float64Array(ab, size); // offset to start of packed coordinates
144
+ let offset = 16;
145
+ let j = unpackString(coder, buf8, buf32, offset);
146
+ col = JSON.parse(j);
147
+ col.features.forEach((f: any) => { f.geometry.packed.buffer = buf64 });
148
+ return col;
149
+ }
150
+
151
+ // Format of packed buffer:
152
+ // [Size of JSON string] [4 bytes]
153
+ // [Size of packedarcs] [4 bytes]
154
+ // [Size of packedarcindices] [4 bytes]
155
+ // [padding] [4 bytes]
156
+ // [JSON string]
157
+ // [pad to 8]
158
+ // [packedarcs]
159
+ // [packedarcindices]
160
+
161
+ const HeaderSize = 16; // 4 Int32's
162
+
163
+ export function topoToBuffer(coder: Util.Coder, topo: any): ArrayBuffer
164
+ {
165
+ // Make sure we're packed
166
+ T.topoPack(topo);
167
+ let savepack = topo.packed;
168
+ delete topo.packed;
169
+ let json = JSON.stringify(topo);
170
+ let byteLength = HeaderSize; // 3 lengths + padding
171
+ let stringLength = sizeOfString(coder, json);
172
+ stringLength += pad(stringLength, 8);
173
+ byteLength += stringLength;
174
+ byteLength += savepack.arcs.byteLength;
175
+ byteLength += savepack.arcindices.byteLength;
176
+ let ab = new ArrayBuffer(byteLength);
177
+ let buf8 = new Uint8Array(ab);
178
+ let buf32 = new Int32Array(ab);
179
+ let buf64 = new Float64Array(ab, HeaderSize + stringLength, savepack.arcs.length);
180
+
181
+ buf32[0] = stringLength;
182
+ buf32[1] = savepack.arcs.byteLength;
183
+ buf32[2] = savepack.arcindices.byteLength;
184
+ buf32[3] = 0;
185
+ packString(coder, buf8, buf32, HeaderSize, json); json = null;
186
+ let af = savepack.arcs as Float64Array;
187
+ let n = af.length;
188
+ let i = 0;
189
+ let j = 0;
190
+ while (i < n)
191
+ buf64[j++] = af[i++];
192
+ let ai = savepack.arcindices as Int32Array;
193
+ n = ai.length;
194
+ i = 0;
195
+ j = (HeaderSize + stringLength + savepack.arcs.byteLength) / 4;
196
+ while (i < n)
197
+ buf32[j++] = ai[i++];
198
+
199
+ // restore
200
+ topo.packed = savepack;
201
+
202
+ return ab;
203
+ }
204
+
205
+ export function topoFromBuffer(coder: Util.Coder, ab: ArrayBuffer): any
206
+ {
207
+ let buf8 = new Uint8Array(ab);
208
+ let buf32 = new Int32Array(ab);
209
+ let stringLength = buf32[0];
210
+ let arcsByteLength = buf32[1];
211
+ let arcindicesByteLength = buf32[2];
212
+ let json = unpackString(coder, buf8, buf32, HeaderSize);
213
+ let topo = JSON.parse(json);
214
+ topo.packed = {};
215
+ topo.packed.arcs = new Float64Array(ab, stringLength + HeaderSize, arcsByteLength / 8);
216
+ topo.packed.arcindices = new Int32Array(ab, stringLength + HeaderSize + arcsByteLength, arcindicesByteLength / 4);
217
+ return topo;
218
+ }
@@ -0,0 +1,204 @@
1
+ import TinyQueue from 'tinyqueue';
2
+ import * as Util from '../util/all';
3
+ import * as P from './poly';
4
+ import * as PP from './polypack';
5
+ import * as BB from './boundbox';
6
+
7
+ interface PolyLabelResult
8
+ {
9
+ x: number;
10
+ y: number;
11
+ d: number;
12
+ }
13
+
14
+ //
15
+ // polyLabel: given polygon, return contained point furthest from any edge, and that distance
16
+ //
17
+
18
+ export function polyLabel(poly: any, precision?: number, debug?: boolean): PolyLabelResult
19
+ {
20
+ let pp = P.polyNormalize(poly);
21
+ if (pp == null) return { x: 0, y: 0, d: 0 };
22
+
23
+ // For multi-polygon, pick largest polygon
24
+ let iLargest: number;
25
+ let nLargestArea: number;
26
+ PP.polyPackEachRing(pp, (b: Float64Array, iPoly: number, iRing: number, iOffset: number, nPoints: number) => {
27
+ if (iRing) return;
28
+ let nArea = P.polySimpleArea(b, iOffset, nPoints);
29
+ if (iLargest === undefined || nArea > nLargestArea) { iLargest = iPoly, nLargestArea = nArea }
30
+ });
31
+
32
+ if (iLargest === undefined)
33
+ return { x: 0, y: 0, d: 0 };
34
+
35
+ precision = precision || 0.00001;
36
+
37
+ let forEachPoint = (iter: any) => {
38
+ PP.polyPackEachPoint(pp, (b: Float64Array, iPoly: number, iRing: number, iOffset: number) => {
39
+ if (iPoly != iLargest || iRing) return;
40
+ iter(b[iOffset], b[iOffset+1]);
41
+ });
42
+ };
43
+ let forEachPointPair = (iter: any) => {
44
+ PP.polyPackEachRing(pp, (b: Float64Array, iPoly, iRing: number, iOffset: number, nPoints: number) => {
45
+ if (iPoly != iLargest || iRing) return;
46
+ let iFirst = iOffset;
47
+ let iLast = iOffset + nPoints * 2;
48
+ let iSecond = iLast - 2;
49
+ for (; iFirst < iLast; iSecond = iFirst, iFirst += 2)
50
+ iter(b[iFirst], b[iFirst+1], b[iSecond], b[iSecond+1]);
51
+ });
52
+ };
53
+
54
+ // find the bounding box of the outer ring
55
+ let minX: number, minY: number, maxX: number, maxY: number;
56
+ forEachPoint((x: number, y: number) => {
57
+ if (minX === undefined || x < minX) minX = x;
58
+ if (minY === undefined || y < minY) minY = y;
59
+ if (maxX === undefined || x > maxX) maxX = x;
60
+ if (maxY === undefined || y > maxY) maxY = y;
61
+ });
62
+
63
+ let width: number = maxX - minX;
64
+ let height: number = maxY - minY;
65
+ let cellSize: number = Math.min(width, height);
66
+ let h: number = cellSize / 2;
67
+
68
+ if (cellSize === 0) return { x: minX, y: minY, d: 0 };
69
+
70
+ // a priority queue of cells in order of their "potential" (max distance to polygon)
71
+ let cellQueue = new TinyQueue<Cell>(undefined, compareMax);
72
+
73
+ // cover polygon with initial cells
74
+ for (let x: number = minX; x < maxX; x += cellSize)
75
+ {
76
+ for (let y: number = minY; y < maxY; y += cellSize)
77
+ cellQueue.push(new Cell(x + h, y + h, h, forEachPointPair));
78
+ }
79
+
80
+ // take centroid as the first best guess
81
+ let bestCell: any = getCentroidCell(forEachPointPair);
82
+
83
+ // special case for rectangular polygons
84
+ let bboxCell: Cell = new Cell(minX + width / 2, minY + height / 2, 0, forEachPointPair);
85
+ if (bboxCell.d > bestCell.d) bestCell = bboxCell;
86
+
87
+ let numProbes = cellQueue.length;
88
+
89
+ while (cellQueue.length)
90
+ {
91
+ // pick the most promising cell from the queue
92
+ let cell = cellQueue.pop();
93
+
94
+ // update the best cell if we found a better one
95
+ if (cell.d > bestCell.d)
96
+ {
97
+ bestCell = cell;
98
+ if (debug) console.log('found best %d after %d probes', Math.round(1e4 * cell.d) / 1e4, numProbes);
99
+ }
100
+
101
+ // do not drill down further if there's no chance of a better solution
102
+ if (cell.max - bestCell.d <= precision) continue;
103
+
104
+ // split the cell into four cells
105
+ h = cell.h / 2;
106
+ cellQueue.push(new Cell(cell.x - h, cell.y - h, h, forEachPointPair));
107
+ cellQueue.push(new Cell(cell.x + h, cell.y - h, h, forEachPointPair));
108
+ cellQueue.push(new Cell(cell.x - h, cell.y + h, h, forEachPointPair));
109
+ cellQueue.push(new Cell(cell.x + h, cell.y + h, h, forEachPointPair));
110
+ numProbes += 4;
111
+ }
112
+
113
+ if (debug)
114
+ {
115
+ console.log('num probes: ' + numProbes);
116
+ console.log('best distance: ' + bestCell.d);
117
+ }
118
+
119
+ return { x: bestCell.x, y: bestCell.y, d: bestCell.d };
120
+ }
121
+
122
+ function compareMax(a: Cell, b: Cell) { return b.max - a.max; }
123
+
124
+ class Cell
125
+ {
126
+ x: number;
127
+ y: number;
128
+ h: number;
129
+ d: number;
130
+ max: number;
131
+
132
+ constructor(x: number, y: number, h: number, forEachPointPair: any)
133
+ {
134
+ this.x = x; // cell center x
135
+ this.y = y; // cell center y
136
+ this.h = h; // half the cell size
137
+ this.d = pointToPolygonDist(x, y, forEachPointPair); // distance from cell center to polygon
138
+ this.max = this.d + this.h * Math.SQRT2; // max distance to polygon within a cell
139
+ }
140
+ }
141
+
142
+ // signed distance from point to polygon outline (negative if point is outside)
143
+ function pointToPolygonDist(x: number, y: number, forEachPointPair: any): number
144
+ {
145
+ let inside: boolean = false;
146
+ let minDistSq: number = Infinity;
147
+
148
+ forEachPointPair((ax: number, ay: number, bx: number, by: number) => {
149
+ if ((ay > y !== by > y) && (x < (bx - ax) * (y - ay) / (by - ay) + ax))
150
+ inside = !inside;
151
+
152
+ minDistSq = Math.min(minDistSq, getSegDistSq(x, y, ax, ay, bx, by));
153
+ });
154
+
155
+ return (inside ? 1 : -1) * Math.sqrt(minDistSq);
156
+ }
157
+
158
+ // get polygon centroid
159
+ function getCentroidCell(forEachPointPair: any): Cell
160
+ {
161
+ let area = 0;
162
+ let x = 0;
163
+ let y = 0;
164
+ let fx: number;
165
+ let fy: number;
166
+
167
+ forEachPointPair((ax: number, ay: number, bx: number, by: number) => {
168
+ if (fx === undefined) fx = ax, fy = ay;
169
+ let f: number = ax * by - bx * ay;
170
+ x += (ax + bx) * f;
171
+ y += (ay + by) * f;
172
+ area += f * 3;
173
+ });
174
+ if (area === 0) return new Cell(fx, fy, 0, forEachPointPair);
175
+ return new Cell(x / area, y / area, 0, forEachPointPair);
176
+ }
177
+
178
+ // get squared distance from a point to a segment
179
+ function getSegDistSq(px: number, py: number, ax: number, ay: number, bx: number, by: number): number
180
+ {
181
+ let dx = bx - ax;
182
+ let dy = by - ay;
183
+
184
+ if (dx !== 0 || dy !== 0)
185
+ {
186
+ let t: number = ((px - ax) * dx + (py - ay) * dy) / (dx * dx + dy * dy);
187
+
188
+ if (t > 1)
189
+ {
190
+ ax = bx;
191
+ ay = by;
192
+ }
193
+ else if (t > 0)
194
+ {
195
+ ax += dx * t;
196
+ ay += dy * t;
197
+ }
198
+ }
199
+
200
+ dx = px - ax;
201
+ dy = py - ay;
202
+
203
+ return dx * dx + dy * dy;
204
+ }