@flowmap.gl/data 8.0.0-alpha.16 → 8.0.0-alpha.17
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/{dist-es5 → dist}/FlowmapAggregateAccessors.d.ts +0 -0
- package/{dist-es5 → dist}/FlowmapAggregateAccessors.d.ts.map +0 -0
- package/dist/FlowmapAggregateAccessors.js +46 -0
- package/{dist-es5 → dist}/FlowmapSelectors.d.ts +0 -0
- package/{dist-es5 → dist}/FlowmapSelectors.d.ts.map +0 -0
- package/dist/FlowmapSelectors.js +887 -0
- package/{dist-es5 → dist}/FlowmapState.d.ts +0 -0
- package/{dist-es5 → dist}/FlowmapState.d.ts.map +0 -0
- package/{dist-es5 → dist}/FlowmapState.js +1 -2
- package/{dist-es5 → dist}/cluster/ClusterIndex.d.ts +0 -0
- package/{dist-es5 → dist}/cluster/ClusterIndex.d.ts.map +0 -0
- package/dist/cluster/ClusterIndex.js +178 -0
- package/{dist-es5 → dist}/cluster/cluster.d.ts +0 -0
- package/{dist-es5 → dist}/cluster/cluster.d.ts.map +0 -0
- package/dist/cluster/cluster.js +211 -0
- package/{dist-es5 → dist}/colors.d.ts +0 -0
- package/{dist-es5 → dist}/colors.d.ts.map +0 -0
- package/dist/colors.js +476 -0
- package/{dist-es5 → dist}/getViewStateForLocations.d.ts +0 -0
- package/{dist-es5 → dist}/getViewStateForLocations.d.ts.map +0 -0
- package/dist/getViewStateForLocations.js +44 -0
- package/{dist-es5 → dist}/index.d.ts +0 -0
- package/{dist-es5 → dist}/index.d.ts.map +0 -0
- package/dist/index.js +10 -0
- package/{dist-es5 → dist}/provider/FlowmapDataProvider.d.ts +0 -0
- package/{dist-es5 → dist}/provider/FlowmapDataProvider.d.ts.map +0 -0
- package/dist/provider/FlowmapDataProvider.js +17 -0
- package/{dist-es5 → dist}/provider/LocalFlowmapDataProvider.d.ts +0 -0
- package/{dist-es5 → dist}/provider/LocalFlowmapDataProvider.d.ts.map +0 -0
- package/dist/provider/LocalFlowmapDataProvider.js +99 -0
- package/{dist-es5 → dist}/time.d.ts +0 -0
- package/{dist-es5 → dist}/time.d.ts.map +0 -0
- package/dist/time.js +126 -0
- package/{dist-es5 → dist}/types.d.ts +0 -0
- package/{dist-es5 → dist}/types.d.ts.map +0 -0
- package/dist/types.js +23 -0
- package/{dist-es5 → dist}/util.d.ts +0 -0
- package/{dist-es5 → dist}/util.d.ts.map +0 -0
- package/dist/util.js +11 -0
- package/package.json +5 -7
- package/dist-es5/FlowmapAggregateAccessors.js +0 -57
- package/dist-es5/FlowmapSelectors.js +0 -1587
- package/dist-es5/cluster/ClusterIndex.js +0 -297
- package/dist-es5/cluster/cluster.js +0 -278
- package/dist-es5/colors.js +0 -510
- package/dist-es5/getViewStateForLocations.js +0 -97
- package/dist-es5/index.js +0 -28
- package/dist-es5/provider/FlowmapDataProvider.js +0 -22
- package/dist-es5/provider/LocalFlowmapDataProvider.js +0 -155
- package/dist-es5/time.js +0 -168
- package/dist-es5/types.js +0 -29
- package/dist-es5/util.js +0 -14
- package/tsconfig.es5.json +0 -11
|
File without changes
|
|
File without changes
|
|
@@ -1,3 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
1
|
+
export {};
|
|
3
2
|
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiRmxvd21hcFN0YXRlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL0Zsb3dtYXBTdGF0ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtMb2NhdGlvbkZpbHRlck1vZGUsIFZpZXdwb3J0UHJvcHN9IGZyb20gJy4vdHlwZXMnO1xuXG5leHBvcnQgaW50ZXJmYWNlIEZpbHRlclN0YXRlIHtcbiAgc2VsZWN0ZWRMb2NhdGlvbnM6IHN0cmluZ1tdIHwgdW5kZWZpbmVkO1xuICBzZWxlY3RlZFRpbWVSYW5nZTogW0RhdGUsIERhdGVdIHwgdW5kZWZpbmVkO1xuICBsb2NhdGlvbkZpbHRlck1vZGU6IExvY2F0aW9uRmlsdGVyTW9kZTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBTZXR0aW5nc1N0YXRlIHtcbiAgYW5pbWF0aW9uRW5hYmxlZDogYm9vbGVhbjtcbiAgZmFkZUVuYWJsZWQ6IGJvb2xlYW47XG4gIGZhZGVPcGFjaXR5RW5hYmxlZDogYm9vbGVhbjtcbiAgbG9jYXRpb25Ub3RhbHNFbmFibGVkOiBib29sZWFuO1xuICBhZGFwdGl2ZVNjYWxlc0VuYWJsZWQ6IGJvb2xlYW47XG4gIGNsdXN0ZXJpbmdFbmFibGVkOiBib29sZWFuO1xuICBjbHVzdGVyaW5nQXV0bzogYm9vbGVhbjtcbiAgY2x1c3RlcmluZ0xldmVsPzogbnVtYmVyO1xuICBkYXJrTW9kZTogYm9vbGVhbjtcbiAgZmFkZUFtb3VudDogbnVtYmVyO1xuICBjb2xvclNjaGVtZTogc3RyaW5nIHwgc3RyaW5nW10gfCB1bmRlZmluZWQ7XG4gIGhpZ2hsaWdodENvbG9yOiBzdHJpbmc7XG4gIG1heFRvcEZsb3dzRGlzcGxheU51bTogbnVtYmVyO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEZsb3dtYXBTdGF0ZSB7XG4gIGZpbHRlclN0YXRlOiBGaWx0ZXJTdGF0ZTtcbiAgc2V0dGluZ3NTdGF0ZTogU2V0dGluZ3NTdGF0ZTtcbiAgdmlld3BvcnQ6IFZpZXdwb3J0UHJvcHM7XG59XG4iXX0=
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2022 FlowmapBlue
|
|
3
|
+
* Copyright 2018-2020 Teralytics, modified by FlowmapBlue
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*
|
|
17
|
+
*/
|
|
18
|
+
import { isCluster, } from './../types';
|
|
19
|
+
import { ascending, bisectLeft, extent } from 'd3-array';
|
|
20
|
+
/**
|
|
21
|
+
* Build ClusterIndex from the given cluster hierarchy
|
|
22
|
+
*/
|
|
23
|
+
export function buildIndex(clusterLevels) {
|
|
24
|
+
const nodesByZoom = new Map();
|
|
25
|
+
const clustersById = new Map();
|
|
26
|
+
const minZoomByLocationId = new Map();
|
|
27
|
+
for (const { zoom, nodes } of clusterLevels) {
|
|
28
|
+
nodesByZoom.set(zoom, nodes);
|
|
29
|
+
for (const node of nodes) {
|
|
30
|
+
if (isCluster(node)) {
|
|
31
|
+
clustersById.set(node.id, node);
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
const { id } = node;
|
|
35
|
+
const mz = minZoomByLocationId.get(id);
|
|
36
|
+
if (mz == null || mz > zoom) {
|
|
37
|
+
minZoomByLocationId.set(id, zoom);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
const [minZoom, maxZoom] = extent(clusterLevels, (cl) => cl.zoom);
|
|
43
|
+
if (minZoom == null || maxZoom == null) {
|
|
44
|
+
throw new Error('Could not determine minZoom or maxZoom');
|
|
45
|
+
}
|
|
46
|
+
const leavesToClustersByZoom = new Map();
|
|
47
|
+
for (const cluster of clustersById.values()) {
|
|
48
|
+
const { zoom } = cluster;
|
|
49
|
+
let leavesToClusters = leavesToClustersByZoom.get(zoom);
|
|
50
|
+
if (!leavesToClusters) {
|
|
51
|
+
leavesToClusters = new Map();
|
|
52
|
+
leavesToClustersByZoom.set(zoom, leavesToClusters);
|
|
53
|
+
}
|
|
54
|
+
visitClusterLeaves(cluster, (leafId) => {
|
|
55
|
+
leavesToClusters === null || leavesToClusters === void 0 ? void 0 : leavesToClusters.set(leafId, cluster);
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
function visitClusterLeaves(cluster, visit) {
|
|
59
|
+
for (const childId of cluster.children) {
|
|
60
|
+
const child = clustersById.get(childId);
|
|
61
|
+
if (child) {
|
|
62
|
+
visitClusterLeaves(child, visit);
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
visit(childId);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
const expandCluster = (cluster, targetZoom = maxZoom) => {
|
|
70
|
+
const ids = [];
|
|
71
|
+
const visit = (c, expandedIds) => {
|
|
72
|
+
if (targetZoom > c.zoom) {
|
|
73
|
+
for (const childId of c.children) {
|
|
74
|
+
const child = clustersById.get(childId);
|
|
75
|
+
if (child) {
|
|
76
|
+
visit(child, expandedIds);
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
expandedIds.push(childId);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
expandedIds.push(c.id);
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
visit(cluster, ids);
|
|
88
|
+
return ids;
|
|
89
|
+
};
|
|
90
|
+
function findClusterFor(locationId, zoom) {
|
|
91
|
+
const leavesToClusters = leavesToClustersByZoom.get(zoom);
|
|
92
|
+
if (!leavesToClusters) {
|
|
93
|
+
return undefined;
|
|
94
|
+
}
|
|
95
|
+
const cluster = leavesToClusters.get(locationId);
|
|
96
|
+
return cluster ? cluster.id : undefined;
|
|
97
|
+
}
|
|
98
|
+
const availableZoomLevels = clusterLevels
|
|
99
|
+
.map((cl) => +cl.zoom)
|
|
100
|
+
.sort((a, b) => ascending(a, b));
|
|
101
|
+
return {
|
|
102
|
+
availableZoomLevels,
|
|
103
|
+
getClusterNodesFor: (zoom) => {
|
|
104
|
+
if (zoom === undefined) {
|
|
105
|
+
return undefined;
|
|
106
|
+
}
|
|
107
|
+
return nodesByZoom.get(zoom);
|
|
108
|
+
},
|
|
109
|
+
getClusterById: (clusterId) => clustersById.get(clusterId),
|
|
110
|
+
getMinZoomForLocation: (locationId) => minZoomByLocationId.get(locationId) || minZoom,
|
|
111
|
+
expandCluster,
|
|
112
|
+
findClusterFor,
|
|
113
|
+
aggregateFlows: (flows, zoom, { getFlowOriginId, getFlowDestId, getFlowMagnitude }, options = {}) => {
|
|
114
|
+
if (zoom > maxZoom) {
|
|
115
|
+
return flows;
|
|
116
|
+
}
|
|
117
|
+
const result = [];
|
|
118
|
+
const aggFlowsByKey = new Map();
|
|
119
|
+
const makeKey = (origin, dest) => `${origin}:${dest}`;
|
|
120
|
+
const { flowCountsMapReduce = {
|
|
121
|
+
map: getFlowMagnitude,
|
|
122
|
+
reduce: (acc, count) => (acc || 0) + count,
|
|
123
|
+
}, } = options;
|
|
124
|
+
for (const flow of flows) {
|
|
125
|
+
const origin = getFlowOriginId(flow);
|
|
126
|
+
const dest = getFlowDestId(flow);
|
|
127
|
+
const originCluster = findClusterFor(origin, zoom) || origin;
|
|
128
|
+
const destCluster = findClusterFor(dest, zoom) || dest;
|
|
129
|
+
const key = makeKey(originCluster, destCluster);
|
|
130
|
+
if (originCluster === origin && destCluster === dest) {
|
|
131
|
+
result.push(flow);
|
|
132
|
+
}
|
|
133
|
+
else {
|
|
134
|
+
let aggregateFlow = aggFlowsByKey.get(key);
|
|
135
|
+
if (!aggregateFlow) {
|
|
136
|
+
aggregateFlow = {
|
|
137
|
+
origin: originCluster,
|
|
138
|
+
dest: destCluster,
|
|
139
|
+
count: flowCountsMapReduce.map(flow),
|
|
140
|
+
aggregate: true,
|
|
141
|
+
};
|
|
142
|
+
result.push(aggregateFlow);
|
|
143
|
+
aggFlowsByKey.set(key, aggregateFlow);
|
|
144
|
+
}
|
|
145
|
+
else {
|
|
146
|
+
aggregateFlow.count = flowCountsMapReduce.reduce(aggregateFlow.count, flowCountsMapReduce.map(flow));
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
return result;
|
|
151
|
+
},
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
export function makeLocationWeightGetter(flows, { getFlowOriginId, getFlowDestId, getFlowMagnitude }) {
|
|
155
|
+
const locationTotals = {
|
|
156
|
+
incoming: new Map(),
|
|
157
|
+
outgoing: new Map(),
|
|
158
|
+
};
|
|
159
|
+
for (const flow of flows) {
|
|
160
|
+
const origin = getFlowOriginId(flow);
|
|
161
|
+
const dest = getFlowDestId(flow);
|
|
162
|
+
const count = getFlowMagnitude(flow);
|
|
163
|
+
locationTotals.incoming.set(dest, (locationTotals.incoming.get(dest) || 0) + count);
|
|
164
|
+
locationTotals.outgoing.set(origin, (locationTotals.outgoing.get(origin) || 0) + count);
|
|
165
|
+
}
|
|
166
|
+
return (id) => Math.max(Math.abs(locationTotals.incoming.get(id) || 0), Math.abs(locationTotals.outgoing.get(id) || 0));
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* @param availableZoomLevels Must be sorted in ascending order
|
|
170
|
+
* @param targetZoom
|
|
171
|
+
*/
|
|
172
|
+
export function findAppropriateZoomLevel(availableZoomLevels, targetZoom) {
|
|
173
|
+
if (!availableZoomLevels.length) {
|
|
174
|
+
throw new Error('No available zoom levels');
|
|
175
|
+
}
|
|
176
|
+
return availableZoomLevels[Math.min(bisectLeft(availableZoomLevels, Math.floor(targetZoom)), availableZoomLevels.length - 1)];
|
|
177
|
+
}
|
|
178
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQ2x1c3RlckluZGV4LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2NsdXN0ZXIvQ2x1c3RlckluZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7Ozs7O0dBZ0JHO0FBRUgsT0FBTyxFQU9MLFNBQVMsR0FDVixNQUFNLFlBQVksQ0FBQztBQUNwQixPQUFPLEVBQUMsU0FBUyxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUMsTUFBTSxVQUFVLENBQUM7QUF1Q3ZEOztHQUVHO0FBQ0gsTUFBTSxVQUFVLFVBQVUsQ0FBSSxhQUE0QjtJQUN4RCxNQUFNLFdBQVcsR0FBRyxJQUFJLEdBQUcsRUFBeUIsQ0FBQztJQUNyRCxNQUFNLFlBQVksR0FBRyxJQUFJLEdBQUcsRUFBbUIsQ0FBQztJQUNoRCxNQUFNLG1CQUFtQixHQUFHLElBQUksR0FBRyxFQUFrQixDQUFDO0lBQ3RELEtBQUssTUFBTSxFQUFDLElBQUksRUFBRSxLQUFLLEVBQUMsSUFBSSxhQUFhLEVBQUU7UUFDekMsV0FBVyxDQUFDLEdBQUcsQ0FBQyxJQUFJLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDN0IsS0FBSyxNQUFNLElBQUksSUFBSSxLQUFLLEVBQUU7WUFDeEIsSUFBSSxTQUFTLENBQUMsSUFBSSxDQUFDLEVBQUU7Z0JBQ25CLFlBQVksQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLEVBQUUsRUFBRSxJQUFJLENBQUMsQ0FBQzthQUNqQztpQkFBTTtnQkFDTCxNQUFNLEVBQUMsRUFBRSxFQUFDLEdBQUcsSUFBSSxDQUFDO2dCQUNsQixNQUFNLEVBQUUsR0FBRyxtQkFBbUIsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUM7Z0JBQ3ZDLElBQUksRUFBRSxJQUFJLElBQUksSUFBSSxFQUFFLEdBQUcsSUFBSSxFQUFFO29CQUMzQixtQkFBbUIsQ0FBQyxHQUFHLENBQUMsRUFBRSxFQUFFLElBQUksQ0FBQyxDQUFDO2lCQUNuQzthQUNGO1NBQ0Y7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QUMsRUFBRSxDQUFDLElBQUksQ0FBQyxDQUFDLEVBQzlDLElBQUksQ0FBQyxHQUFHLENBQUMsY0FBYyxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQy9DLENBQUM7QUFDTixDQUFDO0FBRUQ7OztHQUdHO0FBQ0gsTUFBTSxVQUFVLHdCQUF3QixDQUN0QyxtQkFBNkIsRUFDN0IsVUFBa0I7SUFFbEIsSUFBSSxDQUFDLG1CQUFtQixDQUFDLE1BQU0sRUFBRTtRQUMvQixNQUFNLElBQUksS0FBSyxDQUFDLDBCQUEwQixDQUFDLENBQUM7S0FDN0M7SUFDRCxPQUFPLG1CQUFtQixDQUN4QixJQUFJLENBQUMsR0FBRyxDQUNOLFVBQVUsQ0FBQyxtQkFBbUIsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQyxDQUFDLEVBQ3ZELG1CQUFtQixDQUFDLE1BQU0sR0FBRyxDQUFDLENBQy9CLENBQ0YsQ0FBQztBQUNKLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKlxuICogQ29weXJpZ2h0IDIwMjIgRmxvd21hcEJsdWVcbiAqIENvcHlyaWdodCAyMDE4LTIwMjAgVGVyYWx5dGljcywgbW9kaWZpZWQgYnkgRmxvd21hcEJsdWVcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqXG4gKi9cblxuaW1wb3J0IHtcbiAgQWdncmVnYXRlRmxvdyxcbiAgQ2x1c3RlcixcbiAgQ2x1c3RlckxldmVscyxcbiAgQ2x1c3Rlck5vZGUsXG4gIEZsb3dBY2Nlc3NvcnMsXG4gIEZsb3dDb3VudHNNYXBSZWR1Y2UsXG4gIGlzQ2x1c3Rlcixcbn0gZnJvbSAnLi8uLi90eXBlcyc7XG5pbXBvcnQge2FzY2VuZGluZywgYmlzZWN0TGVmdCwgZXh0ZW50fSBmcm9tICdkMy1hcnJheSc7XG5cbmV4cG9ydCB0eXBlIExvY2F0aW9uV2VpZ2h0R2V0dGVyID0gKGlkOiBzdHJpbmcpID0+IG51bWJlcjtcblxuLyoqXG4gKiBBIGRhdGEgc3RydWN0dXJlIHJlcHJlc2VudGluZyB0aGUgY2x1c3RlciBsZXZlbHMgZm9yIGVmZmljaWVudCBmbG93IGFnZ3JlZ2F0aW9uLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIENsdXN0ZXJJbmRleDxGPiB7XG4gIGF2YWlsYWJsZVpvb21MZXZlbHM6IG51bWJlcltdO1xuICBnZXRDbHVzdGVyQnlJZDogKGNsdXN0ZXJJZDogc3RyaW5nKSA9PiBDbHVzdGVyIHwgdW5kZWZpbmVkO1xuICAvKipcbiAgICogTGlzdCB0aGUgbm9kZXMgb24gdGhlIGdpdmVuIHpvb20gbGV2ZWwuXG4gICAqL1xuICBnZXRDbHVzdGVyTm9kZXNGb3I6ICh6b29tOiBudW1iZXIgfCB1bmRlZmluZWQpID0+IENsdXN0ZXJOb2RlW10gfCB1bmRlZmluZWQ7XG4gIC8qKlxuICAgKiBHZXQgdGhlIG1pbiB6b29tIGxldmVsIG9uIHdoaWNoIHRoZSBsb2NhdGlvbiBpcyBub3QgY2x1c3RlcmVkLlxuICAgKi9cbiAgZ2V0TWluWm9vbUZvckxvY2F0aW9uOiAobG9jYXRpb25JZDogc3RyaW5nKSA9PiBudW1iZXI7XG4gIC8qKlxuICAgKiBMaXN0IHRoZSBJRHMgb2YgYWxsIGxvY2F0aW9ucyBpbiB0aGUgY2x1c3RlciAobGVhdmVzIG9mIHRoZSBzdWJ0cmVlIHN0YXJ0aW5nIGluIHRoZSBjbHVzdGVyKS5cbiAgICovXG4gIGV4cGFuZENsdXN0ZXI6IChjbHVzdGVyOiBDbHVzdGVyLCB0YXJnZXRab29tPzogbnVtYmVyKSA9PiBzdHJpbmdbXTtcbiAgLyoqXG4gICAqIEZpbmQgdGhlIGNsdXN0ZXIgdGhlIGdpdmVuIGxvY2F0aW9uIGlzIHJlc2lkaW5nIGluIG9uIHRoZSBzcGVjaWZpZWQgem9vbSBsZXZlbC5cbiAgICovXG4gIGZpbmRDbHVzdGVyRm9yOiAobG9jYXRpb25JZDogc3RyaW5nLCB6b29tOiBudW1iZXIpID0+IHN0cmluZyB8IHVuZGVmaW5lZDtcbiAgLyoqXG4gICAqIEFnZ3JlZ2F0ZSBmbG93cyBmb3IgdGhlIHNwZWNpZmllZCB6b29tIGxldmVsLlxuICAgKi9cbiAgYWdncmVnYXRlRmxvd3M6IChcbiAgICBmbG93czogRltdLFxuICAgIHpvb206IG51bWJlcixcbiAgICB7Z2V0Rmxvd09yaWdpbklkLCBnZXRGbG93RGVzdElkLCBnZXRGbG93TWFnbml0dWRlfTogRmxvd0FjY2Vzc29yczxGPixcbiAgICBvcHRpb25zPzoge1xuICAgICAgZmxvd0NvdW50c01hcFJlZHVjZT86IEZsb3dDb3VudHNNYXBSZWR1Y2U8Rj47XG4gICAgfSxcbiAgKSA9PiAoRiB8IEFnZ3JlZ2F0ZUZsb3cpW107XG59XG5cbi8qKlxuICogQnVpbGQgQ2x1c3RlckluZGV4IGZyb20gdGhlIGdpdmVuIGNsdXN0ZXIgaGllcmFyY2h5XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBidWlsZEluZGV4PEY+KGNsdXN0ZXJMZXZlbHM6IENsdXN0ZXJMZXZlbHMpOiBDbHVzdGVySW5kZXg8Rj4ge1xuICBjb25zdCBub2Rlc0J5Wm9vbSA9IG5ldyBNYXA8bnVtYmVyLCBDbHVzdGVyTm9kZVtdPigpO1xuICBjb25zdCBjbHVzdGVyc0J5SWQgPSBuZXcgTWFwPHN0cmluZywgQ2x1c3Rlcj4oKTtcbiAgY29uc3QgbWluWm9vbUJ5TG9jYXRpb25JZCA9IG5ldyBNYXA8c3RyaW5nLCBudW1iZXI+KCk7XG4gIGZvciAoY29uc3Qge3pvb20sIG5vZGVzfSBvZiBjbHVzdGVyTGV2ZWxzKSB7XG4gICAgbm9kZXNCeVpvb20uc2V0KHpvb20sIG5vZGVzKTtcbiAgICBmb3IgKGNvbnN0IG5vZGUgb2Ygbm9kZXMpIHtcbiAgICAgIGlmIChpc0NsdXN0ZXIobm9kZSkpIHtcbiAgICAgICAgY2x1c3RlcnNCeUlkLnNldChub2RlLmlkLCBub2RlKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnN0IHtpZH0gPSBub2RlO1xuICAgICAgICBjb25zdCBteiA9IG1pblpvb21CeUxvY2F0aW9uSWQuZ2V0KGlkKTtcbiAgICAgICAgaWYgKG16ID09IG51bGwgfHwgbXogPiB6b29tKSB7XG4gICAgICAgICAgbWluWm9vbUJ5TG9jYXRpb25JZC5zZXQoaWQsIHpvb20pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgY29uc3QgW21pblpvb20sIG1heFpvb21dID0gZXh0ZW50KGNsdXN0ZXJMZXZlbHMsIChjbCkgPT4gY2wuem9vbSk7XG4gIGlmIChtaW5ab29tID09IG51bGwgfHwgbWF4Wm9vbSA9PSBudWxsKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdDb3VsZCBub3QgZGV0ZXJtaW5lIG1pblpvb20gb3IgbWF4Wm9vbScpO1xuICB9XG5cbiAgY29uc3QgbGVhdmVzVG9DbHVzdGVyc0J5Wm9vbSA9IG5ldyBNYXA8bnVtYmVyLCBNYXA8c3RyaW5nLCBDbHVzdGVyPj4oKTtcblxuICBmb3IgKGNvbnN0IGNsdXN0ZXIgb2YgY2x1c3RlcnNCeUlkLnZhbHVlcygpKSB7XG4gICAgY29uc3Qge3pvb219ID0gY2x1c3RlcjtcbiAgICBsZXQgbGVhdmVzVG9DbHVzdGVycyA9IGxlYXZlc1RvQ2x1c3RlcnNCeVpvb20uZ2V0KHpvb20pO1xuICAgIGlmICghbGVhdmVzVG9DbHVzdGVycykge1xuICAgICAgbGVhdmVzVG9DbHVzdGVycyA9IG5ldyBNYXA8c3RyaW5nLCBDbHVzdGVyPigpO1xuICAgICAgbGVhdmVzVG9DbHVzdGVyc0J5Wm9vbS5zZXQoem9vbSwgbGVhdmVzVG9DbHVzdGVycyk7XG4gICAgfVxuICAgIHZpc2l0Q2x1c3RlckxlYXZlcyhjbHVzdGVyLCAobGVhZklkKSA9PiB7XG4gICAgICBsZWF2ZXNUb0NsdXN0ZXJzPy5zZXQobGVhZklkLCBjbHVzdGVyKTtcbiAgICB9KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHZpc2l0Q2x1c3RlckxlYXZlcyhjbHVzdGVyOiBDbHVzdGVyLCB2aXNpdDogKGlkOiBzdHJpbmcpID0+IHZvaWQpIHtcbiAgICBmb3IgKGNvbnN0IGNoaWxkSWQgb2YgY2x1c3Rlci5jaGlsZHJlbikge1xuICAgICAgY29uc3QgY2hpbGQgPSBjbHVzdGVyc0J5SWQuZ2V0KGNoaWxkSWQpO1xuICAgICAgaWYgKGNoaWxkKSB7XG4gICAgICAgIHZpc2l0Q2x1c3RlckxlYXZlcyhjaGlsZCwgdmlzaXQpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdmlzaXQoY2hpbGRJZCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgY29uc3QgZXhwYW5kQ2x1c3RlciA9IChjbHVzdGVyOiBDbHVzdGVyLCB0YXJnZXRab29tOiBudW1iZXIgPSBtYXhab29tKSA9PiB7XG4gICAgY29uc3QgaWRzOiBzdHJpbmdbXSA9IFtdO1xuICAgIGNvbnN0IHZpc2l0ID0gKGM6IENsdXN0ZXIsIGV4cGFuZGVkSWRzOiBzdHJpbmdbXSkgPT4ge1xuICAgICAgaWYgKHRhcmdldFpvb20gPiBjLnpvb20pIHtcbiAgICAgICAgZm9yIChjb25zdCBjaGlsZElkIG9mIGMuY2hpbGRyZW4pIHtcbiAgICAgICAgICBjb25zdCBjaGlsZCA9IGNsdXN0ZXJzQnlJZC5nZXQoY2hpbGRJZCk7XG4gICAgICAgICAgaWYgKGNoaWxkKSB7XG4gICAgICAgICAgICB2aXNpdChjaGlsZCwgZXhwYW5kZWRJZHMpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBleHBhbmRlZElkcy5wdXNoKGNoaWxkSWQpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZXhwYW5kZWRJZHMucHVzaChjLmlkKTtcbiAgICAgIH1cbiAgICB9O1xuICAgIHZpc2l0KGNsdXN0ZXIsIGlkcyk7XG4gICAgcmV0dXJuIGlkcztcbiAgfTtcblxuICBmdW5jdGlvbiBmaW5kQ2x1c3RlckZvcihsb2NhdGlvbklkOiBzdHJpbmcsIHpvb206IG51bWJlcikge1xuICAgIGNvbnN0IGxlYXZlc1RvQ2x1c3RlcnMgPSBsZWF2ZXNUb0NsdXN0ZXJzQnlab29tLmdldCh6b29tKTtcbiAgICBpZiAoIWxlYXZlc1RvQ2x1c3RlcnMpIHtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuICAgIGNvbnN0IGNsdXN0ZXIgPSBsZWF2ZXNUb0NsdXN0ZXJzLmdldChsb2NhdGlvbklkKTtcbiAgICByZXR1cm4gY2x1c3RlciA/IGNsdXN0ZXIuaWQgOiB1bmRlZmluZWQ7XG4gIH1cblxuICBjb25zdCBhdmFpbGFibGVab29tTGV2ZWxzID0gY2x1c3RlckxldmVsc1xuICAgIC5tYXAoKGNsKSA9PiArY2wuem9vbSlcbiAgICAuc29ydCgoYSwgYikgPT4gYXNjZW5kaW5nKGEsIGIpKTtcblxuICByZXR1cm4ge1xuICAgIGF2YWlsYWJsZVpvb21MZXZlbHMsXG5cbiAgICBnZXRDbHVzdGVyTm9kZXNGb3I6ICh6b29tKSA9PiB7XG4gICAgICBpZiAoem9vbSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICB9XG4gICAgICByZXR1cm4gbm9kZXNCeVpvb20uZ2V0KHpvb20pO1xuICAgIH0sXG5cbiAgICBnZXRDbHVzdGVyQnlJZDogKGNsdXN0ZXJJZCkgPT4gY2x1c3RlcnNCeUlkLmdldChjbHVzdGVySWQpLFxuXG4gICAgZ2V0TWluWm9vbUZvckxvY2F0aW9uOiAobG9jYXRpb25JZCkgPT5cbiAgICAgIG1pblpvb21CeUxvY2F0aW9uSWQuZ2V0KGxvY2F0aW9uSWQpIHx8IG1pblpvb20sXG5cbiAgICBleHBhbmRDbHVzdGVyLFxuXG4gICAgZmluZENsdXN0ZXJGb3IsXG5cbiAgICBhZ2dyZWdhdGVGbG93czogKFxuICAgICAgZmxvd3MsXG4gICAgICB6b29tLFxuICAgICAge2dldEZsb3dPcmlnaW5JZCwgZ2V0Rmxvd0Rlc3RJZCwgZ2V0Rmxvd01hZ25pdHVkZX0sXG4gICAgICBvcHRpb25zID0ge30sXG4gICAgKSA9PiB7XG4gICAgICBpZiAoem9vbSA+IG1heFpvb20pIHtcbiAgICAgICAgcmV0dXJuIGZsb3dzO1xuICAgICAgfVxuICAgICAgY29uc3QgcmVzdWx0OiAoRiB8IEFnZ3JlZ2F0ZUZsb3cpW10gPSBbXTtcbiAgICAgIGNvbnN0IGFnZ0Zsb3dzQnlLZXkgPSBuZXcgTWFwPHN0cmluZywgQWdncmVnYXRlRmxvdz4oKTtcbiAgICAgIGNvbnN0IG1ha2VLZXkgPSAob3JpZ2luOiBzdHJpbmcsIGRlc3Q6IHN0cmluZykgPT4gYCR7b3JpZ2lufToke2Rlc3R9YDtcbiAgICAgIGNvbnN0IHtcbiAgICAgICAgZmxvd0NvdW50c01hcFJlZHVjZSA9IHtcbiAgICAgICAgICBtYXA6IGdldEZsb3dNYWduaXR1ZGUsXG4gICAgICAgICAgcmVkdWNlOiAoYWNjOiBhbnksIGNvdW50OiBudW1iZXIpID0+IChhY2MgfHwgMCkgKyBjb3VudCxcbiAgICAgICAgfSxcbiAgICAgIH0gPSBvcHRpb25zO1xuICAgICAgZm9yIChjb25zdCBmbG93IG9mIGZsb3dzKSB7XG4gICAgICAgIGNvbnN0IG9yaWdpbiA9IGdldEZsb3dPcmlnaW5JZChmbG93KTtcbiAgICAgICAgY29uc3QgZGVzdCA9IGdldEZsb3dEZXN0SWQoZmxvdyk7XG4gICAgICAgIGNvbnN0IG9yaWdpbkNsdXN0ZXIgPSBmaW5kQ2x1c3RlckZvcihvcmlnaW4sIHpvb20pIHx8IG9yaWdpbjtcbiAgICAgICAgY29uc3QgZGVzdENsdXN0ZXIgPSBmaW5kQ2x1c3RlckZvcihkZXN0LCB6b29tKSB8fCBkZXN0O1xuICAgICAgICBjb25zdCBrZXkgPSBtYWtlS2V5KG9yaWdpbkNsdXN0ZXIsIGRlc3RDbHVzdGVyKTtcbiAgICAgICAgaWYgKG9yaWdpbkNsdXN0ZXIgPT09IG9yaWdpbiAmJiBkZXN0Q2x1c3RlciA9PT0gZGVzdCkge1xuICAgICAgICAgIHJlc3VsdC5wdXNoKGZsb3cpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGxldCBhZ2dyZWdhdGVGbG93ID0gYWdnRmxvd3NCeUtleS5nZXQoa2V5KTtcbiAgICAgICAgICBpZiAoIWFnZ3JlZ2F0ZUZsb3cpIHtcbiAgICAgICAgICAgIGFnZ3JlZ2F0ZUZsb3cgPSB7XG4gICAgICAgICAgICAgIG9yaWdpbjogb3JpZ2luQ2x1c3RlcixcbiAgICAgICAgICAgICAgZGVzdDogZGVzdENsdXN0ZXIsXG4gICAgICAgICAgICAgIGNvdW50OiBmbG93Q291bnRzTWFwUmVkdWNlLm1hcChmbG93KSxcbiAgICAgICAgICAgICAgYWdncmVnYXRlOiB0cnVlLFxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIHJlc3VsdC5wdXNoKGFnZ3JlZ2F0ZUZsb3cpO1xuICAgICAgICAgICAgYWdnRmxvd3NCeUtleS5zZXQoa2V5LCBhZ2dyZWdhdGVGbG93KTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgYWdncmVnYXRlRmxvdy5jb3VudCA9IGZsb3dDb3VudHNNYXBSZWR1Y2UucmVkdWNlKFxuICAgICAgICAgICAgICBhZ2dyZWdhdGVGbG93LmNvdW50LFxuICAgICAgICAgICAgICBmbG93Q291bnRzTWFwUmVkdWNlLm1hcChmbG93KSxcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH0sXG4gIH07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBtYWtlTG9jYXRpb25XZWlnaHRHZXR0ZXI8Rj4oXG4gIGZsb3dzOiBGW10sXG4gIHtnZXRGbG93T3JpZ2luSWQsIGdldEZsb3dEZXN0SWQsIGdldEZsb3dNYWduaXR1ZGV9OiBGbG93QWNjZXNzb3JzPEY+LFxuKTogTG9jYXRpb25XZWlnaHRHZXR0ZXIge1xuICBjb25zdCBsb2NhdGlvblRvdGFscyA9IHtcbiAgICBpbmNvbWluZzogbmV3IE1hcDxzdHJpbmcsIG51bWJlcj4oKSxcbiAgICBvdXRnb2luZzogbmV3IE1hcDxzdHJpbmcsIG51bWJlcj4oKSxcbiAgfTtcbiAgZm9yIChjb25zdCBmbG93IG9mIGZsb3dzKSB7XG4gICAgY29uc3Qgb3JpZ2luID0gZ2V0Rmxvd09yaWdpbklkKGZsb3cpO1xuICAgIGNvbnN0IGRlc3QgPSBnZXRGbG93RGVzdElkKGZsb3cpO1xuICAgIGNvbnN0IGNvdW50ID0gZ2V0Rmxvd01hZ25pdHVkZShmbG93KTtcbiAgICBsb2NhdGlvblRvdGFscy5pbmNvbWluZy5zZXQoXG4gICAgICBkZXN0LFxuICAgICAgKGxvY2F0aW9uVG90YWxzLmluY29taW5nLmdldChkZXN0KSB8fCAwKSArIGNvdW50LFxuICAgICk7XG4gICAgbG9jYXRpb25Ub3RhbHMub3V0Z29pbmcuc2V0KFxuICAgICAgb3JpZ2luLFxuICAgICAgKGxvY2F0aW9uVG90YWxzLm91dGdvaW5nLmdldChvcmlnaW4pIHx8IDApICsgY291bnQsXG4gICAgKTtcbiAgfVxuICByZXR1cm4gKGlkOiBzdHJpbmcpID0+XG4gICAgTWF0aC5tYXgoXG4gICAgICBNYXRoLmFicyhsb2NhdGlvblRvdGFscy5pbmNvbWluZy5nZXQoaWQpIHx8IDApLFxuICAgICAgTWF0aC5hYnMobG9jYXRpb25Ub3RhbHMub3V0Z29pbmcuZ2V0KGlkKSB8fCAwKSxcbiAgICApO1xufVxuXG4vKipcbiAqIEBwYXJhbSBhdmFpbGFibGVab29tTGV2ZWxzIE11c3QgYmUgc29ydGVkIGluIGFzY2VuZGluZyBvcmRlclxuICogQHBhcmFtIHRhcmdldFpvb21cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGZpbmRBcHByb3ByaWF0ZVpvb21MZXZlbChcbiAgYXZhaWxhYmxlWm9vbUxldmVsczogbnVtYmVyW10sXG4gIHRhcmdldFpvb206IG51bWJlcixcbikge1xuICBpZiAoIWF2YWlsYWJsZVpvb21MZXZlbHMubGVuZ3RoKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdObyBhdmFpbGFibGUgem9vbSBsZXZlbHMnKTtcbiAgfVxuICByZXR1cm4gYXZhaWxhYmxlWm9vbUxldmVsc1tcbiAgICBNYXRoLm1pbihcbiAgICAgIGJpc2VjdExlZnQoYXZhaWxhYmxlWm9vbUxldmVscywgTWF0aC5mbG9vcih0YXJnZXRab29tKSksXG4gICAgICBhdmFpbGFibGVab29tTGV2ZWxzLmxlbmd0aCAtIDEsXG4gICAgKVxuICBdO1xufVxuIl19
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2022 FlowmapBlue
|
|
3
|
+
* Copyright 2018-2020 Teralytics, modified by FlowmapBlue
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*
|
|
17
|
+
*/
|
|
18
|
+
/**
|
|
19
|
+
* The code in this file is a based on https://github.com/mapbox/supercluster
|
|
20
|
+
*/
|
|
21
|
+
// ISC License
|
|
22
|
+
//
|
|
23
|
+
// Copyright (c) 2016, Mapbox
|
|
24
|
+
//
|
|
25
|
+
// Permission to use, copy, modify, and/or distribute this software for any purpose
|
|
26
|
+
// with or without fee is hereby granted, provided that the above copyright notice
|
|
27
|
+
// and this permission notice appear in all copies.
|
|
28
|
+
//
|
|
29
|
+
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
30
|
+
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
|
31
|
+
// FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
32
|
+
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
|
|
33
|
+
// OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
|
34
|
+
// TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
|
35
|
+
// THIS SOFTWARE.
|
|
36
|
+
import { rollup } from 'd3-array';
|
|
37
|
+
import KDBush from 'kdbush';
|
|
38
|
+
const defaultOptions = {
|
|
39
|
+
minZoom: 0,
|
|
40
|
+
maxZoom: 16,
|
|
41
|
+
radius: 40,
|
|
42
|
+
extent: 512,
|
|
43
|
+
nodeSize: 64,
|
|
44
|
+
makeClusterName: (id, numPoints) => undefined,
|
|
45
|
+
makeClusterId: (id) => `{[${id}]}`,
|
|
46
|
+
};
|
|
47
|
+
export function isLeafPoint(p) {
|
|
48
|
+
const { index } = p;
|
|
49
|
+
return index != null;
|
|
50
|
+
}
|
|
51
|
+
export function isClusterPoint(p) {
|
|
52
|
+
const { id } = p;
|
|
53
|
+
return id != null;
|
|
54
|
+
}
|
|
55
|
+
export function clusterLocations(locations, locationAccessors, getLocationWeight, options) {
|
|
56
|
+
const { getLocationLon, getLocationLat, getLocationId } = locationAccessors;
|
|
57
|
+
const opts = Object.assign(Object.assign({}, defaultOptions), options);
|
|
58
|
+
const { minZoom, maxZoom, nodeSize, makeClusterName, makeClusterId } = opts;
|
|
59
|
+
const trees = new Array(maxZoom + 1);
|
|
60
|
+
// generate a cluster object for each point and index input points into a KD-tree
|
|
61
|
+
let clusters = new Array();
|
|
62
|
+
let i = 0;
|
|
63
|
+
for (const location of locations) {
|
|
64
|
+
const x = getLocationLon(location);
|
|
65
|
+
const y = getLocationLat(location);
|
|
66
|
+
clusters.push({
|
|
67
|
+
x: lngX(x),
|
|
68
|
+
y: latY(y),
|
|
69
|
+
weight: getLocationWeight(getLocationId(location)),
|
|
70
|
+
zoom: Infinity,
|
|
71
|
+
index: i,
|
|
72
|
+
parentId: -1,
|
|
73
|
+
location,
|
|
74
|
+
});
|
|
75
|
+
i++;
|
|
76
|
+
}
|
|
77
|
+
trees[maxZoom + 1] = new KDBush(clusters, getX, getY, nodeSize, Float32Array);
|
|
78
|
+
// cluster points on max zoom, then cluster the results on previous zoom, etc.;
|
|
79
|
+
// results in a cluster hierarchy across zoom levels
|
|
80
|
+
for (let z = maxZoom; z >= minZoom; z--) {
|
|
81
|
+
// create a new set of clusters for the zoom and index them with a KD-tree
|
|
82
|
+
clusters = cluster(clusters, z, trees[z + 1], opts);
|
|
83
|
+
trees[z] = new KDBush(clusters, getX, getY, nodeSize, Float32Array);
|
|
84
|
+
}
|
|
85
|
+
if (trees.length === 0) {
|
|
86
|
+
return [];
|
|
87
|
+
}
|
|
88
|
+
const numbersOfClusters = trees.map((d) => d.points.length);
|
|
89
|
+
const maxAvailZoom = numbersOfClusters.indexOf(numbersOfClusters[numbersOfClusters.length - 1]);
|
|
90
|
+
const minAvailZoom = Math.min(maxAvailZoom, numbersOfClusters.lastIndexOf(numbersOfClusters[0]));
|
|
91
|
+
const clusterLevels = new Array();
|
|
92
|
+
for (let zoom = minAvailZoom; zoom <= maxAvailZoom; zoom++) {
|
|
93
|
+
let childrenByParent;
|
|
94
|
+
const tree = trees[zoom];
|
|
95
|
+
if (zoom < maxAvailZoom) {
|
|
96
|
+
childrenByParent = rollup(trees[zoom + 1].points, (points) => points.map((p) => p.id ? makeClusterId(p.id) : getLocationId(p.location)), (point) => point.parentId);
|
|
97
|
+
}
|
|
98
|
+
const nodes = [];
|
|
99
|
+
for (const point of tree.points) {
|
|
100
|
+
const { x, y, numPoints, location } = point;
|
|
101
|
+
if (isLeafPoint(point)) {
|
|
102
|
+
nodes.push({
|
|
103
|
+
id: getLocationId(location),
|
|
104
|
+
zoom,
|
|
105
|
+
lat: getLocationLat(location),
|
|
106
|
+
lon: getLocationLon(location),
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
else if (isClusterPoint(point)) {
|
|
110
|
+
const { id } = point;
|
|
111
|
+
const children = childrenByParent && childrenByParent.get(id);
|
|
112
|
+
if (!children) {
|
|
113
|
+
throw new Error(`Cluster ${id} doesn't have children`);
|
|
114
|
+
}
|
|
115
|
+
nodes.push({
|
|
116
|
+
id: makeClusterId(id),
|
|
117
|
+
name: makeClusterName(id, numPoints),
|
|
118
|
+
zoom,
|
|
119
|
+
lat: yLat(y),
|
|
120
|
+
lon: xLng(x),
|
|
121
|
+
children,
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
clusterLevels.push({
|
|
126
|
+
zoom,
|
|
127
|
+
nodes,
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
return clusterLevels;
|
|
131
|
+
}
|
|
132
|
+
function createCluster(x, y, id, numPoints, weight) {
|
|
133
|
+
return {
|
|
134
|
+
x,
|
|
135
|
+
y,
|
|
136
|
+
zoom: Infinity,
|
|
137
|
+
id,
|
|
138
|
+
parentId: -1,
|
|
139
|
+
numPoints,
|
|
140
|
+
weight,
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
function cluster(points, zoom, tree, options) {
|
|
144
|
+
const clusters = [];
|
|
145
|
+
const { radius, extent } = options;
|
|
146
|
+
const r = radius / (extent * Math.pow(2, zoom));
|
|
147
|
+
// loop through each point
|
|
148
|
+
for (let i = 0; i < points.length; i++) {
|
|
149
|
+
const p = points[i];
|
|
150
|
+
// if we've already visited the point at this zoom level, skip it
|
|
151
|
+
if (p.zoom <= zoom) {
|
|
152
|
+
continue;
|
|
153
|
+
}
|
|
154
|
+
p.zoom = zoom;
|
|
155
|
+
// find all nearby points
|
|
156
|
+
const neighborIds = tree.within(p.x, p.y, r);
|
|
157
|
+
let weight = p.weight || 1;
|
|
158
|
+
let numPoints = isClusterPoint(p) ? p.numPoints : 1;
|
|
159
|
+
let wx = p.x * weight;
|
|
160
|
+
let wy = p.y * weight;
|
|
161
|
+
// encode both zoom and point index on which the cluster originated
|
|
162
|
+
const id = (i << 5) + (zoom + 1);
|
|
163
|
+
for (const neighborId of neighborIds) {
|
|
164
|
+
const b = tree.points[neighborId];
|
|
165
|
+
// filter out neighbors that are already processed
|
|
166
|
+
if (b.zoom <= zoom) {
|
|
167
|
+
continue;
|
|
168
|
+
}
|
|
169
|
+
b.zoom = zoom; // save the zoom (so it doesn't get processed twice)
|
|
170
|
+
const weight2 = b.weight || 1;
|
|
171
|
+
const numPoints2 = b.numPoints || 1;
|
|
172
|
+
wx += b.x * weight2; // accumulate coordinates for calculating weighted center
|
|
173
|
+
wy += b.y * weight2;
|
|
174
|
+
weight += weight2;
|
|
175
|
+
numPoints += numPoints2;
|
|
176
|
+
b.parentId = id;
|
|
177
|
+
}
|
|
178
|
+
if (numPoints === 1) {
|
|
179
|
+
clusters.push(p);
|
|
180
|
+
}
|
|
181
|
+
else {
|
|
182
|
+
p.parentId = id;
|
|
183
|
+
clusters.push(createCluster(wx / weight, wy / weight, id, numPoints, weight));
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
return clusters;
|
|
187
|
+
}
|
|
188
|
+
// spherical mercator to longitude/latitude
|
|
189
|
+
function xLng(x) {
|
|
190
|
+
return (x - 0.5) * 360;
|
|
191
|
+
}
|
|
192
|
+
function yLat(y) {
|
|
193
|
+
const y2 = ((180 - y * 360) * Math.PI) / 180;
|
|
194
|
+
return (360 * Math.atan(Math.exp(y2))) / Math.PI - 90;
|
|
195
|
+
}
|
|
196
|
+
// longitude/latitude to spherical mercator in [0..1] range
|
|
197
|
+
function lngX(lng) {
|
|
198
|
+
return lng / 360 + 0.5;
|
|
199
|
+
}
|
|
200
|
+
function latY(lat) {
|
|
201
|
+
const sin = Math.sin((lat * Math.PI) / 180);
|
|
202
|
+
const y = 0.5 - (0.25 * Math.log((1 + sin) / (1 - sin))) / Math.PI;
|
|
203
|
+
return y < 0 ? 0 : y > 1 ? 1 : y;
|
|
204
|
+
}
|
|
205
|
+
function getX(p) {
|
|
206
|
+
return p.x;
|
|
207
|
+
}
|
|
208
|
+
function getY(p) {
|
|
209
|
+
return p.y;
|
|
210
|
+
}
|
|
211
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2x1c3Rlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jbHVzdGVyL2NsdXN0ZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7R0FnQkc7QUFFSDs7R0FFRztBQUVILGNBQWM7QUFDZCxFQUFFO0FBQ0YsNkJBQTZCO0FBQzdCLEVBQUU7QUFDRixtRkFBbUY7QUFDbkYsa0ZBQWtGO0FBQ2xGLG1EQUFtRDtBQUNuRCxFQUFFO0FBQ0YsZ0ZBQWdGO0FBQ2hGLGtGQUFrRjtBQUNsRiwyRUFBMkU7QUFDM0UsbUZBQW1GO0FBQ25GLGlGQUFpRjtBQUNqRixrRkFBa0Y7QUFDbEYsaUJBQWlCO0FBRWpCLE9BQU8sRUFBQyxNQUFNLEVBQUMsTUFBTSxVQUFVLENBQUM7QUFDaEMsT0FBTyxNQUFNLE1BQU0sUUFBUSxDQUFDO0FBYzVCLE1BQU0sY0FBYyxHQUFZO0lBQzlCLE9BQU8sRUFBRSxDQUFDO0lBQ1YsT0FBTyxFQUFFLEVBQUU7SUFDWCxNQUFNLEVBQUUsRUFBRTtJQUNWLE1BQU0sRUFBRSxHQUFHO0lBQ1gsUUFBUSxFQUFFLEVBQUU7SUFDWixlQUFlLEVBQUUsQ0FBQyxFQUFVLEVBQUUsU0FBaUIsRUFBRSxFQUFFLENBQUMsU0FBUztJQUM3RCxhQUFhLEVBQUUsQ0FBQyxFQUFVLEVBQUUsRUFBRSxDQUFDLEtBQUssRUFBRSxJQUFJO0NBQzNDLENBQUM7QUFzQkYsTUFBTSxVQUFVLFdBQVcsQ0FBSSxDQUFXO0lBQ3hDLE1BQU0sRUFBQyxLQUFLLEVBQUMsR0FBRyxDQUFpQixDQUFDO0lBQ2xDLE9BQU8sS0FBSyxJQUFJLElBQUksQ0FBQztBQUN2QixDQUFDO0FBRUQsTUFBTSxVQUFVLGNBQWMsQ0FBSSxDQUFXO0lBQzNDLE1BQU0sRUFBQyxFQUFFLEVBQUMsR0FBRyxDQUFpQixDQUFDO0lBQy9CLE9BQU8sRUFBRSxJQUFJLElBQUksQ0FBQztBQUNwQixDQUFDO0FBSUQsTUFBTSxVQUFVLGdCQUFn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QUFJLENBQUMsR0FBVztJQUN2QixNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxHQUFHLElBQUksQ0FBQyxFQUFFLENBQUMsR0FBRyxHQUFHLENBQUMsQ0FBQztJQUM1QyxNQUFNLENBQUMsR0FBRyxHQUFHLEdBQUcsQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLEVBQUUsQ0FBQztJQUNuRSxPQUFPLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDbkMsQ0FBQztBQUVELFNBQVMsSUFBSSxDQUFJLENBQVc7SUFDMUIsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2IsQ0FBQztBQUVELFNBQVMsSUFBSSxDQUFJLENBQVc7SUFDMUIsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2IsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qXG4gKiBDb3B5cmlnaHQgMjAyMiBGbG93bWFwQmx1ZVxuICogQ29weXJpZ2h0IDIwMTgtMjAyMCBUZXJhbHl0aWNzLCBtb2RpZmllZCBieSBGbG93bWFwQmx1ZVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG4vKipcbiAqIFRoZSBjb2RlIGluIHRoaXMgZmlsZSBpcyBhIGJhc2VkIG9uIGh0dHBzOi8vZ2l0aHViLmNvbS9tYXBib3gvc3VwZXJjbHVzdGVyXG4gKi9cblxuLy8gSVNDIExpY2Vuc2Vcbi8vXG4vLyBDb3B5cmlnaHQgKGMpIDIwMTYsIE1hcGJveFxuLy9cbi8vIFBlcm1pc3Npb24gdG8gdXNlLCBjb3B5LCBtb2RpZnksIGFuZC9vciBkaXN0cmlidXRlIHRoaXMgc29mdHdhcmUgZm9yIGFueSBwdXJwb3NlXG4vLyB3aXRoIG9yIHdpdGhvdXQgZmVlIGlzIGhlcmVieSBncmFudGVkLCBwcm92aWRlZCB0aGF0IHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlXG4vLyBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBhcHBlYXIgaW4gYWxsIGNvcGllcy5cbi8vXG4vLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiIEFORCBUSEUgQVVUSE9SIERJU0NMQUlNUyBBTEwgV0FSUkFOVElFUyBXSVRIXG4vLyBSRUdBUkQgVE8gVEhJUyBTT0ZUV0FSRSBJTkNMVURJTkcgQUxMIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EXG4vLyBGSVRORVNTLiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SIEJFIExJQUJMRSBGT1IgQU5ZIFNQRUNJQUwsIERJUkVDVCxcbi8vIElORElSRUNULCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgT1IgQU5ZIERBTUFHRVMgV0hBVFNPRVZFUiBSRVNVTFRJTkcgRlJPTSBMT1NTXG4vLyBPRiBVU0UsIERBVEEgT1IgUFJPRklUUywgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIE5FR0xJR0VOQ0UgT1IgT1RIRVJcbi8vIFRPUlRJT1VTIEFDVElPTiwgQVJJU0lORyBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBVU0UgT1IgUEVSRk9STUFOQ0UgT0Zcbi8vIFRISVMgU09GVFdBUkUuXG5cbmltcG9ydCB7cm9sbHVwfSBmcm9tICdkMy1hcnJheSc7XG5pbXBvcnQgS0RCdXNoIGZyb20gJ2tkYnVzaCc7XG5pbXBvcnQge0xvY2F0aW9uV2VpZ2h0R2V0dGVyfSBmcm9tICcuL0NsdXN0ZXJJbmRleCc7XG5pbXBvcnQge0NsdXN0ZXIsIENsdXN0ZXJMZXZlbCwgQ2x1c3Rlck5vZGUsIExvY2F0aW9uQWNjZXNzb3JzfSBmcm9tICcuLi90eXBlcyc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgT3B0aW9ucyB7XG4gIG1pblpvb206IG51bWJlcjsgLy8gbWluIHpvb20gdG8gZ2VuZXJhdGUgY2x1c3RlcnMgb25cbiAgbWF4Wm9vbTogbnVtYmVyOyAvLyBtYXggem9vbSBsZXZlbCB0byBjbHVzdGVyIHRoZSBwb2ludHMgb25cbiAgcmFkaXVzOiBudW1iZXI7IC8vIGNsdXN0ZXIgcmFkaXVzIGluIHBpeGVsc1xuICBleHRlbnQ6IG51bWJlcjsgLy8gdGlsZSBleHRlbnQgKHJhZGl1cyBpcyBjYWxjdWxhdGVkIHJlbGF0aXZlIHRvIGl0KVxuICBub2RlU2l6ZTogbnVtYmVyOyAvLyBzaXplIG9mIHRoZSBLRC10cmVlIGxlYWYgbm9kZSwgYWZmZWN0cyBwZXJmb3JtYW5jZVxuICBtYWtlQ2x1c3Rlck5hbWU6IChpZDogbnVtYmVyLCBudW1Qb2ludHM6IG51bWJlcikgPT4gc3RyaW5nIHwgdW5kZWZpbmVkO1xuICBtYWtlQ2x1c3RlcklkOiAoaWQ6IG51bWJlcikgPT4gc3RyaW5nO1xufVxuXG5jb25zdCBkZWZhdWx0T3B0aW9uczogT3B0aW9ucyA9IHtcbiAgbWluWm9vbTogMCxcbiAgbWF4Wm9vbTogMTYsXG4gIHJhZGl1czogNDAsXG4gIGV4dGVudDogNTEyLFxuICBub2RlU2l6ZTogNjQsXG4gIG1ha2VDbHVzdGVyTmFtZTogKGlkOiBudW1iZXIsIG51bVBvaW50czogbnVtYmVyKSA9PiB1bmRlZmluZWQsXG4gIG1ha2VDbHVzdGVySWQ6IChpZDogbnVtYmVyKSA9PiBge1ske2lkfV19YCxcbn07XG5cbmludGVyZmFjZSBCYXNlUG9pbnQge1xuICB4OiBudW1iZXI7IC8vIHByb2plY3RlZCBwb2ludCBjb29yZGluYXRlc1xuICB5OiBudW1iZXI7XG4gIHdlaWdodDogbnVtYmVyO1xuICB6b29tOiBudW1iZXI7IC8vIHRoZSBsYXN0IHpvb20gdGhlIHBvaW50IHdhcyBwcm9jZXNzZWQgYXRcbiAgcGFyZW50SWQ6IG51bWJlcjsgLy8gcGFyZW50IGNsdXN0ZXIgaWRcbn1cblxuaW50ZXJmYWNlIExlYWZQb2ludDxMPiBleHRlbmRzIEJhc2VQb2ludCB7XG4gIGluZGV4OiBudW1iZXI7IC8vIGluZGV4IG9mIHRoZSBzb3VyY2UgZmVhdHVyZSBpbiB0aGUgb3JpZ2luYWwgaW5wdXQgYXJyYXksXG4gIGxvY2F0aW9uOiBMO1xufVxuXG5pbnRlcmZhY2UgQ2x1c3RlclBvaW50IGV4dGVuZHMgQmFzZVBvaW50IHtcbiAgaWQ6IG51bWJlcjtcbiAgbnVtUG9pbnRzOiBudW1iZXI7XG59XG5cbnR5cGUgUG9pbnQ8TD4gPSBMZWFmUG9pbnQ8TD4gfCBDbHVzdGVyUG9pbnQ7XG5cbmV4cG9ydCBmdW5jdGlvbiBpc0xlYWZQb2ludDxMPihwOiBQb2ludDxMPik6IHAgaXMgTGVhZlBvaW50PEw+IHtcbiAgY29uc3Qge2luZGV4fSA9IHAgYXMgTGVhZlBvaW50PEw+O1xuICByZXR1cm4gaW5kZXggIT0gbnVsbDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGlzQ2x1c3RlclBvaW50PEw+KHA6IFBvaW50PEw+KTogcCBpcyBDbHVzdGVyUG9pbnQge1xuICBjb25zdCB7aWR9ID0gcCBhcyBDbHVzdGVyUG9pbnQ7XG4gIHJldHVybiBpZCAhPSBudWxsO1xufVxuXG50eXBlIFpvb21MZXZlbEtEQnVzaCA9IGFueTtcblxuZXhwb3J0IGZ1bmN0aW9uIGNsdXN0ZXJMb2NhdGlvbnM8TD4oXG4gIGxvY2F0aW9uczogSXRlcmFibGU8TD4sXG4gIGxvY2F0aW9uQWNjZXNzb3JzOiBMb2NhdGlvbkFjY2Vzc29yczxMPixcbiAgZ2V0TG9jYXRpb25XZWlnaHQ6IExvY2F0aW9uV2VpZ2h0R2V0dGVyLFxuICBvcHRpb25zPzogUGFydGlhbDxPcHRpb25zPixcbik6IENsdXN0ZXJMZXZlbFtdIHtcbiAgY29uc3Qge2dldExvY2F0aW9uTG9uLCBnZXRMb2NhdGlvbkxhdCwgZ2V0TG9jYXRpb25JZH0gPSBsb2NhdGlvbkFjY2Vzc29ycztcbiAgY29uc3Qgb3B0cyA9IHtcbiAgICAuLi5kZWZhdWx0T3B0aW9ucyxcbiAgICAuLi5vcHRpb25zLFxuICB9O1xuICBjb25zdCB7bWluWm9vbSwgbWF4Wm9vbSwgbm9kZVNpemUsIG1ha2VDbHVzdGVyTmFtZSwgbWFrZUNsdXN0ZXJJZH0gPSBvcHRzO1xuXG4gIGNvbnN0IHRyZWVzID0gbmV3IEFycmF5PFpvb21MZXZlbEtEQnVzaD4obWF4Wm9vbSArIDEpO1xuXG4gIC8vIGdlbmVyYXRlIGEgY2x1c3RlciBvYmplY3QgZm9yIGVhY2ggcG9pbnQgYW5kIGluZGV4IGlucHV0IHBvaW50cyBpbnRvIGEgS0QtdHJlZVxuICBsZXQgY2x1c3RlcnMgPSBuZXcgQXJyYXk8UG9pbnQ8TD4+KCk7XG4gIGxldCBpID0gMDtcbiAgZm9yIChjb25zdCBsb2NhdGlvbiBvZiBsb2NhdGlvbnMpIHtcbiAgICBjb25zdCB4ID0gZ2V0TG9jYXRpb25Mb24obG9jYXRpb24pO1xuICAgIGNvbnN0IHkgPSBnZXRMb2NhdGlvbkxhdChsb2NhdGlvbik7XG4gICAgY2x1c3RlcnMucHVzaCh7XG4gICAgICB4OiBsbmdYKHgpLCAvLyBwcm9qZWN0ZWQgcG9pbnQgY29vcmRpbmF0ZXNcbiAgICAgIHk6IGxhdFkoeSksXG4gICAgICB3ZWlnaHQ6IGdldExvY2F0aW9uV2VpZ2h0KGdldExvY2F0aW9uSWQobG9jYXRpb24pKSxcbiAgICAgIHpvb206IEluZmluaXR5LCAvLyB0aGUgbGFzdCB6b29tIHRoZSBwb2ludCB3YXMgcHJvY2Vzc2VkIGF0XG4gICAgICBpbmRleDogaSwgLy8gaW5kZXggb2YgdGhlIHNvdXJjZSBmZWF0dXJlIGluIHRoZSBvcmlnaW5hbCBpbnB1dCBhcnJheSxcbiAgICAgIHBhcmVudElkOiAtMSwgLy8gcGFyZW50IGNsdXN0ZXIgaWRcbiAgICAgIGxvY2F0aW9uLFxuICAgIH0pO1xuICAgIGkrKztcbiAgfVxuICB0cmVlc1ttYXhab29tICsgMV0gPSBuZXcgS0RCdXNoKGNsdXN0ZXJzLCBnZXRYLCBnZXRZLCBub2RlU2l6ZSwgRmxvYXQzMkFycmF5KTtcblxuICAvLyBjbHVzdGVyIHBvaW50cyBvbiBtYXggem9vbSwgdGhlbiBjbHVzdGVyIHRoZSByZXN1bHRzIG9uIHByZXZpb3VzIHpvb20sIGV0Yy47XG4gIC8vIHJlc3VsdHMgaW4gYSBjbHVzdGVyIGhpZXJhcmNoeSBhY3Jvc3Mgem9vbSBsZXZlbHNcbiAgZm9yIChsZXQgeiA9IG1heFpvb207IHogPj0gbWluWm9vbTsgei0tKSB7XG4gICAgLy8gY3JlYXRlIGEgbmV3IHNldCBvZiBjbHVzdGVycyBmb3IgdGhlIHpvb20gYW5kIGluZGV4IHRoZW0gd2l0aCBhIEtELXRyZWVcbiAgICBjbHVzdGVycyA9IGNsdXN0ZXIoY2x1c3RlcnMsIHosIHRyZWVzW3ogKyAxXSwgb3B0cyk7XG4gICAgdHJlZXNbel0gPSBuZXcgS0RCdXNoKGNsdXN0ZXJzLCBnZXRYLCBnZXRZLCBub2RlU2l6ZSwgRmxvYXQzMkFycmF5KTtcbiAgfVxuXG4gIGlmICh0cmVlcy5sZW5ndGggPT09IDApIHtcbiAgICByZXR1cm4gW107XG4gIH1cbiAgY29uc3QgbnVtYmVyc09mQ2x1c3RlcnMgPSB0cmVlcy5tYXAoKGQpID0+IGQucG9pbnRzLmxlbmd0aCk7XG4gIGNvbnN0IG1heEF2YWlsWm9vbSA9IG51bWJlcnNPZkNsdXN0ZXJzLmluZGV4T2YoXG4gICAgbnVtYmVyc09mQ2x1c3RlcnNbbnVtYmVyc09mQ2x1c3RlcnMubGVuZ3RoIC0gMV0sXG4gICk7XG4gIGNvbnN0IG1pbkF2YWlsWm9vbSA9IE1hdGgubWluKFxuICAgIG1heEF2YWlsWm9vbSxcbiAgICBudW1iZXJzT2ZDbHVzdGVycy5sYXN0SW5kZXhPZihudW1iZXJzT2ZDbHVzdGVyc1swXSksXG4gICk7XG5cbiAgY29uc3QgY2x1c3RlckxldmVscyA9IG5ldyBBcnJheTxDbHVzdGVyTGV2ZWw+KCk7XG4gIGZvciAobGV0IHpvb20gPSBtaW5BdmFpbFpvb207IHpvb20gPD0gbWF4QXZhaWxab29tOyB6b29tKyspIHtcbiAgICBsZXQgY2hpbGRyZW5CeVBhcmVudDogTWFwPG51bWJlciwgc3RyaW5nW10+IHwgdW5kZWZpbmVkO1xuICAgIGNvbnN0IHRyZWUgPSB0cmVlc1t6b29tXTtcbiAgICBpZiAoem9vbSA8IG1heEF2YWlsWm9vbSkge1xuICAgICAgY2hpbGRyZW5CeVBhcmVudCA9IHJvbGx1cDxQb2ludDxMPiwgc3RyaW5nW10sIG51bWJlcj4oXG4gICAgICAgIHRyZWVzW3pvb20gKyAxXS5wb2ludHMsXG4gICAgICAgIChwb2ludHM6IGFueVtdKSA9PlxuICAgICAgICAgIHBvaW50cy5tYXAoKHA6IGFueSkgPT5cbiAgICAgICAgICAgIHAuaWQgPyBtYWtlQ2x1c3RlcklkKHAuaWQpIDogZ2V0TG9jYXRpb25JZChwLmxvY2F0aW9uKSxcbiAgICAgICAgICApLFxuICAgICAgICAocG9pbnQ6IGFueSkgPT4gcG9pbnQucGFyZW50SWQsXG4gICAgICApO1xuICAgIH1cblxuICAgIGNvbnN0IG5vZGVzOiBDbHVzdGVyTm9kZVtdID0gW107XG4gICAgZm9yIChjb25zdCBwb2ludCBvZiB0cmVlLnBvaW50cykge1xuICAgICAgY29uc3Qge3gsIHksIG51bVBvaW50cywgbG9jYXRpb259ID0gcG9pbnQ7XG4gICAgICBpZiAoaXNMZWFmUG9pbnQocG9pbnQpKSB7XG4gICAgICAgIG5vZGVzLnB1c2goe1xuICAgICAgICAgIGlkOiBnZXRMb2NhdGlvbklkKGxvY2F0aW9uKSxcbiAgICAgICAgICB6b29tLFxuICAgICAgICAgIGxhdDogZ2V0TG9jYXRpb25MYXQobG9jYXRpb24pLFxuICAgICAgICAgIGxvbjogZ2V0TG9jYXRpb25Mb24obG9jYXRpb24pLFxuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSBpZiAoaXNDbHVzdGVyUG9pbnQocG9pbnQpKSB7XG4gICAgICAgIGNvbnN0IHtpZH0gPSBwb2ludDtcbiAgICAgICAgY29uc3QgY2hpbGRyZW4gPSBjaGlsZHJlbkJ5UGFyZW50ICYmIGNoaWxkcmVuQnlQYXJlbnQuZ2V0KGlkKTtcbiAgICAgICAgaWYgKCFjaGlsZHJlbikge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgQ2x1c3RlciAke2lkfSBkb2Vzbid0IGhhdmUgY2hpbGRyZW5gKTtcbiAgICAgICAgfVxuICAgICAgICBub2Rlcy5wdXNoKHtcbiAgICAgICAgICBpZDogbWFrZUNsdXN0ZXJJZChpZCksXG4gICAgICAgICAgbmFtZTogbWFrZUNsdXN0ZXJOYW1lKGlkLCBudW1Qb2ludHMpLFxuICAgICAgICAgIHpvb20sXG4gICAgICAgICAgbGF0OiB5TGF0KHkpLFxuICAgICAgICAgIGxvbjogeExuZyh4KSxcbiAgICAgICAgICBjaGlsZHJlbixcbiAgICAgICAgfSBhcyBDbHVzdGVyKTtcbiAgICAgIH1cbiAgICB9XG4gICAgY2x1c3RlckxldmVscy5wdXNoKHtcbiAgICAgIHpvb20sXG4gICAgICBub2RlcyxcbiAgICB9KTtcbiAgfVxuICByZXR1cm4gY2x1c3RlckxldmVscztcbn1cblxuZnVuY3Rpb24gY3JlYXRlQ2x1c3RlcihcbiAgeDogbnVtYmVyLFxuICB5OiBudW1iZXIsXG4gIGlkOiBudW1iZXIsXG4gIG51bVBvaW50czogbnVtYmVyLFxuICB3ZWlnaHQ6IG51bWJlcixcbik6IENsdXN0ZXJQb2ludCB7XG4gIHJldHVybiB7XG4gICAgeCwgLy8gd2VpZ2h0ZWQgY2x1c3RlciBjZW50ZXJcbiAgICB5LFxuICAgIHpvb206IEluZmluaXR5LCAvLyB0aGUgbGFzdCB6b29tIHRoZSBjbHVzdGVyIHdhcyBwcm9jZXNzZWQgYXRcbiAgICBpZCwgLy8gZW5jb2RlcyBpbmRleCBvZiB0aGUgZmlyc3QgY2hpbGQgb2YgdGhlIGNsdXN0ZXIgYW5kIGl0cyB6b29tIGxldmVsXG4gICAgcGFyZW50SWQ6IC0xLCAvLyBwYXJlbnQgY2x1c3RlciBpZFxuICAgIG51bVBvaW50cyxcbiAgICB3ZWlnaHQsXG4gIH07XG59XG5cbmZ1bmN0aW9uIGNsdXN0ZXI8TD4oXG4gIHBvaW50czogUG9pbnQ8TD5bXSxcbiAgem9vbTogbnVtYmVyLFxuICB0cmVlOiBab29tTGV2ZWxLREJ1c2gsXG4gIG9wdGlvbnM6IE9wdGlvbnMsXG4pIHtcbiAgY29uc3QgY2x1c3RlcnM6IFBvaW50PEw+W10gPSBbXTtcbiAgY29uc3Qge3JhZGl1cywgZXh0ZW50fSA9IG9wdGlvbnM7XG4gIGNvbnN0IHIgPSByYWRpdXMgLyAoZXh0ZW50ICogTWF0aC5wb3coMiwgem9vbSkpO1xuXG4gIC8vIGxvb3AgdGhyb3VnaCBlYWNoIHBvaW50XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgcG9pbnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgY29uc3QgcCA9IHBvaW50c1tpXTtcbiAgICAvLyBpZiB3ZSd2ZSBhbHJlYWR5IHZpc2l0ZWQgdGhlIHBvaW50IGF0IHRoaXMgem9vbSBsZXZlbCwgc2tpcCBpdFxuICAgIGlmIChwLnpvb20gPD0gem9vbSkge1xuICAgICAgY29udGludWU7XG4gICAgfVxuICAgIHAuem9vbSA9IHpvb207XG5cbiAgICAvLyBmaW5kIGFsbCBuZWFyYnkgcG9pbnRzXG4gICAgY29uc3QgbmVpZ2hib3JJZHMgPSB0cmVlLndpdGhpbihwLngsIHAueSwgcik7XG5cbiAgICBsZXQgd2VpZ2h0ID0gcC53ZWlnaHQgfHwgMTtcbiAgICBsZXQgbnVtUG9pbnRzID0gaXNDbHVzdGVyUG9pbnQocCkgPyBwLm51bVBvaW50cyA6IDE7XG4gICAgbGV0IHd4ID0gcC54ICogd2VpZ2h0O1xuICAgIGxldCB3eSA9IHAueSAqIHdlaWdodDtcblxuICAgIC8vIGVuY29kZSBib3RoIHpvb20gYW5kIHBvaW50IGluZGV4IG9uIHdoaWNoIHRoZSBjbHVzdGVyIG9yaWdpbmF0ZWRcbiAgICBjb25zdCBpZCA9IChpIDw8IDUpICsgKHpvb20gKyAxKTtcblxuICAgIGZvciAoY29uc3QgbmVpZ2hib3JJZCBvZiBuZWlnaGJvcklkcykge1xuICAgICAgY29uc3QgYiA9IHRyZWUucG9pbnRzW25laWdoYm9ySWRdO1xuICAgICAgLy8gZmlsdGVyIG91dCBuZWlnaGJvcnMgdGhhdCBhcmUgYWxyZWFkeSBwcm9jZXNzZWRcbiAgICAgIGlmIChiLnpvb20gPD0gem9vbSkge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIGIuem9vbSA9IHpvb207IC8vIHNhdmUgdGhlIHpvb20gKHNvIGl0IGRvZXNuJ3QgZ2V0IHByb2Nlc3NlZCB0d2ljZSlcblxuICAgICAgY29uc3Qgd2VpZ2h0MiA9IGIud2VpZ2h0IHx8IDE7XG4gICAgICBjb25zdCBudW1Qb2ludHMyID0gYi5udW1Qb2ludHMgfHwgMTtcbiAgICAgIHd4ICs9IGIueCAqIHdlaWdodDI7IC8vIGFjY3VtdWxhdGUgY29vcmRpbmF0ZXMgZm9yIGNhbGN1bGF0aW5nIHdlaWdodGVkIGNlbnRlclxuICAgICAgd3kgKz0gYi55ICogd2VpZ2h0MjtcblxuICAgICAgd2VpZ2h0ICs9IHdlaWdodDI7XG4gICAgICBudW1Qb2ludHMgKz0gbnVtUG9pbnRzMjtcbiAgICAgIGIucGFyZW50SWQgPSBpZDtcbiAgICB9XG5cbiAgICBpZiAobnVtUG9pbnRzID09PSAxKSB7XG4gICAgICBjbHVzdGVycy5wdXNoKHApO1xuICAgIH0gZWxzZSB7XG4gICAgICBwLnBhcmVudElkID0gaWQ7XG4gICAgICBjbHVzdGVycy5wdXNoKFxuICAgICAgICBjcmVhdGVDbHVzdGVyKHd4IC8gd2VpZ2h0LCB3eSAvIHdlaWdodCwgaWQsIG51bVBvaW50cywgd2VpZ2h0KSxcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGNsdXN0ZXJzO1xufVxuXG4vLyBzcGhlcmljYWwgbWVyY2F0b3IgdG8gbG9uZ2l0dWRlL2xhdGl0dWRlXG5mdW5jdGlvbiB4TG5nKHg6IG51bWJlcikge1xuICByZXR1cm4gKHggLSAwLjUpICogMzYwO1xufVxuXG5mdW5jdGlvbiB5TGF0KHk6IG51bWJlcikge1xuICBjb25zdCB5MiA9ICgoMTgwIC0geSAqIDM2MCkgKiBNYXRoLlBJKSAvIDE4MDtcbiAgcmV0dXJuICgzNjAgKiBNYXRoLmF0YW4oTWF0aC5leHAoeTIpKSkgLyBNYXRoLlBJIC0gOTA7XG59XG5cbi8vIGxvbmdpdHVkZS9sYXRpdHVkZSB0byBzcGhlcmljYWwgbWVyY2F0b3IgaW4gWzAuLjFdIHJhbmdlXG5mdW5jdGlvbiBsbmdYKGxuZzogbnVtYmVyKSB7XG4gIHJldHVybiBsbmcgLyAzNjAgKyAwLjU7XG59XG5cbmZ1bmN0aW9uIGxhdFkobGF0OiBudW1iZXIpIHtcbiAgY29uc3Qgc2luID0gTWF0aC5zaW4oKGxhdCAqIE1hdGguUEkpIC8gMTgwKTtcbiAgY29uc3QgeSA9IDAuNSAtICgwLjI1ICogTWF0aC5sb2coKDEgKyBzaW4pIC8gKDEgLSBzaW4pKSkgLyBNYXRoLlBJO1xuICByZXR1cm4geSA8IDAgPyAwIDogeSA+IDEgPyAxIDogeTtcbn1cblxuZnVuY3Rpb24gZ2V0WDxMPihwOiBQb2ludDxMPikge1xuICByZXR1cm4gcC54O1xufVxuXG5mdW5jdGlvbiBnZXRZPEw+KHA6IFBvaW50PEw+KSB7XG4gIHJldHVybiBwLnk7XG59XG4iXX0=
|
|
File without changes
|
|
File without changes
|