@fleet-frontend/mower-maps 0.0.6 → 0.0.7
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/config/constants.d.ts +4 -3
- package/dist/config/constants.d.ts.map +1 -1
- package/dist/config/index.d.ts +0 -18
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/styles.d.ts +17 -15
- package/dist/config/styles.d.ts.map +1 -1
- package/dist/index.esm.js +2711 -516
- package/dist/index.js +2713 -518
- package/dist/processor/MapDataProcessor.d.ts +3 -2
- package/dist/processor/MapDataProcessor.d.ts.map +1 -1
- package/dist/processor/PathDataProcessor.d.ts +3 -2
- package/dist/processor/PathDataProcessor.d.ts.map +1 -1
- package/dist/processor/builder/AntennaDataBuilder.d.ts +2 -2
- package/dist/processor/builder/AntennaDataBuilder.d.ts.map +1 -1
- package/dist/processor/builder/BoundaryDataBuilder.d.ts +4 -3
- package/dist/processor/builder/BoundaryDataBuilder.d.ts.map +1 -1
- package/dist/processor/builder/ChannelDataBuilder.d.ts +5 -33
- package/dist/processor/builder/ChannelDataBuilder.d.ts.map +1 -1
- package/dist/processor/builder/ChargingPileDataBuilder.d.ts +4 -4
- package/dist/processor/builder/ChargingPileDataBuilder.d.ts.map +1 -1
- package/dist/processor/builder/ObstacleDataBuilder.d.ts +2 -2
- package/dist/processor/builder/ObstacleDataBuilder.d.ts.map +1 -1
- package/dist/processor/builder/PathDataBuilder.d.ts.map +1 -1
- package/dist/processor/builder/SvgElementDataBuilder.d.ts +2 -2
- package/dist/processor/builder/SvgElementDataBuilder.d.ts.map +1 -1
- package/dist/processor/builder/VisionOffDataBuilder.d.ts +2 -2
- package/dist/processor/builder/VisionOffDataBuilder.d.ts.map +1 -1
- package/dist/render/BoundaryLabelsManager.d.ts +2 -5
- package/dist/render/BoundaryLabelsManager.d.ts.map +1 -1
- package/dist/render/MowerMapOverlay.d.ts +1 -3
- package/dist/render/MowerMapOverlay.d.ts.map +1 -1
- package/dist/render/MowerMapRenderer.d.ts.map +1 -1
- package/dist/render/layers/BoundaryLayer.d.ts.map +1 -1
- package/dist/render/layers/ChannelLayer.d.ts +6 -0
- package/dist/render/layers/ChannelLayer.d.ts.map +1 -1
- package/dist/render/layers/SvgElementLayer.d.ts.map +1 -1
- package/dist/render/layers/VisionOffLayer.d.ts.map +1 -1
- package/dist/render/layers/types.d.ts +3 -45
- package/dist/render/layers/types.d.ts.map +1 -1
- package/dist/types/renderer.d.ts +44 -15
- package/dist/types/renderer.d.ts.map +1 -1
- package/dist/utils/handleRealTime.d.ts.map +1 -1
- package/dist/utils/index.d.ts +2 -0
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/sleep.d.ts +2 -0
- package/dist/utils/sleep.d.ts.map +1 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
var jsxRuntime = require('react/jsx-runtime');
|
|
4
4
|
var React = require('react');
|
|
5
|
-
var lodashEs = require('lodash-es');
|
|
6
5
|
|
|
7
6
|
/**
|
|
8
7
|
* SVG基础MapView
|
|
@@ -604,8 +603,8 @@ const createStoreImpl = (createState) => {
|
|
|
604
603
|
};
|
|
605
604
|
const createStore = (createState) => createState ? createStoreImpl(createState) : createStoreImpl;
|
|
606
605
|
|
|
607
|
-
const identity = (arg) => arg;
|
|
608
|
-
function useStore(api, selector = identity) {
|
|
606
|
+
const identity$1 = (arg) => arg;
|
|
607
|
+
function useStore(api, selector = identity$1) {
|
|
609
608
|
const slice = React.useSyncExternalStore(
|
|
610
609
|
api.subscribe,
|
|
611
610
|
() => selector(api.getState()),
|
|
@@ -656,19 +655,20 @@ const SCALE_FACTOR = 50; // 50像素/米
|
|
|
656
655
|
* 默认线宽设置
|
|
657
656
|
*/
|
|
658
657
|
const DEFAULT_LINE_WIDTHS = {
|
|
659
|
-
BOUNDARY: 2,
|
|
660
658
|
OBSTACLE: 2,
|
|
661
659
|
CHARGING_PILE: 2,
|
|
662
|
-
|
|
660
|
+
CHANNEL: 2,
|
|
661
|
+
PATH: 20,
|
|
663
662
|
VISION_OFF_AREA: 2,
|
|
664
|
-
TIME_LIMIT_OBSTACLE:
|
|
663
|
+
TIME_LIMIT_OBSTACLE: 1,
|
|
665
664
|
};
|
|
666
665
|
/**
|
|
667
666
|
* 默认透明度设置
|
|
668
667
|
*/
|
|
669
668
|
const DEFAULT_OPACITIES = {
|
|
670
669
|
FULL: 1.0,
|
|
671
|
-
HIGH: 0.
|
|
670
|
+
HIGH: 0.7,
|
|
671
|
+
LOW: 0.4};
|
|
672
672
|
/**
|
|
673
673
|
* 默认半径设置
|
|
674
674
|
*/
|
|
@@ -771,6 +771,12 @@ class ChannelLayer extends BaseLayer {
|
|
|
771
771
|
this.scale = 1;
|
|
772
772
|
this.type = LAYER_DEFAULT_TYPE.CHANNEL;
|
|
773
773
|
}
|
|
774
|
+
/**
|
|
775
|
+
* 获取元素
|
|
776
|
+
*/
|
|
777
|
+
getElements() {
|
|
778
|
+
return this.elements;
|
|
779
|
+
}
|
|
774
780
|
/**
|
|
775
781
|
* SVG渲染方法
|
|
776
782
|
*/
|
|
@@ -863,9 +869,9 @@ class ChannelLayer extends BaseLayer {
|
|
|
863
869
|
for (let i = 1; i < coordinates.length; i++) {
|
|
864
870
|
pathData += ` L ${coordinates[i][0]} ${coordinates[i][1]}`;
|
|
865
871
|
}
|
|
866
|
-
const topLineWidth = dp2px(
|
|
867
|
-
const bottomLineWidth = dp2px(
|
|
868
|
-
const dashLength = dp2px(
|
|
872
|
+
const topLineWidth = dp2px(style.lineWidth).toString();
|
|
873
|
+
const bottomLineWidth = dp2px(style.bottomLineWidth).toString();
|
|
874
|
+
const dashLength = dp2px(style.lineWidth);
|
|
869
875
|
// 1. 创建底层path(宽度20,boundaryBorder颜色)
|
|
870
876
|
const bottomPath = document.createElementNS('http://www.w3.org/2000/svg', 'path');
|
|
871
877
|
bottomPath.setAttribute('d', pathData);
|
|
@@ -895,16 +901,8 @@ class ChannelLayer extends BaseLayer {
|
|
|
895
901
|
topPath.style.clipPath = `url(#${clipPathIdsMap[element.originalData?.id.toString()]})`;
|
|
896
902
|
}
|
|
897
903
|
// 支持两种虚线格式:lineDash数组和strokeDasharray字符串
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
}
|
|
901
|
-
else if (style.strokeDasharray) {
|
|
902
|
-
topPath.setAttribute('stroke-dasharray', style.strokeDasharray);
|
|
903
|
-
}
|
|
904
|
-
else {
|
|
905
|
-
// 默认虚线样式
|
|
906
|
-
topPath.setAttribute('stroke-dasharray', `${dashLength * 2}, ${dashLength}`);
|
|
907
|
-
}
|
|
904
|
+
// 默认虚线样式
|
|
905
|
+
topPath.setAttribute('stroke-dasharray', `${dashLength * 2}, ${dashLength}`);
|
|
908
906
|
topPath.classList.add('vector-path-top');
|
|
909
907
|
svgGroup.appendChild(topPath);
|
|
910
908
|
}
|
|
@@ -944,9 +942,9 @@ class PathLayer extends BaseLayer {
|
|
|
944
942
|
Object.values(subBoundaryBorder).forEach((item) => {
|
|
945
943
|
const bCoords = item.coordinates;
|
|
946
944
|
if (bCoords.length >= 3) {
|
|
947
|
-
d += `M ${
|
|
945
|
+
d += `M ${bCoords[0][0]} ${bCoords[0][1]}`;
|
|
948
946
|
for (let i = 1; i < bCoords.length; i++) {
|
|
949
|
-
d += ` L ${
|
|
947
|
+
d += ` L ${bCoords[i][0]} ${bCoords[i][1]}`;
|
|
950
948
|
}
|
|
951
949
|
d += ' Z ';
|
|
952
950
|
}
|
|
@@ -991,9 +989,9 @@ class PathLayer extends BaseLayer {
|
|
|
991
989
|
return;
|
|
992
990
|
const path = document.createElementNS('http://www.w3.org/2000/svg', 'path');
|
|
993
991
|
// 构建路径数据
|
|
994
|
-
let pathData = `M ${
|
|
992
|
+
let pathData = `M ${coordinates[0][0]} ${coordinates[0][1]}`;
|
|
995
993
|
for (let i = 1; i < coordinates.length; i++) {
|
|
996
|
-
pathData += ` L ${
|
|
994
|
+
pathData += ` L ${coordinates[i][0]} ${coordinates[i][1]}`;
|
|
997
995
|
}
|
|
998
996
|
path.style.mixBlendMode = 'normal';
|
|
999
997
|
// 设置路径属性
|
|
@@ -1061,7 +1059,7 @@ class BoundaryLayer extends BaseLayer {
|
|
|
1061
1059
|
const polygon = document.createElementNS('http://www.w3.org/2000/svg', 'polygon');
|
|
1062
1060
|
// 构建点集合,使用整数坐标(只取x,y坐标)
|
|
1063
1061
|
const points = coordinates
|
|
1064
|
-
.map((coord) => `${
|
|
1062
|
+
.map((coord) => `${coord[0]},${coord[1]}`)
|
|
1065
1063
|
.join(' ');
|
|
1066
1064
|
const fillColor = style.fillColor;
|
|
1067
1065
|
polygon.setAttribute('points', points);
|
|
@@ -1107,11 +1105,11 @@ class ObstacleLayer extends BaseLayer {
|
|
|
1107
1105
|
const polygon = document.createElementNS('http://www.w3.org/2000/svg', 'polygon');
|
|
1108
1106
|
// 构建点集合,使用整数坐标
|
|
1109
1107
|
const points = coordinates
|
|
1110
|
-
.map((coord) => `${
|
|
1108
|
+
.map((coord) => `${coord[0]},${coord[1]}`)
|
|
1111
1109
|
.join(' ');
|
|
1112
1110
|
polygon.setAttribute('points', points);
|
|
1113
1111
|
polygon.setAttribute('fill', style.fillColor || 'rgba(220, 53, 69, 0.2)');
|
|
1114
|
-
polygon.setAttribute('stroke', style.
|
|
1112
|
+
polygon.setAttribute('stroke', style.lineColor || '#dc3545');
|
|
1115
1113
|
// 确保最小线条宽度
|
|
1116
1114
|
const lineWidth = Math.max(style.lineWidth || 2, 0.5);
|
|
1117
1115
|
polygon.setAttribute('stroke-width', lineWidth.toString());
|
|
@@ -1165,8 +1163,8 @@ class ChargingPileLayer extends BaseLayer {
|
|
|
1165
1163
|
const rotationDegree = 270 - angle; // 坐标系转换
|
|
1166
1164
|
const image = document.createElementNS('http://www.w3.org/2000/svg', 'image');
|
|
1167
1165
|
// 图片居中定位
|
|
1168
|
-
const x =
|
|
1169
|
-
const y =
|
|
1166
|
+
const x = center[0];
|
|
1167
|
+
const y = center[1];
|
|
1170
1168
|
image.setAttribute('x', x.toString());
|
|
1171
1169
|
image.setAttribute('y', y.toString());
|
|
1172
1170
|
image.setAttribute('width', `${size}px`);
|
|
@@ -1236,8 +1234,8 @@ class PointLayer extends BaseLayer {
|
|
|
1236
1234
|
const coordinate = coordinates[0];
|
|
1237
1235
|
const radius = style.radius || 4;
|
|
1238
1236
|
const circle = document.createElementNS('http://www.w3.org/2000/svg', 'circle');
|
|
1239
|
-
circle.setAttribute('cx',
|
|
1240
|
-
circle.setAttribute('cy',
|
|
1237
|
+
circle.setAttribute('cx', coordinate[0].toString());
|
|
1238
|
+
circle.setAttribute('cy', coordinate[1].toString());
|
|
1241
1239
|
circle.setAttribute('r', radius.toString());
|
|
1242
1240
|
circle.setAttribute('fill', style.fillColor || style.strokeColor || '#000000');
|
|
1243
1241
|
circle.setAttribute('stroke', style.strokeColor || '#000000');
|
|
@@ -1289,6 +1287,7 @@ class SvgElementLayer extends BaseLayer {
|
|
|
1289
1287
|
if (coordinates.length === 0)
|
|
1290
1288
|
return;
|
|
1291
1289
|
const center = coordinates[0];
|
|
1290
|
+
console.log('metadata==', metadata, style, element);
|
|
1292
1291
|
if (!metadata || !metadata.svg) {
|
|
1293
1292
|
this.renderSvgPlaceholder(svgGroup, center, metadata, style);
|
|
1294
1293
|
return;
|
|
@@ -1301,31 +1300,31 @@ class SvgElementLayer extends BaseLayer {
|
|
|
1301
1300
|
const svgElement = svgDoc.documentElement;
|
|
1302
1301
|
if (svgElement.tagName === 'svg') {
|
|
1303
1302
|
// 获取原始SVG尺寸
|
|
1304
|
-
const
|
|
1305
|
-
const
|
|
1303
|
+
const originalWidth = parseFloat(svgElement.getAttribute('width') || '139');
|
|
1304
|
+
const originalHeight = parseFloat(svgElement.getAttribute('height') || '138');
|
|
1306
1305
|
// 计算变换参数
|
|
1307
1306
|
const userScale = metadata.scale || 1;
|
|
1308
1307
|
const direction = metadata.direction || 0;
|
|
1308
|
+
// 设置原始SVG的实际尺寸(限制大小)
|
|
1309
|
+
svgElement.setAttribute('width', originalWidth.toString());
|
|
1310
|
+
svgElement.setAttribute('height', originalHeight.toString());
|
|
1309
1311
|
// 创建变换组
|
|
1310
1312
|
const transformGroup = document.createElementNS('http://www.w3.org/2000/svg', 'g');
|
|
1311
|
-
//
|
|
1313
|
+
// 在transformGroup上应用变换:平移到中心,旋转,缩放,然后居中SVG
|
|
1312
1314
|
const transform = [
|
|
1313
1315
|
`translate(${center[0]}, ${center[1]})`,
|
|
1314
1316
|
`rotate(${(direction * 180) / Math.PI})`,
|
|
1315
1317
|
`scale(${userScale})`,
|
|
1316
|
-
`translate(${-
|
|
1318
|
+
`translate(${-originalWidth / 2}, ${-originalHeight / 2})`,
|
|
1317
1319
|
].join(' ');
|
|
1318
1320
|
transformGroup.setAttribute('transform', transform);
|
|
1319
|
-
// 复制SVG内容
|
|
1320
|
-
while (svgElement.firstChild) {
|
|
1321
|
-
const child = svgElement.firstChild;
|
|
1322
|
-
svgElement.removeChild(child);
|
|
1323
|
-
transformGroup.appendChild(child);
|
|
1324
|
-
}
|
|
1325
1321
|
// 设置样式
|
|
1326
1322
|
if (style.opacity !== undefined) {
|
|
1327
1323
|
transformGroup.setAttribute('opacity', style.opacity.toString());
|
|
1328
1324
|
}
|
|
1325
|
+
// 将限制好尺寸的原始SVG添加到transformGroup中
|
|
1326
|
+
transformGroup.appendChild(svgElement);
|
|
1327
|
+
// 将transformGroup添加到svgGroup中
|
|
1329
1328
|
svgGroup.appendChild(transformGroup);
|
|
1330
1329
|
}
|
|
1331
1330
|
else {
|
|
@@ -1343,14 +1342,15 @@ class SvgElementLayer extends BaseLayer {
|
|
|
1343
1342
|
renderSvgPlaceholder(svgGroup, center, metadata, style) {
|
|
1344
1343
|
const size = (metadata?.scale || 1) * 20;
|
|
1345
1344
|
const rect = document.createElementNS('http://www.w3.org/2000/svg', 'rect');
|
|
1346
|
-
|
|
1347
|
-
rect.setAttribute('
|
|
1345
|
+
console.log('style==', style);
|
|
1346
|
+
rect.setAttribute('x', ((center[0] - size / 2) / 50).toString());
|
|
1347
|
+
rect.setAttribute('y', ((center[1] - size / 2) / 50).toString());
|
|
1348
1348
|
rect.setAttribute('width', size.toString());
|
|
1349
1349
|
rect.setAttribute('height', size.toString());
|
|
1350
|
-
rect.setAttribute('fill', style.fillColor
|
|
1351
|
-
rect.setAttribute('stroke', style.
|
|
1352
|
-
rect.setAttribute('stroke-width',
|
|
1353
|
-
rect.setAttribute('opacity',
|
|
1350
|
+
rect.setAttribute('fill', style.fillColor);
|
|
1351
|
+
rect.setAttribute('stroke', style.lineColor);
|
|
1352
|
+
rect.setAttribute('stroke-width', style.lineWidth.toString());
|
|
1353
|
+
rect.setAttribute('opacity', style.opacity.toString());
|
|
1354
1354
|
svgGroup.appendChild(rect);
|
|
1355
1355
|
}
|
|
1356
1356
|
}
|
|
@@ -1389,12 +1389,12 @@ class VisionOffLayer extends BaseLayer {
|
|
|
1389
1389
|
const polygon = document.createElementNS('http://www.w3.org/2000/svg', 'polygon');
|
|
1390
1390
|
// 构建点集合,使用整数坐标
|
|
1391
1391
|
const points = coordinates
|
|
1392
|
-
.map((coord) => `${
|
|
1392
|
+
.map((coord) => `${coord[0]},${coord[1]}`)
|
|
1393
1393
|
.join(' ');
|
|
1394
1394
|
const fillColor = style.fillColor || 'rgba(0, 255, 0, 0.4)';
|
|
1395
1395
|
polygon.setAttribute('points', points);
|
|
1396
1396
|
polygon.setAttribute('fill', fillColor);
|
|
1397
|
-
polygon.setAttribute('stroke', style.
|
|
1397
|
+
polygon.setAttribute('stroke', style.lineColor);
|
|
1398
1398
|
// 确保最小线条宽度
|
|
1399
1399
|
const lineWidth = Math.max(style.lineWidth || 2, 0.5);
|
|
1400
1400
|
polygon.setAttribute('stroke-width', lineWidth.toString());
|
|
@@ -1411,66 +1411,65 @@ class VisionOffLayer extends BaseLayer {
|
|
|
1411
1411
|
* 边界相关样式配置
|
|
1412
1412
|
*/
|
|
1413
1413
|
const BOUNDARY_STYLES = {
|
|
1414
|
-
|
|
1414
|
+
lineColor: '#ffffff',
|
|
1415
1415
|
fillColor: 'rgba(239, 255, 237, 0.15)', // 更鲜艳的绿色半透明填充,增强可见性
|
|
1416
1416
|
lineWidth: 2,
|
|
1417
|
-
opacity: DEFAULT_OPACITIES.FULL
|
|
1418
|
-
};
|
|
1419
|
-
const BOUNDARY_BORDER_STYLES = {
|
|
1420
|
-
strokeColor: '#ffffff',
|
|
1421
|
-
fillColor: 'rgba(239, 255, 237, 0.15)', // 更鲜艳的绿色半透明填充,增强可见性
|
|
1422
|
-
lineWidth: DEFAULT_LINE_WIDTHS.BOUNDARY,
|
|
1423
|
-
opacity: DEFAULT_OPACITIES.FULL
|
|
1417
|
+
opacity: DEFAULT_OPACITIES.FULL,
|
|
1424
1418
|
};
|
|
1425
1419
|
const VISION_OFF_AREA_STYLES = {
|
|
1426
|
-
|
|
1420
|
+
lineColor: 'rgba(108, 167, 255, 1)',
|
|
1427
1421
|
fillColor: 'rgba(43, 128, 255, 0.45)', // 浅蓝色半透明填充
|
|
1428
1422
|
lineWidth: DEFAULT_LINE_WIDTHS.VISION_OFF_AREA,
|
|
1429
|
-
opacity: DEFAULT_OPACITIES.HIGH
|
|
1423
|
+
opacity: DEFAULT_OPACITIES.HIGH,
|
|
1430
1424
|
};
|
|
1431
1425
|
const OBSTACLE_STYLES = {
|
|
1432
|
-
|
|
1426
|
+
lineColor: 'rgba(255, 122, 51, 1)',
|
|
1433
1427
|
fillColor: 'rgba(255, 113, 51, 0.2)', // 红色半透明填充
|
|
1434
1428
|
lineWidth: DEFAULT_LINE_WIDTHS.OBSTACLE,
|
|
1435
|
-
opacity: DEFAULT_OPACITIES.FULL
|
|
1429
|
+
opacity: DEFAULT_OPACITIES.FULL,
|
|
1436
1430
|
};
|
|
1437
1431
|
const CHARGING_PILE_STYLES = {
|
|
1438
|
-
|
|
1432
|
+
lineColor: 'blue',
|
|
1439
1433
|
fillColor: 'blue',
|
|
1440
1434
|
lineWidth: DEFAULT_LINE_WIDTHS.CHARGING_PILE,
|
|
1441
1435
|
radius: DEFAULT_RADII.CHARGING_PILE,
|
|
1442
|
-
opacity: DEFAULT_OPACITIES.FULL
|
|
1436
|
+
opacity: DEFAULT_OPACITIES.FULL,
|
|
1443
1437
|
};
|
|
1444
1438
|
const DOODLE_STYLES = {
|
|
1445
|
-
|
|
1446
|
-
fillColor: '
|
|
1439
|
+
lineColor: '#ff5722',
|
|
1440
|
+
fillColor: '#ff9800', // 粉色半透明填充
|
|
1447
1441
|
lineWidth: DEFAULT_LINE_WIDTHS.TIME_LIMIT_OBSTACLE,
|
|
1448
|
-
opacity: DEFAULT_OPACITIES.HIGH
|
|
1442
|
+
opacity: DEFAULT_OPACITIES.HIGH,
|
|
1449
1443
|
};
|
|
1450
1444
|
const PATH_EDGE_STYLES = {
|
|
1451
|
-
strokeColor: 'red',
|
|
1452
|
-
lineWidth: DEFAULT_LINE_WIDTHS.PATH};
|
|
1453
|
-
const CHANNEL_STYLES = {
|
|
1454
|
-
strokeColor: 'purple',
|
|
1455
1445
|
lineWidth: DEFAULT_LINE_WIDTHS.PATH,
|
|
1456
|
-
opacity: DEFAULT_OPACITIES.
|
|
1446
|
+
opacity: DEFAULT_OPACITIES.LOW,
|
|
1447
|
+
edgeLineColor: 'rgba(194, 203, 212)',
|
|
1448
|
+
transLineColor: 'transparent',
|
|
1449
|
+
mowingLineColor: 'rgba(194, 203, 212)',
|
|
1450
|
+
};
|
|
1451
|
+
const CHANNEL_STYLES = {
|
|
1452
|
+
lineColor: 'purple',
|
|
1453
|
+
lineWidth: DEFAULT_LINE_WIDTHS.CHANNEL,
|
|
1454
|
+
bottomLineWidth: 20,
|
|
1455
|
+
bottomLineColor: '#8498A9',
|
|
1456
|
+
opacity: DEFAULT_OPACITIES.FULL,
|
|
1457
1457
|
};
|
|
1458
1458
|
const ANTENNA_STYLES = {
|
|
1459
|
-
|
|
1459
|
+
lineColor: 'transparent',
|
|
1460
1460
|
fillColor: 'transparent',
|
|
1461
1461
|
radius: 12, // 默认24px大小
|
|
1462
|
-
opacity: DEFAULT_OPACITIES.FULL
|
|
1462
|
+
opacity: DEFAULT_OPACITIES.FULL,
|
|
1463
1463
|
};
|
|
1464
1464
|
const DEFAULT_STYLES = {
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
ANTENNA: ANTENNA_STYLES
|
|
1465
|
+
boundary: BOUNDARY_STYLES,
|
|
1466
|
+
visionOffArea: VISION_OFF_AREA_STYLES,
|
|
1467
|
+
obstacle: OBSTACLE_STYLES,
|
|
1468
|
+
chargingPile: CHARGING_PILE_STYLES,
|
|
1469
|
+
doodle: DOODLE_STYLES,
|
|
1470
|
+
path: PATH_EDGE_STYLES,
|
|
1471
|
+
channel: CHANNEL_STYLES,
|
|
1472
|
+
antenna: ANTENNA_STYLES,
|
|
1474
1473
|
};
|
|
1475
1474
|
|
|
1476
1475
|
/**
|
|
@@ -2218,18 +2217,20 @@ const handleRealTimeData = ({ realTimeData, isMowing, pathData, partitionBoundar
|
|
|
2218
2217
|
else if (item.type === REAL_TIME_DATA_TYPE.PROCESS) {
|
|
2219
2218
|
// 割草进度
|
|
2220
2219
|
const { mapWorkPosition } = item;
|
|
2221
|
-
|
|
2222
|
-
|
|
2223
|
-
|
|
2224
|
-
|
|
2225
|
-
|
|
2226
|
-
|
|
2227
|
-
|
|
2228
|
-
|
|
2229
|
-
|
|
2230
|
-
newPathData[currentPartitionId]
|
|
2231
|
-
|
|
2232
|
-
|
|
2220
|
+
if (mapWorkPosition) {
|
|
2221
|
+
// 解析mapWorkPosition数据,获取到当前的割草状态,割草进度,割草边界id
|
|
2222
|
+
const { isMowing, currentMowBoundaryId, currentMowProgress } = parseMapWorkPosition(mapWorkPosition);
|
|
2223
|
+
// const { isMowing, currentMowBoundaryId, currentMowProgress } = parseMapWorkPosition(
|
|
2224
|
+
// '000000060000000000000001000000030000001BA5A5A5A5A5A5A5A5240000A024010D50FFFFFFED000000000000000000000000000000010000000000000000'
|
|
2225
|
+
// );
|
|
2226
|
+
console.log('isMowing===', isMowing, currentMowBoundaryId, currentMowProgress);
|
|
2227
|
+
mowingStatus = isMowing;
|
|
2228
|
+
const currentPartitionId = currentMowBoundaryId ? currentMowBoundaryId.toString() : null;
|
|
2229
|
+
if (currentMowProgress && currentPartitionId && newPathData?.[currentPartitionId]) {
|
|
2230
|
+
newPathData[currentPartitionId].partitionPercentage = currentMowProgress / 100;
|
|
2231
|
+
newPathData[currentPartitionId].finishedArea =
|
|
2232
|
+
(newPathData[currentPartitionId].area * currentMowProgress) / 10000;
|
|
2233
|
+
}
|
|
2233
2234
|
}
|
|
2234
2235
|
}
|
|
2235
2236
|
});
|
|
@@ -2281,61 +2282,2486 @@ function getDisabledMowerImageByModal(mowerModal) {
|
|
|
2281
2282
|
}
|
|
2282
2283
|
return iDisabled;
|
|
2283
2284
|
}
|
|
2284
|
-
function getNoPositionMowerImageByModal(mowerModal) {
|
|
2285
|
-
if (mowerModal.includes('i')) {
|
|
2286
|
-
return iNoPosition;
|
|
2287
|
-
}
|
|
2288
|
-
else if (mowerModal.includes('h')) {
|
|
2289
|
-
return hNoPosition;
|
|
2290
|
-
}
|
|
2291
|
-
else if (mowerModal.includes('x3')) {
|
|
2292
|
-
return x3NoPosition;
|
|
2293
|
-
}
|
|
2294
|
-
return iNoPosition;
|
|
2285
|
+
function getNoPositionMowerImageByModal(mowerModal) {
|
|
2286
|
+
if (mowerModal.includes('i')) {
|
|
2287
|
+
return iNoPosition;
|
|
2288
|
+
}
|
|
2289
|
+
else if (mowerModal.includes('h')) {
|
|
2290
|
+
return hNoPosition;
|
|
2291
|
+
}
|
|
2292
|
+
else if (mowerModal.includes('x3')) {
|
|
2293
|
+
return x3NoPosition;
|
|
2294
|
+
}
|
|
2295
|
+
return iNoPosition;
|
|
2296
|
+
}
|
|
2297
|
+
function getMowerImage(positonConfig) {
|
|
2298
|
+
const model = positonConfig.vehicleModel || '';
|
|
2299
|
+
const state = positonConfig.vehicleState;
|
|
2300
|
+
const mowerImage = getMowerImageByModal(model);
|
|
2301
|
+
const disabledImage = getDisabledMowerImageByModal(model);
|
|
2302
|
+
const noPositionImage = getNoPositionMowerImageByModal(model);
|
|
2303
|
+
const positonOutOfRange = isOutOfRange(positonConfig);
|
|
2304
|
+
const positionValid = isInvalidPosition(positonConfig);
|
|
2305
|
+
const isOffLine = state === RobotStatus.DISCONNECTED;
|
|
2306
|
+
if (isOffLine) {
|
|
2307
|
+
return disabledImage;
|
|
2308
|
+
}
|
|
2309
|
+
else if (positionValid || positonOutOfRange) {
|
|
2310
|
+
return noPositionImage;
|
|
2311
|
+
}
|
|
2312
|
+
else {
|
|
2313
|
+
return mowerImage;
|
|
2314
|
+
}
|
|
2315
|
+
}
|
|
2316
|
+
function isNoPosture(posture) {
|
|
2317
|
+
if (posture == null || posture == undefined) {
|
|
2318
|
+
return true;
|
|
2319
|
+
}
|
|
2320
|
+
if (posture == 0) {
|
|
2321
|
+
return true;
|
|
2322
|
+
}
|
|
2323
|
+
else if (posture == -99999) {
|
|
2324
|
+
return true;
|
|
2325
|
+
}
|
|
2326
|
+
return false;
|
|
2327
|
+
}
|
|
2328
|
+
function isInvalidPosition(positonConfig) {
|
|
2329
|
+
return (isNoPosture(positonConfig.postureX) &&
|
|
2330
|
+
isNoPosture(positonConfig.postureY) &&
|
|
2331
|
+
isNoPosture(positonConfig.postureTheta));
|
|
2332
|
+
}
|
|
2333
|
+
function isOutOfRange(positonConfig) {
|
|
2334
|
+
return (positonConfig.postureX != null &&
|
|
2335
|
+
Math.abs(positonConfig.postureX) > 1000 * SCALE_FACTOR &&
|
|
2336
|
+
positonConfig.postureY != null &&
|
|
2337
|
+
Math.abs(positonConfig.postureY) > 1000 * SCALE_FACTOR);
|
|
2338
|
+
}
|
|
2339
|
+
|
|
2340
|
+
/** Detect free variable `global` from Node.js. */
|
|
2341
|
+
var freeGlobal = typeof global == 'object' && global && global.Object === Object && global;
|
|
2342
|
+
|
|
2343
|
+
/** Detect free variable `self`. */
|
|
2344
|
+
var freeSelf = typeof self == 'object' && self && self.Object === Object && self;
|
|
2345
|
+
|
|
2346
|
+
/** Used as a reference to the global object. */
|
|
2347
|
+
var root = freeGlobal || freeSelf || Function('return this')();
|
|
2348
|
+
|
|
2349
|
+
/** Built-in value references. */
|
|
2350
|
+
var Symbol = root.Symbol;
|
|
2351
|
+
|
|
2352
|
+
/** Used for built-in method references. */
|
|
2353
|
+
var objectProto$9 = Object.prototype;
|
|
2354
|
+
|
|
2355
|
+
/** Used to check objects for own properties. */
|
|
2356
|
+
var hasOwnProperty$7 = objectProto$9.hasOwnProperty;
|
|
2357
|
+
|
|
2358
|
+
/**
|
|
2359
|
+
* Used to resolve the
|
|
2360
|
+
* [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
|
|
2361
|
+
* of values.
|
|
2362
|
+
*/
|
|
2363
|
+
var nativeObjectToString$1 = objectProto$9.toString;
|
|
2364
|
+
|
|
2365
|
+
/** Built-in value references. */
|
|
2366
|
+
var symToStringTag$1 = Symbol ? Symbol.toStringTag : undefined;
|
|
2367
|
+
|
|
2368
|
+
/**
|
|
2369
|
+
* A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values.
|
|
2370
|
+
*
|
|
2371
|
+
* @private
|
|
2372
|
+
* @param {*} value The value to query.
|
|
2373
|
+
* @returns {string} Returns the raw `toStringTag`.
|
|
2374
|
+
*/
|
|
2375
|
+
function getRawTag(value) {
|
|
2376
|
+
var isOwn = hasOwnProperty$7.call(value, symToStringTag$1),
|
|
2377
|
+
tag = value[symToStringTag$1];
|
|
2378
|
+
|
|
2379
|
+
try {
|
|
2380
|
+
value[symToStringTag$1] = undefined;
|
|
2381
|
+
var unmasked = true;
|
|
2382
|
+
} catch (e) {}
|
|
2383
|
+
|
|
2384
|
+
var result = nativeObjectToString$1.call(value);
|
|
2385
|
+
if (unmasked) {
|
|
2386
|
+
if (isOwn) {
|
|
2387
|
+
value[symToStringTag$1] = tag;
|
|
2388
|
+
} else {
|
|
2389
|
+
delete value[symToStringTag$1];
|
|
2390
|
+
}
|
|
2391
|
+
}
|
|
2392
|
+
return result;
|
|
2393
|
+
}
|
|
2394
|
+
|
|
2395
|
+
/** Used for built-in method references. */
|
|
2396
|
+
var objectProto$8 = Object.prototype;
|
|
2397
|
+
|
|
2398
|
+
/**
|
|
2399
|
+
* Used to resolve the
|
|
2400
|
+
* [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
|
|
2401
|
+
* of values.
|
|
2402
|
+
*/
|
|
2403
|
+
var nativeObjectToString = objectProto$8.toString;
|
|
2404
|
+
|
|
2405
|
+
/**
|
|
2406
|
+
* Converts `value` to a string using `Object.prototype.toString`.
|
|
2407
|
+
*
|
|
2408
|
+
* @private
|
|
2409
|
+
* @param {*} value The value to convert.
|
|
2410
|
+
* @returns {string} Returns the converted string.
|
|
2411
|
+
*/
|
|
2412
|
+
function objectToString(value) {
|
|
2413
|
+
return nativeObjectToString.call(value);
|
|
2414
|
+
}
|
|
2415
|
+
|
|
2416
|
+
/** `Object#toString` result references. */
|
|
2417
|
+
var nullTag = '[object Null]',
|
|
2418
|
+
undefinedTag = '[object Undefined]';
|
|
2419
|
+
|
|
2420
|
+
/** Built-in value references. */
|
|
2421
|
+
var symToStringTag = Symbol ? Symbol.toStringTag : undefined;
|
|
2422
|
+
|
|
2423
|
+
/**
|
|
2424
|
+
* The base implementation of `getTag` without fallbacks for buggy environments.
|
|
2425
|
+
*
|
|
2426
|
+
* @private
|
|
2427
|
+
* @param {*} value The value to query.
|
|
2428
|
+
* @returns {string} Returns the `toStringTag`.
|
|
2429
|
+
*/
|
|
2430
|
+
function baseGetTag(value) {
|
|
2431
|
+
if (value == null) {
|
|
2432
|
+
return value === undefined ? undefinedTag : nullTag;
|
|
2433
|
+
}
|
|
2434
|
+
return (symToStringTag && symToStringTag in Object(value))
|
|
2435
|
+
? getRawTag(value)
|
|
2436
|
+
: objectToString(value);
|
|
2437
|
+
}
|
|
2438
|
+
|
|
2439
|
+
/**
|
|
2440
|
+
* Checks if `value` is object-like. A value is object-like if it's not `null`
|
|
2441
|
+
* and has a `typeof` result of "object".
|
|
2442
|
+
*
|
|
2443
|
+
* @static
|
|
2444
|
+
* @memberOf _
|
|
2445
|
+
* @since 4.0.0
|
|
2446
|
+
* @category Lang
|
|
2447
|
+
* @param {*} value The value to check.
|
|
2448
|
+
* @returns {boolean} Returns `true` if `value` is object-like, else `false`.
|
|
2449
|
+
* @example
|
|
2450
|
+
*
|
|
2451
|
+
* _.isObjectLike({});
|
|
2452
|
+
* // => true
|
|
2453
|
+
*
|
|
2454
|
+
* _.isObjectLike([1, 2, 3]);
|
|
2455
|
+
* // => true
|
|
2456
|
+
*
|
|
2457
|
+
* _.isObjectLike(_.noop);
|
|
2458
|
+
* // => false
|
|
2459
|
+
*
|
|
2460
|
+
* _.isObjectLike(null);
|
|
2461
|
+
* // => false
|
|
2462
|
+
*/
|
|
2463
|
+
function isObjectLike(value) {
|
|
2464
|
+
return value != null && typeof value == 'object';
|
|
2465
|
+
}
|
|
2466
|
+
|
|
2467
|
+
/** `Object#toString` result references. */
|
|
2468
|
+
var symbolTag = '[object Symbol]';
|
|
2469
|
+
|
|
2470
|
+
/**
|
|
2471
|
+
* Checks if `value` is classified as a `Symbol` primitive or object.
|
|
2472
|
+
*
|
|
2473
|
+
* @static
|
|
2474
|
+
* @memberOf _
|
|
2475
|
+
* @since 4.0.0
|
|
2476
|
+
* @category Lang
|
|
2477
|
+
* @param {*} value The value to check.
|
|
2478
|
+
* @returns {boolean} Returns `true` if `value` is a symbol, else `false`.
|
|
2479
|
+
* @example
|
|
2480
|
+
*
|
|
2481
|
+
* _.isSymbol(Symbol.iterator);
|
|
2482
|
+
* // => true
|
|
2483
|
+
*
|
|
2484
|
+
* _.isSymbol('abc');
|
|
2485
|
+
* // => false
|
|
2486
|
+
*/
|
|
2487
|
+
function isSymbol(value) {
|
|
2488
|
+
return typeof value == 'symbol' ||
|
|
2489
|
+
(isObjectLike(value) && baseGetTag(value) == symbolTag);
|
|
2490
|
+
}
|
|
2491
|
+
|
|
2492
|
+
/**
|
|
2493
|
+
* A specialized version of `_.map` for arrays without support for iteratee
|
|
2494
|
+
* shorthands.
|
|
2495
|
+
*
|
|
2496
|
+
* @private
|
|
2497
|
+
* @param {Array} [array] The array to iterate over.
|
|
2498
|
+
* @param {Function} iteratee The function invoked per iteration.
|
|
2499
|
+
* @returns {Array} Returns the new mapped array.
|
|
2500
|
+
*/
|
|
2501
|
+
function arrayMap(array, iteratee) {
|
|
2502
|
+
var index = -1,
|
|
2503
|
+
length = array == null ? 0 : array.length,
|
|
2504
|
+
result = Array(length);
|
|
2505
|
+
|
|
2506
|
+
while (++index < length) {
|
|
2507
|
+
result[index] = iteratee(array[index], index, array);
|
|
2508
|
+
}
|
|
2509
|
+
return result;
|
|
2510
|
+
}
|
|
2511
|
+
|
|
2512
|
+
/**
|
|
2513
|
+
* Checks if `value` is classified as an `Array` object.
|
|
2514
|
+
*
|
|
2515
|
+
* @static
|
|
2516
|
+
* @memberOf _
|
|
2517
|
+
* @since 0.1.0
|
|
2518
|
+
* @category Lang
|
|
2519
|
+
* @param {*} value The value to check.
|
|
2520
|
+
* @returns {boolean} Returns `true` if `value` is an array, else `false`.
|
|
2521
|
+
* @example
|
|
2522
|
+
*
|
|
2523
|
+
* _.isArray([1, 2, 3]);
|
|
2524
|
+
* // => true
|
|
2525
|
+
*
|
|
2526
|
+
* _.isArray(document.body.children);
|
|
2527
|
+
* // => false
|
|
2528
|
+
*
|
|
2529
|
+
* _.isArray('abc');
|
|
2530
|
+
* // => false
|
|
2531
|
+
*
|
|
2532
|
+
* _.isArray(_.noop);
|
|
2533
|
+
* // => false
|
|
2534
|
+
*/
|
|
2535
|
+
var isArray = Array.isArray;
|
|
2536
|
+
|
|
2537
|
+
/** Used to convert symbols to primitives and strings. */
|
|
2538
|
+
var symbolProto = Symbol ? Symbol.prototype : undefined,
|
|
2539
|
+
symbolToString = symbolProto ? symbolProto.toString : undefined;
|
|
2540
|
+
|
|
2541
|
+
/**
|
|
2542
|
+
* The base implementation of `_.toString` which doesn't convert nullish
|
|
2543
|
+
* values to empty strings.
|
|
2544
|
+
*
|
|
2545
|
+
* @private
|
|
2546
|
+
* @param {*} value The value to process.
|
|
2547
|
+
* @returns {string} Returns the string.
|
|
2548
|
+
*/
|
|
2549
|
+
function baseToString(value) {
|
|
2550
|
+
// Exit early for strings to avoid a performance hit in some environments.
|
|
2551
|
+
if (typeof value == 'string') {
|
|
2552
|
+
return value;
|
|
2553
|
+
}
|
|
2554
|
+
if (isArray(value)) {
|
|
2555
|
+
// Recursively convert values (susceptible to call stack limits).
|
|
2556
|
+
return arrayMap(value, baseToString) + '';
|
|
2557
|
+
}
|
|
2558
|
+
if (isSymbol(value)) {
|
|
2559
|
+
return symbolToString ? symbolToString.call(value) : '';
|
|
2560
|
+
}
|
|
2561
|
+
var result = (value + '');
|
|
2562
|
+
return (result == '0' && (1 / value) == -Infinity) ? '-0' : result;
|
|
2563
|
+
}
|
|
2564
|
+
|
|
2565
|
+
/** Used to match a single whitespace character. */
|
|
2566
|
+
var reWhitespace = /\s/;
|
|
2567
|
+
|
|
2568
|
+
/**
|
|
2569
|
+
* Used by `_.trim` and `_.trimEnd` to get the index of the last non-whitespace
|
|
2570
|
+
* character of `string`.
|
|
2571
|
+
*
|
|
2572
|
+
* @private
|
|
2573
|
+
* @param {string} string The string to inspect.
|
|
2574
|
+
* @returns {number} Returns the index of the last non-whitespace character.
|
|
2575
|
+
*/
|
|
2576
|
+
function trimmedEndIndex(string) {
|
|
2577
|
+
var index = string.length;
|
|
2578
|
+
|
|
2579
|
+
while (index-- && reWhitespace.test(string.charAt(index))) {}
|
|
2580
|
+
return index;
|
|
2581
|
+
}
|
|
2582
|
+
|
|
2583
|
+
/** Used to match leading whitespace. */
|
|
2584
|
+
var reTrimStart = /^\s+/;
|
|
2585
|
+
|
|
2586
|
+
/**
|
|
2587
|
+
* The base implementation of `_.trim`.
|
|
2588
|
+
*
|
|
2589
|
+
* @private
|
|
2590
|
+
* @param {string} string The string to trim.
|
|
2591
|
+
* @returns {string} Returns the trimmed string.
|
|
2592
|
+
*/
|
|
2593
|
+
function baseTrim(string) {
|
|
2594
|
+
return string
|
|
2595
|
+
? string.slice(0, trimmedEndIndex(string) + 1).replace(reTrimStart, '')
|
|
2596
|
+
: string;
|
|
2597
|
+
}
|
|
2598
|
+
|
|
2599
|
+
/**
|
|
2600
|
+
* Checks if `value` is the
|
|
2601
|
+
* [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)
|
|
2602
|
+
* of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
|
|
2603
|
+
*
|
|
2604
|
+
* @static
|
|
2605
|
+
* @memberOf _
|
|
2606
|
+
* @since 0.1.0
|
|
2607
|
+
* @category Lang
|
|
2608
|
+
* @param {*} value The value to check.
|
|
2609
|
+
* @returns {boolean} Returns `true` if `value` is an object, else `false`.
|
|
2610
|
+
* @example
|
|
2611
|
+
*
|
|
2612
|
+
* _.isObject({});
|
|
2613
|
+
* // => true
|
|
2614
|
+
*
|
|
2615
|
+
* _.isObject([1, 2, 3]);
|
|
2616
|
+
* // => true
|
|
2617
|
+
*
|
|
2618
|
+
* _.isObject(_.noop);
|
|
2619
|
+
* // => true
|
|
2620
|
+
*
|
|
2621
|
+
* _.isObject(null);
|
|
2622
|
+
* // => false
|
|
2623
|
+
*/
|
|
2624
|
+
function isObject(value) {
|
|
2625
|
+
var type = typeof value;
|
|
2626
|
+
return value != null && (type == 'object' || type == 'function');
|
|
2627
|
+
}
|
|
2628
|
+
|
|
2629
|
+
/** Used as references for various `Number` constants. */
|
|
2630
|
+
var NAN = 0 / 0;
|
|
2631
|
+
|
|
2632
|
+
/** Used to detect bad signed hexadecimal string values. */
|
|
2633
|
+
var reIsBadHex = /^[-+]0x[0-9a-f]+$/i;
|
|
2634
|
+
|
|
2635
|
+
/** Used to detect binary string values. */
|
|
2636
|
+
var reIsBinary = /^0b[01]+$/i;
|
|
2637
|
+
|
|
2638
|
+
/** Used to detect octal string values. */
|
|
2639
|
+
var reIsOctal = /^0o[0-7]+$/i;
|
|
2640
|
+
|
|
2641
|
+
/** Built-in method references without a dependency on `root`. */
|
|
2642
|
+
var freeParseInt = parseInt;
|
|
2643
|
+
|
|
2644
|
+
/**
|
|
2645
|
+
* Converts `value` to a number.
|
|
2646
|
+
*
|
|
2647
|
+
* @static
|
|
2648
|
+
* @memberOf _
|
|
2649
|
+
* @since 4.0.0
|
|
2650
|
+
* @category Lang
|
|
2651
|
+
* @param {*} value The value to process.
|
|
2652
|
+
* @returns {number} Returns the number.
|
|
2653
|
+
* @example
|
|
2654
|
+
*
|
|
2655
|
+
* _.toNumber(3.2);
|
|
2656
|
+
* // => 3.2
|
|
2657
|
+
*
|
|
2658
|
+
* _.toNumber(Number.MIN_VALUE);
|
|
2659
|
+
* // => 5e-324
|
|
2660
|
+
*
|
|
2661
|
+
* _.toNumber(Infinity);
|
|
2662
|
+
* // => Infinity
|
|
2663
|
+
*
|
|
2664
|
+
* _.toNumber('3.2');
|
|
2665
|
+
* // => 3.2
|
|
2666
|
+
*/
|
|
2667
|
+
function toNumber(value) {
|
|
2668
|
+
if (typeof value == 'number') {
|
|
2669
|
+
return value;
|
|
2670
|
+
}
|
|
2671
|
+
if (isSymbol(value)) {
|
|
2672
|
+
return NAN;
|
|
2673
|
+
}
|
|
2674
|
+
if (isObject(value)) {
|
|
2675
|
+
var other = typeof value.valueOf == 'function' ? value.valueOf() : value;
|
|
2676
|
+
value = isObject(other) ? (other + '') : other;
|
|
2677
|
+
}
|
|
2678
|
+
if (typeof value != 'string') {
|
|
2679
|
+
return value === 0 ? value : +value;
|
|
2680
|
+
}
|
|
2681
|
+
value = baseTrim(value);
|
|
2682
|
+
var isBinary = reIsBinary.test(value);
|
|
2683
|
+
return (isBinary || reIsOctal.test(value))
|
|
2684
|
+
? freeParseInt(value.slice(2), isBinary ? 2 : 8)
|
|
2685
|
+
: (reIsBadHex.test(value) ? NAN : +value);
|
|
2686
|
+
}
|
|
2687
|
+
|
|
2688
|
+
/** Used as references for various `Number` constants. */
|
|
2689
|
+
var INFINITY = 1 / 0,
|
|
2690
|
+
MAX_INTEGER = 1.7976931348623157e+308;
|
|
2691
|
+
|
|
2692
|
+
/**
|
|
2693
|
+
* Converts `value` to a finite number.
|
|
2694
|
+
*
|
|
2695
|
+
* @static
|
|
2696
|
+
* @memberOf _
|
|
2697
|
+
* @since 4.12.0
|
|
2698
|
+
* @category Lang
|
|
2699
|
+
* @param {*} value The value to convert.
|
|
2700
|
+
* @returns {number} Returns the converted number.
|
|
2701
|
+
* @example
|
|
2702
|
+
*
|
|
2703
|
+
* _.toFinite(3.2);
|
|
2704
|
+
* // => 3.2
|
|
2705
|
+
*
|
|
2706
|
+
* _.toFinite(Number.MIN_VALUE);
|
|
2707
|
+
* // => 5e-324
|
|
2708
|
+
*
|
|
2709
|
+
* _.toFinite(Infinity);
|
|
2710
|
+
* // => 1.7976931348623157e+308
|
|
2711
|
+
*
|
|
2712
|
+
* _.toFinite('3.2');
|
|
2713
|
+
* // => 3.2
|
|
2714
|
+
*/
|
|
2715
|
+
function toFinite(value) {
|
|
2716
|
+
if (!value) {
|
|
2717
|
+
return value === 0 ? value : 0;
|
|
2718
|
+
}
|
|
2719
|
+
value = toNumber(value);
|
|
2720
|
+
if (value === INFINITY || value === -INFINITY) {
|
|
2721
|
+
var sign = (value < 0 ? -1 : 1);
|
|
2722
|
+
return sign * MAX_INTEGER;
|
|
2723
|
+
}
|
|
2724
|
+
return value === value ? value : 0;
|
|
2725
|
+
}
|
|
2726
|
+
|
|
2727
|
+
/**
|
|
2728
|
+
* Converts `value` to an integer.
|
|
2729
|
+
*
|
|
2730
|
+
* **Note:** This method is loosely based on
|
|
2731
|
+
* [`ToInteger`](http://www.ecma-international.org/ecma-262/7.0/#sec-tointeger).
|
|
2732
|
+
*
|
|
2733
|
+
* @static
|
|
2734
|
+
* @memberOf _
|
|
2735
|
+
* @since 4.0.0
|
|
2736
|
+
* @category Lang
|
|
2737
|
+
* @param {*} value The value to convert.
|
|
2738
|
+
* @returns {number} Returns the converted integer.
|
|
2739
|
+
* @example
|
|
2740
|
+
*
|
|
2741
|
+
* _.toInteger(3.2);
|
|
2742
|
+
* // => 3
|
|
2743
|
+
*
|
|
2744
|
+
* _.toInteger(Number.MIN_VALUE);
|
|
2745
|
+
* // => 0
|
|
2746
|
+
*
|
|
2747
|
+
* _.toInteger(Infinity);
|
|
2748
|
+
* // => 1.7976931348623157e+308
|
|
2749
|
+
*
|
|
2750
|
+
* _.toInteger('3.2');
|
|
2751
|
+
* // => 3
|
|
2752
|
+
*/
|
|
2753
|
+
function toInteger(value) {
|
|
2754
|
+
var result = toFinite(value),
|
|
2755
|
+
remainder = result % 1;
|
|
2756
|
+
|
|
2757
|
+
return result === result ? (remainder ? result - remainder : result) : 0;
|
|
2758
|
+
}
|
|
2759
|
+
|
|
2760
|
+
/**
|
|
2761
|
+
* This method returns the first argument it receives.
|
|
2762
|
+
*
|
|
2763
|
+
* @static
|
|
2764
|
+
* @since 0.1.0
|
|
2765
|
+
* @memberOf _
|
|
2766
|
+
* @category Util
|
|
2767
|
+
* @param {*} value Any value.
|
|
2768
|
+
* @returns {*} Returns `value`.
|
|
2769
|
+
* @example
|
|
2770
|
+
*
|
|
2771
|
+
* var object = { 'a': 1 };
|
|
2772
|
+
*
|
|
2773
|
+
* console.log(_.identity(object) === object);
|
|
2774
|
+
* // => true
|
|
2775
|
+
*/
|
|
2776
|
+
function identity(value) {
|
|
2777
|
+
return value;
|
|
2778
|
+
}
|
|
2779
|
+
|
|
2780
|
+
/** `Object#toString` result references. */
|
|
2781
|
+
var asyncTag = '[object AsyncFunction]',
|
|
2782
|
+
funcTag$1 = '[object Function]',
|
|
2783
|
+
genTag = '[object GeneratorFunction]',
|
|
2784
|
+
proxyTag = '[object Proxy]';
|
|
2785
|
+
|
|
2786
|
+
/**
|
|
2787
|
+
* Checks if `value` is classified as a `Function` object.
|
|
2788
|
+
*
|
|
2789
|
+
* @static
|
|
2790
|
+
* @memberOf _
|
|
2791
|
+
* @since 0.1.0
|
|
2792
|
+
* @category Lang
|
|
2793
|
+
* @param {*} value The value to check.
|
|
2794
|
+
* @returns {boolean} Returns `true` if `value` is a function, else `false`.
|
|
2795
|
+
* @example
|
|
2796
|
+
*
|
|
2797
|
+
* _.isFunction(_);
|
|
2798
|
+
* // => true
|
|
2799
|
+
*
|
|
2800
|
+
* _.isFunction(/abc/);
|
|
2801
|
+
* // => false
|
|
2802
|
+
*/
|
|
2803
|
+
function isFunction(value) {
|
|
2804
|
+
if (!isObject(value)) {
|
|
2805
|
+
return false;
|
|
2806
|
+
}
|
|
2807
|
+
// The use of `Object#toString` avoids issues with the `typeof` operator
|
|
2808
|
+
// in Safari 9 which returns 'object' for typed arrays and other constructors.
|
|
2809
|
+
var tag = baseGetTag(value);
|
|
2810
|
+
return tag == funcTag$1 || tag == genTag || tag == asyncTag || tag == proxyTag;
|
|
2811
|
+
}
|
|
2812
|
+
|
|
2813
|
+
/** Used to detect overreaching core-js shims. */
|
|
2814
|
+
var coreJsData = root['__core-js_shared__'];
|
|
2815
|
+
|
|
2816
|
+
/** Used to detect methods masquerading as native. */
|
|
2817
|
+
var maskSrcKey = (function() {
|
|
2818
|
+
var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || '');
|
|
2819
|
+
return uid ? ('Symbol(src)_1.' + uid) : '';
|
|
2820
|
+
}());
|
|
2821
|
+
|
|
2822
|
+
/**
|
|
2823
|
+
* Checks if `func` has its source masked.
|
|
2824
|
+
*
|
|
2825
|
+
* @private
|
|
2826
|
+
* @param {Function} func The function to check.
|
|
2827
|
+
* @returns {boolean} Returns `true` if `func` is masked, else `false`.
|
|
2828
|
+
*/
|
|
2829
|
+
function isMasked(func) {
|
|
2830
|
+
return !!maskSrcKey && (maskSrcKey in func);
|
|
2831
|
+
}
|
|
2832
|
+
|
|
2833
|
+
/** Used for built-in method references. */
|
|
2834
|
+
var funcProto$2 = Function.prototype;
|
|
2835
|
+
|
|
2836
|
+
/** Used to resolve the decompiled source of functions. */
|
|
2837
|
+
var funcToString$2 = funcProto$2.toString;
|
|
2838
|
+
|
|
2839
|
+
/**
|
|
2840
|
+
* Converts `func` to its source code.
|
|
2841
|
+
*
|
|
2842
|
+
* @private
|
|
2843
|
+
* @param {Function} func The function to convert.
|
|
2844
|
+
* @returns {string} Returns the source code.
|
|
2845
|
+
*/
|
|
2846
|
+
function toSource(func) {
|
|
2847
|
+
if (func != null) {
|
|
2848
|
+
try {
|
|
2849
|
+
return funcToString$2.call(func);
|
|
2850
|
+
} catch (e) {}
|
|
2851
|
+
try {
|
|
2852
|
+
return (func + '');
|
|
2853
|
+
} catch (e) {}
|
|
2854
|
+
}
|
|
2855
|
+
return '';
|
|
2856
|
+
}
|
|
2857
|
+
|
|
2858
|
+
/**
|
|
2859
|
+
* Used to match `RegExp`
|
|
2860
|
+
* [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns).
|
|
2861
|
+
*/
|
|
2862
|
+
var reRegExpChar = /[\\^$.*+?()[\]{}|]/g;
|
|
2863
|
+
|
|
2864
|
+
/** Used to detect host constructors (Safari). */
|
|
2865
|
+
var reIsHostCtor = /^\[object .+?Constructor\]$/;
|
|
2866
|
+
|
|
2867
|
+
/** Used for built-in method references. */
|
|
2868
|
+
var funcProto$1 = Function.prototype,
|
|
2869
|
+
objectProto$7 = Object.prototype;
|
|
2870
|
+
|
|
2871
|
+
/** Used to resolve the decompiled source of functions. */
|
|
2872
|
+
var funcToString$1 = funcProto$1.toString;
|
|
2873
|
+
|
|
2874
|
+
/** Used to check objects for own properties. */
|
|
2875
|
+
var hasOwnProperty$6 = objectProto$7.hasOwnProperty;
|
|
2876
|
+
|
|
2877
|
+
/** Used to detect if a method is native. */
|
|
2878
|
+
var reIsNative = RegExp('^' +
|
|
2879
|
+
funcToString$1.call(hasOwnProperty$6).replace(reRegExpChar, '\\$&')
|
|
2880
|
+
.replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'
|
|
2881
|
+
);
|
|
2882
|
+
|
|
2883
|
+
/**
|
|
2884
|
+
* The base implementation of `_.isNative` without bad shim checks.
|
|
2885
|
+
*
|
|
2886
|
+
* @private
|
|
2887
|
+
* @param {*} value The value to check.
|
|
2888
|
+
* @returns {boolean} Returns `true` if `value` is a native function,
|
|
2889
|
+
* else `false`.
|
|
2890
|
+
*/
|
|
2891
|
+
function baseIsNative(value) {
|
|
2892
|
+
if (!isObject(value) || isMasked(value)) {
|
|
2893
|
+
return false;
|
|
2894
|
+
}
|
|
2895
|
+
var pattern = isFunction(value) ? reIsNative : reIsHostCtor;
|
|
2896
|
+
return pattern.test(toSource(value));
|
|
2897
|
+
}
|
|
2898
|
+
|
|
2899
|
+
/**
|
|
2900
|
+
* Gets the value at `key` of `object`.
|
|
2901
|
+
*
|
|
2902
|
+
* @private
|
|
2903
|
+
* @param {Object} [object] The object to query.
|
|
2904
|
+
* @param {string} key The key of the property to get.
|
|
2905
|
+
* @returns {*} Returns the property value.
|
|
2906
|
+
*/
|
|
2907
|
+
function getValue(object, key) {
|
|
2908
|
+
return object == null ? undefined : object[key];
|
|
2909
|
+
}
|
|
2910
|
+
|
|
2911
|
+
/**
|
|
2912
|
+
* Gets the native function at `key` of `object`.
|
|
2913
|
+
*
|
|
2914
|
+
* @private
|
|
2915
|
+
* @param {Object} object The object to query.
|
|
2916
|
+
* @param {string} key The key of the method to get.
|
|
2917
|
+
* @returns {*} Returns the function if it's native, else `undefined`.
|
|
2918
|
+
*/
|
|
2919
|
+
function getNative(object, key) {
|
|
2920
|
+
var value = getValue(object, key);
|
|
2921
|
+
return baseIsNative(value) ? value : undefined;
|
|
2922
|
+
}
|
|
2923
|
+
|
|
2924
|
+
/** Built-in value references. */
|
|
2925
|
+
var objectCreate = Object.create;
|
|
2926
|
+
|
|
2927
|
+
/**
|
|
2928
|
+
* The base implementation of `_.create` without support for assigning
|
|
2929
|
+
* properties to the created object.
|
|
2930
|
+
*
|
|
2931
|
+
* @private
|
|
2932
|
+
* @param {Object} proto The object to inherit from.
|
|
2933
|
+
* @returns {Object} Returns the new object.
|
|
2934
|
+
*/
|
|
2935
|
+
var baseCreate = (function() {
|
|
2936
|
+
function object() {}
|
|
2937
|
+
return function(proto) {
|
|
2938
|
+
if (!isObject(proto)) {
|
|
2939
|
+
return {};
|
|
2940
|
+
}
|
|
2941
|
+
if (objectCreate) {
|
|
2942
|
+
return objectCreate(proto);
|
|
2943
|
+
}
|
|
2944
|
+
object.prototype = proto;
|
|
2945
|
+
var result = new object;
|
|
2946
|
+
object.prototype = undefined;
|
|
2947
|
+
return result;
|
|
2948
|
+
};
|
|
2949
|
+
}());
|
|
2950
|
+
|
|
2951
|
+
/**
|
|
2952
|
+
* A faster alternative to `Function#apply`, this function invokes `func`
|
|
2953
|
+
* with the `this` binding of `thisArg` and the arguments of `args`.
|
|
2954
|
+
*
|
|
2955
|
+
* @private
|
|
2956
|
+
* @param {Function} func The function to invoke.
|
|
2957
|
+
* @param {*} thisArg The `this` binding of `func`.
|
|
2958
|
+
* @param {Array} args The arguments to invoke `func` with.
|
|
2959
|
+
* @returns {*} Returns the result of `func`.
|
|
2960
|
+
*/
|
|
2961
|
+
function apply(func, thisArg, args) {
|
|
2962
|
+
switch (args.length) {
|
|
2963
|
+
case 0: return func.call(thisArg);
|
|
2964
|
+
case 1: return func.call(thisArg, args[0]);
|
|
2965
|
+
case 2: return func.call(thisArg, args[0], args[1]);
|
|
2966
|
+
case 3: return func.call(thisArg, args[0], args[1], args[2]);
|
|
2967
|
+
}
|
|
2968
|
+
return func.apply(thisArg, args);
|
|
2969
|
+
}
|
|
2970
|
+
|
|
2971
|
+
/**
|
|
2972
|
+
* Copies the values of `source` to `array`.
|
|
2973
|
+
*
|
|
2974
|
+
* @private
|
|
2975
|
+
* @param {Array} source The array to copy values from.
|
|
2976
|
+
* @param {Array} [array=[]] The array to copy values to.
|
|
2977
|
+
* @returns {Array} Returns `array`.
|
|
2978
|
+
*/
|
|
2979
|
+
function copyArray(source, array) {
|
|
2980
|
+
var index = -1,
|
|
2981
|
+
length = source.length;
|
|
2982
|
+
|
|
2983
|
+
array || (array = Array(length));
|
|
2984
|
+
while (++index < length) {
|
|
2985
|
+
array[index] = source[index];
|
|
2986
|
+
}
|
|
2987
|
+
return array;
|
|
2988
|
+
}
|
|
2989
|
+
|
|
2990
|
+
/** Used to detect hot functions by number of calls within a span of milliseconds. */
|
|
2991
|
+
var HOT_COUNT = 800,
|
|
2992
|
+
HOT_SPAN = 16;
|
|
2993
|
+
|
|
2994
|
+
/* Built-in method references for those with the same name as other `lodash` methods. */
|
|
2995
|
+
var nativeNow = Date.now;
|
|
2996
|
+
|
|
2997
|
+
/**
|
|
2998
|
+
* Creates a function that'll short out and invoke `identity` instead
|
|
2999
|
+
* of `func` when it's called `HOT_COUNT` or more times in `HOT_SPAN`
|
|
3000
|
+
* milliseconds.
|
|
3001
|
+
*
|
|
3002
|
+
* @private
|
|
3003
|
+
* @param {Function} func The function to restrict.
|
|
3004
|
+
* @returns {Function} Returns the new shortable function.
|
|
3005
|
+
*/
|
|
3006
|
+
function shortOut(func) {
|
|
3007
|
+
var count = 0,
|
|
3008
|
+
lastCalled = 0;
|
|
3009
|
+
|
|
3010
|
+
return function() {
|
|
3011
|
+
var stamp = nativeNow(),
|
|
3012
|
+
remaining = HOT_SPAN - (stamp - lastCalled);
|
|
3013
|
+
|
|
3014
|
+
lastCalled = stamp;
|
|
3015
|
+
if (remaining > 0) {
|
|
3016
|
+
if (++count >= HOT_COUNT) {
|
|
3017
|
+
return arguments[0];
|
|
3018
|
+
}
|
|
3019
|
+
} else {
|
|
3020
|
+
count = 0;
|
|
3021
|
+
}
|
|
3022
|
+
return func.apply(undefined, arguments);
|
|
3023
|
+
};
|
|
3024
|
+
}
|
|
3025
|
+
|
|
3026
|
+
/**
|
|
3027
|
+
* Creates a function that returns `value`.
|
|
3028
|
+
*
|
|
3029
|
+
* @static
|
|
3030
|
+
* @memberOf _
|
|
3031
|
+
* @since 2.4.0
|
|
3032
|
+
* @category Util
|
|
3033
|
+
* @param {*} value The value to return from the new function.
|
|
3034
|
+
* @returns {Function} Returns the new constant function.
|
|
3035
|
+
* @example
|
|
3036
|
+
*
|
|
3037
|
+
* var objects = _.times(2, _.constant({ 'a': 1 }));
|
|
3038
|
+
*
|
|
3039
|
+
* console.log(objects);
|
|
3040
|
+
* // => [{ 'a': 1 }, { 'a': 1 }]
|
|
3041
|
+
*
|
|
3042
|
+
* console.log(objects[0] === objects[1]);
|
|
3043
|
+
* // => true
|
|
3044
|
+
*/
|
|
3045
|
+
function constant(value) {
|
|
3046
|
+
return function() {
|
|
3047
|
+
return value;
|
|
3048
|
+
};
|
|
3049
|
+
}
|
|
3050
|
+
|
|
3051
|
+
var defineProperty = (function() {
|
|
3052
|
+
try {
|
|
3053
|
+
var func = getNative(Object, 'defineProperty');
|
|
3054
|
+
func({}, '', {});
|
|
3055
|
+
return func;
|
|
3056
|
+
} catch (e) {}
|
|
3057
|
+
}());
|
|
3058
|
+
|
|
3059
|
+
/**
|
|
3060
|
+
* The base implementation of `setToString` without support for hot loop shorting.
|
|
3061
|
+
*
|
|
3062
|
+
* @private
|
|
3063
|
+
* @param {Function} func The function to modify.
|
|
3064
|
+
* @param {Function} string The `toString` result.
|
|
3065
|
+
* @returns {Function} Returns `func`.
|
|
3066
|
+
*/
|
|
3067
|
+
var baseSetToString = !defineProperty ? identity : function(func, string) {
|
|
3068
|
+
return defineProperty(func, 'toString', {
|
|
3069
|
+
'configurable': true,
|
|
3070
|
+
'enumerable': false,
|
|
3071
|
+
'value': constant(string),
|
|
3072
|
+
'writable': true
|
|
3073
|
+
});
|
|
3074
|
+
};
|
|
3075
|
+
|
|
3076
|
+
/**
|
|
3077
|
+
* Sets the `toString` method of `func` to return `string`.
|
|
3078
|
+
*
|
|
3079
|
+
* @private
|
|
3080
|
+
* @param {Function} func The function to modify.
|
|
3081
|
+
* @param {Function} string The `toString` result.
|
|
3082
|
+
* @returns {Function} Returns `func`.
|
|
3083
|
+
*/
|
|
3084
|
+
var setToString = shortOut(baseSetToString);
|
|
3085
|
+
|
|
3086
|
+
/** Used as references for various `Number` constants. */
|
|
3087
|
+
var MAX_SAFE_INTEGER$1 = 9007199254740991;
|
|
3088
|
+
|
|
3089
|
+
/** Used to detect unsigned integer values. */
|
|
3090
|
+
var reIsUint = /^(?:0|[1-9]\d*)$/;
|
|
3091
|
+
|
|
3092
|
+
/**
|
|
3093
|
+
* Checks if `value` is a valid array-like index.
|
|
3094
|
+
*
|
|
3095
|
+
* @private
|
|
3096
|
+
* @param {*} value The value to check.
|
|
3097
|
+
* @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.
|
|
3098
|
+
* @returns {boolean} Returns `true` if `value` is a valid index, else `false`.
|
|
3099
|
+
*/
|
|
3100
|
+
function isIndex(value, length) {
|
|
3101
|
+
var type = typeof value;
|
|
3102
|
+
length = length == null ? MAX_SAFE_INTEGER$1 : length;
|
|
3103
|
+
|
|
3104
|
+
return !!length &&
|
|
3105
|
+
(type == 'number' ||
|
|
3106
|
+
(type != 'symbol' && reIsUint.test(value))) &&
|
|
3107
|
+
(value > -1 && value % 1 == 0 && value < length);
|
|
3108
|
+
}
|
|
3109
|
+
|
|
3110
|
+
/**
|
|
3111
|
+
* The base implementation of `assignValue` and `assignMergeValue` without
|
|
3112
|
+
* value checks.
|
|
3113
|
+
*
|
|
3114
|
+
* @private
|
|
3115
|
+
* @param {Object} object The object to modify.
|
|
3116
|
+
* @param {string} key The key of the property to assign.
|
|
3117
|
+
* @param {*} value The value to assign.
|
|
3118
|
+
*/
|
|
3119
|
+
function baseAssignValue(object, key, value) {
|
|
3120
|
+
if (key == '__proto__' && defineProperty) {
|
|
3121
|
+
defineProperty(object, key, {
|
|
3122
|
+
'configurable': true,
|
|
3123
|
+
'enumerable': true,
|
|
3124
|
+
'value': value,
|
|
3125
|
+
'writable': true
|
|
3126
|
+
});
|
|
3127
|
+
} else {
|
|
3128
|
+
object[key] = value;
|
|
3129
|
+
}
|
|
3130
|
+
}
|
|
3131
|
+
|
|
3132
|
+
/**
|
|
3133
|
+
* Performs a
|
|
3134
|
+
* [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
|
|
3135
|
+
* comparison between two values to determine if they are equivalent.
|
|
3136
|
+
*
|
|
3137
|
+
* @static
|
|
3138
|
+
* @memberOf _
|
|
3139
|
+
* @since 4.0.0
|
|
3140
|
+
* @category Lang
|
|
3141
|
+
* @param {*} value The value to compare.
|
|
3142
|
+
* @param {*} other The other value to compare.
|
|
3143
|
+
* @returns {boolean} Returns `true` if the values are equivalent, else `false`.
|
|
3144
|
+
* @example
|
|
3145
|
+
*
|
|
3146
|
+
* var object = { 'a': 1 };
|
|
3147
|
+
* var other = { 'a': 1 };
|
|
3148
|
+
*
|
|
3149
|
+
* _.eq(object, object);
|
|
3150
|
+
* // => true
|
|
3151
|
+
*
|
|
3152
|
+
* _.eq(object, other);
|
|
3153
|
+
* // => false
|
|
3154
|
+
*
|
|
3155
|
+
* _.eq('a', 'a');
|
|
3156
|
+
* // => true
|
|
3157
|
+
*
|
|
3158
|
+
* _.eq('a', Object('a'));
|
|
3159
|
+
* // => false
|
|
3160
|
+
*
|
|
3161
|
+
* _.eq(NaN, NaN);
|
|
3162
|
+
* // => true
|
|
3163
|
+
*/
|
|
3164
|
+
function eq(value, other) {
|
|
3165
|
+
return value === other || (value !== value && other !== other);
|
|
3166
|
+
}
|
|
3167
|
+
|
|
3168
|
+
/** Used for built-in method references. */
|
|
3169
|
+
var objectProto$6 = Object.prototype;
|
|
3170
|
+
|
|
3171
|
+
/** Used to check objects for own properties. */
|
|
3172
|
+
var hasOwnProperty$5 = objectProto$6.hasOwnProperty;
|
|
3173
|
+
|
|
3174
|
+
/**
|
|
3175
|
+
* Assigns `value` to `key` of `object` if the existing value is not equivalent
|
|
3176
|
+
* using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
|
|
3177
|
+
* for equality comparisons.
|
|
3178
|
+
*
|
|
3179
|
+
* @private
|
|
3180
|
+
* @param {Object} object The object to modify.
|
|
3181
|
+
* @param {string} key The key of the property to assign.
|
|
3182
|
+
* @param {*} value The value to assign.
|
|
3183
|
+
*/
|
|
3184
|
+
function assignValue(object, key, value) {
|
|
3185
|
+
var objValue = object[key];
|
|
3186
|
+
if (!(hasOwnProperty$5.call(object, key) && eq(objValue, value)) ||
|
|
3187
|
+
(value === undefined && !(key in object))) {
|
|
3188
|
+
baseAssignValue(object, key, value);
|
|
3189
|
+
}
|
|
3190
|
+
}
|
|
3191
|
+
|
|
3192
|
+
/**
|
|
3193
|
+
* Copies properties of `source` to `object`.
|
|
3194
|
+
*
|
|
3195
|
+
* @private
|
|
3196
|
+
* @param {Object} source The object to copy properties from.
|
|
3197
|
+
* @param {Array} props The property identifiers to copy.
|
|
3198
|
+
* @param {Object} [object={}] The object to copy properties to.
|
|
3199
|
+
* @param {Function} [customizer] The function to customize copied values.
|
|
3200
|
+
* @returns {Object} Returns `object`.
|
|
3201
|
+
*/
|
|
3202
|
+
function copyObject(source, props, object, customizer) {
|
|
3203
|
+
var isNew = !object;
|
|
3204
|
+
object || (object = {});
|
|
3205
|
+
|
|
3206
|
+
var index = -1,
|
|
3207
|
+
length = props.length;
|
|
3208
|
+
|
|
3209
|
+
while (++index < length) {
|
|
3210
|
+
var key = props[index];
|
|
3211
|
+
|
|
3212
|
+
var newValue = undefined;
|
|
3213
|
+
|
|
3214
|
+
if (newValue === undefined) {
|
|
3215
|
+
newValue = source[key];
|
|
3216
|
+
}
|
|
3217
|
+
if (isNew) {
|
|
3218
|
+
baseAssignValue(object, key, newValue);
|
|
3219
|
+
} else {
|
|
3220
|
+
assignValue(object, key, newValue);
|
|
3221
|
+
}
|
|
3222
|
+
}
|
|
3223
|
+
return object;
|
|
3224
|
+
}
|
|
3225
|
+
|
|
3226
|
+
/* Built-in method references for those with the same name as other `lodash` methods. */
|
|
3227
|
+
var nativeMax = Math.max;
|
|
3228
|
+
|
|
3229
|
+
/**
|
|
3230
|
+
* A specialized version of `baseRest` which transforms the rest array.
|
|
3231
|
+
*
|
|
3232
|
+
* @private
|
|
3233
|
+
* @param {Function} func The function to apply a rest parameter to.
|
|
3234
|
+
* @param {number} [start=func.length-1] The start position of the rest parameter.
|
|
3235
|
+
* @param {Function} transform The rest array transform.
|
|
3236
|
+
* @returns {Function} Returns the new function.
|
|
3237
|
+
*/
|
|
3238
|
+
function overRest(func, start, transform) {
|
|
3239
|
+
start = nativeMax(start === undefined ? (func.length - 1) : start, 0);
|
|
3240
|
+
return function() {
|
|
3241
|
+
var args = arguments,
|
|
3242
|
+
index = -1,
|
|
3243
|
+
length = nativeMax(args.length - start, 0),
|
|
3244
|
+
array = Array(length);
|
|
3245
|
+
|
|
3246
|
+
while (++index < length) {
|
|
3247
|
+
array[index] = args[start + index];
|
|
3248
|
+
}
|
|
3249
|
+
index = -1;
|
|
3250
|
+
var otherArgs = Array(start + 1);
|
|
3251
|
+
while (++index < start) {
|
|
3252
|
+
otherArgs[index] = args[index];
|
|
3253
|
+
}
|
|
3254
|
+
otherArgs[start] = transform(array);
|
|
3255
|
+
return apply(func, this, otherArgs);
|
|
3256
|
+
};
|
|
3257
|
+
}
|
|
3258
|
+
|
|
3259
|
+
/**
|
|
3260
|
+
* The base implementation of `_.rest` which doesn't validate or coerce arguments.
|
|
3261
|
+
*
|
|
3262
|
+
* @private
|
|
3263
|
+
* @param {Function} func The function to apply a rest parameter to.
|
|
3264
|
+
* @param {number} [start=func.length-1] The start position of the rest parameter.
|
|
3265
|
+
* @returns {Function} Returns the new function.
|
|
3266
|
+
*/
|
|
3267
|
+
function baseRest(func, start) {
|
|
3268
|
+
return setToString(overRest(func, start, identity), func + '');
|
|
3269
|
+
}
|
|
3270
|
+
|
|
3271
|
+
/** Used as references for various `Number` constants. */
|
|
3272
|
+
var MAX_SAFE_INTEGER = 9007199254740991;
|
|
3273
|
+
|
|
3274
|
+
/**
|
|
3275
|
+
* Checks if `value` is a valid array-like length.
|
|
3276
|
+
*
|
|
3277
|
+
* **Note:** This method is loosely based on
|
|
3278
|
+
* [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).
|
|
3279
|
+
*
|
|
3280
|
+
* @static
|
|
3281
|
+
* @memberOf _
|
|
3282
|
+
* @since 4.0.0
|
|
3283
|
+
* @category Lang
|
|
3284
|
+
* @param {*} value The value to check.
|
|
3285
|
+
* @returns {boolean} Returns `true` if `value` is a valid length, else `false`.
|
|
3286
|
+
* @example
|
|
3287
|
+
*
|
|
3288
|
+
* _.isLength(3);
|
|
3289
|
+
* // => true
|
|
3290
|
+
*
|
|
3291
|
+
* _.isLength(Number.MIN_VALUE);
|
|
3292
|
+
* // => false
|
|
3293
|
+
*
|
|
3294
|
+
* _.isLength(Infinity);
|
|
3295
|
+
* // => false
|
|
3296
|
+
*
|
|
3297
|
+
* _.isLength('3');
|
|
3298
|
+
* // => false
|
|
3299
|
+
*/
|
|
3300
|
+
function isLength(value) {
|
|
3301
|
+
return typeof value == 'number' &&
|
|
3302
|
+
value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
|
|
3303
|
+
}
|
|
3304
|
+
|
|
3305
|
+
/**
|
|
3306
|
+
* Checks if `value` is array-like. A value is considered array-like if it's
|
|
3307
|
+
* not a function and has a `value.length` that's an integer greater than or
|
|
3308
|
+
* equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.
|
|
3309
|
+
*
|
|
3310
|
+
* @static
|
|
3311
|
+
* @memberOf _
|
|
3312
|
+
* @since 4.0.0
|
|
3313
|
+
* @category Lang
|
|
3314
|
+
* @param {*} value The value to check.
|
|
3315
|
+
* @returns {boolean} Returns `true` if `value` is array-like, else `false`.
|
|
3316
|
+
* @example
|
|
3317
|
+
*
|
|
3318
|
+
* _.isArrayLike([1, 2, 3]);
|
|
3319
|
+
* // => true
|
|
3320
|
+
*
|
|
3321
|
+
* _.isArrayLike(document.body.children);
|
|
3322
|
+
* // => true
|
|
3323
|
+
*
|
|
3324
|
+
* _.isArrayLike('abc');
|
|
3325
|
+
* // => true
|
|
3326
|
+
*
|
|
3327
|
+
* _.isArrayLike(_.noop);
|
|
3328
|
+
* // => false
|
|
3329
|
+
*/
|
|
3330
|
+
function isArrayLike(value) {
|
|
3331
|
+
return value != null && isLength(value.length) && !isFunction(value);
|
|
3332
|
+
}
|
|
3333
|
+
|
|
3334
|
+
/**
|
|
3335
|
+
* Checks if the given arguments are from an iteratee call.
|
|
3336
|
+
*
|
|
3337
|
+
* @private
|
|
3338
|
+
* @param {*} value The potential iteratee value argument.
|
|
3339
|
+
* @param {*} index The potential iteratee index or key argument.
|
|
3340
|
+
* @param {*} object The potential iteratee object argument.
|
|
3341
|
+
* @returns {boolean} Returns `true` if the arguments are from an iteratee call,
|
|
3342
|
+
* else `false`.
|
|
3343
|
+
*/
|
|
3344
|
+
function isIterateeCall(value, index, object) {
|
|
3345
|
+
if (!isObject(object)) {
|
|
3346
|
+
return false;
|
|
3347
|
+
}
|
|
3348
|
+
var type = typeof index;
|
|
3349
|
+
if (type == 'number'
|
|
3350
|
+
? (isArrayLike(object) && isIndex(index, object.length))
|
|
3351
|
+
: (type == 'string' && index in object)
|
|
3352
|
+
) {
|
|
3353
|
+
return eq(object[index], value);
|
|
3354
|
+
}
|
|
3355
|
+
return false;
|
|
3356
|
+
}
|
|
3357
|
+
|
|
3358
|
+
/**
|
|
3359
|
+
* Creates a function like `_.assign`.
|
|
3360
|
+
*
|
|
3361
|
+
* @private
|
|
3362
|
+
* @param {Function} assigner The function to assign values.
|
|
3363
|
+
* @returns {Function} Returns the new assigner function.
|
|
3364
|
+
*/
|
|
3365
|
+
function createAssigner(assigner) {
|
|
3366
|
+
return baseRest(function(object, sources) {
|
|
3367
|
+
var index = -1,
|
|
3368
|
+
length = sources.length,
|
|
3369
|
+
customizer = length > 1 ? sources[length - 1] : undefined,
|
|
3370
|
+
guard = length > 2 ? sources[2] : undefined;
|
|
3371
|
+
|
|
3372
|
+
customizer = (assigner.length > 3 && typeof customizer == 'function')
|
|
3373
|
+
? (length--, customizer)
|
|
3374
|
+
: undefined;
|
|
3375
|
+
|
|
3376
|
+
if (guard && isIterateeCall(sources[0], sources[1], guard)) {
|
|
3377
|
+
customizer = length < 3 ? undefined : customizer;
|
|
3378
|
+
length = 1;
|
|
3379
|
+
}
|
|
3380
|
+
object = Object(object);
|
|
3381
|
+
while (++index < length) {
|
|
3382
|
+
var source = sources[index];
|
|
3383
|
+
if (source) {
|
|
3384
|
+
assigner(object, source, index, customizer);
|
|
3385
|
+
}
|
|
3386
|
+
}
|
|
3387
|
+
return object;
|
|
3388
|
+
});
|
|
3389
|
+
}
|
|
3390
|
+
|
|
3391
|
+
/** Used for built-in method references. */
|
|
3392
|
+
var objectProto$5 = Object.prototype;
|
|
3393
|
+
|
|
3394
|
+
/**
|
|
3395
|
+
* Checks if `value` is likely a prototype object.
|
|
3396
|
+
*
|
|
3397
|
+
* @private
|
|
3398
|
+
* @param {*} value The value to check.
|
|
3399
|
+
* @returns {boolean} Returns `true` if `value` is a prototype, else `false`.
|
|
3400
|
+
*/
|
|
3401
|
+
function isPrototype(value) {
|
|
3402
|
+
var Ctor = value && value.constructor,
|
|
3403
|
+
proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto$5;
|
|
3404
|
+
|
|
3405
|
+
return value === proto;
|
|
3406
|
+
}
|
|
3407
|
+
|
|
3408
|
+
/**
|
|
3409
|
+
* The base implementation of `_.times` without support for iteratee shorthands
|
|
3410
|
+
* or max array length checks.
|
|
3411
|
+
*
|
|
3412
|
+
* @private
|
|
3413
|
+
* @param {number} n The number of times to invoke `iteratee`.
|
|
3414
|
+
* @param {Function} iteratee The function invoked per iteration.
|
|
3415
|
+
* @returns {Array} Returns the array of results.
|
|
3416
|
+
*/
|
|
3417
|
+
function baseTimes(n, iteratee) {
|
|
3418
|
+
var index = -1,
|
|
3419
|
+
result = Array(n);
|
|
3420
|
+
|
|
3421
|
+
while (++index < n) {
|
|
3422
|
+
result[index] = iteratee(index);
|
|
3423
|
+
}
|
|
3424
|
+
return result;
|
|
3425
|
+
}
|
|
3426
|
+
|
|
3427
|
+
/** `Object#toString` result references. */
|
|
3428
|
+
var argsTag$1 = '[object Arguments]';
|
|
3429
|
+
|
|
3430
|
+
/**
|
|
3431
|
+
* The base implementation of `_.isArguments`.
|
|
3432
|
+
*
|
|
3433
|
+
* @private
|
|
3434
|
+
* @param {*} value The value to check.
|
|
3435
|
+
* @returns {boolean} Returns `true` if `value` is an `arguments` object,
|
|
3436
|
+
*/
|
|
3437
|
+
function baseIsArguments(value) {
|
|
3438
|
+
return isObjectLike(value) && baseGetTag(value) == argsTag$1;
|
|
3439
|
+
}
|
|
3440
|
+
|
|
3441
|
+
/** Used for built-in method references. */
|
|
3442
|
+
var objectProto$4 = Object.prototype;
|
|
3443
|
+
|
|
3444
|
+
/** Used to check objects for own properties. */
|
|
3445
|
+
var hasOwnProperty$4 = objectProto$4.hasOwnProperty;
|
|
3446
|
+
|
|
3447
|
+
/** Built-in value references. */
|
|
3448
|
+
var propertyIsEnumerable = objectProto$4.propertyIsEnumerable;
|
|
3449
|
+
|
|
3450
|
+
/**
|
|
3451
|
+
* Checks if `value` is likely an `arguments` object.
|
|
3452
|
+
*
|
|
3453
|
+
* @static
|
|
3454
|
+
* @memberOf _
|
|
3455
|
+
* @since 0.1.0
|
|
3456
|
+
* @category Lang
|
|
3457
|
+
* @param {*} value The value to check.
|
|
3458
|
+
* @returns {boolean} Returns `true` if `value` is an `arguments` object,
|
|
3459
|
+
* else `false`.
|
|
3460
|
+
* @example
|
|
3461
|
+
*
|
|
3462
|
+
* _.isArguments(function() { return arguments; }());
|
|
3463
|
+
* // => true
|
|
3464
|
+
*
|
|
3465
|
+
* _.isArguments([1, 2, 3]);
|
|
3466
|
+
* // => false
|
|
3467
|
+
*/
|
|
3468
|
+
var isArguments = baseIsArguments(function() { return arguments; }()) ? baseIsArguments : function(value) {
|
|
3469
|
+
return isObjectLike(value) && hasOwnProperty$4.call(value, 'callee') &&
|
|
3470
|
+
!propertyIsEnumerable.call(value, 'callee');
|
|
3471
|
+
};
|
|
3472
|
+
|
|
3473
|
+
/**
|
|
3474
|
+
* This method returns `false`.
|
|
3475
|
+
*
|
|
3476
|
+
* @static
|
|
3477
|
+
* @memberOf _
|
|
3478
|
+
* @since 4.13.0
|
|
3479
|
+
* @category Util
|
|
3480
|
+
* @returns {boolean} Returns `false`.
|
|
3481
|
+
* @example
|
|
3482
|
+
*
|
|
3483
|
+
* _.times(2, _.stubFalse);
|
|
3484
|
+
* // => [false, false]
|
|
3485
|
+
*/
|
|
3486
|
+
function stubFalse() {
|
|
3487
|
+
return false;
|
|
3488
|
+
}
|
|
3489
|
+
|
|
3490
|
+
/** Detect free variable `exports`. */
|
|
3491
|
+
var freeExports$2 = typeof exports == 'object' && exports && !exports.nodeType && exports;
|
|
3492
|
+
|
|
3493
|
+
/** Detect free variable `module`. */
|
|
3494
|
+
var freeModule$2 = freeExports$2 && typeof module == 'object' && module && !module.nodeType && module;
|
|
3495
|
+
|
|
3496
|
+
/** Detect the popular CommonJS extension `module.exports`. */
|
|
3497
|
+
var moduleExports$2 = freeModule$2 && freeModule$2.exports === freeExports$2;
|
|
3498
|
+
|
|
3499
|
+
/** Built-in value references. */
|
|
3500
|
+
var Buffer$1 = moduleExports$2 ? root.Buffer : undefined;
|
|
3501
|
+
|
|
3502
|
+
/* Built-in method references for those with the same name as other `lodash` methods. */
|
|
3503
|
+
var nativeIsBuffer = Buffer$1 ? Buffer$1.isBuffer : undefined;
|
|
3504
|
+
|
|
3505
|
+
/**
|
|
3506
|
+
* Checks if `value` is a buffer.
|
|
3507
|
+
*
|
|
3508
|
+
* @static
|
|
3509
|
+
* @memberOf _
|
|
3510
|
+
* @since 4.3.0
|
|
3511
|
+
* @category Lang
|
|
3512
|
+
* @param {*} value The value to check.
|
|
3513
|
+
* @returns {boolean} Returns `true` if `value` is a buffer, else `false`.
|
|
3514
|
+
* @example
|
|
3515
|
+
*
|
|
3516
|
+
* _.isBuffer(new Buffer(2));
|
|
3517
|
+
* // => true
|
|
3518
|
+
*
|
|
3519
|
+
* _.isBuffer(new Uint8Array(2));
|
|
3520
|
+
* // => false
|
|
3521
|
+
*/
|
|
3522
|
+
var isBuffer = nativeIsBuffer || stubFalse;
|
|
3523
|
+
|
|
3524
|
+
/** `Object#toString` result references. */
|
|
3525
|
+
var argsTag = '[object Arguments]',
|
|
3526
|
+
arrayTag = '[object Array]',
|
|
3527
|
+
boolTag = '[object Boolean]',
|
|
3528
|
+
dateTag = '[object Date]',
|
|
3529
|
+
errorTag = '[object Error]',
|
|
3530
|
+
funcTag = '[object Function]',
|
|
3531
|
+
mapTag = '[object Map]',
|
|
3532
|
+
numberTag = '[object Number]',
|
|
3533
|
+
objectTag$1 = '[object Object]',
|
|
3534
|
+
regexpTag = '[object RegExp]',
|
|
3535
|
+
setTag = '[object Set]',
|
|
3536
|
+
stringTag = '[object String]',
|
|
3537
|
+
weakMapTag = '[object WeakMap]';
|
|
3538
|
+
|
|
3539
|
+
var arrayBufferTag = '[object ArrayBuffer]',
|
|
3540
|
+
dataViewTag = '[object DataView]',
|
|
3541
|
+
float32Tag = '[object Float32Array]',
|
|
3542
|
+
float64Tag = '[object Float64Array]',
|
|
3543
|
+
int8Tag = '[object Int8Array]',
|
|
3544
|
+
int16Tag = '[object Int16Array]',
|
|
3545
|
+
int32Tag = '[object Int32Array]',
|
|
3546
|
+
uint8Tag = '[object Uint8Array]',
|
|
3547
|
+
uint8ClampedTag = '[object Uint8ClampedArray]',
|
|
3548
|
+
uint16Tag = '[object Uint16Array]',
|
|
3549
|
+
uint32Tag = '[object Uint32Array]';
|
|
3550
|
+
|
|
3551
|
+
/** Used to identify `toStringTag` values of typed arrays. */
|
|
3552
|
+
var typedArrayTags = {};
|
|
3553
|
+
typedArrayTags[float32Tag] = typedArrayTags[float64Tag] =
|
|
3554
|
+
typedArrayTags[int8Tag] = typedArrayTags[int16Tag] =
|
|
3555
|
+
typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] =
|
|
3556
|
+
typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] =
|
|
3557
|
+
typedArrayTags[uint32Tag] = true;
|
|
3558
|
+
typedArrayTags[argsTag] = typedArrayTags[arrayTag] =
|
|
3559
|
+
typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] =
|
|
3560
|
+
typedArrayTags[dataViewTag] = typedArrayTags[dateTag] =
|
|
3561
|
+
typedArrayTags[errorTag] = typedArrayTags[funcTag] =
|
|
3562
|
+
typedArrayTags[mapTag] = typedArrayTags[numberTag] =
|
|
3563
|
+
typedArrayTags[objectTag$1] = typedArrayTags[regexpTag] =
|
|
3564
|
+
typedArrayTags[setTag] = typedArrayTags[stringTag] =
|
|
3565
|
+
typedArrayTags[weakMapTag] = false;
|
|
3566
|
+
|
|
3567
|
+
/**
|
|
3568
|
+
* The base implementation of `_.isTypedArray` without Node.js optimizations.
|
|
3569
|
+
*
|
|
3570
|
+
* @private
|
|
3571
|
+
* @param {*} value The value to check.
|
|
3572
|
+
* @returns {boolean} Returns `true` if `value` is a typed array, else `false`.
|
|
3573
|
+
*/
|
|
3574
|
+
function baseIsTypedArray(value) {
|
|
3575
|
+
return isObjectLike(value) &&
|
|
3576
|
+
isLength(value.length) && !!typedArrayTags[baseGetTag(value)];
|
|
3577
|
+
}
|
|
3578
|
+
|
|
3579
|
+
/**
|
|
3580
|
+
* The base implementation of `_.unary` without support for storing metadata.
|
|
3581
|
+
*
|
|
3582
|
+
* @private
|
|
3583
|
+
* @param {Function} func The function to cap arguments for.
|
|
3584
|
+
* @returns {Function} Returns the new capped function.
|
|
3585
|
+
*/
|
|
3586
|
+
function baseUnary(func) {
|
|
3587
|
+
return function(value) {
|
|
3588
|
+
return func(value);
|
|
3589
|
+
};
|
|
3590
|
+
}
|
|
3591
|
+
|
|
3592
|
+
/** Detect free variable `exports`. */
|
|
3593
|
+
var freeExports$1 = typeof exports == 'object' && exports && !exports.nodeType && exports;
|
|
3594
|
+
|
|
3595
|
+
/** Detect free variable `module`. */
|
|
3596
|
+
var freeModule$1 = freeExports$1 && typeof module == 'object' && module && !module.nodeType && module;
|
|
3597
|
+
|
|
3598
|
+
/** Detect the popular CommonJS extension `module.exports`. */
|
|
3599
|
+
var moduleExports$1 = freeModule$1 && freeModule$1.exports === freeExports$1;
|
|
3600
|
+
|
|
3601
|
+
/** Detect free variable `process` from Node.js. */
|
|
3602
|
+
var freeProcess = moduleExports$1 && freeGlobal.process;
|
|
3603
|
+
|
|
3604
|
+
/** Used to access faster Node.js helpers. */
|
|
3605
|
+
var nodeUtil = (function() {
|
|
3606
|
+
try {
|
|
3607
|
+
// Use `util.types` for Node.js 10+.
|
|
3608
|
+
var types = freeModule$1 && freeModule$1.require && freeModule$1.require('util').types;
|
|
3609
|
+
|
|
3610
|
+
if (types) {
|
|
3611
|
+
return types;
|
|
3612
|
+
}
|
|
3613
|
+
|
|
3614
|
+
// Legacy `process.binding('util')` for Node.js < 10.
|
|
3615
|
+
return freeProcess && freeProcess.binding && freeProcess.binding('util');
|
|
3616
|
+
} catch (e) {}
|
|
3617
|
+
}());
|
|
3618
|
+
|
|
3619
|
+
/* Node.js helper references. */
|
|
3620
|
+
var nodeIsTypedArray = nodeUtil && nodeUtil.isTypedArray;
|
|
3621
|
+
|
|
3622
|
+
/**
|
|
3623
|
+
* Checks if `value` is classified as a typed array.
|
|
3624
|
+
*
|
|
3625
|
+
* @static
|
|
3626
|
+
* @memberOf _
|
|
3627
|
+
* @since 3.0.0
|
|
3628
|
+
* @category Lang
|
|
3629
|
+
* @param {*} value The value to check.
|
|
3630
|
+
* @returns {boolean} Returns `true` if `value` is a typed array, else `false`.
|
|
3631
|
+
* @example
|
|
3632
|
+
*
|
|
3633
|
+
* _.isTypedArray(new Uint8Array);
|
|
3634
|
+
* // => true
|
|
3635
|
+
*
|
|
3636
|
+
* _.isTypedArray([]);
|
|
3637
|
+
* // => false
|
|
3638
|
+
*/
|
|
3639
|
+
var isTypedArray = nodeIsTypedArray ? baseUnary(nodeIsTypedArray) : baseIsTypedArray;
|
|
3640
|
+
|
|
3641
|
+
/**
|
|
3642
|
+
* Creates an array of the enumerable property names of the array-like `value`.
|
|
3643
|
+
*
|
|
3644
|
+
* @private
|
|
3645
|
+
* @param {*} value The value to query.
|
|
3646
|
+
* @param {boolean} inherited Specify returning inherited property names.
|
|
3647
|
+
* @returns {Array} Returns the array of property names.
|
|
3648
|
+
*/
|
|
3649
|
+
function arrayLikeKeys(value, inherited) {
|
|
3650
|
+
var isArr = isArray(value),
|
|
3651
|
+
isArg = !isArr && isArguments(value),
|
|
3652
|
+
isBuff = !isArr && !isArg && isBuffer(value),
|
|
3653
|
+
isType = !isArr && !isArg && !isBuff && isTypedArray(value),
|
|
3654
|
+
skipIndexes = isArr || isArg || isBuff || isType,
|
|
3655
|
+
result = skipIndexes ? baseTimes(value.length, String) : [],
|
|
3656
|
+
length = result.length;
|
|
3657
|
+
|
|
3658
|
+
for (var key in value) {
|
|
3659
|
+
if (!(skipIndexes && (
|
|
3660
|
+
// Safari 9 has enumerable `arguments.length` in strict mode.
|
|
3661
|
+
key == 'length' ||
|
|
3662
|
+
// Node.js 0.10 has enumerable non-index properties on buffers.
|
|
3663
|
+
(isBuff && (key == 'offset' || key == 'parent')) ||
|
|
3664
|
+
// PhantomJS 2 has enumerable non-index properties on typed arrays.
|
|
3665
|
+
(isType && (key == 'buffer' || key == 'byteLength' || key == 'byteOffset')) ||
|
|
3666
|
+
// Skip index properties.
|
|
3667
|
+
isIndex(key, length)
|
|
3668
|
+
))) {
|
|
3669
|
+
result.push(key);
|
|
3670
|
+
}
|
|
3671
|
+
}
|
|
3672
|
+
return result;
|
|
3673
|
+
}
|
|
3674
|
+
|
|
3675
|
+
/**
|
|
3676
|
+
* Creates a unary function that invokes `func` with its argument transformed.
|
|
3677
|
+
*
|
|
3678
|
+
* @private
|
|
3679
|
+
* @param {Function} func The function to wrap.
|
|
3680
|
+
* @param {Function} transform The argument transform.
|
|
3681
|
+
* @returns {Function} Returns the new function.
|
|
3682
|
+
*/
|
|
3683
|
+
function overArg(func, transform) {
|
|
3684
|
+
return function(arg) {
|
|
3685
|
+
return func(transform(arg));
|
|
3686
|
+
};
|
|
3687
|
+
}
|
|
3688
|
+
|
|
3689
|
+
/**
|
|
3690
|
+
* This function is like
|
|
3691
|
+
* [`Object.keys`](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)
|
|
3692
|
+
* except that it includes inherited enumerable properties.
|
|
3693
|
+
*
|
|
3694
|
+
* @private
|
|
3695
|
+
* @param {Object} object The object to query.
|
|
3696
|
+
* @returns {Array} Returns the array of property names.
|
|
3697
|
+
*/
|
|
3698
|
+
function nativeKeysIn(object) {
|
|
3699
|
+
var result = [];
|
|
3700
|
+
if (object != null) {
|
|
3701
|
+
for (var key in Object(object)) {
|
|
3702
|
+
result.push(key);
|
|
3703
|
+
}
|
|
3704
|
+
}
|
|
3705
|
+
return result;
|
|
3706
|
+
}
|
|
3707
|
+
|
|
3708
|
+
/** Used for built-in method references. */
|
|
3709
|
+
var objectProto$3 = Object.prototype;
|
|
3710
|
+
|
|
3711
|
+
/** Used to check objects for own properties. */
|
|
3712
|
+
var hasOwnProperty$3 = objectProto$3.hasOwnProperty;
|
|
3713
|
+
|
|
3714
|
+
/**
|
|
3715
|
+
* The base implementation of `_.keysIn` which doesn't treat sparse arrays as dense.
|
|
3716
|
+
*
|
|
3717
|
+
* @private
|
|
3718
|
+
* @param {Object} object The object to query.
|
|
3719
|
+
* @returns {Array} Returns the array of property names.
|
|
3720
|
+
*/
|
|
3721
|
+
function baseKeysIn(object) {
|
|
3722
|
+
if (!isObject(object)) {
|
|
3723
|
+
return nativeKeysIn(object);
|
|
3724
|
+
}
|
|
3725
|
+
var isProto = isPrototype(object),
|
|
3726
|
+
result = [];
|
|
3727
|
+
|
|
3728
|
+
for (var key in object) {
|
|
3729
|
+
if (!(key == 'constructor' && (isProto || !hasOwnProperty$3.call(object, key)))) {
|
|
3730
|
+
result.push(key);
|
|
3731
|
+
}
|
|
3732
|
+
}
|
|
3733
|
+
return result;
|
|
3734
|
+
}
|
|
3735
|
+
|
|
3736
|
+
/**
|
|
3737
|
+
* Creates an array of the own and inherited enumerable property names of `object`.
|
|
3738
|
+
*
|
|
3739
|
+
* **Note:** Non-object values are coerced to objects.
|
|
3740
|
+
*
|
|
3741
|
+
* @static
|
|
3742
|
+
* @memberOf _
|
|
3743
|
+
* @since 3.0.0
|
|
3744
|
+
* @category Object
|
|
3745
|
+
* @param {Object} object The object to query.
|
|
3746
|
+
* @returns {Array} Returns the array of property names.
|
|
3747
|
+
* @example
|
|
3748
|
+
*
|
|
3749
|
+
* function Foo() {
|
|
3750
|
+
* this.a = 1;
|
|
3751
|
+
* this.b = 2;
|
|
3752
|
+
* }
|
|
3753
|
+
*
|
|
3754
|
+
* Foo.prototype.c = 3;
|
|
3755
|
+
*
|
|
3756
|
+
* _.keysIn(new Foo);
|
|
3757
|
+
* // => ['a', 'b', 'c'] (iteration order is not guaranteed)
|
|
3758
|
+
*/
|
|
3759
|
+
function keysIn(object) {
|
|
3760
|
+
return isArrayLike(object) ? arrayLikeKeys(object) : baseKeysIn(object);
|
|
3761
|
+
}
|
|
3762
|
+
|
|
3763
|
+
/* Built-in method references that are verified to be native. */
|
|
3764
|
+
var nativeCreate = getNative(Object, 'create');
|
|
3765
|
+
|
|
3766
|
+
/**
|
|
3767
|
+
* Removes all key-value entries from the hash.
|
|
3768
|
+
*
|
|
3769
|
+
* @private
|
|
3770
|
+
* @name clear
|
|
3771
|
+
* @memberOf Hash
|
|
3772
|
+
*/
|
|
3773
|
+
function hashClear() {
|
|
3774
|
+
this.__data__ = nativeCreate ? nativeCreate(null) : {};
|
|
3775
|
+
this.size = 0;
|
|
3776
|
+
}
|
|
3777
|
+
|
|
3778
|
+
/**
|
|
3779
|
+
* Removes `key` and its value from the hash.
|
|
3780
|
+
*
|
|
3781
|
+
* @private
|
|
3782
|
+
* @name delete
|
|
3783
|
+
* @memberOf Hash
|
|
3784
|
+
* @param {Object} hash The hash to modify.
|
|
3785
|
+
* @param {string} key The key of the value to remove.
|
|
3786
|
+
* @returns {boolean} Returns `true` if the entry was removed, else `false`.
|
|
3787
|
+
*/
|
|
3788
|
+
function hashDelete(key) {
|
|
3789
|
+
var result = this.has(key) && delete this.__data__[key];
|
|
3790
|
+
this.size -= result ? 1 : 0;
|
|
3791
|
+
return result;
|
|
3792
|
+
}
|
|
3793
|
+
|
|
3794
|
+
/** Used to stand-in for `undefined` hash values. */
|
|
3795
|
+
var HASH_UNDEFINED$1 = '__lodash_hash_undefined__';
|
|
3796
|
+
|
|
3797
|
+
/** Used for built-in method references. */
|
|
3798
|
+
var objectProto$2 = Object.prototype;
|
|
3799
|
+
|
|
3800
|
+
/** Used to check objects for own properties. */
|
|
3801
|
+
var hasOwnProperty$2 = objectProto$2.hasOwnProperty;
|
|
3802
|
+
|
|
3803
|
+
/**
|
|
3804
|
+
* Gets the hash value for `key`.
|
|
3805
|
+
*
|
|
3806
|
+
* @private
|
|
3807
|
+
* @name get
|
|
3808
|
+
* @memberOf Hash
|
|
3809
|
+
* @param {string} key The key of the value to get.
|
|
3810
|
+
* @returns {*} Returns the entry value.
|
|
3811
|
+
*/
|
|
3812
|
+
function hashGet(key) {
|
|
3813
|
+
var data = this.__data__;
|
|
3814
|
+
if (nativeCreate) {
|
|
3815
|
+
var result = data[key];
|
|
3816
|
+
return result === HASH_UNDEFINED$1 ? undefined : result;
|
|
3817
|
+
}
|
|
3818
|
+
return hasOwnProperty$2.call(data, key) ? data[key] : undefined;
|
|
3819
|
+
}
|
|
3820
|
+
|
|
3821
|
+
/** Used for built-in method references. */
|
|
3822
|
+
var objectProto$1 = Object.prototype;
|
|
3823
|
+
|
|
3824
|
+
/** Used to check objects for own properties. */
|
|
3825
|
+
var hasOwnProperty$1 = objectProto$1.hasOwnProperty;
|
|
3826
|
+
|
|
3827
|
+
/**
|
|
3828
|
+
* Checks if a hash value for `key` exists.
|
|
3829
|
+
*
|
|
3830
|
+
* @private
|
|
3831
|
+
* @name has
|
|
3832
|
+
* @memberOf Hash
|
|
3833
|
+
* @param {string} key The key of the entry to check.
|
|
3834
|
+
* @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
|
|
3835
|
+
*/
|
|
3836
|
+
function hashHas(key) {
|
|
3837
|
+
var data = this.__data__;
|
|
3838
|
+
return nativeCreate ? (data[key] !== undefined) : hasOwnProperty$1.call(data, key);
|
|
3839
|
+
}
|
|
3840
|
+
|
|
3841
|
+
/** Used to stand-in for `undefined` hash values. */
|
|
3842
|
+
var HASH_UNDEFINED = '__lodash_hash_undefined__';
|
|
3843
|
+
|
|
3844
|
+
/**
|
|
3845
|
+
* Sets the hash `key` to `value`.
|
|
3846
|
+
*
|
|
3847
|
+
* @private
|
|
3848
|
+
* @name set
|
|
3849
|
+
* @memberOf Hash
|
|
3850
|
+
* @param {string} key The key of the value to set.
|
|
3851
|
+
* @param {*} value The value to set.
|
|
3852
|
+
* @returns {Object} Returns the hash instance.
|
|
3853
|
+
*/
|
|
3854
|
+
function hashSet(key, value) {
|
|
3855
|
+
var data = this.__data__;
|
|
3856
|
+
this.size += this.has(key) ? 0 : 1;
|
|
3857
|
+
data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value;
|
|
3858
|
+
return this;
|
|
3859
|
+
}
|
|
3860
|
+
|
|
3861
|
+
/**
|
|
3862
|
+
* Creates a hash object.
|
|
3863
|
+
*
|
|
3864
|
+
* @private
|
|
3865
|
+
* @constructor
|
|
3866
|
+
* @param {Array} [entries] The key-value pairs to cache.
|
|
3867
|
+
*/
|
|
3868
|
+
function Hash(entries) {
|
|
3869
|
+
var index = -1,
|
|
3870
|
+
length = entries == null ? 0 : entries.length;
|
|
3871
|
+
|
|
3872
|
+
this.clear();
|
|
3873
|
+
while (++index < length) {
|
|
3874
|
+
var entry = entries[index];
|
|
3875
|
+
this.set(entry[0], entry[1]);
|
|
3876
|
+
}
|
|
3877
|
+
}
|
|
3878
|
+
|
|
3879
|
+
// Add methods to `Hash`.
|
|
3880
|
+
Hash.prototype.clear = hashClear;
|
|
3881
|
+
Hash.prototype['delete'] = hashDelete;
|
|
3882
|
+
Hash.prototype.get = hashGet;
|
|
3883
|
+
Hash.prototype.has = hashHas;
|
|
3884
|
+
Hash.prototype.set = hashSet;
|
|
3885
|
+
|
|
3886
|
+
/**
|
|
3887
|
+
* Removes all key-value entries from the list cache.
|
|
3888
|
+
*
|
|
3889
|
+
* @private
|
|
3890
|
+
* @name clear
|
|
3891
|
+
* @memberOf ListCache
|
|
3892
|
+
*/
|
|
3893
|
+
function listCacheClear() {
|
|
3894
|
+
this.__data__ = [];
|
|
3895
|
+
this.size = 0;
|
|
3896
|
+
}
|
|
3897
|
+
|
|
3898
|
+
/**
|
|
3899
|
+
* Gets the index at which the `key` is found in `array` of key-value pairs.
|
|
3900
|
+
*
|
|
3901
|
+
* @private
|
|
3902
|
+
* @param {Array} array The array to inspect.
|
|
3903
|
+
* @param {*} key The key to search for.
|
|
3904
|
+
* @returns {number} Returns the index of the matched value, else `-1`.
|
|
3905
|
+
*/
|
|
3906
|
+
function assocIndexOf(array, key) {
|
|
3907
|
+
var length = array.length;
|
|
3908
|
+
while (length--) {
|
|
3909
|
+
if (eq(array[length][0], key)) {
|
|
3910
|
+
return length;
|
|
3911
|
+
}
|
|
3912
|
+
}
|
|
3913
|
+
return -1;
|
|
3914
|
+
}
|
|
3915
|
+
|
|
3916
|
+
/** Used for built-in method references. */
|
|
3917
|
+
var arrayProto = Array.prototype;
|
|
3918
|
+
|
|
3919
|
+
/** Built-in value references. */
|
|
3920
|
+
var splice = arrayProto.splice;
|
|
3921
|
+
|
|
3922
|
+
/**
|
|
3923
|
+
* Removes `key` and its value from the list cache.
|
|
3924
|
+
*
|
|
3925
|
+
* @private
|
|
3926
|
+
* @name delete
|
|
3927
|
+
* @memberOf ListCache
|
|
3928
|
+
* @param {string} key The key of the value to remove.
|
|
3929
|
+
* @returns {boolean} Returns `true` if the entry was removed, else `false`.
|
|
3930
|
+
*/
|
|
3931
|
+
function listCacheDelete(key) {
|
|
3932
|
+
var data = this.__data__,
|
|
3933
|
+
index = assocIndexOf(data, key);
|
|
3934
|
+
|
|
3935
|
+
if (index < 0) {
|
|
3936
|
+
return false;
|
|
3937
|
+
}
|
|
3938
|
+
var lastIndex = data.length - 1;
|
|
3939
|
+
if (index == lastIndex) {
|
|
3940
|
+
data.pop();
|
|
3941
|
+
} else {
|
|
3942
|
+
splice.call(data, index, 1);
|
|
3943
|
+
}
|
|
3944
|
+
--this.size;
|
|
3945
|
+
return true;
|
|
3946
|
+
}
|
|
3947
|
+
|
|
3948
|
+
/**
|
|
3949
|
+
* Gets the list cache value for `key`.
|
|
3950
|
+
*
|
|
3951
|
+
* @private
|
|
3952
|
+
* @name get
|
|
3953
|
+
* @memberOf ListCache
|
|
3954
|
+
* @param {string} key The key of the value to get.
|
|
3955
|
+
* @returns {*} Returns the entry value.
|
|
3956
|
+
*/
|
|
3957
|
+
function listCacheGet(key) {
|
|
3958
|
+
var data = this.__data__,
|
|
3959
|
+
index = assocIndexOf(data, key);
|
|
3960
|
+
|
|
3961
|
+
return index < 0 ? undefined : data[index][1];
|
|
3962
|
+
}
|
|
3963
|
+
|
|
3964
|
+
/**
|
|
3965
|
+
* Checks if a list cache value for `key` exists.
|
|
3966
|
+
*
|
|
3967
|
+
* @private
|
|
3968
|
+
* @name has
|
|
3969
|
+
* @memberOf ListCache
|
|
3970
|
+
* @param {string} key The key of the entry to check.
|
|
3971
|
+
* @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
|
|
3972
|
+
*/
|
|
3973
|
+
function listCacheHas(key) {
|
|
3974
|
+
return assocIndexOf(this.__data__, key) > -1;
|
|
3975
|
+
}
|
|
3976
|
+
|
|
3977
|
+
/**
|
|
3978
|
+
* Sets the list cache `key` to `value`.
|
|
3979
|
+
*
|
|
3980
|
+
* @private
|
|
3981
|
+
* @name set
|
|
3982
|
+
* @memberOf ListCache
|
|
3983
|
+
* @param {string} key The key of the value to set.
|
|
3984
|
+
* @param {*} value The value to set.
|
|
3985
|
+
* @returns {Object} Returns the list cache instance.
|
|
3986
|
+
*/
|
|
3987
|
+
function listCacheSet(key, value) {
|
|
3988
|
+
var data = this.__data__,
|
|
3989
|
+
index = assocIndexOf(data, key);
|
|
3990
|
+
|
|
3991
|
+
if (index < 0) {
|
|
3992
|
+
++this.size;
|
|
3993
|
+
data.push([key, value]);
|
|
3994
|
+
} else {
|
|
3995
|
+
data[index][1] = value;
|
|
3996
|
+
}
|
|
3997
|
+
return this;
|
|
3998
|
+
}
|
|
3999
|
+
|
|
4000
|
+
/**
|
|
4001
|
+
* Creates an list cache object.
|
|
4002
|
+
*
|
|
4003
|
+
* @private
|
|
4004
|
+
* @constructor
|
|
4005
|
+
* @param {Array} [entries] The key-value pairs to cache.
|
|
4006
|
+
*/
|
|
4007
|
+
function ListCache(entries) {
|
|
4008
|
+
var index = -1,
|
|
4009
|
+
length = entries == null ? 0 : entries.length;
|
|
4010
|
+
|
|
4011
|
+
this.clear();
|
|
4012
|
+
while (++index < length) {
|
|
4013
|
+
var entry = entries[index];
|
|
4014
|
+
this.set(entry[0], entry[1]);
|
|
4015
|
+
}
|
|
4016
|
+
}
|
|
4017
|
+
|
|
4018
|
+
// Add methods to `ListCache`.
|
|
4019
|
+
ListCache.prototype.clear = listCacheClear;
|
|
4020
|
+
ListCache.prototype['delete'] = listCacheDelete;
|
|
4021
|
+
ListCache.prototype.get = listCacheGet;
|
|
4022
|
+
ListCache.prototype.has = listCacheHas;
|
|
4023
|
+
ListCache.prototype.set = listCacheSet;
|
|
4024
|
+
|
|
4025
|
+
/* Built-in method references that are verified to be native. */
|
|
4026
|
+
var Map$1 = getNative(root, 'Map');
|
|
4027
|
+
|
|
4028
|
+
/**
|
|
4029
|
+
* Removes all key-value entries from the map.
|
|
4030
|
+
*
|
|
4031
|
+
* @private
|
|
4032
|
+
* @name clear
|
|
4033
|
+
* @memberOf MapCache
|
|
4034
|
+
*/
|
|
4035
|
+
function mapCacheClear() {
|
|
4036
|
+
this.size = 0;
|
|
4037
|
+
this.__data__ = {
|
|
4038
|
+
'hash': new Hash,
|
|
4039
|
+
'map': new (Map$1 || ListCache),
|
|
4040
|
+
'string': new Hash
|
|
4041
|
+
};
|
|
4042
|
+
}
|
|
4043
|
+
|
|
4044
|
+
/**
|
|
4045
|
+
* Checks if `value` is suitable for use as unique object key.
|
|
4046
|
+
*
|
|
4047
|
+
* @private
|
|
4048
|
+
* @param {*} value The value to check.
|
|
4049
|
+
* @returns {boolean} Returns `true` if `value` is suitable, else `false`.
|
|
4050
|
+
*/
|
|
4051
|
+
function isKeyable(value) {
|
|
4052
|
+
var type = typeof value;
|
|
4053
|
+
return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean')
|
|
4054
|
+
? (value !== '__proto__')
|
|
4055
|
+
: (value === null);
|
|
4056
|
+
}
|
|
4057
|
+
|
|
4058
|
+
/**
|
|
4059
|
+
* Gets the data for `map`.
|
|
4060
|
+
*
|
|
4061
|
+
* @private
|
|
4062
|
+
* @param {Object} map The map to query.
|
|
4063
|
+
* @param {string} key The reference key.
|
|
4064
|
+
* @returns {*} Returns the map data.
|
|
4065
|
+
*/
|
|
4066
|
+
function getMapData(map, key) {
|
|
4067
|
+
var data = map.__data__;
|
|
4068
|
+
return isKeyable(key)
|
|
4069
|
+
? data[typeof key == 'string' ? 'string' : 'hash']
|
|
4070
|
+
: data.map;
|
|
4071
|
+
}
|
|
4072
|
+
|
|
4073
|
+
/**
|
|
4074
|
+
* Removes `key` and its value from the map.
|
|
4075
|
+
*
|
|
4076
|
+
* @private
|
|
4077
|
+
* @name delete
|
|
4078
|
+
* @memberOf MapCache
|
|
4079
|
+
* @param {string} key The key of the value to remove.
|
|
4080
|
+
* @returns {boolean} Returns `true` if the entry was removed, else `false`.
|
|
4081
|
+
*/
|
|
4082
|
+
function mapCacheDelete(key) {
|
|
4083
|
+
var result = getMapData(this, key)['delete'](key);
|
|
4084
|
+
this.size -= result ? 1 : 0;
|
|
4085
|
+
return result;
|
|
4086
|
+
}
|
|
4087
|
+
|
|
4088
|
+
/**
|
|
4089
|
+
* Gets the map value for `key`.
|
|
4090
|
+
*
|
|
4091
|
+
* @private
|
|
4092
|
+
* @name get
|
|
4093
|
+
* @memberOf MapCache
|
|
4094
|
+
* @param {string} key The key of the value to get.
|
|
4095
|
+
* @returns {*} Returns the entry value.
|
|
4096
|
+
*/
|
|
4097
|
+
function mapCacheGet(key) {
|
|
4098
|
+
return getMapData(this, key).get(key);
|
|
4099
|
+
}
|
|
4100
|
+
|
|
4101
|
+
/**
|
|
4102
|
+
* Checks if a map value for `key` exists.
|
|
4103
|
+
*
|
|
4104
|
+
* @private
|
|
4105
|
+
* @name has
|
|
4106
|
+
* @memberOf MapCache
|
|
4107
|
+
* @param {string} key The key of the entry to check.
|
|
4108
|
+
* @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
|
|
4109
|
+
*/
|
|
4110
|
+
function mapCacheHas(key) {
|
|
4111
|
+
return getMapData(this, key).has(key);
|
|
4112
|
+
}
|
|
4113
|
+
|
|
4114
|
+
/**
|
|
4115
|
+
* Sets the map `key` to `value`.
|
|
4116
|
+
*
|
|
4117
|
+
* @private
|
|
4118
|
+
* @name set
|
|
4119
|
+
* @memberOf MapCache
|
|
4120
|
+
* @param {string} key The key of the value to set.
|
|
4121
|
+
* @param {*} value The value to set.
|
|
4122
|
+
* @returns {Object} Returns the map cache instance.
|
|
4123
|
+
*/
|
|
4124
|
+
function mapCacheSet(key, value) {
|
|
4125
|
+
var data = getMapData(this, key),
|
|
4126
|
+
size = data.size;
|
|
4127
|
+
|
|
4128
|
+
data.set(key, value);
|
|
4129
|
+
this.size += data.size == size ? 0 : 1;
|
|
4130
|
+
return this;
|
|
4131
|
+
}
|
|
4132
|
+
|
|
4133
|
+
/**
|
|
4134
|
+
* Creates a map cache object to store key-value pairs.
|
|
4135
|
+
*
|
|
4136
|
+
* @private
|
|
4137
|
+
* @constructor
|
|
4138
|
+
* @param {Array} [entries] The key-value pairs to cache.
|
|
4139
|
+
*/
|
|
4140
|
+
function MapCache(entries) {
|
|
4141
|
+
var index = -1,
|
|
4142
|
+
length = entries == null ? 0 : entries.length;
|
|
4143
|
+
|
|
4144
|
+
this.clear();
|
|
4145
|
+
while (++index < length) {
|
|
4146
|
+
var entry = entries[index];
|
|
4147
|
+
this.set(entry[0], entry[1]);
|
|
4148
|
+
}
|
|
4149
|
+
}
|
|
4150
|
+
|
|
4151
|
+
// Add methods to `MapCache`.
|
|
4152
|
+
MapCache.prototype.clear = mapCacheClear;
|
|
4153
|
+
MapCache.prototype['delete'] = mapCacheDelete;
|
|
4154
|
+
MapCache.prototype.get = mapCacheGet;
|
|
4155
|
+
MapCache.prototype.has = mapCacheHas;
|
|
4156
|
+
MapCache.prototype.set = mapCacheSet;
|
|
4157
|
+
|
|
4158
|
+
/**
|
|
4159
|
+
* Converts `value` to a string. An empty string is returned for `null`
|
|
4160
|
+
* and `undefined` values. The sign of `-0` is preserved.
|
|
4161
|
+
*
|
|
4162
|
+
* @static
|
|
4163
|
+
* @memberOf _
|
|
4164
|
+
* @since 4.0.0
|
|
4165
|
+
* @category Lang
|
|
4166
|
+
* @param {*} value The value to convert.
|
|
4167
|
+
* @returns {string} Returns the converted string.
|
|
4168
|
+
* @example
|
|
4169
|
+
*
|
|
4170
|
+
* _.toString(null);
|
|
4171
|
+
* // => ''
|
|
4172
|
+
*
|
|
4173
|
+
* _.toString(-0);
|
|
4174
|
+
* // => '-0'
|
|
4175
|
+
*
|
|
4176
|
+
* _.toString([1, 2, 3]);
|
|
4177
|
+
* // => '1,2,3'
|
|
4178
|
+
*/
|
|
4179
|
+
function toString(value) {
|
|
4180
|
+
return value == null ? '' : baseToString(value);
|
|
4181
|
+
}
|
|
4182
|
+
|
|
4183
|
+
/** Built-in value references. */
|
|
4184
|
+
var getPrototype = overArg(Object.getPrototypeOf, Object);
|
|
4185
|
+
|
|
4186
|
+
/** `Object#toString` result references. */
|
|
4187
|
+
var objectTag = '[object Object]';
|
|
4188
|
+
|
|
4189
|
+
/** Used for built-in method references. */
|
|
4190
|
+
var funcProto = Function.prototype,
|
|
4191
|
+
objectProto = Object.prototype;
|
|
4192
|
+
|
|
4193
|
+
/** Used to resolve the decompiled source of functions. */
|
|
4194
|
+
var funcToString = funcProto.toString;
|
|
4195
|
+
|
|
4196
|
+
/** Used to check objects for own properties. */
|
|
4197
|
+
var hasOwnProperty = objectProto.hasOwnProperty;
|
|
4198
|
+
|
|
4199
|
+
/** Used to infer the `Object` constructor. */
|
|
4200
|
+
var objectCtorString = funcToString.call(Object);
|
|
4201
|
+
|
|
4202
|
+
/**
|
|
4203
|
+
* Checks if `value` is a plain object, that is, an object created by the
|
|
4204
|
+
* `Object` constructor or one with a `[[Prototype]]` of `null`.
|
|
4205
|
+
*
|
|
4206
|
+
* @static
|
|
4207
|
+
* @memberOf _
|
|
4208
|
+
* @since 0.8.0
|
|
4209
|
+
* @category Lang
|
|
4210
|
+
* @param {*} value The value to check.
|
|
4211
|
+
* @returns {boolean} Returns `true` if `value` is a plain object, else `false`.
|
|
4212
|
+
* @example
|
|
4213
|
+
*
|
|
4214
|
+
* function Foo() {
|
|
4215
|
+
* this.a = 1;
|
|
4216
|
+
* }
|
|
4217
|
+
*
|
|
4218
|
+
* _.isPlainObject(new Foo);
|
|
4219
|
+
* // => false
|
|
4220
|
+
*
|
|
4221
|
+
* _.isPlainObject([1, 2, 3]);
|
|
4222
|
+
* // => false
|
|
4223
|
+
*
|
|
4224
|
+
* _.isPlainObject({ 'x': 0, 'y': 0 });
|
|
4225
|
+
* // => true
|
|
4226
|
+
*
|
|
4227
|
+
* _.isPlainObject(Object.create(null));
|
|
4228
|
+
* // => true
|
|
4229
|
+
*/
|
|
4230
|
+
function isPlainObject(value) {
|
|
4231
|
+
if (!isObjectLike(value) || baseGetTag(value) != objectTag) {
|
|
4232
|
+
return false;
|
|
4233
|
+
}
|
|
4234
|
+
var proto = getPrototype(value);
|
|
4235
|
+
if (proto === null) {
|
|
4236
|
+
return true;
|
|
4237
|
+
}
|
|
4238
|
+
var Ctor = hasOwnProperty.call(proto, 'constructor') && proto.constructor;
|
|
4239
|
+
return typeof Ctor == 'function' && Ctor instanceof Ctor &&
|
|
4240
|
+
funcToString.call(Ctor) == objectCtorString;
|
|
4241
|
+
}
|
|
4242
|
+
|
|
4243
|
+
/* Built-in method references for those with the same name as other `lodash` methods. */
|
|
4244
|
+
var nativeIsFinite = root.isFinite,
|
|
4245
|
+
nativeMin = Math.min;
|
|
4246
|
+
|
|
4247
|
+
/**
|
|
4248
|
+
* Creates a function like `_.round`.
|
|
4249
|
+
*
|
|
4250
|
+
* @private
|
|
4251
|
+
* @param {string} methodName The name of the `Math` method to use when rounding.
|
|
4252
|
+
* @returns {Function} Returns the new round function.
|
|
4253
|
+
*/
|
|
4254
|
+
function createRound(methodName) {
|
|
4255
|
+
var func = Math[methodName];
|
|
4256
|
+
return function(number, precision) {
|
|
4257
|
+
number = toNumber(number);
|
|
4258
|
+
precision = precision == null ? 0 : nativeMin(toInteger(precision), 292);
|
|
4259
|
+
if (precision && nativeIsFinite(number)) {
|
|
4260
|
+
// Shift with exponential notation to avoid floating-point issues.
|
|
4261
|
+
// See [MDN](https://mdn.io/round#Examples) for more details.
|
|
4262
|
+
var pair = (toString(number) + 'e').split('e'),
|
|
4263
|
+
value = func(pair[0] + 'e' + (+pair[1] + precision));
|
|
4264
|
+
|
|
4265
|
+
pair = (toString(value) + 'e').split('e');
|
|
4266
|
+
return +(pair[0] + 'e' + (+pair[1] - precision));
|
|
4267
|
+
}
|
|
4268
|
+
return func(number);
|
|
4269
|
+
};
|
|
4270
|
+
}
|
|
4271
|
+
|
|
4272
|
+
/**
|
|
4273
|
+
* Removes all key-value entries from the stack.
|
|
4274
|
+
*
|
|
4275
|
+
* @private
|
|
4276
|
+
* @name clear
|
|
4277
|
+
* @memberOf Stack
|
|
4278
|
+
*/
|
|
4279
|
+
function stackClear() {
|
|
4280
|
+
this.__data__ = new ListCache;
|
|
4281
|
+
this.size = 0;
|
|
4282
|
+
}
|
|
4283
|
+
|
|
4284
|
+
/**
|
|
4285
|
+
* Removes `key` and its value from the stack.
|
|
4286
|
+
*
|
|
4287
|
+
* @private
|
|
4288
|
+
* @name delete
|
|
4289
|
+
* @memberOf Stack
|
|
4290
|
+
* @param {string} key The key of the value to remove.
|
|
4291
|
+
* @returns {boolean} Returns `true` if the entry was removed, else `false`.
|
|
4292
|
+
*/
|
|
4293
|
+
function stackDelete(key) {
|
|
4294
|
+
var data = this.__data__,
|
|
4295
|
+
result = data['delete'](key);
|
|
4296
|
+
|
|
4297
|
+
this.size = data.size;
|
|
4298
|
+
return result;
|
|
4299
|
+
}
|
|
4300
|
+
|
|
4301
|
+
/**
|
|
4302
|
+
* Gets the stack value for `key`.
|
|
4303
|
+
*
|
|
4304
|
+
* @private
|
|
4305
|
+
* @name get
|
|
4306
|
+
* @memberOf Stack
|
|
4307
|
+
* @param {string} key The key of the value to get.
|
|
4308
|
+
* @returns {*} Returns the entry value.
|
|
4309
|
+
*/
|
|
4310
|
+
function stackGet(key) {
|
|
4311
|
+
return this.__data__.get(key);
|
|
4312
|
+
}
|
|
4313
|
+
|
|
4314
|
+
/**
|
|
4315
|
+
* Checks if a stack value for `key` exists.
|
|
4316
|
+
*
|
|
4317
|
+
* @private
|
|
4318
|
+
* @name has
|
|
4319
|
+
* @memberOf Stack
|
|
4320
|
+
* @param {string} key The key of the entry to check.
|
|
4321
|
+
* @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
|
|
4322
|
+
*/
|
|
4323
|
+
function stackHas(key) {
|
|
4324
|
+
return this.__data__.has(key);
|
|
4325
|
+
}
|
|
4326
|
+
|
|
4327
|
+
/** Used as the size to enable large array optimizations. */
|
|
4328
|
+
var LARGE_ARRAY_SIZE = 200;
|
|
4329
|
+
|
|
4330
|
+
/**
|
|
4331
|
+
* Sets the stack `key` to `value`.
|
|
4332
|
+
*
|
|
4333
|
+
* @private
|
|
4334
|
+
* @name set
|
|
4335
|
+
* @memberOf Stack
|
|
4336
|
+
* @param {string} key The key of the value to set.
|
|
4337
|
+
* @param {*} value The value to set.
|
|
4338
|
+
* @returns {Object} Returns the stack cache instance.
|
|
4339
|
+
*/
|
|
4340
|
+
function stackSet(key, value) {
|
|
4341
|
+
var data = this.__data__;
|
|
4342
|
+
if (data instanceof ListCache) {
|
|
4343
|
+
var pairs = data.__data__;
|
|
4344
|
+
if (!Map$1 || (pairs.length < LARGE_ARRAY_SIZE - 1)) {
|
|
4345
|
+
pairs.push([key, value]);
|
|
4346
|
+
this.size = ++data.size;
|
|
4347
|
+
return this;
|
|
4348
|
+
}
|
|
4349
|
+
data = this.__data__ = new MapCache(pairs);
|
|
4350
|
+
}
|
|
4351
|
+
data.set(key, value);
|
|
4352
|
+
this.size = data.size;
|
|
4353
|
+
return this;
|
|
4354
|
+
}
|
|
4355
|
+
|
|
4356
|
+
/**
|
|
4357
|
+
* Creates a stack cache object to store key-value pairs.
|
|
4358
|
+
*
|
|
4359
|
+
* @private
|
|
4360
|
+
* @constructor
|
|
4361
|
+
* @param {Array} [entries] The key-value pairs to cache.
|
|
4362
|
+
*/
|
|
4363
|
+
function Stack(entries) {
|
|
4364
|
+
var data = this.__data__ = new ListCache(entries);
|
|
4365
|
+
this.size = data.size;
|
|
4366
|
+
}
|
|
4367
|
+
|
|
4368
|
+
// Add methods to `Stack`.
|
|
4369
|
+
Stack.prototype.clear = stackClear;
|
|
4370
|
+
Stack.prototype['delete'] = stackDelete;
|
|
4371
|
+
Stack.prototype.get = stackGet;
|
|
4372
|
+
Stack.prototype.has = stackHas;
|
|
4373
|
+
Stack.prototype.set = stackSet;
|
|
4374
|
+
|
|
4375
|
+
/** Detect free variable `exports`. */
|
|
4376
|
+
var freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports;
|
|
4377
|
+
|
|
4378
|
+
/** Detect free variable `module`. */
|
|
4379
|
+
var freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module;
|
|
4380
|
+
|
|
4381
|
+
/** Detect the popular CommonJS extension `module.exports`. */
|
|
4382
|
+
var moduleExports = freeModule && freeModule.exports === freeExports;
|
|
4383
|
+
|
|
4384
|
+
/** Built-in value references. */
|
|
4385
|
+
var Buffer = moduleExports ? root.Buffer : undefined;
|
|
4386
|
+
Buffer ? Buffer.allocUnsafe : undefined;
|
|
4387
|
+
|
|
4388
|
+
/**
|
|
4389
|
+
* Creates a clone of `buffer`.
|
|
4390
|
+
*
|
|
4391
|
+
* @private
|
|
4392
|
+
* @param {Buffer} buffer The buffer to clone.
|
|
4393
|
+
* @param {boolean} [isDeep] Specify a deep clone.
|
|
4394
|
+
* @returns {Buffer} Returns the cloned buffer.
|
|
4395
|
+
*/
|
|
4396
|
+
function cloneBuffer(buffer, isDeep) {
|
|
4397
|
+
{
|
|
4398
|
+
return buffer.slice();
|
|
4399
|
+
}
|
|
4400
|
+
}
|
|
4401
|
+
|
|
4402
|
+
/** Built-in value references. */
|
|
4403
|
+
var Uint8Array$1 = root.Uint8Array;
|
|
4404
|
+
|
|
4405
|
+
/**
|
|
4406
|
+
* Creates a clone of `arrayBuffer`.
|
|
4407
|
+
*
|
|
4408
|
+
* @private
|
|
4409
|
+
* @param {ArrayBuffer} arrayBuffer The array buffer to clone.
|
|
4410
|
+
* @returns {ArrayBuffer} Returns the cloned array buffer.
|
|
4411
|
+
*/
|
|
4412
|
+
function cloneArrayBuffer(arrayBuffer) {
|
|
4413
|
+
var result = new arrayBuffer.constructor(arrayBuffer.byteLength);
|
|
4414
|
+
new Uint8Array$1(result).set(new Uint8Array$1(arrayBuffer));
|
|
4415
|
+
return result;
|
|
4416
|
+
}
|
|
4417
|
+
|
|
4418
|
+
/**
|
|
4419
|
+
* Creates a clone of `typedArray`.
|
|
4420
|
+
*
|
|
4421
|
+
* @private
|
|
4422
|
+
* @param {Object} typedArray The typed array to clone.
|
|
4423
|
+
* @param {boolean} [isDeep] Specify a deep clone.
|
|
4424
|
+
* @returns {Object} Returns the cloned typed array.
|
|
4425
|
+
*/
|
|
4426
|
+
function cloneTypedArray(typedArray, isDeep) {
|
|
4427
|
+
var buffer = cloneArrayBuffer(typedArray.buffer) ;
|
|
4428
|
+
return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length);
|
|
4429
|
+
}
|
|
4430
|
+
|
|
4431
|
+
/**
|
|
4432
|
+
* Initializes an object clone.
|
|
4433
|
+
*
|
|
4434
|
+
* @private
|
|
4435
|
+
* @param {Object} object The object to clone.
|
|
4436
|
+
* @returns {Object} Returns the initialized clone.
|
|
4437
|
+
*/
|
|
4438
|
+
function initCloneObject(object) {
|
|
4439
|
+
return (typeof object.constructor == 'function' && !isPrototype(object))
|
|
4440
|
+
? baseCreate(getPrototype(object))
|
|
4441
|
+
: {};
|
|
4442
|
+
}
|
|
4443
|
+
|
|
4444
|
+
/**
|
|
4445
|
+
* Creates a base function for methods like `_.forIn` and `_.forOwn`.
|
|
4446
|
+
*
|
|
4447
|
+
* @private
|
|
4448
|
+
* @param {boolean} [fromRight] Specify iterating from right to left.
|
|
4449
|
+
* @returns {Function} Returns the new base function.
|
|
4450
|
+
*/
|
|
4451
|
+
function createBaseFor(fromRight) {
|
|
4452
|
+
return function(object, iteratee, keysFunc) {
|
|
4453
|
+
var index = -1,
|
|
4454
|
+
iterable = Object(object),
|
|
4455
|
+
props = keysFunc(object),
|
|
4456
|
+
length = props.length;
|
|
4457
|
+
|
|
4458
|
+
while (length--) {
|
|
4459
|
+
var key = props[++index];
|
|
4460
|
+
if (iteratee(iterable[key], key, iterable) === false) {
|
|
4461
|
+
break;
|
|
4462
|
+
}
|
|
4463
|
+
}
|
|
4464
|
+
return object;
|
|
4465
|
+
};
|
|
4466
|
+
}
|
|
4467
|
+
|
|
4468
|
+
/**
|
|
4469
|
+
* The base implementation of `baseForOwn` which iterates over `object`
|
|
4470
|
+
* properties returned by `keysFunc` and invokes `iteratee` for each property.
|
|
4471
|
+
* Iteratee functions may exit iteration early by explicitly returning `false`.
|
|
4472
|
+
*
|
|
4473
|
+
* @private
|
|
4474
|
+
* @param {Object} object The object to iterate over.
|
|
4475
|
+
* @param {Function} iteratee The function invoked per iteration.
|
|
4476
|
+
* @param {Function} keysFunc The function to get the keys of `object`.
|
|
4477
|
+
* @returns {Object} Returns `object`.
|
|
4478
|
+
*/
|
|
4479
|
+
var baseFor = createBaseFor();
|
|
4480
|
+
|
|
4481
|
+
/**
|
|
4482
|
+
* This function is like `assignValue` except that it doesn't assign
|
|
4483
|
+
* `undefined` values.
|
|
4484
|
+
*
|
|
4485
|
+
* @private
|
|
4486
|
+
* @param {Object} object The object to modify.
|
|
4487
|
+
* @param {string} key The key of the property to assign.
|
|
4488
|
+
* @param {*} value The value to assign.
|
|
4489
|
+
*/
|
|
4490
|
+
function assignMergeValue(object, key, value) {
|
|
4491
|
+
if ((value !== undefined && !eq(object[key], value)) ||
|
|
4492
|
+
(value === undefined && !(key in object))) {
|
|
4493
|
+
baseAssignValue(object, key, value);
|
|
4494
|
+
}
|
|
4495
|
+
}
|
|
4496
|
+
|
|
4497
|
+
/**
|
|
4498
|
+
* This method is like `_.isArrayLike` except that it also checks if `value`
|
|
4499
|
+
* is an object.
|
|
4500
|
+
*
|
|
4501
|
+
* @static
|
|
4502
|
+
* @memberOf _
|
|
4503
|
+
* @since 4.0.0
|
|
4504
|
+
* @category Lang
|
|
4505
|
+
* @param {*} value The value to check.
|
|
4506
|
+
* @returns {boolean} Returns `true` if `value` is an array-like object,
|
|
4507
|
+
* else `false`.
|
|
4508
|
+
* @example
|
|
4509
|
+
*
|
|
4510
|
+
* _.isArrayLikeObject([1, 2, 3]);
|
|
4511
|
+
* // => true
|
|
4512
|
+
*
|
|
4513
|
+
* _.isArrayLikeObject(document.body.children);
|
|
4514
|
+
* // => true
|
|
4515
|
+
*
|
|
4516
|
+
* _.isArrayLikeObject('abc');
|
|
4517
|
+
* // => false
|
|
4518
|
+
*
|
|
4519
|
+
* _.isArrayLikeObject(_.noop);
|
|
4520
|
+
* // => false
|
|
4521
|
+
*/
|
|
4522
|
+
function isArrayLikeObject(value) {
|
|
4523
|
+
return isObjectLike(value) && isArrayLike(value);
|
|
4524
|
+
}
|
|
4525
|
+
|
|
4526
|
+
/**
|
|
4527
|
+
* Gets the value at `key`, unless `key` is "__proto__" or "constructor".
|
|
4528
|
+
*
|
|
4529
|
+
* @private
|
|
4530
|
+
* @param {Object} object The object to query.
|
|
4531
|
+
* @param {string} key The key of the property to get.
|
|
4532
|
+
* @returns {*} Returns the property value.
|
|
4533
|
+
*/
|
|
4534
|
+
function safeGet(object, key) {
|
|
4535
|
+
if (key === 'constructor' && typeof object[key] === 'function') {
|
|
4536
|
+
return;
|
|
4537
|
+
}
|
|
4538
|
+
|
|
4539
|
+
if (key == '__proto__') {
|
|
4540
|
+
return;
|
|
4541
|
+
}
|
|
4542
|
+
|
|
4543
|
+
return object[key];
|
|
2295
4544
|
}
|
|
2296
|
-
|
|
2297
|
-
|
|
2298
|
-
|
|
2299
|
-
|
|
2300
|
-
|
|
2301
|
-
|
|
2302
|
-
|
|
2303
|
-
|
|
2304
|
-
|
|
2305
|
-
|
|
2306
|
-
|
|
2307
|
-
|
|
2308
|
-
|
|
2309
|
-
|
|
4545
|
+
|
|
4546
|
+
/**
|
|
4547
|
+
* Converts `value` to a plain object flattening inherited enumerable string
|
|
4548
|
+
* keyed properties of `value` to own properties of the plain object.
|
|
4549
|
+
*
|
|
4550
|
+
* @static
|
|
4551
|
+
* @memberOf _
|
|
4552
|
+
* @since 3.0.0
|
|
4553
|
+
* @category Lang
|
|
4554
|
+
* @param {*} value The value to convert.
|
|
4555
|
+
* @returns {Object} Returns the converted plain object.
|
|
4556
|
+
* @example
|
|
4557
|
+
*
|
|
4558
|
+
* function Foo() {
|
|
4559
|
+
* this.b = 2;
|
|
4560
|
+
* }
|
|
4561
|
+
*
|
|
4562
|
+
* Foo.prototype.c = 3;
|
|
4563
|
+
*
|
|
4564
|
+
* _.assign({ 'a': 1 }, new Foo);
|
|
4565
|
+
* // => { 'a': 1, 'b': 2 }
|
|
4566
|
+
*
|
|
4567
|
+
* _.assign({ 'a': 1 }, _.toPlainObject(new Foo));
|
|
4568
|
+
* // => { 'a': 1, 'b': 2, 'c': 3 }
|
|
4569
|
+
*/
|
|
4570
|
+
function toPlainObject(value) {
|
|
4571
|
+
return copyObject(value, keysIn(value));
|
|
4572
|
+
}
|
|
4573
|
+
|
|
4574
|
+
/**
|
|
4575
|
+
* A specialized version of `baseMerge` for arrays and objects which performs
|
|
4576
|
+
* deep merges and tracks traversed objects enabling objects with circular
|
|
4577
|
+
* references to be merged.
|
|
4578
|
+
*
|
|
4579
|
+
* @private
|
|
4580
|
+
* @param {Object} object The destination object.
|
|
4581
|
+
* @param {Object} source The source object.
|
|
4582
|
+
* @param {string} key The key of the value to merge.
|
|
4583
|
+
* @param {number} srcIndex The index of `source`.
|
|
4584
|
+
* @param {Function} mergeFunc The function to merge values.
|
|
4585
|
+
* @param {Function} [customizer] The function to customize assigned values.
|
|
4586
|
+
* @param {Object} [stack] Tracks traversed source values and their merged
|
|
4587
|
+
* counterparts.
|
|
4588
|
+
*/
|
|
4589
|
+
function baseMergeDeep(object, source, key, srcIndex, mergeFunc, customizer, stack) {
|
|
4590
|
+
var objValue = safeGet(object, key),
|
|
4591
|
+
srcValue = safeGet(source, key),
|
|
4592
|
+
stacked = stack.get(srcValue);
|
|
4593
|
+
|
|
4594
|
+
if (stacked) {
|
|
4595
|
+
assignMergeValue(object, key, stacked);
|
|
4596
|
+
return;
|
|
4597
|
+
}
|
|
4598
|
+
var newValue = customizer
|
|
4599
|
+
? customizer(objValue, srcValue, (key + ''), object, source, stack)
|
|
4600
|
+
: undefined;
|
|
4601
|
+
|
|
4602
|
+
var isCommon = newValue === undefined;
|
|
4603
|
+
|
|
4604
|
+
if (isCommon) {
|
|
4605
|
+
var isArr = isArray(srcValue),
|
|
4606
|
+
isBuff = !isArr && isBuffer(srcValue),
|
|
4607
|
+
isTyped = !isArr && !isBuff && isTypedArray(srcValue);
|
|
4608
|
+
|
|
4609
|
+
newValue = srcValue;
|
|
4610
|
+
if (isArr || isBuff || isTyped) {
|
|
4611
|
+
if (isArray(objValue)) {
|
|
4612
|
+
newValue = objValue;
|
|
4613
|
+
}
|
|
4614
|
+
else if (isArrayLikeObject(objValue)) {
|
|
4615
|
+
newValue = copyArray(objValue);
|
|
4616
|
+
}
|
|
4617
|
+
else if (isBuff) {
|
|
4618
|
+
isCommon = false;
|
|
4619
|
+
newValue = cloneBuffer(srcValue);
|
|
4620
|
+
}
|
|
4621
|
+
else if (isTyped) {
|
|
4622
|
+
isCommon = false;
|
|
4623
|
+
newValue = cloneTypedArray(srcValue);
|
|
4624
|
+
}
|
|
4625
|
+
else {
|
|
4626
|
+
newValue = [];
|
|
4627
|
+
}
|
|
4628
|
+
}
|
|
4629
|
+
else if (isPlainObject(srcValue) || isArguments(srcValue)) {
|
|
4630
|
+
newValue = objValue;
|
|
4631
|
+
if (isArguments(objValue)) {
|
|
4632
|
+
newValue = toPlainObject(objValue);
|
|
4633
|
+
}
|
|
4634
|
+
else if (!isObject(objValue) || isFunction(objValue)) {
|
|
4635
|
+
newValue = initCloneObject(srcValue);
|
|
4636
|
+
}
|
|
2310
4637
|
}
|
|
2311
4638
|
else {
|
|
2312
|
-
|
|
2313
|
-
}
|
|
4639
|
+
isCommon = false;
|
|
4640
|
+
}
|
|
4641
|
+
}
|
|
4642
|
+
if (isCommon) {
|
|
4643
|
+
// Recursively merge objects and arrays (susceptible to call stack limits).
|
|
4644
|
+
stack.set(srcValue, newValue);
|
|
4645
|
+
mergeFunc(newValue, srcValue, srcIndex, customizer, stack);
|
|
4646
|
+
stack['delete'](srcValue);
|
|
4647
|
+
}
|
|
4648
|
+
assignMergeValue(object, key, newValue);
|
|
2314
4649
|
}
|
|
2315
|
-
|
|
2316
|
-
|
|
2317
|
-
|
|
2318
|
-
|
|
2319
|
-
|
|
2320
|
-
|
|
4650
|
+
|
|
4651
|
+
/**
|
|
4652
|
+
* The base implementation of `_.merge` without support for multiple sources.
|
|
4653
|
+
*
|
|
4654
|
+
* @private
|
|
4655
|
+
* @param {Object} object The destination object.
|
|
4656
|
+
* @param {Object} source The source object.
|
|
4657
|
+
* @param {number} srcIndex The index of `source`.
|
|
4658
|
+
* @param {Function} [customizer] The function to customize merged values.
|
|
4659
|
+
* @param {Object} [stack] Tracks traversed source values and their merged
|
|
4660
|
+
* counterparts.
|
|
4661
|
+
*/
|
|
4662
|
+
function baseMerge(object, source, srcIndex, customizer, stack) {
|
|
4663
|
+
if (object === source) {
|
|
4664
|
+
return;
|
|
4665
|
+
}
|
|
4666
|
+
baseFor(source, function(srcValue, key) {
|
|
4667
|
+
stack || (stack = new Stack);
|
|
4668
|
+
if (isObject(srcValue)) {
|
|
4669
|
+
baseMergeDeep(object, source, key, srcIndex, baseMerge, customizer, stack);
|
|
2321
4670
|
}
|
|
2322
|
-
else
|
|
2323
|
-
|
|
4671
|
+
else {
|
|
4672
|
+
var newValue = customizer
|
|
4673
|
+
? customizer(safeGet(object, key), srcValue, (key + ''), object, source, stack)
|
|
4674
|
+
: undefined;
|
|
4675
|
+
|
|
4676
|
+
if (newValue === undefined) {
|
|
4677
|
+
newValue = srcValue;
|
|
4678
|
+
}
|
|
4679
|
+
assignMergeValue(object, key, newValue);
|
|
2324
4680
|
}
|
|
2325
|
-
|
|
2326
|
-
}
|
|
2327
|
-
function isInvalidPosition(positonConfig) {
|
|
2328
|
-
return (isNoPosture(positonConfig.postureX) &&
|
|
2329
|
-
isNoPosture(positonConfig.postureY) &&
|
|
2330
|
-
isNoPosture(positonConfig.postureTheta));
|
|
2331
|
-
}
|
|
2332
|
-
function isOutOfRange(positonConfig) {
|
|
2333
|
-
return (positonConfig.postureX != null &&
|
|
2334
|
-
Math.abs(positonConfig.postureX) > 1000 * SCALE_FACTOR &&
|
|
2335
|
-
positonConfig.postureY != null &&
|
|
2336
|
-
Math.abs(positonConfig.postureY) > 1000 * SCALE_FACTOR);
|
|
4681
|
+
}, keysIn);
|
|
2337
4682
|
}
|
|
2338
4683
|
|
|
4684
|
+
/**
|
|
4685
|
+
* Computes `number` rounded down to `precision`.
|
|
4686
|
+
*
|
|
4687
|
+
* @static
|
|
4688
|
+
* @memberOf _
|
|
4689
|
+
* @since 3.10.0
|
|
4690
|
+
* @category Math
|
|
4691
|
+
* @param {number} number The number to round down.
|
|
4692
|
+
* @param {number} [precision=0] The precision to round down to.
|
|
4693
|
+
* @returns {number} Returns the rounded down number.
|
|
4694
|
+
* @example
|
|
4695
|
+
*
|
|
4696
|
+
* _.floor(4.006);
|
|
4697
|
+
* // => 4
|
|
4698
|
+
*
|
|
4699
|
+
* _.floor(0.046, 2);
|
|
4700
|
+
* // => 0.04
|
|
4701
|
+
*
|
|
4702
|
+
* _.floor(4060, -2);
|
|
4703
|
+
* // => 4000
|
|
4704
|
+
*/
|
|
4705
|
+
var floor = createRound('floor');
|
|
4706
|
+
|
|
4707
|
+
/**
|
|
4708
|
+
* This method is like `_.assign` except that it recursively merges own and
|
|
4709
|
+
* inherited enumerable string keyed properties of source objects into the
|
|
4710
|
+
* destination object. Source properties that resolve to `undefined` are
|
|
4711
|
+
* skipped if a destination value exists. Array and plain object properties
|
|
4712
|
+
* are merged recursively. Other objects and value types are overridden by
|
|
4713
|
+
* assignment. Source objects are applied from left to right. Subsequent
|
|
4714
|
+
* sources overwrite property assignments of previous sources.
|
|
4715
|
+
*
|
|
4716
|
+
* **Note:** This method mutates `object`.
|
|
4717
|
+
*
|
|
4718
|
+
* @static
|
|
4719
|
+
* @memberOf _
|
|
4720
|
+
* @since 0.5.0
|
|
4721
|
+
* @category Object
|
|
4722
|
+
* @param {Object} object The destination object.
|
|
4723
|
+
* @param {...Object} [sources] The source objects.
|
|
4724
|
+
* @returns {Object} Returns `object`.
|
|
4725
|
+
* @example
|
|
4726
|
+
*
|
|
4727
|
+
* var object = {
|
|
4728
|
+
* 'a': [{ 'b': 2 }, { 'd': 4 }]
|
|
4729
|
+
* };
|
|
4730
|
+
*
|
|
4731
|
+
* var other = {
|
|
4732
|
+
* 'a': [{ 'c': 3 }, { 'e': 5 }]
|
|
4733
|
+
* };
|
|
4734
|
+
*
|
|
4735
|
+
* _.merge(object, other);
|
|
4736
|
+
* // => { 'a': [{ 'b': 2, 'c': 3 }, { 'd': 4, 'e': 5 }] }
|
|
4737
|
+
*/
|
|
4738
|
+
var merge = createAssigner(function(object, source, srcIndex) {
|
|
4739
|
+
baseMerge(object, source, srcIndex);
|
|
4740
|
+
});
|
|
4741
|
+
|
|
4742
|
+
/**
|
|
4743
|
+
* Computes `number` rounded to `precision`.
|
|
4744
|
+
*
|
|
4745
|
+
* @static
|
|
4746
|
+
* @memberOf _
|
|
4747
|
+
* @since 3.10.0
|
|
4748
|
+
* @category Math
|
|
4749
|
+
* @param {number} number The number to round.
|
|
4750
|
+
* @param {number} [precision=0] The precision to round to.
|
|
4751
|
+
* @returns {number} Returns the rounded number.
|
|
4752
|
+
* @example
|
|
4753
|
+
*
|
|
4754
|
+
* _.round(4.006);
|
|
4755
|
+
* // => 4
|
|
4756
|
+
*
|
|
4757
|
+
* _.round(4.006, 2);
|
|
4758
|
+
* // => 4.01
|
|
4759
|
+
*
|
|
4760
|
+
* _.round(4060, -2);
|
|
4761
|
+
* // => 4100
|
|
4762
|
+
*/
|
|
4763
|
+
var round = createRound('round');
|
|
4764
|
+
|
|
2339
4765
|
/**
|
|
2340
4766
|
* 默认航向相对于canvas的偏移角度: 航向默认是东
|
|
2341
4767
|
*/
|
|
@@ -2368,10 +4794,10 @@ function calAngle(x1, y1, x2, y2) {
|
|
|
2368
4794
|
return Math.atan2((y2 - y1), (x2 - x1));
|
|
2369
4795
|
}
|
|
2370
4796
|
const mathRound = (value, decimals = 2) => {
|
|
2371
|
-
return Number.isInteger(value) ? value :
|
|
4797
|
+
return Number.isInteger(value) ? value : round(value, decimals);
|
|
2372
4798
|
};
|
|
2373
4799
|
const mathFloor = (value, decimals = 2) => {
|
|
2374
|
-
return Number.isInteger(value) ? value :
|
|
4800
|
+
return Number.isInteger(value) ? value : floor(value, decimals);
|
|
2375
4801
|
};
|
|
2376
4802
|
// 公制平方米-》英制平方英尺
|
|
2377
4803
|
function areaToft2(area) {
|
|
@@ -2656,7 +5082,7 @@ class BoundaryBorderLayer extends BaseLayer {
|
|
|
2656
5082
|
* 创建直接路径(type=2)
|
|
2657
5083
|
*/
|
|
2658
5084
|
createDirectPath(svgGroup, points, style) {
|
|
2659
|
-
const strokeColor = style.
|
|
5085
|
+
const strokeColor = style.lineColor;
|
|
2660
5086
|
const lineWidth = dp2px(style.lineWidth || 3);
|
|
2661
5087
|
const path = document.createElementNS('http://www.w3.org/2000/svg', 'path');
|
|
2662
5088
|
// 构建路径数据
|
|
@@ -2685,7 +5111,7 @@ class BoundaryBorderLayer extends BaseLayer {
|
|
|
2685
5111
|
* 使用PathMeasure逻辑创建平行路径(type=1)
|
|
2686
5112
|
*/
|
|
2687
5113
|
createParallelPathsWithMeasure(svgGroup, points, style) {
|
|
2688
|
-
const strokeColor = style.
|
|
5114
|
+
const strokeColor = style.lineColor;
|
|
2689
5115
|
const lineWidth = dp2px(style.lineWidth || 3);
|
|
2690
5116
|
// 获取当前SVG的缩放级别,计算固定屏幕像素间距
|
|
2691
5117
|
const fixedScreenDistance = lineWidth; // 固定的屏幕像素距离
|
|
@@ -2851,8 +5277,8 @@ class AntennaLayer extends BaseLayer {
|
|
|
2851
5277
|
}
|
|
2852
5278
|
const image = document.createElementNS('http://www.w3.org/2000/svg', 'image');
|
|
2853
5279
|
// 图片居中定位
|
|
2854
|
-
const x =
|
|
2855
|
-
const y =
|
|
5280
|
+
const x = center[0] - size / 2;
|
|
5281
|
+
const y = center[1] - size / 2;
|
|
2856
5282
|
image.setAttribute('x', x.toString());
|
|
2857
5283
|
image.setAttribute('y', y.toString());
|
|
2858
5284
|
image.setAttribute('width', `${size}px`);
|
|
@@ -3033,19 +5459,19 @@ class BoundaryDataBuilder {
|
|
|
3033
5459
|
/**
|
|
3034
5460
|
* 从地图元素创建边界数据
|
|
3035
5461
|
*/
|
|
3036
|
-
static fromMapElement(element) {
|
|
5462
|
+
static fromMapElement(element, style) {
|
|
3037
5463
|
const convertedPoints = convertPointsFormat(element.points);
|
|
3038
5464
|
if (!convertedPoints || convertedPoints.length < 3)
|
|
3039
5465
|
return null;
|
|
3040
|
-
const drawElement = this.create('boundary', convertedPoints,
|
|
5466
|
+
const drawElement = this.create('boundary', convertedPoints, style);
|
|
3041
5467
|
drawElement.originalData = element; // 保存完整的原始数据
|
|
3042
5468
|
return drawElement;
|
|
3043
5469
|
}
|
|
3044
|
-
static createBoundaryBorder(element) {
|
|
5470
|
+
static createBoundaryBorder(element, style) {
|
|
3045
5471
|
const convertedPoints = convertPointsFormat(element.points);
|
|
3046
5472
|
if (!convertedPoints || convertedPoints.length < 3)
|
|
3047
5473
|
return null;
|
|
3048
|
-
const drawElement = this.create('boundary_border', convertedPoints,
|
|
5474
|
+
const drawElement = this.create('boundary_border', convertedPoints, style);
|
|
3049
5475
|
drawElement.originalData = element; // 保存完整的原始数据
|
|
3050
5476
|
return drawElement;
|
|
3051
5477
|
}
|
|
@@ -3068,27 +5494,22 @@ class ObstacleDataBuilder {
|
|
|
3068
5494
|
/**
|
|
3069
5495
|
* 从地图元素创建障碍物数据
|
|
3070
5496
|
*/
|
|
3071
|
-
static fromMapElement(element) {
|
|
5497
|
+
static fromMapElement(element, style) {
|
|
3072
5498
|
const convertedPoints = convertPointsFormat(element.points);
|
|
3073
5499
|
if (!convertedPoints || convertedPoints.length < 3)
|
|
3074
5500
|
return null;
|
|
3075
|
-
const drawElement = this.create(convertedPoints,
|
|
5501
|
+
const drawElement = this.create(convertedPoints, style);
|
|
3076
5502
|
drawElement.originalData = element; // 保存完整的原始数据
|
|
3077
5503
|
return drawElement;
|
|
3078
5504
|
}
|
|
3079
5505
|
/**
|
|
3080
5506
|
* 创建时间限制障碍物多边形数据
|
|
3081
5507
|
*/
|
|
3082
|
-
static createTimeLimitObstacle(element) {
|
|
5508
|
+
static createTimeLimitObstacle(element, style) {
|
|
3083
5509
|
const convertedPoints = convertPointsFormat(element.points);
|
|
3084
5510
|
if (!convertedPoints || convertedPoints.length < 3)
|
|
3085
5511
|
return null;
|
|
3086
|
-
const drawElement = this.create(convertedPoints,
|
|
3087
|
-
strokeColor: DEFAULT_STYLES.OBSTACLE.strokeColor,
|
|
3088
|
-
fillColor: 'rgba(255, 192, 203, 0.3)', // 粉色半透明填充
|
|
3089
|
-
lineWidth: 2,
|
|
3090
|
-
opacity: 0.8,
|
|
3091
|
-
});
|
|
5512
|
+
const drawElement = this.create(convertedPoints, style);
|
|
3092
5513
|
drawElement.originalData = element; // 保存完整的原始数据
|
|
3093
5514
|
return drawElement;
|
|
3094
5515
|
}
|
|
@@ -3111,12 +5532,12 @@ class ChargingPileDataBuilder {
|
|
|
3111
5532
|
/**
|
|
3112
5533
|
* 从地图元素创建充电桩数据
|
|
3113
5534
|
*/
|
|
3114
|
-
static fromMapElement(element) {
|
|
5535
|
+
static fromMapElement(element, style) {
|
|
3115
5536
|
const elements = [];
|
|
3116
5537
|
// 创建充电桩本体
|
|
3117
5538
|
const point = convertPositionFormat(element.position);
|
|
3118
5539
|
if (point) {
|
|
3119
|
-
const mainPileElement = this.create([point.x, point.y],
|
|
5540
|
+
const mainPileElement = this.create([point.x, point.y], style);
|
|
3120
5541
|
mainPileElement.originalData = element; // 保存完整的原始数据
|
|
3121
5542
|
elements.push(mainPileElement);
|
|
3122
5543
|
}
|
|
@@ -3144,7 +5565,7 @@ class AntennaDataBuilder {
|
|
|
3144
5565
|
* 1. 如果副天线位置数据的相对坐标都是0,则需要展示在主天线旁边
|
|
3145
5566
|
* 2. 否则,副天线有自己的独立位置
|
|
3146
5567
|
*/
|
|
3147
|
-
static fromAntennaData(antennas) {
|
|
5568
|
+
static fromAntennaData(antennas, style) {
|
|
3148
5569
|
const elements = [];
|
|
3149
5570
|
const size = 30;
|
|
3150
5571
|
// 查找主天线(ID=1)和副天线(ID=2)
|
|
@@ -3159,7 +5580,7 @@ class AntennaDataBuilder {
|
|
|
3159
5580
|
online: antenna1.status === 1,
|
|
3160
5581
|
size
|
|
3161
5582
|
};
|
|
3162
|
-
const element1 = this.create([point1.x, point1.y],
|
|
5583
|
+
const element1 = this.create([point1.x, point1.y], style, metadata1);
|
|
3163
5584
|
element1.originalData = antenna1;
|
|
3164
5585
|
elements.push(element1);
|
|
3165
5586
|
}
|
|
@@ -3174,7 +5595,7 @@ class AntennaDataBuilder {
|
|
|
3174
5595
|
online: antenna2.status === 2,
|
|
3175
5596
|
size
|
|
3176
5597
|
};
|
|
3177
|
-
const element2 = this.create([point2.x, point2.y],
|
|
5598
|
+
const element2 = this.create([point2.x, point2.y], style, metadata2);
|
|
3178
5599
|
element2.originalData = antenna2;
|
|
3179
5600
|
elements.push(element2);
|
|
3180
5601
|
}
|
|
@@ -3201,7 +5622,7 @@ class SvgElementDataBuilder {
|
|
|
3201
5622
|
/**
|
|
3202
5623
|
* 从地图元素创建SVG数据(用于时间限制障碍物)
|
|
3203
5624
|
*/
|
|
3204
|
-
static fromMapElement(element) {
|
|
5625
|
+
static fromMapElement(element, style) {
|
|
3205
5626
|
if (!element.svg ||
|
|
3206
5627
|
!element.center ||
|
|
3207
5628
|
element.scale === undefined ||
|
|
@@ -3215,7 +5636,7 @@ class SvgElementDataBuilder {
|
|
|
3215
5636
|
svg: element.svg,
|
|
3216
5637
|
scale: element.scale,
|
|
3217
5638
|
direction: element.direction,
|
|
3218
|
-
},
|
|
5639
|
+
}, style);
|
|
3219
5640
|
drawElement.originalData = element; // 保存完整的原始数据
|
|
3220
5641
|
return drawElement;
|
|
3221
5642
|
}
|
|
@@ -3249,11 +5670,11 @@ class VisionOffDataBuilder {
|
|
|
3249
5670
|
/**
|
|
3250
5671
|
* 创建视觉盲区元素数据(使用边界样式)
|
|
3251
5672
|
*/
|
|
3252
|
-
static createVisionOffArea(element) {
|
|
5673
|
+
static createVisionOffArea(element, style) {
|
|
3253
5674
|
const convertedPoints = convertPointsFormat(element.points);
|
|
3254
5675
|
if (!convertedPoints || convertedPoints.length < 3)
|
|
3255
5676
|
return null;
|
|
3256
|
-
const drawElement = this.create(convertedPoints,
|
|
5677
|
+
const drawElement = this.create(convertedPoints, style);
|
|
3257
5678
|
drawElement.originalData = element; // 保存完整的原始数据
|
|
3258
5679
|
return drawElement;
|
|
3259
5680
|
}
|
|
@@ -3276,33 +5697,18 @@ class ChannelDataBuilder {
|
|
|
3276
5697
|
/**
|
|
3277
5698
|
* 创建隧道元素数据
|
|
3278
5699
|
*/
|
|
3279
|
-
static createTunnel(element) {
|
|
5700
|
+
static createTunnel(element, style) {
|
|
3280
5701
|
const convertedPoints = convertPointsFormat(element.tunnel?.points || element.points);
|
|
3281
5702
|
if (!convertedPoints || convertedPoints.length < 2)
|
|
3282
5703
|
return null;
|
|
3283
|
-
const drawElement = this.create(convertedPoints,
|
|
3284
|
-
drawElement.originalData = element; // 保存完整的原始数据
|
|
3285
|
-
return drawElement;
|
|
3286
|
-
}
|
|
3287
|
-
/**
|
|
3288
|
-
* 创建充电桩隧道元素数据
|
|
3289
|
-
*/
|
|
3290
|
-
static createTunnelToChargingPile(element) {
|
|
3291
|
-
const convertedPoints = convertPointsFormat(element.points);
|
|
3292
|
-
if (!convertedPoints || convertedPoints.length < 2)
|
|
3293
|
-
return null;
|
|
3294
|
-
const drawElement = this.create(convertedPoints, {
|
|
3295
|
-
strokeColor: DEFAULT_STYLES.CHANNEL.strokeColor,
|
|
3296
|
-
lineWidth: 2,
|
|
3297
|
-
opacity: 1.0,
|
|
3298
|
-
});
|
|
5704
|
+
const drawElement = this.create(convertedPoints, style);
|
|
3299
5705
|
drawElement.originalData = element; // 保存完整的原始数据
|
|
3300
5706
|
return drawElement;
|
|
3301
5707
|
}
|
|
3302
5708
|
/**
|
|
3303
5709
|
* 创建充电桩内部隧道路径(用于CHARGING_PILE元素中的tunnel.points)
|
|
3304
5710
|
*/
|
|
3305
|
-
static createChargingPileTunnelPath(element) {
|
|
5711
|
+
static createChargingPileTunnelPath(element, style) {
|
|
3306
5712
|
if (!element.tunnel || !element.tunnel.points)
|
|
3307
5713
|
return null;
|
|
3308
5714
|
// 对应android代码逻辑modules/deviceModule/src/main/java/com/segway/mower/device/map/data/MapDataManager.java
|
|
@@ -3316,45 +5722,10 @@ class ChannelDataBuilder {
|
|
|
3316
5722
|
]);
|
|
3317
5723
|
if (!convertedTunnelPoints || convertedTunnelPoints.length < 2)
|
|
3318
5724
|
return null;
|
|
3319
|
-
const drawElement = this.create(convertedTunnelPoints,
|
|
3320
|
-
strokeColor: DEFAULT_STYLES.CHANNEL.strokeColor,
|
|
3321
|
-
lineWidth: 2,
|
|
3322
|
-
opacity: 1.0,
|
|
3323
|
-
});
|
|
5725
|
+
const drawElement = this.create(convertedTunnelPoints, style);
|
|
3324
5726
|
drawElement.originalData = element; // 保存完整的原始数据
|
|
3325
5727
|
return drawElement;
|
|
3326
5728
|
}
|
|
3327
|
-
/**
|
|
3328
|
-
* 创建边缘路径
|
|
3329
|
-
*/
|
|
3330
|
-
static createEdgePath(points, config) {
|
|
3331
|
-
return this.create(points, {
|
|
3332
|
-
strokeColor: config?.color || DEFAULT_STYLES.PATH_EDGE.strokeColor,
|
|
3333
|
-
lineWidth: config?.lineWidth || 2,
|
|
3334
|
-
opacity: config?.opacity || 1.0,
|
|
3335
|
-
});
|
|
3336
|
-
}
|
|
3337
|
-
/**
|
|
3338
|
-
* 创建割草路径
|
|
3339
|
-
*/
|
|
3340
|
-
static createMowingPath(points, config) {
|
|
3341
|
-
return this.create(points, {
|
|
3342
|
-
strokeColor: config?.color || DEFAULT_STYLES.PATH_EDGE.strokeColor,
|
|
3343
|
-
lineWidth: config?.lineWidth || 2,
|
|
3344
|
-
opacity: config?.opacity || 1.0,
|
|
3345
|
-
});
|
|
3346
|
-
}
|
|
3347
|
-
/**
|
|
3348
|
-
* 创建传输路径
|
|
3349
|
-
*/
|
|
3350
|
-
static createTransPath(points, config) {
|
|
3351
|
-
return this.create(points, {
|
|
3352
|
-
strokeColor: config?.color || DEFAULT_STYLES.PATH_EDGE.strokeColor,
|
|
3353
|
-
lineWidth: config?.lineWidth || 1,
|
|
3354
|
-
lineDash: [5, 5], // 虚线样式
|
|
3355
|
-
opacity: config?.opacity || 1.0,
|
|
3356
|
-
});
|
|
3357
|
-
}
|
|
3358
5729
|
}
|
|
3359
5730
|
|
|
3360
5731
|
/**
|
|
@@ -3365,7 +5736,8 @@ class MapDataProcessor {
|
|
|
3365
5736
|
/**
|
|
3366
5737
|
* 处理地图数据,返回绘制图层
|
|
3367
5738
|
*/
|
|
3368
|
-
static processMapData(mapData) {
|
|
5739
|
+
static processMapData(mapData, mapConfig) {
|
|
5740
|
+
this.mapConfig = mapConfig;
|
|
3369
5741
|
// 收集所有地图元素
|
|
3370
5742
|
const allElements = [];
|
|
3371
5743
|
// 处理子地图中的元素
|
|
@@ -3456,10 +5828,10 @@ class MapDataProcessor {
|
|
|
3456
5828
|
switch (element.type) {
|
|
3457
5829
|
case 'BOUNDARY': {
|
|
3458
5830
|
try {
|
|
3459
|
-
const boundaryElement = BoundaryDataBuilder.fromMapElement(element);
|
|
5831
|
+
const boundaryElement = BoundaryDataBuilder.fromMapElement(element, this.mapConfig.boundary);
|
|
3460
5832
|
if (boundaryElement)
|
|
3461
5833
|
result.push(boundaryElement);
|
|
3462
|
-
const boundaryBorderElement = BoundaryDataBuilder.createBoundaryBorder(element);
|
|
5834
|
+
const boundaryBorderElement = BoundaryDataBuilder.createBoundaryBorder(element, this.mapConfig.boundary);
|
|
3463
5835
|
if (boundaryBorderElement) {
|
|
3464
5836
|
result.push(boundaryBorderElement);
|
|
3465
5837
|
// 将边界边框存储到 store 中,以分区ID为key
|
|
@@ -3480,7 +5852,7 @@ class MapDataProcessor {
|
|
|
3480
5852
|
try {
|
|
3481
5853
|
// 为ObstacleData创建兼容的MapElement接口
|
|
3482
5854
|
const mapElement = element;
|
|
3483
|
-
const obstacleElement = ObstacleDataBuilder.fromMapElement(mapElement);
|
|
5855
|
+
const obstacleElement = ObstacleDataBuilder.fromMapElement(mapElement, this.mapConfig.obstacle);
|
|
3484
5856
|
if (obstacleElement)
|
|
3485
5857
|
result.push(obstacleElement);
|
|
3486
5858
|
}
|
|
@@ -3491,10 +5863,10 @@ class MapDataProcessor {
|
|
|
3491
5863
|
}
|
|
3492
5864
|
case 'CHARGING_PILE': {
|
|
3493
5865
|
try {
|
|
3494
|
-
const chargingPileElements = ChargingPileDataBuilder.fromMapElement(element);
|
|
5866
|
+
const chargingPileElements = ChargingPileDataBuilder.fromMapElement(element, this.mapConfig.chargingPile);
|
|
3495
5867
|
result.push(...chargingPileElements);
|
|
3496
5868
|
// 有充电桩通道时再连接到充电桩
|
|
3497
|
-
const tunnelPath = ChannelDataBuilder.createChargingPileTunnelPath(element);
|
|
5869
|
+
const tunnelPath = ChannelDataBuilder.createChargingPileTunnelPath(element, this.mapConfig.channel);
|
|
3498
5870
|
if (tunnelPath)
|
|
3499
5871
|
result.push(tunnelPath);
|
|
3500
5872
|
// 创建导航位置(如果存在)
|
|
@@ -3507,7 +5879,7 @@ class MapDataProcessor {
|
|
|
3507
5879
|
case 'VISION_OFF_AREA': {
|
|
3508
5880
|
try {
|
|
3509
5881
|
const mapElement = element;
|
|
3510
|
-
const visionOffElement = VisionOffDataBuilder.createVisionOffArea(mapElement);
|
|
5882
|
+
const visionOffElement = VisionOffDataBuilder.createVisionOffArea(mapElement, this.mapConfig.visionOffArea);
|
|
3511
5883
|
if (visionOffElement)
|
|
3512
5884
|
result.push(visionOffElement);
|
|
3513
5885
|
}
|
|
@@ -3519,7 +5891,7 @@ class MapDataProcessor {
|
|
|
3519
5891
|
case 'TUNNEL': {
|
|
3520
5892
|
try {
|
|
3521
5893
|
const mapElement = element;
|
|
3522
|
-
const tunnelElement = ChannelDataBuilder.createTunnel(mapElement);
|
|
5894
|
+
const tunnelElement = ChannelDataBuilder.createTunnel(mapElement, this.mapConfig.channel);
|
|
3523
5895
|
if (tunnelElement)
|
|
3524
5896
|
result.push({
|
|
3525
5897
|
...tunnelElement,
|
|
@@ -3542,7 +5914,8 @@ class MapDataProcessor {
|
|
|
3542
5914
|
'direction' in element &&
|
|
3543
5915
|
element.direction !== undefined) {
|
|
3544
5916
|
const mapElement = element;
|
|
3545
|
-
const svgElement = SvgElementDataBuilder.fromMapElement(mapElement);
|
|
5917
|
+
const svgElement = SvgElementDataBuilder.fromMapElement(mapElement, this.mapConfig.doodle);
|
|
5918
|
+
console.log('svgElement==', svgElement);
|
|
3546
5919
|
if (svgElement)
|
|
3547
5920
|
result.push(svgElement);
|
|
3548
5921
|
}
|
|
@@ -3552,7 +5925,7 @@ class MapDataProcessor {
|
|
|
3552
5925
|
Array.isArray(element.points) &&
|
|
3553
5926
|
element.points.length >= 3) {
|
|
3554
5927
|
const mapElement = element;
|
|
3555
|
-
const polygonElement = ObstacleDataBuilder.createTimeLimitObstacle(mapElement);
|
|
5928
|
+
const polygonElement = ObstacleDataBuilder.createTimeLimitObstacle(mapElement, this.mapConfig.obstacle);
|
|
3556
5929
|
if (polygonElement)
|
|
3557
5930
|
result.push(polygonElement);
|
|
3558
5931
|
}
|
|
@@ -3562,21 +5935,6 @@ class MapDataProcessor {
|
|
|
3562
5935
|
}
|
|
3563
5936
|
break;
|
|
3564
5937
|
}
|
|
3565
|
-
// case 'TUNNEL_TO_CHARGING_PILE': {
|
|
3566
|
-
// try {
|
|
3567
|
-
// // const chargingPileElement = elements.find(e => e.type === 'CHARGING_PILE');
|
|
3568
|
-
// // if (chargingPileElement) {
|
|
3569
|
-
// // const tunnelToChargingPileElement = ChannelDataBuilder.createTunnelToChargingPile(chargingPileElement);
|
|
3570
|
-
// // if (tunnelToChargingPileElement) result.push(tunnelToChargingPileElement);
|
|
3571
|
-
// // }
|
|
3572
|
-
// const tunnelToChargingPileElement =
|
|
3573
|
-
// ChannelDataBuilder.createTunnelToChargingPile(element);
|
|
3574
|
-
// if (tunnelToChargingPileElement) result.push(tunnelToChargingPileElement);
|
|
3575
|
-
// } catch (error) {
|
|
3576
|
-
// console.warn(`Error processing TUNNEL_TO_CHARGING_PILE element:`, element, error);
|
|
3577
|
-
// }
|
|
3578
|
-
// break;
|
|
3579
|
-
// }
|
|
3580
5938
|
default: {
|
|
3581
5939
|
console.warn(`Unknown element type: ${element.type}`, element);
|
|
3582
5940
|
break;
|
|
@@ -3623,18 +5981,6 @@ class PathDataBuilder {
|
|
|
3623
5981
|
// return this.create(convertedPoints, DEFAULT_STYLES.PATH_EDGE);
|
|
3624
5982
|
// }
|
|
3625
5983
|
// /**
|
|
3626
|
-
// * 创建充电桩隧道元素数据
|
|
3627
|
-
// */
|
|
3628
|
-
// static createTunnelToChargingPile(element: MapElement): DrawElement | null {
|
|
3629
|
-
// const convertedPoints = convertPointsFormat(element.points);
|
|
3630
|
-
// if (!convertedPoints || convertedPoints.length < 2) return null;
|
|
3631
|
-
// return this.create(convertedPoints, {
|
|
3632
|
-
// strokeColor: DEFAULT_STYLES.CHANNEL.strokeColor,
|
|
3633
|
-
// lineWidth: 2,
|
|
3634
|
-
// opacity: 1.0
|
|
3635
|
-
// });
|
|
3636
|
-
// }
|
|
3637
|
-
// /**
|
|
3638
5984
|
// * 创建充电桩内部隧道路径(用于CHARGING_PILE元素中的tunnel.points)
|
|
3639
5985
|
// */
|
|
3640
5986
|
// static createChargingPileTunnelPath(element: MapElement): DrawElement | null {
|
|
@@ -3694,7 +6040,7 @@ class PathDataProcessor {
|
|
|
3694
6040
|
/**
|
|
3695
6041
|
* 处理路径数据,创建路径绘制图层
|
|
3696
6042
|
*/
|
|
3697
|
-
static processPathData(pathData,
|
|
6043
|
+
static processPathData(pathData, mapConfig) {
|
|
3698
6044
|
if (!pathData || typeof pathData !== 'object') {
|
|
3699
6045
|
return [];
|
|
3700
6046
|
}
|
|
@@ -3706,62 +6052,45 @@ class PathDataProcessor {
|
|
|
3706
6052
|
return acc;
|
|
3707
6053
|
}, []);
|
|
3708
6054
|
// 合并配置
|
|
3709
|
-
const config =
|
|
3710
|
-
lineWidth: pathConfig?.lineWidth ?? 6,
|
|
3711
|
-
showEdgePaths: pathConfig?.showEdgePaths ?? false,
|
|
3712
|
-
showTransPaths: pathConfig?.showTransPaths ?? false,
|
|
3713
|
-
showMowingPaths: pathConfig?.showMowingPaths ?? true,
|
|
3714
|
-
edgePathColor: pathConfig?.edgePathColor,
|
|
3715
|
-
transPathColor: pathConfig?.transPathColor,
|
|
3716
|
-
mowingPathColor: pathConfig?.mowingPathColor,
|
|
3717
|
-
edgePathOpacity: pathConfig?.edgePathOpacity ?? 1.0,
|
|
3718
|
-
transPathOpacity: pathConfig?.transPathOpacity ?? 1.0,
|
|
3719
|
-
mowingPathOpacity: pathConfig?.mowingPathOpacity ?? 1.0,
|
|
3720
|
-
};
|
|
6055
|
+
const config = mapConfig.path;
|
|
3721
6056
|
// 使用Python相同的逻辑:按线段分组而不是按点分组
|
|
3722
6057
|
const pathSegments = createPathSegmentsByType(allPathItems);
|
|
3723
6058
|
const elements = [];
|
|
3724
|
-
//
|
|
3725
|
-
|
|
3726
|
-
|
|
3727
|
-
|
|
3728
|
-
|
|
3729
|
-
|
|
3730
|
-
|
|
3731
|
-
|
|
3732
|
-
|
|
3733
|
-
|
|
3734
|
-
|
|
3735
|
-
|
|
3736
|
-
|
|
3737
|
-
|
|
3738
|
-
|
|
3739
|
-
|
|
3740
|
-
|
|
3741
|
-
|
|
3742
|
-
|
|
3743
|
-
|
|
3744
|
-
|
|
3745
|
-
|
|
3746
|
-
|
|
3747
|
-
});
|
|
3748
|
-
element.originalData = points;
|
|
3749
|
-
elements.push(element);
|
|
3750
|
-
}
|
|
6059
|
+
// 处理边缘路径段
|
|
6060
|
+
for (const segment of pathSegments.edge) {
|
|
6061
|
+
// 转换 Point[] 为 number[][]
|
|
6062
|
+
const points = segment.points.map((point) => [point.x, point.y]);
|
|
6063
|
+
const element = PathDataBuilder.createEdgePath(points, {
|
|
6064
|
+
lineWidth: config.lineWidth,
|
|
6065
|
+
color: config.edgeLineColor,
|
|
6066
|
+
opacity: config.opacity,
|
|
6067
|
+
});
|
|
6068
|
+
element.originalData = points;
|
|
6069
|
+
elements.push(element);
|
|
6070
|
+
}
|
|
6071
|
+
// 处理割草路径段
|
|
6072
|
+
for (const segment of pathSegments.mowing) {
|
|
6073
|
+
// 转换 Point[] 为 number[][]
|
|
6074
|
+
const points = segment.points.map((point) => [point.x, point.y]);
|
|
6075
|
+
const element = PathDataBuilder.createMowingPath(points, {
|
|
6076
|
+
lineWidth: config.lineWidth,
|
|
6077
|
+
color: config.mowingLineColor,
|
|
6078
|
+
opacity: config.opacity,
|
|
6079
|
+
});
|
|
6080
|
+
element.originalData = points;
|
|
6081
|
+
elements.push(element);
|
|
3751
6082
|
}
|
|
3752
6083
|
// 处理传输路径段(只有在showTransPaths为true时才添加)
|
|
3753
|
-
|
|
3754
|
-
|
|
3755
|
-
|
|
3756
|
-
|
|
3757
|
-
|
|
3758
|
-
|
|
3759
|
-
|
|
3760
|
-
|
|
3761
|
-
|
|
3762
|
-
|
|
3763
|
-
elements.push(element);
|
|
3764
|
-
}
|
|
6084
|
+
for (const segment of pathSegments.trans) {
|
|
6085
|
+
// 转换 Point[] 为 number[][]
|
|
6086
|
+
const points = segment.points.map((point) => [point.x, point.y]);
|
|
6087
|
+
const element = PathDataBuilder.createTransPath(points, {
|
|
6088
|
+
lineWidth: config.lineWidth,
|
|
6089
|
+
color: config.transLineColor,
|
|
6090
|
+
opacity: config.opacity,
|
|
6091
|
+
});
|
|
6092
|
+
element.originalData = points;
|
|
6093
|
+
elements.push(element);
|
|
3765
6094
|
}
|
|
3766
6095
|
return elements;
|
|
3767
6096
|
}
|
|
@@ -3776,6 +6105,8 @@ class BoundaryLabelsManager {
|
|
|
3776
6105
|
this.container = null;
|
|
3777
6106
|
this.overlayDiv = null;
|
|
3778
6107
|
this.globalClickHandler = null;
|
|
6108
|
+
// 当前展开的边界id
|
|
6109
|
+
this.currentExpandedBoundaryId = null;
|
|
3779
6110
|
this.svgView = svgView;
|
|
3780
6111
|
this.boundaryData = boundaryData;
|
|
3781
6112
|
this.initializeContainer();
|
|
@@ -3874,7 +6205,7 @@ class BoundaryLabelsManager {
|
|
|
3874
6205
|
extendedContent.style.marginTop = '6px';
|
|
3875
6206
|
extendedContent.style.fontSize = '11px';
|
|
3876
6207
|
extendedContent.style.opacity = '0.9';
|
|
3877
|
-
extendedContent.style.display = 'none';
|
|
6208
|
+
extendedContent.style.display = this.currentExpandedBoundaryId === boundary.id ? 'block' : 'none';
|
|
3878
6209
|
extendedContent.style.borderTop = '1px solid rgba(255,255,255,0.2)';
|
|
3879
6210
|
extendedContent.style.paddingTop = '6px';
|
|
3880
6211
|
// 面积信息
|
|
@@ -3899,17 +6230,17 @@ class BoundaryLabelsManager {
|
|
|
3899
6230
|
labelDiv.addEventListener('click', (e) => {
|
|
3900
6231
|
e.stopPropagation();
|
|
3901
6232
|
this.elevateLabelZIndex();
|
|
3902
|
-
this.expandLabel(
|
|
3903
|
-
});
|
|
3904
|
-
// 添加悬停效果
|
|
3905
|
-
labelDiv.addEventListener('mouseenter', () => {
|
|
3906
|
-
labelDiv.style.backgroundColor = 'rgba(30, 30, 31, 0.6)';
|
|
3907
|
-
labelDiv.style.transform = 'translate(-50%, -50%) scale(1.05)';
|
|
3908
|
-
});
|
|
3909
|
-
labelDiv.addEventListener('mouseleave', () => {
|
|
3910
|
-
labelDiv.style.backgroundColor = 'rgba(30, 30, 31, 0.3)';
|
|
3911
|
-
labelDiv.style.transform = 'translate(-50%, -50%) scale(1)';
|
|
6233
|
+
this.expandLabel(boundary.id);
|
|
3912
6234
|
});
|
|
6235
|
+
// // 添加悬停效果
|
|
6236
|
+
// labelDiv.addEventListener('mouseenter', () => {
|
|
6237
|
+
// labelDiv.style.backgroundColor = 'rgba(30, 30, 31, 0.6)';
|
|
6238
|
+
// labelDiv.style.transform = 'translate(-50%, -50%) scale(1.05)';
|
|
6239
|
+
// });
|
|
6240
|
+
// labelDiv.addEventListener('mouseleave', () => {
|
|
6241
|
+
// labelDiv.style.backgroundColor = 'rgba(30, 30, 31, 0.3)';
|
|
6242
|
+
// labelDiv.style.transform = 'translate(-50%, -50%) scale(1)';
|
|
6243
|
+
// });
|
|
3913
6244
|
this.container.appendChild(labelDiv);
|
|
3914
6245
|
return labelDiv;
|
|
3915
6246
|
}
|
|
@@ -3934,25 +6265,30 @@ class BoundaryLabelsManager {
|
|
|
3934
6265
|
/**
|
|
3935
6266
|
* 展开标签
|
|
3936
6267
|
*/
|
|
3937
|
-
expandLabel(
|
|
6268
|
+
expandLabel(boundaryId) {
|
|
6269
|
+
const labelDiv = this.getLabelElement(boundaryId);
|
|
6270
|
+
if (!labelDiv)
|
|
6271
|
+
return;
|
|
3938
6272
|
const extendedContent = labelDiv.querySelector('.boundary-label-extended');
|
|
3939
6273
|
if (!extendedContent)
|
|
3940
6274
|
return;
|
|
3941
6275
|
// 关闭其他展开的标签
|
|
3942
|
-
this.collapseOtherLabels(
|
|
6276
|
+
this.collapseOtherLabels(boundaryId);
|
|
3943
6277
|
// 展开当前标签
|
|
3944
6278
|
extendedContent.style.display = 'block';
|
|
3945
6279
|
labelDiv.style.whiteSpace = 'normal';
|
|
6280
|
+
this.currentExpandedBoundaryId = boundaryId;
|
|
3946
6281
|
}
|
|
3947
6282
|
/**
|
|
3948
6283
|
* 关闭其他展开的标签
|
|
3949
6284
|
*/
|
|
3950
|
-
collapseOtherLabels(
|
|
6285
|
+
collapseOtherLabels(boundaryId) {
|
|
3951
6286
|
if (!this.container)
|
|
3952
6287
|
return;
|
|
3953
6288
|
const allLabels = this.container.querySelectorAll('.boundary-label');
|
|
3954
6289
|
allLabels.forEach(label => {
|
|
3955
|
-
|
|
6290
|
+
const labelBoundaryId = label.getAttribute('data-boundary-id');
|
|
6291
|
+
if (labelBoundaryId && labelBoundaryId !== boundaryId.toString()) {
|
|
3956
6292
|
const extendedContent = label.querySelector('.boundary-label-extended');
|
|
3957
6293
|
if (extendedContent) {
|
|
3958
6294
|
extendedContent.style.display = 'none';
|
|
@@ -3968,6 +6304,7 @@ class BoundaryLabelsManager {
|
|
|
3968
6304
|
this.boundaryData.forEach((boundary) => {
|
|
3969
6305
|
this.addElement(boundary);
|
|
3970
6306
|
});
|
|
6307
|
+
this.updatePositionsWithPrecomputedData();
|
|
3971
6308
|
}
|
|
3972
6309
|
/**
|
|
3973
6310
|
* 获取容器元素
|
|
@@ -3975,28 +6312,6 @@ class BoundaryLabelsManager {
|
|
|
3975
6312
|
getElement() {
|
|
3976
6313
|
return this.container;
|
|
3977
6314
|
}
|
|
3978
|
-
/**
|
|
3979
|
-
* 更新所有边界标签位置
|
|
3980
|
-
*/
|
|
3981
|
-
updatePositions() {
|
|
3982
|
-
if (!this.container || !this.overlayDiv)
|
|
3983
|
-
return;
|
|
3984
|
-
const labels = this.container.querySelectorAll('.boundary-label');
|
|
3985
|
-
labels.forEach((label, index) => {
|
|
3986
|
-
const boundary = this.boundaryData[index];
|
|
3987
|
-
if (!boundary)
|
|
3988
|
-
return;
|
|
3989
|
-
// 计算边界中心点
|
|
3990
|
-
const center = this.calculateBoundaryCenter(boundary);
|
|
3991
|
-
if (!center) {
|
|
3992
|
-
console.warn(`BoundaryLabelsManager: 无法计算边界 ${boundary.name} (ID: ${boundary.id}) 的中心点`);
|
|
3993
|
-
return;
|
|
3994
|
-
}
|
|
3995
|
-
// 设置标签位置
|
|
3996
|
-
label.style.left = `${center.x}px`;
|
|
3997
|
-
label.style.top = `${center.y}px`;
|
|
3998
|
-
});
|
|
3999
|
-
}
|
|
4000
6315
|
/**
|
|
4001
6316
|
* 使用预计算的数据更新边界标签位置(优化版本)
|
|
4002
6317
|
* @param divWidth 叠加层div的宽度
|
|
@@ -4004,8 +6319,11 @@ class BoundaryLabelsManager {
|
|
|
4004
6319
|
* @param viewBox SVG的viewBox信息
|
|
4005
6320
|
*/
|
|
4006
6321
|
updatePositionsWithPrecomputedData(divWidth, divHeight, viewBox) {
|
|
4007
|
-
if (!this.container)
|
|
6322
|
+
if (!this.container || !this.svgView)
|
|
4008
6323
|
return;
|
|
6324
|
+
const dw = parseFloat(this.svgView.getSVG().getAttribute('width')) || divWidth;
|
|
6325
|
+
const dh = parseFloat(this.svgView.getSVG().getAttribute('height')) || divHeight;
|
|
6326
|
+
const vb = this.svgView.getSVG().viewBox.baseVal || viewBox;
|
|
4009
6327
|
const labels = this.container.querySelectorAll('.boundary-label');
|
|
4010
6328
|
labels.forEach((label, index) => {
|
|
4011
6329
|
const boundary = this.boundaryData[index];
|
|
@@ -4018,7 +6336,7 @@ class BoundaryLabelsManager {
|
|
|
4018
6336
|
return;
|
|
4019
6337
|
}
|
|
4020
6338
|
// 直接使用预计算的数据进行坐标转换
|
|
4021
|
-
const center = this.convertMapCoordinateToPixelWithPrecomputedData(mapCenter.x, mapCenter.y,
|
|
6339
|
+
const center = this.convertMapCoordinateToPixelWithPrecomputedData(mapCenter.x, mapCenter.y, dw, dh, vb);
|
|
4022
6340
|
if (!center)
|
|
4023
6341
|
return;
|
|
4024
6342
|
// 设置标签位置
|
|
@@ -4215,6 +6533,7 @@ class BoundaryLabelsManager {
|
|
|
4215
6533
|
if (!this.container)
|
|
4216
6534
|
return;
|
|
4217
6535
|
const allLabels = this.container.querySelectorAll('.boundary-label');
|
|
6536
|
+
this.currentExpandedBoundaryId = null;
|
|
4218
6537
|
allLabels.forEach(label => {
|
|
4219
6538
|
const extendedContent = label.querySelector('.boundary-label-extended');
|
|
4220
6539
|
if (extendedContent) {
|
|
@@ -4269,8 +6588,7 @@ class BoundaryLabelsManager {
|
|
|
4269
6588
|
const allLabels = this.container.querySelectorAll('.boundary-label');
|
|
4270
6589
|
allLabels.forEach((label, index) => {
|
|
4271
6590
|
const labelElement = label;
|
|
4272
|
-
|
|
4273
|
-
console.log(`Label ${index} z-index: ${currentZIndex}`);
|
|
6591
|
+
labelElement.style.zIndex;
|
|
4274
6592
|
});
|
|
4275
6593
|
}
|
|
4276
6594
|
}
|
|
@@ -4967,31 +7285,6 @@ const EDIT_STYLES = {
|
|
|
4967
7285
|
const EDIT_BEHAVIOR = {
|
|
4968
7286
|
SUCCESS_MESSAGE_DURATION_MS: 3000,
|
|
4969
7287
|
};
|
|
4970
|
-
// 默认配置
|
|
4971
|
-
const DEFAULT_MAP_CONFIG = {
|
|
4972
|
-
showScale: true,
|
|
4973
|
-
fitToView: true,
|
|
4974
|
-
initialZoom: 1,
|
|
4975
|
-
enableDrag: true,
|
|
4976
|
-
width: 800,
|
|
4977
|
-
height: 600,
|
|
4978
|
-
backgroundColor: '#f5f5f5',
|
|
4979
|
-
borderRadius: '8px',
|
|
4980
|
-
border: '1px solid #ddd',
|
|
4981
|
-
useGoogleMaps: true,
|
|
4982
|
-
};
|
|
4983
|
-
const DEFAULT_PATH_CONFIG = {
|
|
4984
|
-
lineWidth: 20,
|
|
4985
|
-
showEdgePaths: true,
|
|
4986
|
-
showTransPaths: true,
|
|
4987
|
-
showMowingPaths: true,
|
|
4988
|
-
edgePathColor: 'rgba(194, 203, 212)',
|
|
4989
|
-
transPathColor: 'transparent',
|
|
4990
|
-
mowingPathColor: 'rgba(194, 203, 212)',
|
|
4991
|
-
edgePathOpacity: 1,
|
|
4992
|
-
transPathOpacity: 0.6,
|
|
4993
|
-
mowingPathOpacity: 1,
|
|
4994
|
-
};
|
|
4995
7288
|
|
|
4996
7289
|
class MowerPostionManager {
|
|
4997
7290
|
constructor(svgView, mowerPositonConfig, overlayDiv, onAnimationComplete) {
|
|
@@ -5299,7 +7592,7 @@ class MowerPostionManager {
|
|
|
5299
7592
|
|
|
5300
7593
|
// Google Maps 叠加层类 - 带编辑功能
|
|
5301
7594
|
class MowerMapOverlay {
|
|
5302
|
-
constructor(bounds, mapData, mowerPositonConfig, pathData, isEditMode = false, mapConfig = {},
|
|
7595
|
+
constructor(bounds, mapData, mowerPositonConfig, pathData, isEditMode = false, mapConfig = {}, antennaConfig = {}, onMapLoad, onPathLoad, dragCallbacks) {
|
|
5303
7596
|
this.div = null;
|
|
5304
7597
|
this.svgMapView = null;
|
|
5305
7598
|
this.offscreenContainer = null;
|
|
@@ -5341,7 +7634,6 @@ class MowerMapOverlay {
|
|
|
5341
7634
|
this.pathData = pathData;
|
|
5342
7635
|
this.isEditMode = isEditMode;
|
|
5343
7636
|
this.mapConfig = mapConfig;
|
|
5344
|
-
this.pathConfig = pathConfig;
|
|
5345
7637
|
this.antennaConfig = antennaConfig;
|
|
5346
7638
|
this.onMapLoad = onMapLoad;
|
|
5347
7639
|
this.onPathLoad = onPathLoad;
|
|
@@ -5525,12 +7817,6 @@ class MowerMapOverlay {
|
|
|
5525
7817
|
this.div.appendChild(container);
|
|
5526
7818
|
}
|
|
5527
7819
|
}
|
|
5528
|
-
// 更新边界标签位置
|
|
5529
|
-
updateBoundaryLabelsPosition() {
|
|
5530
|
-
if (this.boundaryLabelsManager) {
|
|
5531
|
-
this.boundaryLabelsManager.updatePositions();
|
|
5532
|
-
}
|
|
5533
|
-
}
|
|
5534
7820
|
// 使用优化版本更新边界标签位置
|
|
5535
7821
|
updateBoundaryLabelsPositionOptimized(width, height) {
|
|
5536
7822
|
if (!this.boundaryLabelsManager || !this.div)
|
|
@@ -6076,7 +8362,6 @@ class MowerMapOverlay {
|
|
|
6076
8362
|
try {
|
|
6077
8363
|
// 创建SvgMapView实例
|
|
6078
8364
|
this.svgMapView = new SvgMapView(this.offscreenContainer, 800, 600);
|
|
6079
|
-
this.svgMapView.setShowScale(this.mapConfig.showScale !== false);
|
|
6080
8365
|
// 加载地图数据
|
|
6081
8366
|
this.loadMapData();
|
|
6082
8367
|
// 加载路径数据
|
|
@@ -6103,7 +8388,7 @@ class MowerMapOverlay {
|
|
|
6103
8388
|
return;
|
|
6104
8389
|
try {
|
|
6105
8390
|
// 使用现有的MapDataProcessor处理地图数据
|
|
6106
|
-
const elements = MapDataProcessor.processMapData(this.mapData);
|
|
8391
|
+
const elements = MapDataProcessor.processMapData(this.mapData, this.mapConfig);
|
|
6107
8392
|
// 分离充电桩和天线元素,其他元素添加到SVG图层
|
|
6108
8393
|
// const svgElements = elements.filter(element =>
|
|
6109
8394
|
// element.type !== 'charging_pile' && element.type !== 'antenna'
|
|
@@ -6152,7 +8437,7 @@ class MowerMapOverlay {
|
|
|
6152
8437
|
loadPathData(pathData) {
|
|
6153
8438
|
try {
|
|
6154
8439
|
// 使用现有的PathDataProcessor处理路径数据
|
|
6155
|
-
const pathElements = PathDataProcessor.processPathData(pathData, this.
|
|
8440
|
+
const pathElements = PathDataProcessor.processPathData(pathData, this.mapConfig);
|
|
6156
8441
|
const pathLayer = new PathLayer();
|
|
6157
8442
|
pathLayer.addElements(pathElements);
|
|
6158
8443
|
// 添加图层到SvgMapView
|
|
@@ -6178,6 +8463,7 @@ class MowerMapOverlay {
|
|
|
6178
8463
|
if (!pathJson)
|
|
6179
8464
|
return;
|
|
6180
8465
|
const boundaryData = generateBoundaryData(this.mapData, pathJson);
|
|
8466
|
+
console.log('boundaryData==', boundaryData);
|
|
6181
8467
|
this.boundaryLabelsManager?.updateBoundaryData(boundaryData);
|
|
6182
8468
|
}
|
|
6183
8469
|
draw() {
|
|
@@ -6370,11 +8656,10 @@ const getValidGpsBounds = (mapData) => {
|
|
|
6370
8656
|
};
|
|
6371
8657
|
};
|
|
6372
8658
|
// 默认配置
|
|
6373
|
-
const defaultMapConfig =
|
|
6374
|
-
const defaultPathConfig = DEFAULT_PATH_CONFIG;
|
|
8659
|
+
const defaultMapConfig = DEFAULT_STYLES;
|
|
6375
8660
|
// 地图渲染器组件
|
|
6376
|
-
const MowerMapRenderer = React.forwardRef(({ mapRef, mapJson, pathJson, realTimeData,
|
|
6377
|
-
|
|
8661
|
+
const MowerMapRenderer = React.forwardRef(({ mapConfig, modelType, mapRef, mapJson, pathJson, realTimeData, currentPositionData, antennaConfig, onMapLoad, onPathLoad, onZoomChange, onError, className, style, googleMapInstance, isEditMode = false, dragCallbacks, }, ref) => {
|
|
8662
|
+
React.useRef(null);
|
|
6378
8663
|
const svgMapViewRef = React.useRef(null);
|
|
6379
8664
|
const [elementCount, setElementCount] = React.useState(0);
|
|
6380
8665
|
const [pathCount, setPathCount] = React.useState(0);
|
|
@@ -6404,25 +8689,21 @@ const MowerMapRenderer = React.forwardRef(({ mapRef, mapJson, pathJson, realTime
|
|
|
6404
8689
|
}, [mapJson]);
|
|
6405
8690
|
// 合并配置
|
|
6406
8691
|
const mergedMapConfig = React.useMemo(() => {
|
|
6407
|
-
|
|
6408
|
-
// return defaultMapConfig;
|
|
6409
|
-
// }
|
|
6410
|
-
return { ...defaultMapConfig, ...(mapConfig || {}) };
|
|
8692
|
+
return merge({}, defaultMapConfig, mapConfig);
|
|
6411
8693
|
}, [mapConfig]);
|
|
6412
|
-
const mergedPathConfig = React.useMemo(() => {
|
|
6413
|
-
return { ...defaultPathConfig, ...(pathConfig || {}) };
|
|
6414
|
-
}, [pathConfig]);
|
|
6415
8694
|
const mergedAntennaConfig = React.useMemo(() => antennaConfig, [antennaConfig]);
|
|
6416
8695
|
const mowerPositionData = React.useMemo(() => {
|
|
6417
8696
|
return {
|
|
6418
|
-
postureTheta:
|
|
6419
|
-
|
|
6420
|
-
|
|
6421
|
-
|
|
6422
|
-
|
|
8697
|
+
postureTheta: currentPositionData?.postureTheta
|
|
8698
|
+
? Number(currentPositionData.postureTheta)
|
|
8699
|
+
: 0,
|
|
8700
|
+
postureX: currentPositionData?.postureX ? Number(currentPositionData.postureX) : 0,
|
|
8701
|
+
postureY: currentPositionData?.postureY ? Number(currentPositionData.postureY) : 0,
|
|
8702
|
+
vehicleState: currentPositionData?.vehicleState || RobotStatus.STANDBY,
|
|
8703
|
+
vehicleModel: modelType,
|
|
6423
8704
|
};
|
|
6424
|
-
}, [
|
|
6425
|
-
console.log('mowerPositionData==', mowerPositionData);
|
|
8705
|
+
}, [currentPositionData, modelType]);
|
|
8706
|
+
console.log('mowerPositionData==', currentPositionData, mowerPositionData);
|
|
6426
8707
|
// 处理错误
|
|
6427
8708
|
const handleError = (error) => {
|
|
6428
8709
|
setCurrentError(error);
|
|
@@ -6430,7 +8711,7 @@ const MowerMapRenderer = React.forwardRef(({ mapRef, mapJson, pathJson, realTime
|
|
|
6430
8711
|
};
|
|
6431
8712
|
// 初始化Google Maps叠加层
|
|
6432
8713
|
const initializeGoogleMapsOverlay = async () => {
|
|
6433
|
-
if (!mapJson
|
|
8714
|
+
if (!mapJson)
|
|
6434
8715
|
return;
|
|
6435
8716
|
try {
|
|
6436
8717
|
// 等待Google Maps API加载
|
|
@@ -6470,7 +8751,7 @@ const MowerMapRenderer = React.forwardRef(({ mapRef, mapJson, pathJson, realTime
|
|
|
6470
8751
|
overlayRef.current = null;
|
|
6471
8752
|
}
|
|
6472
8753
|
// 创建叠加层
|
|
6473
|
-
const overlay = new MowerMapOverlay(googleBounds, mapJson, mowerPositionData, pathJson || {}, isEditMode, mergedMapConfig,
|
|
8754
|
+
const overlay = new MowerMapOverlay(googleBounds, mapJson, mowerPositionData, pathJson || {}, isEditMode, mergedMapConfig, mergedAntennaConfig, (count) => {
|
|
6474
8755
|
setElementCount(count);
|
|
6475
8756
|
onMapLoad?.(count);
|
|
6476
8757
|
}, (count) => {
|
|
@@ -6481,7 +8762,7 @@ const MowerMapRenderer = React.forwardRef(({ mapRef, mapJson, pathJson, realTime
|
|
|
6481
8762
|
overlay.setMap(mapInstance);
|
|
6482
8763
|
overlayRef.current = overlay;
|
|
6483
8764
|
// 只在首次初始化时自适应视图
|
|
6484
|
-
if (
|
|
8765
|
+
if (!hasInitializedBounds) {
|
|
6485
8766
|
mapInstance.fitBounds(googleBounds);
|
|
6486
8767
|
setHasInitializedBounds(true);
|
|
6487
8768
|
}
|
|
@@ -6491,87 +8772,26 @@ const MowerMapRenderer = React.forwardRef(({ mapRef, mapJson, pathJson, realTime
|
|
|
6491
8772
|
handleError(`初始化Google Maps叠加层失败: ${error instanceof Error ? error.message : String(error)}`);
|
|
6492
8773
|
}
|
|
6493
8774
|
};
|
|
6494
|
-
|
|
6495
|
-
|
|
6496
|
-
|
|
6497
|
-
|
|
6498
|
-
|
|
6499
|
-
|
|
6500
|
-
|
|
6501
|
-
|
|
6502
|
-
|
|
6503
|
-
|
|
6504
|
-
|
|
6505
|
-
|
|
6506
|
-
|
|
6507
|
-
|
|
6508
|
-
}
|
|
6509
|
-
// 初始缩放
|
|
6510
|
-
setZoom(mergedMapConfig.initialZoom || 1);
|
|
6511
|
-
svgView.setZoom(mergedMapConfig.initialZoom || 1);
|
|
6512
|
-
// 自适应视图
|
|
6513
|
-
if (mergedMapConfig.fitToView) {
|
|
6514
|
-
const bounds = calculateMapBounds(mapJson);
|
|
6515
|
-
if (bounds) {
|
|
6516
|
-
svgView.fitToView(bounds);
|
|
6517
|
-
}
|
|
6518
|
-
}
|
|
6519
|
-
}
|
|
6520
|
-
catch (error) {
|
|
6521
|
-
handleError(`初始化SVG视图失败: ${error instanceof Error ? error.message : String(error)}`);
|
|
6522
|
-
}
|
|
6523
|
-
};
|
|
6524
|
-
// 加载地图数据
|
|
6525
|
-
const loadMapData = (svgView) => {
|
|
6526
|
-
if (!mapJson)
|
|
6527
|
-
return;
|
|
6528
|
-
try {
|
|
6529
|
-
const elements = MapDataProcessor.processMapData(mapJson);
|
|
6530
|
-
const drawLayer = new DrawLayer();
|
|
6531
|
-
drawLayer.addElements(elements);
|
|
6532
|
-
// 处理天线数据
|
|
6533
|
-
if (mapJson.antennas && mapJson.antennas.length > 0) {
|
|
6534
|
-
const antennaElements = AntennaDataBuilder.fromAntennaData(mapJson.antennas);
|
|
6535
|
-
drawLayer.addElements(antennaElements);
|
|
6536
|
-
}
|
|
6537
|
-
const layers = drawLayer.getLayers();
|
|
6538
|
-
svgView.clear();
|
|
6539
|
-
layers.forEach((layer) => {
|
|
6540
|
-
svgView.addLayer(layer);
|
|
6541
|
-
});
|
|
6542
|
-
const count = elements.length;
|
|
6543
|
-
setElementCount(count);
|
|
6544
|
-
onMapLoad?.(count);
|
|
6545
|
-
}
|
|
6546
|
-
catch (error) {
|
|
6547
|
-
handleError(`加载地图数据失败: ${error instanceof Error ? error.message : String(error)}`);
|
|
6548
|
-
}
|
|
6549
|
-
};
|
|
6550
|
-
// 加载路径数据
|
|
6551
|
-
const loadPathData = (svgView) => {
|
|
6552
|
-
if (!pathJson)
|
|
6553
|
-
return;
|
|
6554
|
-
try {
|
|
6555
|
-
const pathElements = PathDataProcessor.processPathData(pathJson, mergedPathConfig);
|
|
6556
|
-
const pathLayer = new DrawLayer();
|
|
6557
|
-
pathLayer.addElements(pathElements);
|
|
6558
|
-
svgView.addLayer(pathLayer);
|
|
6559
|
-
const count = pathElements.length;
|
|
6560
|
-
setPathCount(count);
|
|
6561
|
-
onPathLoad?.(count);
|
|
6562
|
-
}
|
|
6563
|
-
catch (error) {
|
|
6564
|
-
handleError(`加载路径数据失败: ${error instanceof Error ? error.message : String(error)}`);
|
|
8775
|
+
const formatRealTimeData = async (realTimeData) => {
|
|
8776
|
+
// await sleep(1000);
|
|
8777
|
+
const newRealTimeData = handleRealTimeData({
|
|
8778
|
+
realTimeData,
|
|
8779
|
+
isMowing: currentProcessMowingStatusRef.current,
|
|
8780
|
+
pathData: pathJson,
|
|
8781
|
+
partitionBoundary,
|
|
8782
|
+
});
|
|
8783
|
+
console.log('newRealTimeData==', newRealTimeData);
|
|
8784
|
+
// currentProcessMowingStatusRef.current = newRealTimeData.isMowing;
|
|
8785
|
+
currentProcessMowingStatusRef.current = true;
|
|
8786
|
+
// 调用overlay的updatePathData方法,更新历史路径数据
|
|
8787
|
+
if (overlayRef.current) {
|
|
8788
|
+
overlayRef.current.updatePathData(newRealTimeData.pathData);
|
|
6565
8789
|
}
|
|
8790
|
+
overlayRef.current.updateBoundaryLabelInfo(newRealTimeData.pathData);
|
|
6566
8791
|
};
|
|
6567
8792
|
// 初始化效果
|
|
6568
8793
|
React.useEffect(() => {
|
|
6569
|
-
|
|
6570
|
-
initializeGoogleMapsOverlay();
|
|
6571
|
-
}
|
|
6572
|
-
else {
|
|
6573
|
-
initializeSvgView();
|
|
6574
|
-
}
|
|
8794
|
+
initializeGoogleMapsOverlay();
|
|
6575
8795
|
// 清理函数
|
|
6576
8796
|
return () => {
|
|
6577
8797
|
clearSubBoundaryBorder();
|
|
@@ -6585,7 +8805,7 @@ const MowerMapRenderer = React.forwardRef(({ mapRef, mapJson, pathJson, realTime
|
|
|
6585
8805
|
svgMapViewRef.current = null;
|
|
6586
8806
|
}
|
|
6587
8807
|
};
|
|
6588
|
-
}, [mapJson, pathJson, mergedMapConfig,
|
|
8808
|
+
}, [mapJson, pathJson, mergedMapConfig, mergedAntennaConfig]);
|
|
6589
8809
|
// 监听编辑模式变化
|
|
6590
8810
|
React.useEffect(() => {
|
|
6591
8811
|
if (overlayRef.current) {
|
|
@@ -6603,7 +8823,7 @@ const MowerMapRenderer = React.forwardRef(({ mapRef, mapJson, pathJson, realTime
|
|
|
6603
8823
|
return;
|
|
6604
8824
|
const elements = MapDataProcessor.processMapData(mapJson);
|
|
6605
8825
|
const chargingPiles = elements.find((element) => element.type === 'charging_pile');
|
|
6606
|
-
console.log('chargingPiles==', chargingPiles,
|
|
8826
|
+
console.log('chargingPiles==', chargingPiles, currentPositionData);
|
|
6607
8827
|
if (!mowerPositionData || !overlayRef.current)
|
|
6608
8828
|
return;
|
|
6609
8829
|
const inChargingPiles = [RobotStatus.CHARGING, RobotStatus.PARKED];
|
|
@@ -6634,7 +8854,7 @@ const MowerMapRenderer = React.forwardRef(({ mapRef, mapJson, pathJson, realTime
|
|
|
6634
8854
|
overlayRef.current.updatePosition(mowerPositionData, isStandyBy ? 0 : 2200);
|
|
6635
8855
|
}
|
|
6636
8856
|
}
|
|
6637
|
-
}, [
|
|
8857
|
+
}, [currentPositionData]);
|
|
6638
8858
|
React.useEffect(() => {
|
|
6639
8859
|
if (!mapJson ||
|
|
6640
8860
|
!pathJson ||
|
|
@@ -6645,19 +8865,7 @@ const MowerMapRenderer = React.forwardRef(({ mapRef, mapJson, pathJson, realTime
|
|
|
6645
8865
|
// 根据后端推送的实时数据,进行不同处理
|
|
6646
8866
|
// TODO:需要根据返回的数据,处理车辆的移动位置
|
|
6647
8867
|
// 这里是根据返回的数据,处理实时轨迹
|
|
6648
|
-
|
|
6649
|
-
realTimeData,
|
|
6650
|
-
isMowing: currentProcessMowingStatusRef.current,
|
|
6651
|
-
pathData: pathJson,
|
|
6652
|
-
partitionBoundary,
|
|
6653
|
-
});
|
|
6654
|
-
console.log('newRealTimeData==', newRealTimeData);
|
|
6655
|
-
// currentProcessMowingStatusRef.current = newRealTimeData.isMowing;
|
|
6656
|
-
currentProcessMowingStatusRef.current = true;
|
|
6657
|
-
// 调用overlay的updatePathData方法,更新历史路径数据
|
|
6658
|
-
if (overlayRef.current) {
|
|
6659
|
-
overlayRef.current.updatePathData(newRealTimeData.pathData);
|
|
6660
|
-
}
|
|
8868
|
+
formatRealTimeData(realTimeData);
|
|
6661
8869
|
}, [realTimeData, mapJson, pathJson]);
|
|
6662
8870
|
// 提供ref方法
|
|
6663
8871
|
React.useImperativeHandle(ref, () => ({
|
|
@@ -6726,21 +8934,8 @@ const MowerMapRenderer = React.forwardRef(({ mapRef, mapJson, pathJson, realTime
|
|
|
6726
8934
|
if (currentError) {
|
|
6727
8935
|
return (jsxRuntime.jsx("div", { className: className, style: style, children: jsxRuntime.jsxs("div", { style: { color: 'red', padding: '10px' }, children: ["\u9519\u8BEF: ", currentError] }) }));
|
|
6728
8936
|
}
|
|
6729
|
-
//
|
|
6730
|
-
|
|
6731
|
-
return null;
|
|
6732
|
-
}
|
|
6733
|
-
// 渲染普通SVG容器
|
|
6734
|
-
return (jsxRuntime.jsx("div", { ref: containerRef, className: className, style: {
|
|
6735
|
-
width: mergedMapConfig.width || 800,
|
|
6736
|
-
height: mergedMapConfig.height || 600,
|
|
6737
|
-
backgroundColor: mergedMapConfig.backgroundColor || '#f5f5f5',
|
|
6738
|
-
borderRadius: mergedMapConfig.borderRadius || '8px',
|
|
6739
|
-
border: mergedMapConfig.border || '1px solid #ddd',
|
|
6740
|
-
position: 'relative',
|
|
6741
|
-
overflow: 'hidden',
|
|
6742
|
-
...style,
|
|
6743
|
-
} }));
|
|
8937
|
+
// 使用goole maps自定义叠加层,不需要实际返回组件内容
|
|
8938
|
+
return null;
|
|
6744
8939
|
});
|
|
6745
8940
|
MowerMapRenderer.displayName = 'MowerMapRenderer';
|
|
6746
8941
|
|