mapshaper 0.6.78 → 0.6.80
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/mapshaper.js +8 -5
- package/package.json +1 -1
- package/www/mapshaper-gui.js +285 -96
- package/www/mapshaper.js +8 -5
- package/www/page.css +6 -8
package/mapshaper.js
CHANGED
|
@@ -1612,6 +1612,7 @@
|
|
|
1612
1612
|
this.ymin -= halfHeight * ky;
|
|
1613
1613
|
this.xmax += halfWidth * kx;
|
|
1614
1614
|
this.ymax += halfHeight * ky;
|
|
1615
|
+
return this;
|
|
1615
1616
|
};
|
|
1616
1617
|
|
|
1617
1618
|
// Return a bounding box with the same extent as this one.
|
|
@@ -5003,7 +5004,7 @@
|
|
|
5003
5004
|
if (isLatLngCRS(P)) {
|
|
5004
5005
|
return xy.concat();
|
|
5005
5006
|
}
|
|
5006
|
-
proj =
|
|
5007
|
+
proj = getProjTransform2(P, parseCrsString('wgs84'));
|
|
5007
5008
|
return proj(xy[0], xy[1]);
|
|
5008
5009
|
}
|
|
5009
5010
|
|
|
@@ -26664,7 +26665,7 @@ ${svg}
|
|
|
26664
26665
|
codepage = lookupCodePage(ldid),
|
|
26665
26666
|
samples = getNonAsciiSamples(),
|
|
26666
26667
|
only7bit = samples.length === 0,
|
|
26667
|
-
encoding
|
|
26668
|
+
encoding;
|
|
26668
26669
|
|
|
26669
26670
|
// First, check the ldid (language driver id) (an obsolete way to specify which
|
|
26670
26671
|
// codepage to use for text encoding.)
|
|
@@ -26684,10 +26685,12 @@ ${svg}
|
|
|
26684
26685
|
// As a last resort, try to guess the encoding:
|
|
26685
26686
|
if (!encoding) {
|
|
26686
26687
|
var info = detectEncoding(samples);
|
|
26688
|
+
var msg;
|
|
26687
26689
|
encoding = info.encoding;
|
|
26688
26690
|
if (info.confidence < 2) {
|
|
26689
|
-
msg = 'Warning: Unable to auto-detect the DBF file text encoding
|
|
26690
|
-
|
|
26691
|
+
msg = 'Warning: Unable to auto-detect the DBF file text encoding' +
|
|
26692
|
+
(info.confidence == 1 ? ' with high confidence' : '') + '.';
|
|
26693
|
+
msg += ' Defaulting to ' + encoding + (encoding in encodingNames ? ' (' + encodingNames[encoding] + ').' : '.');
|
|
26691
26694
|
msg += '\n\nSample of how non-ascii text was imported:\n';
|
|
26692
26695
|
if (runningInBrowser()) {
|
|
26693
26696
|
msg += '<pre>' + formatStringsAsGrid(decodeSamples(encoding, samples), 50) + '</pre>';
|
|
@@ -45532,7 +45535,7 @@ ${svg}
|
|
|
45532
45535
|
});
|
|
45533
45536
|
}
|
|
45534
45537
|
|
|
45535
|
-
var version = "0.6.
|
|
45538
|
+
var version = "0.6.80";
|
|
45536
45539
|
|
|
45537
45540
|
// Parse command line args into commands and run them
|
|
45538
45541
|
// Function takes an optional Node-style callback. A Promise is returned if no callback is given.
|
package/package.json
CHANGED
package/www/mapshaper-gui.js
CHANGED
|
@@ -2544,6 +2544,20 @@
|
|
|
2544
2544
|
};
|
|
2545
2545
|
}
|
|
2546
2546
|
|
|
2547
|
+
// p1: [x, y] coords
|
|
2548
|
+
// p2: [x, y] coords offset by 1x1 pixel
|
|
2549
|
+
function formatCoordsForDisplay(p1, p2) {
|
|
2550
|
+
var dx = Math.abs(p1[0] - p2[0]);
|
|
2551
|
+
var dy = Math.abs(p1[1] - p2[1]);
|
|
2552
|
+
var offs = (dx + dy) / 2;
|
|
2553
|
+
var decimals = 0;
|
|
2554
|
+
while (offs < 1 && decimals < 6) {
|
|
2555
|
+
offs *= 10;
|
|
2556
|
+
decimals++;
|
|
2557
|
+
}
|
|
2558
|
+
return [p1[0].toFixed(decimals), p1[1].toFixed(decimals)];
|
|
2559
|
+
}
|
|
2560
|
+
|
|
2547
2561
|
// Convert a point from display CRS coordinates to data coordinates.
|
|
2548
2562
|
// These are only different when using dynamic reprojection (basemap view).
|
|
2549
2563
|
function translateDisplayPoint(lyr, p) {
|
|
@@ -2563,8 +2577,7 @@
|
|
|
2563
2577
|
}
|
|
2564
2578
|
|
|
2565
2579
|
function isProjectedLayer(lyr) {
|
|
2566
|
-
|
|
2567
|
-
return !!lyr.gui.invertPoint;
|
|
2580
|
+
return !!lyr?.gui.invertPoint;
|
|
2568
2581
|
}
|
|
2569
2582
|
|
|
2570
2583
|
var darkStroke = "#334",
|
|
@@ -2765,30 +2778,7 @@
|
|
|
2765
2778
|
|
|
2766
2779
|
|
|
2767
2780
|
function getDefaultStyle(lyr, baseStyle) {
|
|
2768
|
-
|
|
2769
|
-
// reduce the dot size of large point layers
|
|
2770
|
-
if (lyr.geometry_type == 'point' && style.dotSize > 0) {
|
|
2771
|
-
style.dotSize *= getDotScale$1(lyr);
|
|
2772
|
-
}
|
|
2773
|
-
return style;
|
|
2774
|
-
}
|
|
2775
|
-
|
|
2776
|
-
function getDotScale$1(lyr) {
|
|
2777
|
-
var topTier = 10000;
|
|
2778
|
-
var n = countPoints(lyr.shapes, topTier); // short-circuit point counting above top threshold
|
|
2779
|
-
var k = n < 200 && 4 || n < 2500 && 3 || n < topTier && 2 || 1;
|
|
2780
|
-
return k;
|
|
2781
|
-
}
|
|
2782
|
-
|
|
2783
|
-
function countPoints(shapes, max) {
|
|
2784
|
-
var count = 0;
|
|
2785
|
-
var i, n, shp;
|
|
2786
|
-
max = max || Infinity;
|
|
2787
|
-
for (i=0, n=shapes.length; i<n && count<max; i++) {
|
|
2788
|
-
shp = shapes[i];
|
|
2789
|
-
count += shp ? shp.length : 0;
|
|
2790
|
-
}
|
|
2791
|
-
return count;
|
|
2781
|
+
return Object.assign({}, baseStyle);
|
|
2792
2782
|
}
|
|
2793
2783
|
|
|
2794
2784
|
|
|
@@ -3232,6 +3222,58 @@
|
|
|
3232
3222
|
return layers.reverse();
|
|
3233
3223
|
}
|
|
3234
3224
|
|
|
3225
|
+
|
|
3226
|
+
function adjustPointSymbolSizes(layers, overlayLyr, ext) {
|
|
3227
|
+
var bbox = ext.getBounds().scale(1.5).toArray();
|
|
3228
|
+
var testInBounds = function(p) {
|
|
3229
|
+
return p[0] > bbox[0] && p[0] < bbox[2] && p[1] > bbox[1] && p[1] < bbox[3];
|
|
3230
|
+
};
|
|
3231
|
+
var topTier = 50000;
|
|
3232
|
+
var count = 0;
|
|
3233
|
+
layers = layers.filter(function(lyr) {
|
|
3234
|
+
return lyr.geometry_type == 'point' && lyr.gui.style.dotSize > 0;
|
|
3235
|
+
});
|
|
3236
|
+
layers.forEach(function(lyr) {
|
|
3237
|
+
// short-circuit point counting above top threshold
|
|
3238
|
+
count += countPoints(lyr.gui.displayLayer.shapes, topTier, testInBounds);
|
|
3239
|
+
});
|
|
3240
|
+
count = Math.min(topTier, count) || 1;
|
|
3241
|
+
var k = Math.pow(6 - utils$1.clamp(Math.log10(count), 1, 5), 1.3);
|
|
3242
|
+
|
|
3243
|
+
// zoom adjustments
|
|
3244
|
+
var mapScale = ext.scale();
|
|
3245
|
+
if (mapScale < 0.5) {
|
|
3246
|
+
k *= Math.pow(mapScale + 0.5, 0.35);
|
|
3247
|
+
} else if (mapScale > 1) {
|
|
3248
|
+
// scale faster at first
|
|
3249
|
+
k *= Math.pow(Math.min(mapScale, 4), 0.15);
|
|
3250
|
+
k *= Math.pow(mapScale, 0.05);
|
|
3251
|
+
}
|
|
3252
|
+
|
|
3253
|
+
// scale down when map is small
|
|
3254
|
+
var smallSide = Math.min(ext.width(), ext.height());
|
|
3255
|
+
k *= utils$1.clamp(smallSide / 500, 0.5, 1);
|
|
3256
|
+
|
|
3257
|
+
layers.forEach(function(lyr) {
|
|
3258
|
+
lyr.gui.style.dotScale = k;
|
|
3259
|
+
});
|
|
3260
|
+
if (overlayLyr && overlayLyr.geometry_type == 'point' && overlayLyr.gui.style.dotSize > 0) {
|
|
3261
|
+
overlayLyr.gui.style.dotScale = k;
|
|
3262
|
+
}
|
|
3263
|
+
}
|
|
3264
|
+
|
|
3265
|
+
function countPoints(shapes, max, filter) {
|
|
3266
|
+
var count = 0;
|
|
3267
|
+
var i, j, n, m, shp;
|
|
3268
|
+
for (i=0, n=shapes.length; i<n && count<max; i++) {
|
|
3269
|
+
shp = shapes[i];
|
|
3270
|
+
for (j=0, m=(shp ? shp.length : 0); j<m; j++) {
|
|
3271
|
+
count += filter(shp[j]) ? 1 : 0;
|
|
3272
|
+
}
|
|
3273
|
+
}
|
|
3274
|
+
return count;
|
|
3275
|
+
}
|
|
3276
|
+
|
|
3235
3277
|
// lyr: a map layer with gui property
|
|
3236
3278
|
// displayCRS: CRS to use for display, or null (which clears any current display CRS)
|
|
3237
3279
|
function projectLayerForDisplay(lyr, displayCRS) {
|
|
@@ -3286,6 +3328,13 @@
|
|
|
3286
3328
|
}
|
|
3287
3329
|
}
|
|
3288
3330
|
|
|
3331
|
+
// make sure that every path layer has an associated arc collection
|
|
3332
|
+
// (if the layer is empty, its dataset may not have an arc collection).
|
|
3333
|
+
// this enables adding shapes using the drawing tools.
|
|
3334
|
+
if (!dataset.arcs && (layer.geometry_type == 'polygon' || layer.geometry_type == 'polyline')) {
|
|
3335
|
+
dataset.arcs = new internal.ArcCollection();
|
|
3336
|
+
}
|
|
3337
|
+
|
|
3289
3338
|
// Assume that dataset.displayArcs is in the display CRS
|
|
3290
3339
|
// (it must be deleted upstream if reprojection is needed)
|
|
3291
3340
|
// if (!obj.empty && dataset.arcs && !displayArcs) {
|
|
@@ -3370,6 +3419,17 @@
|
|
|
3370
3419
|
}
|
|
3371
3420
|
}
|
|
3372
3421
|
|
|
3422
|
+
function pencilPointIsSkippable(p2, points) {
|
|
3423
|
+
var p1 = points[0];
|
|
3424
|
+
var dist;
|
|
3425
|
+
if (points.length < 2) return true;
|
|
3426
|
+
for (var i=1; i<points.length; i++) {
|
|
3427
|
+
dist = Math.sqrt(geom.pointSegDistSq(points[i][0], points[i][1], p1[0], p1[1], p2[0], p2[1]));
|
|
3428
|
+
if (dist > 1.5) return false;
|
|
3429
|
+
}
|
|
3430
|
+
return true;
|
|
3431
|
+
}
|
|
3432
|
+
|
|
3373
3433
|
function setZ(lyr, z) {
|
|
3374
3434
|
lyr.gui.source.dataset.arcs.setRetainedInterval(z);
|
|
3375
3435
|
if (isProjectedLayer(lyr)) {
|
|
@@ -3451,6 +3511,25 @@
|
|
|
3451
3511
|
}
|
|
3452
3512
|
}
|
|
3453
3513
|
|
|
3514
|
+
function deletePoint(lyr, fid) {
|
|
3515
|
+
var records = lyr.data?.getRecords();
|
|
3516
|
+
lyr.shapes.splice(fid, 1);
|
|
3517
|
+
if (records) records.splice(fid, 1);
|
|
3518
|
+
if (isProjectedLayer(lyr)) {
|
|
3519
|
+
lyr.gui.displayLayer.shapes.splice(fid, 1);
|
|
3520
|
+
}
|
|
3521
|
+
}
|
|
3522
|
+
|
|
3523
|
+
function insertPoint(lyr, fid, shp, d) {
|
|
3524
|
+
var records = lyr.data?.getRecords();
|
|
3525
|
+
if (records) records.splice(fid, 0, d);
|
|
3526
|
+
lyr.shapes.splice(fid, 0, shp);
|
|
3527
|
+
if (isProjectedLayer(lyr)) {
|
|
3528
|
+
var shp2 = projectPointCoords(shp, lyr.gui.projectPoint);
|
|
3529
|
+
lyr.gui.displayLayer.shapes.splice(fid, 0, shp2);
|
|
3530
|
+
}
|
|
3531
|
+
}
|
|
3532
|
+
|
|
3454
3533
|
function deleteLastPoint(lyr) {
|
|
3455
3534
|
if (lyr.data) {
|
|
3456
3535
|
lyr.data.getRecords().pop();
|
|
@@ -5522,6 +5601,16 @@
|
|
|
5522
5601
|
addHistoryState(undo, redo);
|
|
5523
5602
|
});
|
|
5524
5603
|
|
|
5604
|
+
gui.on('point_delete', function(e) {
|
|
5605
|
+
var redo = function() {
|
|
5606
|
+
deletePoint(e.data.target, e.fid);
|
|
5607
|
+
};
|
|
5608
|
+
var undo = function() {
|
|
5609
|
+
insertPoint(e.data.target, e.fid, e.coords, e.d);
|
|
5610
|
+
};
|
|
5611
|
+
addHistoryState(undo, redo);
|
|
5612
|
+
});
|
|
5613
|
+
|
|
5525
5614
|
gui.on('path_add', function(e) {
|
|
5526
5615
|
var redo = function() {
|
|
5527
5616
|
gui.dispatchEvent('redo_path_add', {p1: e.p1, p2: e.p2});
|
|
@@ -5619,10 +5708,7 @@
|
|
|
5619
5708
|
};
|
|
5620
5709
|
|
|
5621
5710
|
function updateVisibility() {
|
|
5622
|
-
|
|
5623
|
-
if (GUI.isActiveInstance(gui) && !_hidden && !noData) {
|
|
5624
|
-
buttons.show();
|
|
5625
|
-
} else if (noData && gui.getMode() != 'import') {
|
|
5711
|
+
if (GUI.isActiveInstance(gui) && !_hidden) {
|
|
5626
5712
|
buttons.show();
|
|
5627
5713
|
} else {
|
|
5628
5714
|
buttons.hide();
|
|
@@ -5716,24 +5802,37 @@
|
|
|
5716
5802
|
var self = this;
|
|
5717
5803
|
var shiftDown = false;
|
|
5718
5804
|
var ctrlDown = false;
|
|
5805
|
+
var metaDown = false;
|
|
5806
|
+
var altDown = false;
|
|
5807
|
+
|
|
5808
|
+
function updateControlKeys(e) {
|
|
5809
|
+
shiftDown = e.shiftKey;
|
|
5810
|
+
ctrlDown = e.ctrlKey;
|
|
5811
|
+
metaDown = e.metaKey;
|
|
5812
|
+
altDown = e.altKey;
|
|
5813
|
+
}
|
|
5719
5814
|
document.addEventListener('keyup', function(e) {
|
|
5720
5815
|
if (!GUI.isActiveInstance(gui)) return;
|
|
5721
5816
|
// this can fail to fire if keyup occurs over a context menu
|
|
5722
|
-
|
|
5723
|
-
shiftDown = e.shiftKey;
|
|
5724
|
-
if (e.keyCode == 17) ctrlDown = false;
|
|
5817
|
+
updateControlKeys(e);
|
|
5725
5818
|
self.dispatchEvent('keyup', getEventData(e));
|
|
5726
5819
|
});
|
|
5727
5820
|
|
|
5728
5821
|
document.addEventListener('keydown', function(e) {
|
|
5729
5822
|
if (!GUI.isActiveInstance(gui)) return;
|
|
5730
|
-
|
|
5731
|
-
if (e.keyCode == 17) ctrlDown = true;
|
|
5823
|
+
updateControlKeys(e);
|
|
5732
5824
|
self.dispatchEvent('keydown', getEventData(e));
|
|
5733
5825
|
});
|
|
5734
5826
|
|
|
5827
|
+
document.addEventListener('mousemove', function(e) {
|
|
5828
|
+
// refreshing these here to prevent problems when context menu opens
|
|
5829
|
+
updateControlKeys(e);
|
|
5830
|
+
});
|
|
5831
|
+
|
|
5735
5832
|
this.shiftIsPressed = function() { return shiftDown; };
|
|
5736
5833
|
this.ctrlIsPressed = function() { return ctrlDown; };
|
|
5834
|
+
this.altIsPressed = function() { return altDown; };
|
|
5835
|
+
this.metaIsPressed = function() { return metaDown; };
|
|
5737
5836
|
|
|
5738
5837
|
this.onMenuSubmit = function(menuEl, cb) {
|
|
5739
5838
|
gui.on('enter_key', function(e) {
|
|
@@ -7964,7 +8063,9 @@
|
|
|
7964
8063
|
return;
|
|
7965
8064
|
}
|
|
7966
8065
|
e.originalEvent.preventDefault();
|
|
7967
|
-
if (!
|
|
8066
|
+
if (!El('body').hasClass('map-view')) {
|
|
8067
|
+
return;
|
|
8068
|
+
}
|
|
7968
8069
|
triggerHitEvent('contextmenu', e);
|
|
7969
8070
|
}, false);
|
|
7970
8071
|
|
|
@@ -8060,7 +8161,7 @@
|
|
|
8060
8161
|
self.setHitId = function(id) {
|
|
8061
8162
|
if (storedData.id == id) return;
|
|
8062
8163
|
storedData.id = id;
|
|
8063
|
-
storedData.ids = [id];
|
|
8164
|
+
storedData.ids = id == -1 ? [] : [id];
|
|
8064
8165
|
triggerHitEvent('change');
|
|
8065
8166
|
};
|
|
8066
8167
|
|
|
@@ -8388,7 +8489,9 @@
|
|
|
8388
8489
|
mode: interactionMode
|
|
8389
8490
|
};
|
|
8390
8491
|
if (evt) {
|
|
8492
|
+
// data coordinates
|
|
8391
8493
|
eventData.coordinates = translateDisplayPoint(targetLayer, ext.translatePixelCoords(evt.x, evt.y));
|
|
8494
|
+
eventData.display_coordinates = gui.map.pixelCoordsToDisplayCoords(evt.x, evt.y);
|
|
8392
8495
|
eventData.originalEvent = evt;
|
|
8393
8496
|
eventData.overMap = isOverMap(evt);
|
|
8394
8497
|
}
|
|
@@ -9269,8 +9372,7 @@
|
|
|
9269
9372
|
|
|
9270
9373
|
function useBoxZoom() {
|
|
9271
9374
|
var mode = gui.getMode();
|
|
9272
|
-
|
|
9273
|
-
return !disabled;
|
|
9375
|
+
return !'selection_tool,box_tool,rectangle_tool,drawing_tool'.includes(mode);
|
|
9274
9376
|
}
|
|
9275
9377
|
|
|
9276
9378
|
function getBoxData(e) {
|
|
@@ -9803,8 +9905,8 @@
|
|
|
9803
9905
|
|
|
9804
9906
|
hit.on('contextmenu', function(e) {
|
|
9805
9907
|
var target = hit.getHitTarget();
|
|
9806
|
-
if (!e.overMap ||
|
|
9807
|
-
e.mode == 'edit_polygons') {
|
|
9908
|
+
if (!e.overMap || e.mode == 'edit_lines' ||
|
|
9909
|
+
e.mode == 'edit_polygons' || e.mode == 'edit_points') {
|
|
9808
9910
|
return;
|
|
9809
9911
|
}
|
|
9810
9912
|
gui.contextMenu.open(e, hit.getHitTarget());
|
|
@@ -10099,7 +10201,8 @@
|
|
|
10099
10201
|
}
|
|
10100
10202
|
|
|
10101
10203
|
function initPointEditing(gui, ext, hit) {
|
|
10102
|
-
var
|
|
10204
|
+
var instructionsShown = false;
|
|
10205
|
+
var symbolInfo, alert;
|
|
10103
10206
|
function active(e) {
|
|
10104
10207
|
return gui.interaction.getMode() == 'edit_points';
|
|
10105
10208
|
}
|
|
@@ -10108,17 +10211,57 @@
|
|
|
10108
10211
|
return active(e) && e.id > -1;
|
|
10109
10212
|
}
|
|
10110
10213
|
|
|
10214
|
+
function hideInstructions() {
|
|
10215
|
+
if (!alert) return;
|
|
10216
|
+
alert.close('fade');
|
|
10217
|
+
alert = null;
|
|
10218
|
+
}
|
|
10219
|
+
|
|
10220
|
+
function showInstructions() {
|
|
10221
|
+
var isMac = navigator.userAgent.includes('Mac');
|
|
10222
|
+
var symbol = isMac ? '⌘' : '^';
|
|
10223
|
+
var msg = `Instructions: Click on the map to add points. Move points by dragging. Type ${symbol}Z/${symbol}Y to undo/redo.`;
|
|
10224
|
+
alert = showPopupAlert(msg, null, { non_blocking: true, max_width: '360px'});
|
|
10225
|
+
}
|
|
10226
|
+
|
|
10111
10227
|
gui.on('interaction_mode_change', function(e) {
|
|
10112
10228
|
if (e.mode == 'edit_points' && !gui.model.getActiveLayer()) {
|
|
10113
10229
|
addEmptyLayer(gui, undefined, 'point');
|
|
10114
10230
|
} else if (e.prev_mode == 'edit_points') {
|
|
10231
|
+
hideInstructions();
|
|
10115
10232
|
gui.container.findChild('.map-layers').classed('add-points', false);
|
|
10116
10233
|
}
|
|
10234
|
+
if (e.mode == 'edit_points' && !instructionsShown) {
|
|
10235
|
+
instructionsShown = true;
|
|
10236
|
+
showInstructions();
|
|
10237
|
+
}
|
|
10238
|
+
});
|
|
10117
10239
|
|
|
10240
|
+
hit.on('contextmenu', function(e) {
|
|
10241
|
+
if (!active(e)) return;
|
|
10242
|
+
var target = hit.getHitTarget();
|
|
10243
|
+
var id = e.id;
|
|
10244
|
+
if (id > -1) {
|
|
10245
|
+
e.deletePoint = function() {
|
|
10246
|
+
removePoint(target, id);
|
|
10247
|
+
};
|
|
10248
|
+
}
|
|
10249
|
+
gui.contextMenu.open(e, target);
|
|
10118
10250
|
});
|
|
10119
10251
|
|
|
10252
|
+
function removePoint(target, id) {
|
|
10253
|
+
var d = target.data ? target.data.getRecords()[id] : null;
|
|
10254
|
+
var coords = target.shapes[id];
|
|
10255
|
+
deletePoint(target, id);
|
|
10256
|
+
gui.dispatchEvent('point_delete', {coords, d, target, fid: id});
|
|
10257
|
+
gui.dispatchEvent('map-needs-refresh');
|
|
10258
|
+
hit.setHitId(-1);
|
|
10259
|
+
}
|
|
10260
|
+
|
|
10120
10261
|
hit.on('click', function(e) {
|
|
10121
10262
|
if (overPoint(e) || !active(e)) return;
|
|
10263
|
+
hideInstructions();
|
|
10264
|
+
|
|
10122
10265
|
// add point
|
|
10123
10266
|
var p = pixToDataCoords(e.x, e.y);
|
|
10124
10267
|
var target = hit.getHitTarget();
|
|
@@ -10135,6 +10278,7 @@
|
|
|
10135
10278
|
|
|
10136
10279
|
hit.on('dragstart', function(e) {
|
|
10137
10280
|
if (!overPoint(e)) return;
|
|
10281
|
+
hideInstructions();
|
|
10138
10282
|
var target = hit.getHitTarget();
|
|
10139
10283
|
symbolInfo = {
|
|
10140
10284
|
FID: e.id,
|
|
@@ -10188,6 +10332,7 @@
|
|
|
10188
10332
|
var drawingId = -1; // feature id of path being drawn
|
|
10189
10333
|
var sessionCount = 0;
|
|
10190
10334
|
var alert;
|
|
10335
|
+
var pencilPoints;
|
|
10191
10336
|
var _dragging = false;
|
|
10192
10337
|
|
|
10193
10338
|
function active() {
|
|
@@ -10202,6 +10347,10 @@
|
|
|
10202
10347
|
return drawingId > -1;
|
|
10203
10348
|
}
|
|
10204
10349
|
|
|
10350
|
+
function usingPencil() {
|
|
10351
|
+
return (gui.keyboard.altIsPressed() || gui.keyboard.metaIsPressed()) && active() && !dragging();
|
|
10352
|
+
}
|
|
10353
|
+
|
|
10205
10354
|
function polygonMode() {
|
|
10206
10355
|
return active() && hit.getHitTarget().geometry_type == 'polygon';
|
|
10207
10356
|
}
|
|
@@ -10283,11 +10432,12 @@
|
|
|
10283
10432
|
|
|
10284
10433
|
function showInstructions() {
|
|
10285
10434
|
var isMac = navigator.userAgent.includes('Mac');
|
|
10286
|
-
var
|
|
10435
|
+
var undoKey = isMac ? '⌘' : '^';
|
|
10436
|
+
var drawKey = isMac ? '⌘' : 'Alt';
|
|
10287
10437
|
var pathStr = polygonMode() ? 'closed paths' : 'paths';
|
|
10288
|
-
var msg = `Instructions: Click
|
|
10438
|
+
var msg = `Instructions: Click to start a path or add a point. ${drawKey}-drag draws a path. Drag points to reshape. Type ${undoKey}Z/${undoKey}Y to undo/redo.`;
|
|
10289
10439
|
alert = showPopupAlert(msg, null, {
|
|
10290
|
-
non_blocking: true, max_width: '
|
|
10440
|
+
non_blocking: true, max_width: '388px'});
|
|
10291
10441
|
}
|
|
10292
10442
|
|
|
10293
10443
|
function hideInstructions() {
|
|
@@ -10372,9 +10522,28 @@
|
|
|
10372
10522
|
hit.setHoverVertex(hoverVertexInfo.displayPoint, hoverVertexInfo.type);
|
|
10373
10523
|
});
|
|
10374
10524
|
|
|
10525
|
+
gui.map.getMouse().on('drag', function(e) {
|
|
10526
|
+
if (!usingPencil()) return;
|
|
10527
|
+
e.stopPropagation();
|
|
10528
|
+
var xy = [e.x, e.y];
|
|
10529
|
+
var p = pixToDataCoords(e.x, e.y);
|
|
10530
|
+
if (!drawing()) {
|
|
10531
|
+
pencilPoints = [xy];
|
|
10532
|
+
startNewPath(p);
|
|
10533
|
+
} else if (!pencilPoints || !pencilPointIsSkippable(xy, pencilPoints)) {
|
|
10534
|
+
pencilPoints = [xy];
|
|
10535
|
+
extendCurrentPath(p);
|
|
10536
|
+
} else {
|
|
10537
|
+
// skip this point, update the hover line
|
|
10538
|
+
pencilPoints.push(xy);
|
|
10539
|
+
updatePathEndpoint(p);
|
|
10540
|
+
}
|
|
10541
|
+
}, null, 3); // higher priority than hit control
|
|
10542
|
+
|
|
10375
10543
|
hit.on('drag', function(e) {
|
|
10376
10544
|
if (!dragging() || drawing()) return;
|
|
10377
10545
|
e.originalEvent.stopPropagation();
|
|
10546
|
+
// dragging a vertex
|
|
10378
10547
|
var target = hit.getHitTarget();
|
|
10379
10548
|
var p = ext.translatePixelCoords(e.x, e.y);
|
|
10380
10549
|
if (gui.keyboard.shiftIsPressed()) {
|
|
@@ -10453,8 +10622,6 @@
|
|
|
10453
10622
|
deleteActiveVertex(e);
|
|
10454
10623
|
} else {
|
|
10455
10624
|
startNewPath(p);
|
|
10456
|
-
hideInstructions();
|
|
10457
|
-
updateCursor();
|
|
10458
10625
|
}
|
|
10459
10626
|
prevClickEvent = e;
|
|
10460
10627
|
});
|
|
@@ -10565,6 +10732,14 @@
|
|
|
10565
10732
|
gui.dispatchEvent('path_add', {target, p1, p2});
|
|
10566
10733
|
drawingId = target.shapes.length - 1;
|
|
10567
10734
|
hit.setDrawingId(drawingId);
|
|
10735
|
+
hideInstructions();
|
|
10736
|
+
updateCursor();
|
|
10737
|
+
}
|
|
10738
|
+
|
|
10739
|
+
function pencilDraw(e) {
|
|
10740
|
+
var p = pixToDataCoords(e.x, e.y);
|
|
10741
|
+
extendCurrentPath(p);
|
|
10742
|
+
|
|
10568
10743
|
}
|
|
10569
10744
|
|
|
10570
10745
|
// p: [x, y] source data coordinates of new point on path
|
|
@@ -10585,7 +10760,6 @@
|
|
|
10585
10760
|
gui.dispatchEvent('path_extend', {target, p, shapes1, shapes2});
|
|
10586
10761
|
clearDrawingInfo();
|
|
10587
10762
|
fullRedraw();
|
|
10588
|
-
|
|
10589
10763
|
} else {
|
|
10590
10764
|
appendVertex$1(target, p);
|
|
10591
10765
|
gui.dispatchEvent('path_extend', {target, p});
|
|
@@ -10622,20 +10796,19 @@
|
|
|
10622
10796
|
function findPathStartInfo(e) {
|
|
10623
10797
|
var target = hit.getHitTarget();
|
|
10624
10798
|
var arcId = target.gui.displayArcs.size() - 1;
|
|
10625
|
-
var
|
|
10799
|
+
var p1 = ext.translatePixelCoords(e.x, e.y); // mouse coords
|
|
10800
|
+
var p2 = internal.getArcStartCoords(arcId, target.gui.displayArcs); // vertex coords
|
|
10801
|
+
var p3 = internal.getArcStartCoords(arcId, target.gui.source.dataset.arcs);
|
|
10802
|
+
var dist = geom.distance2D(p1[0], p1[1], p2[0], p2[1]);
|
|
10803
|
+
var data = target.gui.source.dataset.arcs.getVertexData();
|
|
10626
10804
|
var i = data.ii[arcId];
|
|
10627
|
-
var x = data.xx[i];
|
|
10628
|
-
var y = data.yy[i];
|
|
10629
|
-
var p = ext.translatePixelCoords(e.x, e.y);
|
|
10630
|
-
var dist = geom.distance2D(p[0], p[1], x, y);
|
|
10631
10805
|
var pathLen = data.nn[arcId];
|
|
10632
10806
|
var pixelDist = dist / ext.getPixelSize();
|
|
10633
10807
|
if (pixelDist > HOVER_THRESHOLD || pathLen < 4) {
|
|
10634
10808
|
return null;
|
|
10635
10809
|
}
|
|
10636
|
-
var point = translateDisplayPoint(target, [x, y]);
|
|
10637
10810
|
return {
|
|
10638
|
-
target, ids: [i], extendable: false,
|
|
10811
|
+
target, ids: [i], extendable: false, displayPoint: p2, point: p3, type: 'vertex'
|
|
10639
10812
|
};
|
|
10640
10813
|
}
|
|
10641
10814
|
|
|
@@ -10871,6 +11044,7 @@
|
|
|
10871
11044
|
}
|
|
10872
11045
|
};
|
|
10873
11046
|
|
|
11047
|
+
// translate display CRS coords to pixel coords
|
|
10874
11048
|
this.translateCoords = function(x, y) {
|
|
10875
11049
|
return this.getTransform().transform(x, y);
|
|
10876
11050
|
};
|
|
@@ -10890,6 +11064,7 @@
|
|
|
10890
11064
|
return bounds2.width() / _frame.width;
|
|
10891
11065
|
};
|
|
10892
11066
|
|
|
11067
|
+
// convert pixel coords (0,0 is top left corner of map) to display CRS coords
|
|
10893
11068
|
this.translatePixelCoords = function(x, y) {
|
|
10894
11069
|
return this.getTransform().invert().transform(x, y);
|
|
10895
11070
|
};
|
|
@@ -11352,8 +11527,7 @@
|
|
|
11352
11527
|
|
|
11353
11528
|
_self.drawSquareDots = function(shapes, style) {
|
|
11354
11529
|
var t = getScaledTransform(_ext),
|
|
11355
|
-
|
|
11356
|
-
size = Math.round((style.dotSize || 1) * scaleRatio),
|
|
11530
|
+
size = getDotSize(style),
|
|
11357
11531
|
styler = style.styler || null,
|
|
11358
11532
|
xmax = _canvas.width + size,
|
|
11359
11533
|
ymax = _canvas.height + size,
|
|
@@ -11373,7 +11547,7 @@
|
|
|
11373
11547
|
for (i=0, n=shapes.length; i<n; i++) {
|
|
11374
11548
|
if (styler !== null) { // e.g. selected points
|
|
11375
11549
|
styler(style, i);
|
|
11376
|
-
size = style
|
|
11550
|
+
size = getDotSize(style);
|
|
11377
11551
|
if (style.dotColor != color) {
|
|
11378
11552
|
color = style.dotColor;
|
|
11379
11553
|
_ctx.fillStyle = color;
|
|
@@ -11520,25 +11694,16 @@
|
|
|
11520
11694
|
return s;
|
|
11521
11695
|
}
|
|
11522
11696
|
|
|
11523
|
-
function
|
|
11524
|
-
var
|
|
11525
|
-
|
|
11526
|
-
|
|
11527
|
-
|
|
11528
|
-
|
|
11529
|
-
|
|
11530
|
-
|
|
11531
|
-
|
|
11532
|
-
|
|
11533
|
-
// scale faster at first, so small dots in large datasets
|
|
11534
|
-
// become easily visible and clickable after zooming in a bit
|
|
11535
|
-
k *= Math.pow(Math.min(mapScale, 10), 0.3);
|
|
11536
|
-
k *= Math.pow(mapScale, 0.1);
|
|
11537
|
-
}
|
|
11538
|
-
// grow pixels more slowly on retina displays (to reduce number of pixels to
|
|
11539
|
-
// draw for large point datasets when slightly zoomed in)
|
|
11540
|
-
var l = Math.pow(GUI.getPixelRatio(), 0.8);
|
|
11541
|
-
return j * k * l;
|
|
11697
|
+
function getDotSize(style) {
|
|
11698
|
+
var size = style.dotSize || 1;
|
|
11699
|
+
// TODO: improve
|
|
11700
|
+
var scale = style.dotScale || 1;
|
|
11701
|
+
size += (scale - 1) / 2;
|
|
11702
|
+
size *= Math.pow(scale, 0.3);
|
|
11703
|
+
|
|
11704
|
+
// shrink dots slightly on retina displays, to adjust for greater clarity
|
|
11705
|
+
// and reduce number of pixels to draw on large datasets.
|
|
11706
|
+
return Math.round(Math.pow(GUI.getPixelRatio(), 0.8) * size);
|
|
11542
11707
|
}
|
|
11543
11708
|
|
|
11544
11709
|
function getScaledTransform(ext) {
|
|
@@ -12460,16 +12625,27 @@ GUI and setting the size and crop of SVG output.</p><div><input type="text" clas
|
|
|
12460
12625
|
return internal.toLngLat(p, _dynamicCRS);
|
|
12461
12626
|
};
|
|
12462
12627
|
|
|
12463
|
-
this.
|
|
12464
|
-
var
|
|
12628
|
+
this.pixelCoordsToDisplayCoords = function(x, y) {
|
|
12629
|
+
var p1 = _ext.translatePixelCoords(x, y);
|
|
12630
|
+
var p2 = _ext.translatePixelCoords(x+1, y+1);
|
|
12465
12631
|
var crs = this.getDisplayCRS();
|
|
12466
|
-
|
|
12467
|
-
|
|
12468
|
-
|
|
12632
|
+
if (crs) {
|
|
12633
|
+
p1 = internal.toLngLat(p1, crs) || p1;
|
|
12634
|
+
p2 = internal.toLngLat(p2, crs) || p2;
|
|
12469
12635
|
}
|
|
12470
|
-
return
|
|
12636
|
+
return formatCoordsForDisplay(p1, p2);
|
|
12471
12637
|
};
|
|
12472
12638
|
|
|
12639
|
+
// this.getCenterLngLat = function() {
|
|
12640
|
+
// var bounds = _ext.getBounds();
|
|
12641
|
+
// var crs = this.getDisplayCRS();
|
|
12642
|
+
// // TODO: handle case where active layer is a frame layer
|
|
12643
|
+
// if (!bounds.hasBounds() || !crs) {
|
|
12644
|
+
// return null;
|
|
12645
|
+
// }
|
|
12646
|
+
// return internal.toLngLat([bounds.centerX(), bounds.centerY()], crs);
|
|
12647
|
+
// };
|
|
12648
|
+
|
|
12473
12649
|
this.getDisplayCRS = function() {
|
|
12474
12650
|
if (!_activeLyr) {
|
|
12475
12651
|
return _dynamicCRS || internal.parseCrsString('wgs84');
|
|
@@ -12536,7 +12712,6 @@ GUI and setting the size and crop of SVG output.</p><div><input type="text" clas
|
|
|
12536
12712
|
_ext.setFullBounds(calcFullBounds());
|
|
12537
12713
|
_ext.resize();
|
|
12538
12714
|
_renderer = new LayerRenderer(gui, el);
|
|
12539
|
-
gui.buttons.show();
|
|
12540
12715
|
|
|
12541
12716
|
if (opts.inspectorControl) {
|
|
12542
12717
|
_hit = new HitControl(gui, _ext, _mouse),
|
|
@@ -12598,10 +12773,7 @@ GUI and setting the size and crop of SVG output.</p><div><input type="text" clas
|
|
|
12598
12773
|
}
|
|
12599
12774
|
|
|
12600
12775
|
if (e.layer) {
|
|
12601
|
-
|
|
12602
|
-
_activeLyr = e.layer;
|
|
12603
|
-
_activeLyr.gui.style = getActiveLayerStyle(_activeLyr.gui.displayLayer, getGlobalStyleOptions());
|
|
12604
|
-
_activeLyr.active = true;
|
|
12776
|
+
_activeLyr = initActiveLayer(e.layer, e.dataset);
|
|
12605
12777
|
} else {
|
|
12606
12778
|
_activeLyr = null;
|
|
12607
12779
|
}
|
|
@@ -12639,10 +12811,12 @@ GUI and setting the size and crop of SVG output.</p><div><input type="text" clas
|
|
|
12639
12811
|
|
|
12640
12812
|
|
|
12641
12813
|
function updateOverlayLayer(e) {
|
|
12642
|
-
var style =
|
|
12814
|
+
var style = !_activeLyr?.gui?.style ? null :
|
|
12815
|
+
getOverlayStyle(_activeLyr.gui.displayLayer, e, getGlobalStyleOptions());
|
|
12643
12816
|
if (style) {
|
|
12644
12817
|
var displayLayer = filterLayerByIds(_activeLyr.gui.displayLayer, style.ids);
|
|
12645
12818
|
var gui = Object.assign({}, _activeLyr.gui, {style, displayLayer});
|
|
12819
|
+
style.dotScale = _activeLyr.gui.style.dotScale;
|
|
12646
12820
|
_overlayLyr = utils$1.defaults({gui}, _activeLyr);
|
|
12647
12821
|
} else {
|
|
12648
12822
|
_overlayLyr = null;
|
|
@@ -12786,6 +12960,17 @@ GUI and setting the size and crop of SVG output.</p><div><input type="text" clas
|
|
|
12786
12960
|
});
|
|
12787
12961
|
}
|
|
12788
12962
|
|
|
12963
|
+
function initActiveLayer(lyr, dataset) {
|
|
12964
|
+
enhanceLayerForDisplay(lyr, dataset, getDisplayOptions());
|
|
12965
|
+
lyr.gui.style = getActiveLayerStyle(lyr.gui.displayLayer, getGlobalStyleOptions());
|
|
12966
|
+
lyr.active = true;
|
|
12967
|
+
getVisibleMapLayers().forEach(function(lyr) {
|
|
12968
|
+
delete lyr.active;
|
|
12969
|
+
});
|
|
12970
|
+
lyr.active = true;
|
|
12971
|
+
return lyr;
|
|
12972
|
+
}
|
|
12973
|
+
|
|
12789
12974
|
function getDrawableFurnitureLayers(layers) {
|
|
12790
12975
|
if (!isPreviewView()) return [];
|
|
12791
12976
|
return getVisibleMapLayers().filter(function(o) {
|
|
@@ -12852,6 +13037,7 @@ GUI and setting the size and crop of SVG output.</p><div><input type="text" clas
|
|
|
12852
13037
|
updateLayerStyles(contentLayers);
|
|
12853
13038
|
updateLayerStackOrder(model.getLayers());// update menu_order property of all layers
|
|
12854
13039
|
}
|
|
13040
|
+
adjustPointSymbolSizes(contentLayers, _overlayLyr, _ext);
|
|
12855
13041
|
sortMapLayers(contentLayers);
|
|
12856
13042
|
if (_intersectionLyr) {
|
|
12857
13043
|
contentLayers = contentLayers.concat(_intersectionLyr);
|
|
@@ -12920,7 +13106,7 @@ GUI and setting the size and crop of SVG output.</p><div><input type="text" clas
|
|
|
12920
13106
|
menu.hide();
|
|
12921
13107
|
_open = false;
|
|
12922
13108
|
}
|
|
12923
|
-
},
|
|
13109
|
+
}, 200);
|
|
12924
13110
|
}
|
|
12925
13111
|
|
|
12926
13112
|
function addMenuItem(label, func) {
|
|
@@ -12933,7 +13119,7 @@ GUI and setting the size and crop of SVG output.</p><div><input type="text" clas
|
|
|
12933
13119
|
}
|
|
12934
13120
|
|
|
12935
13121
|
this.open = function(e, lyr) {
|
|
12936
|
-
if (
|
|
13122
|
+
if (lyr && !lyr.gui.geographic) return; // no popup for tabular data
|
|
12937
13123
|
_open = true;
|
|
12938
13124
|
_openCount++;
|
|
12939
13125
|
var rspace = body.clientWidth - e.pageX;
|
|
@@ -12949,19 +13135,22 @@ GUI and setting the size and crop of SVG output.</p><div><input type="text" clas
|
|
|
12949
13135
|
menu.css('top', (e.pageY - 15) + 'px');
|
|
12950
13136
|
|
|
12951
13137
|
// menu contents
|
|
12952
|
-
|
|
12953
|
-
|
|
13138
|
+
//
|
|
13139
|
+
if (e.display_coordinates) {
|
|
13140
|
+
addCoords(e.display_coordinates);
|
|
12954
13141
|
}
|
|
12955
13142
|
if (e.deleteVertex) {
|
|
12956
13143
|
addMenuItem('Delete vertex', e.deleteVertex);
|
|
12957
13144
|
}
|
|
13145
|
+
if (e.deletePoint) {
|
|
13146
|
+
addMenuItem('Delete point', e.deletePoint);
|
|
13147
|
+
}
|
|
12958
13148
|
if (e.ids?.length) {
|
|
12959
13149
|
addMenuItem('Copy as GeoJSON', copyGeoJSON);
|
|
12960
13150
|
}
|
|
12961
13151
|
|
|
12962
|
-
function
|
|
12963
|
-
var
|
|
12964
|
-
var coordStr = internal.getRoundedCoordString(e.coordinates, internal.getBoundsPrecisionForDisplay(bbox));
|
|
13152
|
+
function addCoords(p) {
|
|
13153
|
+
var coordStr = p[0] + ',' + p[1];
|
|
12965
13154
|
var displayStr = '• ' + coordStr.replace(/-/g, '–').replace(',', ', ');
|
|
12966
13155
|
addMenuItem(displayStr, function() {
|
|
12967
13156
|
saveFileContentToClipboard(coordStr);
|
package/www/mapshaper.js
CHANGED
|
@@ -1612,6 +1612,7 @@
|
|
|
1612
1612
|
this.ymin -= halfHeight * ky;
|
|
1613
1613
|
this.xmax += halfWidth * kx;
|
|
1614
1614
|
this.ymax += halfHeight * ky;
|
|
1615
|
+
return this;
|
|
1615
1616
|
};
|
|
1616
1617
|
|
|
1617
1618
|
// Return a bounding box with the same extent as this one.
|
|
@@ -5003,7 +5004,7 @@
|
|
|
5003
5004
|
if (isLatLngCRS(P)) {
|
|
5004
5005
|
return xy.concat();
|
|
5005
5006
|
}
|
|
5006
|
-
proj =
|
|
5007
|
+
proj = getProjTransform2(P, parseCrsString('wgs84'));
|
|
5007
5008
|
return proj(xy[0], xy[1]);
|
|
5008
5009
|
}
|
|
5009
5010
|
|
|
@@ -26664,7 +26665,7 @@ ${svg}
|
|
|
26664
26665
|
codepage = lookupCodePage(ldid),
|
|
26665
26666
|
samples = getNonAsciiSamples(),
|
|
26666
26667
|
only7bit = samples.length === 0,
|
|
26667
|
-
encoding
|
|
26668
|
+
encoding;
|
|
26668
26669
|
|
|
26669
26670
|
// First, check the ldid (language driver id) (an obsolete way to specify which
|
|
26670
26671
|
// codepage to use for text encoding.)
|
|
@@ -26684,10 +26685,12 @@ ${svg}
|
|
|
26684
26685
|
// As a last resort, try to guess the encoding:
|
|
26685
26686
|
if (!encoding) {
|
|
26686
26687
|
var info = detectEncoding(samples);
|
|
26688
|
+
var msg;
|
|
26687
26689
|
encoding = info.encoding;
|
|
26688
26690
|
if (info.confidence < 2) {
|
|
26689
|
-
msg = 'Warning: Unable to auto-detect the DBF file text encoding
|
|
26690
|
-
|
|
26691
|
+
msg = 'Warning: Unable to auto-detect the DBF file text encoding' +
|
|
26692
|
+
(info.confidence == 1 ? ' with high confidence' : '') + '.';
|
|
26693
|
+
msg += ' Defaulting to ' + encoding + (encoding in encodingNames ? ' (' + encodingNames[encoding] + ').' : '.');
|
|
26691
26694
|
msg += '\n\nSample of how non-ascii text was imported:\n';
|
|
26692
26695
|
if (runningInBrowser()) {
|
|
26693
26696
|
msg += '<pre>' + formatStringsAsGrid(decodeSamples(encoding, samples), 50) + '</pre>';
|
|
@@ -45532,7 +45535,7 @@ ${svg}
|
|
|
45532
45535
|
});
|
|
45533
45536
|
}
|
|
45534
45537
|
|
|
45535
|
-
var version = "0.6.
|
|
45538
|
+
var version = "0.6.80";
|
|
45536
45539
|
|
|
45537
45540
|
// Parse command line args into commands and run them
|
|
45538
45541
|
// Function takes an optional Node-style callback. A Promise is returned if no callback is given.
|
package/www/page.css
CHANGED
|
@@ -59,7 +59,7 @@ body.map-view {
|
|
|
59
59
|
|
|
60
60
|
|
|
61
61
|
.selectable,.selectable * {
|
|
62
|
-
user-select:
|
|
62
|
+
user-select: text;
|
|
63
63
|
cursor: text;
|
|
64
64
|
}
|
|
65
65
|
|
|
@@ -343,17 +343,15 @@ div.alert-box {
|
|
|
343
343
|
}
|
|
344
344
|
|
|
345
345
|
.mini-drop-area {
|
|
346
|
-
border: 1.5px dashed #
|
|
347
|
-
max-width:
|
|
346
|
+
border: 1.5px dashed #999;
|
|
347
|
+
max-width: 245px;
|
|
348
348
|
border-radius: 9px;
|
|
349
|
-
font-size:
|
|
349
|
+
font-size: 14px;
|
|
350
350
|
line-height: 1.5;
|
|
351
|
-
|
|
352
|
-
/* background-color: #FFFEF8;*/
|
|
353
|
-
padding: 6px 4px 7px 7px;
|
|
354
|
-
padding: 11px 14px;
|
|
351
|
+
padding: 9px 11px 6px 11px;
|
|
355
352
|
margin: 9px -1px 3px -1px;
|
|
356
353
|
min-height: 120px;
|
|
354
|
+
background: #f8fdff;
|
|
357
355
|
}
|
|
358
356
|
|
|
359
357
|
.catalog-mode .file-catalog {
|