microboard-temp 0.5.75 → 0.5.77
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/cjs/browser.js +116 -99
- package/dist/cjs/index.js +116 -99
- package/dist/cjs/node.js +116 -99
- package/dist/esm/browser.js +116 -99
- package/dist/esm/index.js +116 -99
- package/dist/esm/node.js +116 -99
- package/dist/types/Settings.d.ts +1 -0
- package/package.json +1 -1
package/dist/esm/index.js
CHANGED
|
@@ -6902,7 +6902,8 @@ var conf = {
|
|
|
6902
6902
|
DECK_VERTICAL_OFFSET: 2,
|
|
6903
6903
|
CARD_DIMENSIONS: { width: 250, height: 400 },
|
|
6904
6904
|
DEFAULT_GAME_ITEM_DIMENSIONS: { width: 200, height: 200 },
|
|
6905
|
-
MAX_CARD_SIZE: 500
|
|
6905
|
+
MAX_CARD_SIZE: 500,
|
|
6906
|
+
CONNECTOR_ITEM_OFFSET: 20
|
|
6906
6907
|
};
|
|
6907
6908
|
initDefaultI18N();
|
|
6908
6909
|
|
|
@@ -36507,7 +36508,6 @@ function radiansBetweenPoints(point1, point22) {
|
|
|
36507
36508
|
}
|
|
36508
36509
|
|
|
36509
36510
|
// src/Items/Connector/getLine/findOrthogonalPath.ts
|
|
36510
|
-
var ITEM_OFFSET = 1;
|
|
36511
36511
|
function getDirection(from, to) {
|
|
36512
36512
|
if (!to) {
|
|
36513
36513
|
return null;
|
|
@@ -36548,9 +36548,9 @@ function getNeighbors(node2, grid, obstacles) {
|
|
|
36548
36548
|
{ x: node2.xGrid, y: node2.yGrid + 1 }
|
|
36549
36549
|
];
|
|
36550
36550
|
for (const pos of potentialNeighbors) {
|
|
36551
|
-
if (pos.x >= 0 && pos.x < grid.length && pos.y >= 0) {
|
|
36551
|
+
if (pos.x >= 0 && pos.x < grid.length && pos.y >= 0 && grid[pos.x] && grid[pos.x][pos.y]) {
|
|
36552
36552
|
const newPoint = grid[pos.x][pos.y];
|
|
36553
|
-
if (newPoint && !obstacles.some((obstacle) => obstacle.isAlmostInside(newPoint,
|
|
36553
|
+
if (newPoint && !obstacles.some((obstacle) => obstacle.isAlmostInside(newPoint, conf.CONNECTOR_ITEM_OFFSET - 1))) {
|
|
36554
36554
|
neighbors.push({
|
|
36555
36555
|
point: newPoint,
|
|
36556
36556
|
costSoFar: 0,
|
|
@@ -36578,16 +36578,20 @@ function findCenterLine(grid, start, end, middle) {
|
|
|
36578
36578
|
}
|
|
36579
36579
|
if (width > height) {
|
|
36580
36580
|
const centerIdx = grid.findIndex((row2) => row2[0].x === middlePoint.x || Math.abs(row2[0].x - middlePoint.x) < 0.01);
|
|
36581
|
-
|
|
36582
|
-
|
|
36583
|
-
|
|
36581
|
+
if (centerIdx !== -1) {
|
|
36582
|
+
for (let y = 0;y < grid[0].length; y++) {
|
|
36583
|
+
if (grid[centerIdx][y] && grid[centerIdx][y].x >= min2.x - 0.01 && grid[centerIdx][y].x <= max2.x + 0.01 && grid[centerIdx][y].y >= min2.y - 0.01 && grid[centerIdx][y].y <= max2.y + 0.01) {
|
|
36584
|
+
centerLine.push(grid[centerIdx][y]);
|
|
36585
|
+
}
|
|
36584
36586
|
}
|
|
36585
36587
|
}
|
|
36586
36588
|
} else {
|
|
36587
36589
|
const centerIdx = grid[0].findIndex((point5) => point5.y === middlePoint.y || Math.abs(point5.y - middlePoint.y) < 0.01);
|
|
36588
|
-
|
|
36589
|
-
|
|
36590
|
-
|
|
36590
|
+
if (centerIdx !== -1) {
|
|
36591
|
+
for (let x = 0;x < grid.length; x++) {
|
|
36592
|
+
if (grid[x][centerIdx] && grid[x][centerIdx].x >= min2.x - 0.01 && grid[x][centerIdx].x <= max2.x + 0.01 && grid[x][centerIdx].y >= min2.y - 0.01 && grid[x][centerIdx].y <= max2.y + 0.01) {
|
|
36593
|
+
centerLine.push(grid[x][centerIdx]);
|
|
36594
|
+
}
|
|
36591
36595
|
}
|
|
36592
36596
|
}
|
|
36593
36597
|
}
|
|
@@ -36598,69 +36602,24 @@ function createGrid(start, end, toVisitPoints = []) {
|
|
|
36598
36602
|
const endDir = getPointerDirection(end);
|
|
36599
36603
|
const revertMapDir = { top: 0, bottom: 1, right: 2, left: 3 };
|
|
36600
36604
|
const offsetMap = {
|
|
36601
|
-
top: { x: 0, y: -
|
|
36602
|
-
bottom: { x: 0, y:
|
|
36603
|
-
right: { x:
|
|
36604
|
-
left: { x: -
|
|
36605
|
+
top: { x: 0, y: -conf.CONNECTOR_ITEM_OFFSET },
|
|
36606
|
+
bottom: { x: 0, y: conf.CONNECTOR_ITEM_OFFSET },
|
|
36607
|
+
right: { x: conf.CONNECTOR_ITEM_OFFSET, y: 0 },
|
|
36608
|
+
left: { x: -conf.CONNECTOR_ITEM_OFFSET, y: 0 }
|
|
36605
36609
|
};
|
|
36606
36610
|
const horizontalLines = [];
|
|
36607
36611
|
const verticalLines = [];
|
|
36608
|
-
if (start.pointType !== "Board") {
|
|
36609
|
-
const itemMbr = start.item.getMbr();
|
|
36610
|
-
verticalLines.push(itemMbr.left - ITEM_OFFSET, itemMbr.left, itemMbr.right, itemMbr.right + ITEM_OFFSET);
|
|
36611
|
-
horizontalLines.push(itemMbr.top - ITEM_OFFSET, itemMbr.top, itemMbr.bottom, itemMbr.bottom + ITEM_OFFSET);
|
|
36612
|
-
}
|
|
36613
|
-
if (end.pointType !== "Board") {
|
|
36614
|
-
const itemMbr = end.item.getMbr();
|
|
36615
|
-
verticalLines.push(itemMbr.left - ITEM_OFFSET, itemMbr.left, itemMbr.right, itemMbr.right + ITEM_OFFSET);
|
|
36616
|
-
horizontalLines.push(itemMbr.top - ITEM_OFFSET, itemMbr.top, itemMbr.bottom, itemMbr.bottom + ITEM_OFFSET);
|
|
36617
|
-
}
|
|
36618
|
-
const tempStart = start;
|
|
36619
|
-
const tempEnd = end;
|
|
36620
|
-
const middle = new Point((tempStart.x + tempEnd.x) / 2, (tempStart.y + tempEnd.y) / 2);
|
|
36621
|
-
horizontalLines.push(middle.y, tempStart.y, tempEnd.y);
|
|
36622
|
-
verticalLines.push(middle.x, tempStart.x, tempEnd.x);
|
|
36623
|
-
toVisitPoints.forEach((p3) => {
|
|
36624
|
-
horizontalLines.push(p3.y);
|
|
36625
|
-
verticalLines.push(p3.x);
|
|
36626
|
-
});
|
|
36627
|
-
const uniqueHorizontalLines = Array.from(new Set(horizontalLines)).sort((a2, b) => a2 - b);
|
|
36628
|
-
const uniqueVerticalLines = Array.from(new Set(verticalLines)).sort((a2, b) => a2 - b);
|
|
36629
36612
|
let newStart;
|
|
36630
36613
|
let newEnd;
|
|
36631
36614
|
const processPoint = (point5, dir2) => {
|
|
36632
36615
|
const itemMbr = point5.item.getMbr();
|
|
36633
|
-
const
|
|
36616
|
+
const mbrFloored = new Mbr(Math.floor(itemMbr.left), Math.floor(itemMbr.top), Math.floor(itemMbr.right), Math.floor(itemMbr.bottom));
|
|
36617
|
+
const pointOnMbr = mbrFloored.getLines()[revertMapDir[dir2]].getNearestPointOnLineSegment(point5);
|
|
36634
36618
|
const newPoint = Object.create(Object.getPrototypeOf(point5), Object.getOwnPropertyDescriptors(point5));
|
|
36635
|
-
|
|
36636
|
-
|
|
36637
|
-
|
|
36638
|
-
|
|
36639
|
-
newPoint.y = uniqueHorizontalLines[nextYIndex];
|
|
36640
|
-
newPoint.x = pointOnMbr.x;
|
|
36641
|
-
}
|
|
36642
|
-
} else if (dir2 === "bottom") {
|
|
36643
|
-
const currentYIndex = uniqueHorizontalLines.findIndex((y) => Math.abs(y - pointOnMbr.y) < 0.01);
|
|
36644
|
-
const nextYIndex = currentYIndex + 1;
|
|
36645
|
-
if (nextYIndex < uniqueHorizontalLines.length) {
|
|
36646
|
-
newPoint.y = uniqueHorizontalLines[nextYIndex];
|
|
36647
|
-
newPoint.x = pointOnMbr.x;
|
|
36648
|
-
}
|
|
36649
|
-
} else if (dir2 === "left") {
|
|
36650
|
-
const currentXIndex = uniqueVerticalLines.findIndex((x) => Math.abs(x - pointOnMbr.x) < 0.01);
|
|
36651
|
-
const nextXIndex = currentXIndex - 1;
|
|
36652
|
-
if (nextXIndex >= 0) {
|
|
36653
|
-
newPoint.x = uniqueVerticalLines[nextXIndex];
|
|
36654
|
-
newPoint.y = pointOnMbr.y;
|
|
36655
|
-
}
|
|
36656
|
-
} else if (dir2 === "right") {
|
|
36657
|
-
const currentXIndex = uniqueVerticalLines.findIndex((x) => Math.abs(x - pointOnMbr.x) < 0.01);
|
|
36658
|
-
const nextXIndex = currentXIndex + 1;
|
|
36659
|
-
if (nextXIndex < uniqueVerticalLines.length) {
|
|
36660
|
-
newPoint.x = uniqueVerticalLines[nextXIndex];
|
|
36661
|
-
newPoint.y = pointOnMbr.y;
|
|
36662
|
-
}
|
|
36663
|
-
}
|
|
36619
|
+
newPoint.x = pointOnMbr.x + offsetMap[dir2].x;
|
|
36620
|
+
newPoint.y = pointOnMbr.y + offsetMap[dir2].y;
|
|
36621
|
+
verticalLines.push(mbrFloored.left - conf.CONNECTOR_ITEM_OFFSET, mbrFloored.left, pointOnMbr.x, mbrFloored.right, mbrFloored.right + conf.CONNECTOR_ITEM_OFFSET);
|
|
36622
|
+
horizontalLines.push(mbrFloored.top - conf.CONNECTOR_ITEM_OFFSET, mbrFloored.top, pointOnMbr.y, mbrFloored.bottom, mbrFloored.bottom + conf.CONNECTOR_ITEM_OFFSET);
|
|
36664
36623
|
return newPoint;
|
|
36665
36624
|
};
|
|
36666
36625
|
if (start.pointType !== "Board" && startDir) {
|
|
@@ -36669,6 +36628,17 @@ function createGrid(start, end, toVisitPoints = []) {
|
|
|
36669
36628
|
if (end.pointType !== "Board" && endDir) {
|
|
36670
36629
|
newEnd = processPoint(end, endDir);
|
|
36671
36630
|
}
|
|
36631
|
+
const finalStart = newStart || start;
|
|
36632
|
+
const finalEnd = newEnd || end;
|
|
36633
|
+
const middle = new Point((finalStart.x + finalEnd.x) / 2, (finalStart.y + finalEnd.y) / 2);
|
|
36634
|
+
horizontalLines.push(middle.y, finalStart.y, finalEnd.y);
|
|
36635
|
+
verticalLines.push(middle.x, finalStart.x, finalEnd.x);
|
|
36636
|
+
toVisitPoints.forEach((p3) => {
|
|
36637
|
+
horizontalLines.push(p3.y);
|
|
36638
|
+
verticalLines.push(p3.x);
|
|
36639
|
+
});
|
|
36640
|
+
const uniqueHorizontalLines = Array.from(new Set(horizontalLines)).sort((a2, b) => a2 - b);
|
|
36641
|
+
const uniqueVerticalLines = Array.from(new Set(verticalLines)).sort((a2, b) => a2 - b);
|
|
36672
36642
|
const grid = uniqueVerticalLines.map((x) => uniqueHorizontalLines.map((y) => new Point(x, y)));
|
|
36673
36643
|
return {
|
|
36674
36644
|
grid,
|
|
@@ -36677,18 +36647,27 @@ function createGrid(start, end, toVisitPoints = []) {
|
|
|
36677
36647
|
middlePoint: middle
|
|
36678
36648
|
};
|
|
36679
36649
|
}
|
|
36680
|
-
function findPath(start, end, grid, obstacles, newStart, newEnd) {
|
|
36681
|
-
const
|
|
36682
|
-
|
|
36683
|
-
|
|
36684
|
-
|
|
36650
|
+
function findPath(start, end, grid, obstacles, existingPath, newStart, newEnd) {
|
|
36651
|
+
const startRowIndex = grid.findIndex((row2) => row2.some((point5) => point5.barelyEqual(start)));
|
|
36652
|
+
if (startRowIndex === -1) {
|
|
36653
|
+
throw new Error("Start point not found in the grid row");
|
|
36654
|
+
}
|
|
36655
|
+
const startPointIndex = grid[startRowIndex].findIndex((point5) => point5.barelyEqual(start));
|
|
36656
|
+
if (startPointIndex === -1) {
|
|
36657
|
+
throw new Error("Start point not found in the grid column");
|
|
36658
|
+
}
|
|
36659
|
+
const endRowIndex = grid.findIndex((row2) => row2.some((point5) => point5.barelyEqual(end)));
|
|
36660
|
+
if (endRowIndex === -1) {
|
|
36661
|
+
throw new Error("End point not found in the grid row");
|
|
36662
|
+
}
|
|
36663
|
+
const endPointIndex = grid[endRowIndex].findIndex((point5) => point5.barelyEqual(end));
|
|
36664
|
+
if (endPointIndex === -1) {
|
|
36665
|
+
throw new Error("End point not found in the grid column");
|
|
36685
36666
|
}
|
|
36686
|
-
const startPointIdx = grid[startIdx].findIndex((point5) => point5.barelyEqual(start));
|
|
36687
|
-
const endPointIdx = grid[endIdx].findIndex((point5) => point5.barelyEqual(end));
|
|
36688
36667
|
const endNode = {
|
|
36689
36668
|
point: end,
|
|
36690
|
-
xGrid:
|
|
36691
|
-
yGrid:
|
|
36669
|
+
xGrid: endRowIndex,
|
|
36670
|
+
yGrid: endPointIndex,
|
|
36692
36671
|
costSoFar: 0,
|
|
36693
36672
|
heuristic: 0,
|
|
36694
36673
|
toFinish: 0
|
|
@@ -36696,53 +36675,72 @@ function findPath(start, end, grid, obstacles, newStart, newEnd) {
|
|
|
36696
36675
|
const startNode = {
|
|
36697
36676
|
point: start,
|
|
36698
36677
|
costSoFar: 0,
|
|
36699
|
-
heuristic: heuristic({ point: start, xGrid:
|
|
36700
|
-
toFinish: heuristic({ point: start, xGrid:
|
|
36701
|
-
xGrid:
|
|
36702
|
-
yGrid:
|
|
36678
|
+
heuristic: heuristic({ point: start, xGrid: startRowIndex, yGrid: startPointIndex }, endNode),
|
|
36679
|
+
toFinish: heuristic({ point: start, xGrid: startRowIndex, yGrid: startPointIndex }, endNode),
|
|
36680
|
+
xGrid: startRowIndex,
|
|
36681
|
+
yGrid: startPointIndex
|
|
36703
36682
|
};
|
|
36704
36683
|
const openSet = [startNode];
|
|
36705
36684
|
const closedSet = new Set;
|
|
36706
36685
|
while (openSet.length > 0) {
|
|
36707
36686
|
openSet.sort((aa, bb) => aa.toFinish - bb.toFinish);
|
|
36708
36687
|
const current = openSet.shift();
|
|
36688
|
+
const currentKey = `${current.point.x},${current.point.y}`;
|
|
36709
36689
|
if (current.point.barelyEqual(end)) {
|
|
36710
36690
|
const path2 = reconstructPath(current);
|
|
36711
36691
|
return path2;
|
|
36712
36692
|
}
|
|
36713
|
-
closedSet.add(
|
|
36693
|
+
closedSet.add(currentKey);
|
|
36714
36694
|
const neighbors = getNeighbors(current, grid, obstacles);
|
|
36715
36695
|
for (const neighbor of neighbors) {
|
|
36716
|
-
|
|
36696
|
+
const neighborKey = `${neighbor.point.x},${neighbor.point.y}`;
|
|
36697
|
+
if (closedSet.has(neighborKey) || existingPath.has(neighborKey) && !neighbor.point.barelyEqual(end)) {
|
|
36717
36698
|
continue;
|
|
36718
36699
|
}
|
|
36719
36700
|
const extraCost = isChangingDirection(current, neighbor, newStart, newEnd);
|
|
36720
|
-
const
|
|
36721
|
-
|
|
36722
|
-
|
|
36723
|
-
|
|
36724
|
-
|
|
36725
|
-
|
|
36701
|
+
const pathOverlapCost = existingPath.has(neighborKey) ? 1000 : 0;
|
|
36702
|
+
const tentativeCost = current.costSoFar + 1 + pathOverlapCost;
|
|
36703
|
+
let existingNodeInOpenSet = openSet.find((node2) => node2.point.barelyEqual(neighbor.point));
|
|
36704
|
+
if (!existingNodeInOpenSet || tentativeCost < existingNodeInOpenSet.costSoFar) {
|
|
36705
|
+
if (existingNodeInOpenSet) {
|
|
36706
|
+
existingNodeInOpenSet.costSoFar = tentativeCost + extraCost;
|
|
36707
|
+
existingNodeInOpenSet.heuristic = heuristic(neighbor, endNode);
|
|
36708
|
+
existingNodeInOpenSet.toFinish = existingNodeInOpenSet.costSoFar + existingNodeInOpenSet.heuristic;
|
|
36709
|
+
existingNodeInOpenSet.parent = current;
|
|
36710
|
+
} else {
|
|
36711
|
+
neighbor.costSoFar = tentativeCost + extraCost;
|
|
36712
|
+
neighbor.heuristic = heuristic(neighbor, endNode);
|
|
36713
|
+
neighbor.toFinish = neighbor.costSoFar + neighbor.heuristic;
|
|
36714
|
+
openSet.push(neighbor);
|
|
36715
|
+
}
|
|
36726
36716
|
}
|
|
36727
36717
|
}
|
|
36728
36718
|
}
|
|
36729
36719
|
return;
|
|
36730
36720
|
}
|
|
36731
36721
|
function findPathPoints(points, grid, obstacles, newStart, newEnd) {
|
|
36732
|
-
const
|
|
36722
|
+
const finalPath = [];
|
|
36723
|
+
const existingPathSegments = new Set;
|
|
36724
|
+
if (points.length > 0) {
|
|
36725
|
+
finalPath.push(points[0]);
|
|
36726
|
+
const startKey = `${points[0].x},${points[0].y}`;
|
|
36727
|
+
existingPathSegments.add(startKey);
|
|
36728
|
+
}
|
|
36733
36729
|
for (let i = 0;i < points.length - 1; i += 1) {
|
|
36734
|
-
const segmentPath = findPath(points[i], points[i + 1], grid, obstacles, newStart, newEnd);
|
|
36735
|
-
if (segmentPath) {
|
|
36736
|
-
|
|
36730
|
+
const segmentPath = findPath(points[i], points[i + 1], grid, obstacles, existingPathSegments, newStart, newEnd);
|
|
36731
|
+
if (segmentPath && segmentPath.length > 0) {
|
|
36732
|
+
for (let j = 1;j < segmentPath.length; j++) {
|
|
36733
|
+
const point5 = segmentPath[j];
|
|
36734
|
+
const key = `${point5.x},${point5.y}`;
|
|
36735
|
+
finalPath.push(point5);
|
|
36736
|
+
existingPathSegments.add(key);
|
|
36737
|
+
}
|
|
36737
36738
|
} else {
|
|
36738
36739
|
points.splice(i + 1, 1);
|
|
36739
36740
|
i--;
|
|
36740
36741
|
}
|
|
36741
36742
|
}
|
|
36742
|
-
|
|
36743
|
-
pathPoints.push(points[points.length - 1]);
|
|
36744
|
-
}
|
|
36745
|
-
return pathPoints;
|
|
36743
|
+
return finalPath;
|
|
36746
36744
|
}
|
|
36747
36745
|
function reducePoints(points) {
|
|
36748
36746
|
const uniquePoints = new Map;
|
|
@@ -36753,6 +36751,12 @@ function reducePoints(points) {
|
|
|
36753
36751
|
if (uniquePoints.has(key)) {
|
|
36754
36752
|
const loopStartIndex = uniquePoints.get(key);
|
|
36755
36753
|
result.splice(loopStartIndex + 1);
|
|
36754
|
+
const removedPoints = points.slice(loopStartIndex + 1, i + 1);
|
|
36755
|
+
removedPoints.forEach((p3) => {
|
|
36756
|
+
uniquePoints.delete(`${p3.x},${p3.y}`);
|
|
36757
|
+
});
|
|
36758
|
+
uniquePoints.set(key, result.length);
|
|
36759
|
+
result.push(point5);
|
|
36756
36760
|
} else {
|
|
36757
36761
|
uniquePoints.set(key, result.length);
|
|
36758
36762
|
result.push(point5);
|
|
@@ -36762,19 +36766,32 @@ function reducePoints(points) {
|
|
|
36762
36766
|
}
|
|
36763
36767
|
function getLines(pathPoints) {
|
|
36764
36768
|
const lines = [];
|
|
36769
|
+
if (pathPoints.length < 2) {
|
|
36770
|
+
return [];
|
|
36771
|
+
}
|
|
36765
36772
|
const reducedPoints = reducePoints(pathPoints);
|
|
36773
|
+
if (reducedPoints.length < 2) {
|
|
36774
|
+
return [];
|
|
36775
|
+
}
|
|
36766
36776
|
let startPoint = reducedPoints[0];
|
|
36767
|
-
for (let i = 1;i < reducedPoints.length
|
|
36777
|
+
for (let i = 1;i < reducedPoints.length; i += 1) {
|
|
36768
36778
|
const prevPoint = reducedPoints[i - 1];
|
|
36769
36779
|
const currPoint = reducedPoints[i];
|
|
36770
|
-
const nextPoint = reducedPoints[i + 1];
|
|
36771
|
-
if (prevPoint.x !== nextPoint.x && prevPoint.y !== nextPoint.y) {
|
|
36780
|
+
const nextPoint = i + 1 < reducedPoints.length ? reducedPoints[i + 1] : null;
|
|
36781
|
+
if (!nextPoint || prevPoint.x !== nextPoint.x && prevPoint.y !== nextPoint.y) {
|
|
36772
36782
|
lines.push(new Line(startPoint, currPoint));
|
|
36773
36783
|
startPoint = currPoint;
|
|
36774
36784
|
}
|
|
36775
36785
|
}
|
|
36776
|
-
if (lines.length >
|
|
36777
|
-
lines.push(new Line(
|
|
36786
|
+
if (lines.length === 0 && reducedPoints.length > 1) {
|
|
36787
|
+
lines.push(new Line(reducedPoints[0], reducedPoints[reducedPoints.length - 1]));
|
|
36788
|
+
} else if (lines.length > 0) {
|
|
36789
|
+
const lastLine = lines[lines.length - 1];
|
|
36790
|
+
const lastPointInLines = lastLine.getEndPoint();
|
|
36791
|
+
const lastPointInReduced = reducedPoints[reducedPoints.length - 1];
|
|
36792
|
+
if (!lastPointInLines.barelyEqual(lastPointInReduced)) {
|
|
36793
|
+
lines.push(new Line(lastPointInLines, lastPointInReduced));
|
|
36794
|
+
}
|
|
36778
36795
|
}
|
|
36779
36796
|
return lines;
|
|
36780
36797
|
}
|