mapshaper 0.6.54 → 0.6.56

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  (function () {
2
2
 
3
- var VERSION = "0.6.54";
3
+ var VERSION = "0.6.56";
4
4
 
5
5
 
6
6
  var utils = /*#__PURE__*/Object.freeze({
@@ -1403,6 +1403,14 @@
1403
1403
  else console.error(msg);
1404
1404
  }
1405
1405
 
1406
+ function truncateString(str, maxLen) {
1407
+ maxLen = maxLen || 80;
1408
+ if (str.length > maxLen) {
1409
+ str = str.substring(0, maxLen - 3).trimEnd() + '...';
1410
+ }
1411
+ return str;
1412
+ }
1413
+
1406
1414
  var Logging = /*#__PURE__*/Object.freeze({
1407
1415
  __proto__: null,
1408
1416
  getLoggingSetter: getLoggingSetter,
@@ -1424,7 +1432,8 @@
1424
1432
  formatColumns: formatColumns,
1425
1433
  formatStringsAsGrid: formatStringsAsGrid,
1426
1434
  formatLogArgs: formatLogArgs,
1427
- logArgs: logArgs
1435
+ logArgs: logArgs,
1436
+ truncateString: truncateString
1428
1437
  });
1429
1438
 
1430
1439
  function Transform() {
@@ -14209,6 +14218,87 @@
14209
14218
  };
14210
14219
  }
14211
14220
 
14221
+ // Return array of variables on the left side of assignment operations
14222
+ // @hasDot (bool) Return property assignments via dot notation
14223
+ function getAssignedVars(exp, hasDot) {
14224
+ var rxp = /[a-z_$][.a-z0-9_$]*(?= *=[^>=])/ig; // ignore arrow functions and comparisons
14225
+ var matches = exp.match(rxp) || [];
14226
+ var f = function(s) {
14227
+ var i = s.indexOf('.');
14228
+ return hasDot ? i > -1 : i == -1;
14229
+ };
14230
+ var vars = utils.uniq(matches.filter(f));
14231
+ return vars;
14232
+ }
14233
+
14234
+ // Return array of objects with properties assigned via dot notation
14235
+ // e.g. 'd.value = 45' -> ['d']
14236
+ // export function getAssignmentObjects(exp) {
14237
+ // var matches = getAssignedVars(exp, true),
14238
+ // names = [];
14239
+ // matches.forEach(function(s) {
14240
+ // var match = /^([^.]+)\.[^.]+$/.exec(s);
14241
+ // var name = match ? match[1] : null;
14242
+ // if (name && name != 'this') {
14243
+ // names.push(name);
14244
+ // }
14245
+ // });
14246
+ // return utils.uniq(names);
14247
+ // }
14248
+
14249
+ function getExpressionFunction(exp, opts) {
14250
+ var func = compileExpressionToFunction(exp, opts);
14251
+ return function(rec, ctx) {
14252
+ var val;
14253
+ try {
14254
+ val = func.call(ctx.$, rec, ctx);
14255
+ } catch(e) {
14256
+ stop(e.name, "in expression [" + exp + "]:", e.message);
14257
+ }
14258
+ return val;
14259
+ };
14260
+ }
14261
+
14262
+ function compileExpressionToFunction(exp, opts) {
14263
+ // $$ added to avoid duplication with data field variables (an error condition)
14264
+ var functionBody, func;
14265
+ if (opts.returns) {
14266
+ // functionBody = 'return ' + functionBody;
14267
+ functionBody = 'var $$retn = ' + exp + '; return $$retn;';
14268
+ } else {
14269
+ functionBody = exp;
14270
+ }
14271
+ functionBody = 'with($$env){with($$record){ ' + functionBody + '}}';
14272
+ try {
14273
+ func = new Function('$$record,$$env', functionBody);
14274
+ } catch(e) {
14275
+ // if (opts.quiet) throw e;
14276
+ stop(e.name, 'in expression [' + exp + ']');
14277
+ }
14278
+ return func;
14279
+ }
14280
+
14281
+ function getBaseContext(ctx) {
14282
+ ctx = ctx || {};
14283
+ // Mask global properties (is this effective/worth doing?)
14284
+ ctx.globalThis = void 0; // some globals are not iterable
14285
+ (function() {
14286
+ for (var key in this) {
14287
+ ctx[key] = void 0;
14288
+ }
14289
+ }());
14290
+ ctx.console = console;
14291
+ return ctx;
14292
+ }
14293
+
14294
+ var Expressions = /*#__PURE__*/Object.freeze({
14295
+ __proto__: null,
14296
+ getAssignedVars: getAssignedVars,
14297
+ getExpressionFunction: getExpressionFunction,
14298
+ compileExpressionToFunction: compileExpressionToFunction,
14299
+ getBaseContext: getBaseContext
14300
+ });
14301
+
14212
14302
  // Compiled expression returns a value
14213
14303
  function compileValueExpression(exp, lyr, arcs, opts) {
14214
14304
  opts = opts || {};
@@ -14216,7 +14306,6 @@
14216
14306
  return compileFeatureExpression(exp, lyr, arcs, opts);
14217
14307
  }
14218
14308
 
14219
-
14220
14309
  function compileFeaturePairFilterExpression(exp, lyr, arcs) {
14221
14310
  var func = compileFeaturePairExpression(exp, lyr, arcs);
14222
14311
  return function(idA, idB) {
@@ -14232,13 +14321,16 @@
14232
14321
  var exp = cleanExpression(rawExp);
14233
14322
  // don't add layer data to the context
14234
14323
  // (fields are not added to the pair expression context)
14235
- var ctx = getExpressionContext({});
14324
+ var ctx = getFeatureExpressionContext({});
14236
14325
  var getA = getProxyFactory(lyr, arcs);
14237
14326
  var getB = getProxyFactory(lyr, arcs);
14238
14327
  var vars = getAssignedVars(exp);
14239
14328
  var functionBody = "with($$env){with($$record){return " + exp + "}}";
14240
14329
  var func;
14241
14330
 
14331
+ // protect global object from assigned values
14332
+ nullifyUnsetProperties(vars, ctx);
14333
+
14242
14334
  try {
14243
14335
  func = new Function("$$record,$$env", functionBody);
14244
14336
  } catch(e) {
@@ -14246,9 +14338,6 @@
14246
14338
  stop(e.name, "in expression [" + exp + "]");
14247
14339
  }
14248
14340
 
14249
- // protect global object from assigned values
14250
- nullifyUnsetProperties(vars, ctx);
14251
-
14252
14341
  function getProxyFactory(lyr, arcs) {
14253
14342
  var records = lyr.data ? lyr.data.getRecords() : [];
14254
14343
  var getFeatureById = initFeatureProxy(lyr, arcs);
@@ -14284,12 +14373,12 @@
14284
14373
  };
14285
14374
  }
14286
14375
 
14287
- function compileFeatureExpression(rawExp, lyr, arcs, opts_) {
14288
- var opts = utils.extend({}, opts_),
14376
+ function compileFeatureExpression(rawExp, lyr, arcs, optsArg) {
14377
+ var opts = optsArg || {},
14378
+ ctx = opts.context || {},
14289
14379
  exp = cleanExpression(rawExp || ''),
14290
14380
  mutable = !opts.no_assign, // block assignment expressions
14291
- vars = getAssignedVars(exp),
14292
- func, records;
14381
+ vars = getAssignedVars(exp);
14293
14382
 
14294
14383
  if (mutable && vars.length > 0 && !lyr.data) {
14295
14384
  initDataTable(lyr);
@@ -14297,110 +14386,45 @@
14297
14386
 
14298
14387
  if (!mutable) {
14299
14388
  // protect global object from assigned values
14300
- opts.context = opts.context || {};
14301
- nullifyUnsetProperties(vars, opts.context);
14389
+ nullifyUnsetProperties(vars, ctx);
14302
14390
  }
14303
14391
 
14304
- records = lyr.data ? lyr.data.getRecords() : [];
14305
- func = getExpressionFunction(exp, lyr, arcs, opts);
14392
+ var records = lyr.data ? lyr.data.getRecords() : [];
14393
+ var getFeatureById = initFeatureProxy(lyr, arcs, opts);
14394
+ var layerOnlyProxy = addLayerGetters({}, lyr, arcs);
14395
+ var func = getExpressionFunction(exp, opts);
14396
+ ctx = getFeatureExpressionContext(lyr, ctx, opts);
14306
14397
 
14307
- // @destRec (optional) substitute for records[recId] (used by -calc)
14398
+ // recId: index of a data record in the records array.
14399
+ // destRec: (optional argument, used by -calc) an object used to capture assignments
14400
+ // By default, assignments are captured by records[recId]
14401
+ //
14308
14402
  return function(recId, destRec) {
14309
- var record;
14403
+ var rec;
14310
14404
  if (destRec) {
14311
- record = destRec;
14405
+ rec = destRec;
14312
14406
  } else {
14313
- record = records[recId] || (records[recId] = {});
14314
- }
14407
+ rec = records[recId] || (records[recId] = {});
14408
+ }
14409
+ // Assigning feature/layer proxy to '$' ... ctx.$ is also exposed as 'this'
14410
+ // in the expression context.
14411
+ ctx.$ = recId >= 0 ? getFeatureById(recId) : layerOnlyProxy;
14412
+ // "_" is used as an alias for the expression context, so functions can still
14413
+ // be used when masked by variables of the same name.
14414
+ ctx._ = ctx;
14415
+ // Expose data properties using "d", like d3 does. (data propertries are
14416
+ // also available as "this.properties")
14417
+ ctx.d = rec || null;
14315
14418
 
14316
- // initialize new fields to null so assignments work
14317
14419
  if (mutable) {
14318
- nullifyUnsetProperties(vars, record);
14319
- }
14320
- return func(record, recId);
14321
- };
14322
- }
14323
-
14324
- // Return array of variables on the left side of assignment operations
14325
- // @hasDot (bool) Return property assignments via dot notation
14326
- function getAssignedVars(exp, hasDot) {
14327
- var rxp = /[a-z_$][.a-z0-9_$]*(?= *=[^>=])/ig; // ignore arrow functions and comparisons
14328
- var matches = exp.match(rxp) || [];
14329
- var f = function(s) {
14330
- var i = s.indexOf('.');
14331
- return hasDot ? i > -1 : i == -1;
14332
- };
14333
- var vars = utils.uniq(matches.filter(f));
14334
- return vars;
14335
- }
14336
-
14337
- // Return array of objects with properties assigned via dot notation
14338
- // e.g. 'd.value = 45' -> ['d']
14339
- function getAssignmentObjects(exp) {
14340
- var matches = getAssignedVars(exp, true),
14341
- names = [];
14342
- matches.forEach(function(s) {
14343
- var match = /^([^.]+)\.[^.]+$/.exec(s);
14344
- var name = match ? match[1] : null;
14345
- if (name && name != 'this') {
14346
- names.push(name);
14347
- }
14348
- });
14349
- return utils.uniq(names);
14350
- }
14351
-
14352
- function compileExpressionToFunction(exp, opts) {
14353
- // $$ added to avoid duplication with data field variables (an error condition)
14354
- var functionBody, func;
14355
- if (opts.returns) {
14356
- // functionBody = 'return ' + functionBody;
14357
- functionBody = 'var $$retn = ' + exp + '; return $$retn;';
14358
- } else {
14359
- functionBody = exp;
14360
- }
14361
- functionBody = 'with($$env){with($$record){ ' + functionBody + '}}';
14362
- try {
14363
- func = new Function('$$record,$$env', functionBody);
14364
- } catch(e) {
14365
- // if (opts.quiet) throw e;
14366
- stop(e.name, 'in expression [' + exp + ']');
14367
- }
14368
- return func;
14369
- }
14370
-
14371
- function getExpressionFunction(exp, lyr, arcs, opts) {
14372
- var getFeatureById = initFeatureProxy(lyr, arcs, opts);
14373
- var layerOnlyProxy = addLayerGetters({}, lyr, arcs);
14374
- var ctx = getExpressionContext(lyr, opts.context, opts);
14375
- var func = compileExpressionToFunction(exp, opts);
14376
- return function(rec, i) {
14377
- var val;
14378
- // Assigning feature/layer proxy to '$' -- maybe this should be removed,
14379
- // since it is also exposed as "this".
14380
- // (kludge) i is undefined in calc expressions ... we still
14381
- // may need layer data (but not single-feature data)
14382
- ctx.$ = i >= 0 ? getFeatureById(i) : layerOnlyProxy;
14383
- ctx._ = ctx; // provide access to functions when masked by variable names
14384
- ctx.d = rec || null; // expose data properties a la d3 (also exposed as this.properties)
14385
- try {
14386
- val = func.call(ctx.$, rec, ctx);
14387
- } catch(e) {
14388
- // if (opts.quiet) throw e;
14389
- stop(e.name, "in expression [" + exp + "]:", e.message);
14420
+ // initialize assigned variables to rec.null so rec can capture them
14421
+ nullifyUnsetProperties(vars, rec);
14390
14422
  }
14391
- return val;
14423
+ return func(rec, ctx);
14392
14424
  };
14393
14425
  }
14394
14426
 
14395
- function nullifyUnsetProperties(vars, obj) {
14396
- for (var i=0; i<vars.length; i++) {
14397
- if (vars[i] in obj === false) {
14398
- obj[vars[i]] = null;
14399
- }
14400
- }
14401
- }
14402
-
14403
- function getExpressionContext(lyr, mixins, opts) {
14427
+ function getFeatureExpressionContext(lyr, mixins, opts) {
14404
14428
  var defs = getStashedVar('defs');
14405
14429
  var env = getBaseContext();
14406
14430
  var ctx = {};
@@ -14446,29 +14470,20 @@
14446
14470
  }, ctx);
14447
14471
  }
14448
14472
 
14449
- function getBaseContext(ctx) {
14450
- ctx = ctx || {};
14451
- // Mask global properties (is this effective/worth doing?)
14452
- ctx.globalThis = void 0; // some globals are not iterable
14453
- (function() {
14454
- for (var key in this) {
14455
- ctx[key] = void 0;
14473
+ function nullifyUnsetProperties(vars, obj) {
14474
+ for (var i=0; i<vars.length; i++) {
14475
+ if (vars[i] in obj === false) {
14476
+ obj[vars[i]] = null;
14456
14477
  }
14457
- }());
14458
- ctx.console = console;
14459
- return ctx;
14478
+ }
14460
14479
  }
14461
14480
 
14462
- var Expressions = /*#__PURE__*/Object.freeze({
14481
+ var FeatureExpressions = /*#__PURE__*/Object.freeze({
14463
14482
  __proto__: null,
14464
14483
  compileValueExpression: compileValueExpression,
14465
14484
  compileFeaturePairFilterExpression: compileFeaturePairFilterExpression,
14466
14485
  compileFeaturePairExpression: compileFeaturePairExpression,
14467
- compileFeatureExpression: compileFeatureExpression,
14468
- getAssignedVars: getAssignedVars,
14469
- getAssignmentObjects: getAssignmentObjects,
14470
- compileExpressionToFunction: compileExpressionToFunction,
14471
- getBaseContext: getBaseContext
14486
+ compileFeatureExpression: compileFeatureExpression
14472
14487
  });
14473
14488
 
14474
14489
  function getMode(values) {
@@ -25221,11 +25236,12 @@ ${svg}
25221
25236
  describe: 'use field values to calculate data island weights'
25222
25237
  });
25223
25238
 
25224
- parser.command('external')
25225
- .option('module', {
25226
- DEFAULT: true,
25227
- describe: 'name of Node module containing the command'
25228
- });
25239
+ // replaced by -require
25240
+ // parser.command('external')
25241
+ // .option('module', {
25242
+ // DEFAULT: true,
25243
+ // describe: 'name of Node module containing the command'
25244
+ // });
25229
25245
 
25230
25246
  parser.command('filter-points')
25231
25247
  // .describe('remove points that are not part of a group')
@@ -25311,17 +25327,17 @@ ${svg}
25311
25327
  .option('no-replace', noReplaceOpt);
25312
25328
 
25313
25329
  parser.command('require')
25314
- .describe('require a Node module for use in -each expressions')
25330
+ .describe('require a Node module or ES module to use in JS expressions')
25315
25331
  .option('module', {
25316
25332
  DEFAULT: true,
25317
- describe: 'name of Node module or path to module file'
25333
+ describe: 'name of installed module or path to module file'
25318
25334
  })
25319
25335
  .option('alias', {
25320
25336
  describe: 'Set the module name to an alias'
25321
- })
25322
- .option('init', {
25323
- describe: 'JS expression to run after the module loads'
25324
25337
  });
25338
+ // .option('init', {
25339
+ // describe: 'JS expression to run after the module loads'
25340
+ // });
25325
25341
 
25326
25342
  parser.command('rotate')
25327
25343
  // .describe('apply d3-style 3-axis rotation to a lat-long dataset')
@@ -35318,7 +35334,6 @@ ${svg}
35318
35334
  if (targets.length === 0 && targetId) {
35319
35335
  stop('Layer not found:', targetId);
35320
35336
  }
35321
- // var vars = getAssignedVars(exp);
35322
35337
  var defs = getStashedVar('defs') || {};
35323
35338
 
35324
35339
  var ctx;
@@ -41983,8 +41998,8 @@ ${svg}
41983
41998
  return true;
41984
41999
  }
41985
42000
 
41986
- cmd.require = async function(targets, opts) {
41987
- var defs = getStashedVar('defs');
42001
+ cmd.require = async function(opts) {
42002
+ var globals = getStashedVar('defs');
41988
42003
  var moduleFile, moduleName, mod;
41989
42004
  if (!opts.module) {
41990
42005
  stop("Missing module name or path to module");
@@ -42000,25 +42015,33 @@ ${svg}
42000
42015
  moduleFile = require$1('path').join(process.cwd(), moduleFile);
42001
42016
  }
42002
42017
  try {
42003
- mod = require$1(moduleFile || moduleName);
42018
+ // import CJS and ES modules
42019
+ mod = await import(moduleFile || moduleName);
42020
+ if (mod.default) {
42021
+ mod = mod.default;
42022
+ }
42004
42023
  if (typeof mod == 'function') {
42005
- // -require now includes the functionality of the old -external command
42024
+ // assuming that functions are mapshpaper command generators...
42025
+ // this MUST be changed asap.
42006
42026
  var retn = mod(api);
42007
42027
  if (retn && isValidExternalCommand(retn)) {
42008
42028
  cmd.registerCommand(retn.name, retn);
42009
42029
  }
42010
42030
  }
42011
42031
  } catch(e) {
42012
- stop('Unable to load external module:', e.message, getErrorDetail(e));
42032
+ if (!mod) {
42033
+ stop('Unable to load external module:', e.message, getErrorDetail(e));
42034
+ }
42013
42035
  }
42014
42036
  if (moduleName || opts.alias) {
42015
- defs[opts.alias || moduleName] = mod;
42037
+ globals[opts.alias || moduleName] = mod;
42016
42038
  } else {
42017
- Object.assign(defs, mod);
42018
- }
42019
- if (opts.init) {
42020
- await evalTemplateExpression(opts.init, targets);
42039
+ Object.assign(globals, mod);
42021
42040
  }
42041
+ // instead of an init expression, you could use -run <expression>
42042
+ // if (opts.init) {
42043
+ // await evalTemplateExpression(opts.init, targets);
42044
+ // }
42022
42045
  };
42023
42046
 
42024
42047
  // Parse an array or a string of command line tokens into an array of
@@ -42123,7 +42146,8 @@ ${svg}
42123
42146
  stop('Expected a string containing mapshaper commands; received:', tmp);
42124
42147
  }
42125
42148
  if (tmp) {
42126
- message(`command: [${tmp}]`);
42149
+ // truncate message (command might include a large GeoJSON string in an -i command)
42150
+ message(`command: [${truncateString(tmp, 150)}]`);
42127
42151
  commands = parseCommands(tmp);
42128
42152
 
42129
42153
  // TODO: remove duplication with mapshaper-run-commands.mjs
@@ -44473,9 +44497,9 @@ ${svg}
44473
44497
  } else if (name == 'explode') {
44474
44498
  outputLayers = applyCommandToEachLayer(cmd.explodeFeatures, targetLayers, arcs, opts);
44475
44499
 
44476
- } else if (name == 'external') {
44477
- // -require now incorporates -external
44478
- cmd.require(targets, opts);
44500
+ // -require now incorporates functionality of -external
44501
+ // } else if (name == 'external') {
44502
+ // cmd.require(targets, opts);
44479
44503
 
44480
44504
  } else if (name == 'filter') {
44481
44505
  outputLayers = applyCommandToEachLayer(cmd.filterFeatures, targetLayers, arcs, opts);
@@ -44617,7 +44641,7 @@ ${svg}
44617
44641
  cmd.renameLayers(targetLayers, opts.names, job.catalog);
44618
44642
 
44619
44643
  } else if (name == 'require') {
44620
- cmd.require(targets, opts);
44644
+ await cmd.require(opts);
44621
44645
 
44622
44646
  } else if (name == 'rotate') {
44623
44647
  targets.forEach(function(targ) {
@@ -45445,6 +45469,7 @@ ${svg}
45445
45469
  Explode,
45446
45470
  Export,
45447
45471
  Expressions,
45472
+ FeatureExpressions,
45448
45473
  FileExport,
45449
45474
  FileImport,
45450
45475
  FilenameUtils,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mapshaper",
3
- "version": "0.6.54",
3
+ "version": "0.6.56",
4
4
  "description": "A tool for editing vector datasets for mapping and GIS.",
5
5
  "keywords": [
6
6
  "shapefile",
package/www/index.html CHANGED
@@ -308,9 +308,10 @@ encoding=big5</span>. Click to see all options.</div></div></div></div>
308
308
  <div class="mshp-main-map main-area map-area">
309
309
  <div class="coordinate-info colored-text selectable"></div>
310
310
  <div class="intersection-display">
311
- <div class="intersection-check text-btn colored-text">Check line intersections</div>
312
- <div class="intersection-count">0 line intersections</div>
311
+ <span class="intersection-check text-btn colored-text">Check line intersections</span><span class="intersection-count">0 line intersections</span>
312
+ <img class="close-btn" draggable="false" src="images/close.png">
313
313
  <div class="repair-btn text-btn colored-text">Repair</div>
314
+
314
315
  </div>
315
316
  <div class="map-layers"></div>
316
317
  <div class="basemap-container"><div class="basemap"></div></div>
@@ -654,8 +654,9 @@
654
654
  },
655
655
 
656
656
  show: function(css) {
657
+ var tag = this.el && this.el.tagName;
657
658
  if (!this.visible()) {
658
- this.css('display:block;');
659
+ this.css('display', tag == 'SPAN' ? 'inline-block' : 'block');
659
660
  this._hidden = false;
660
661
  }
661
662
  return this;
@@ -3561,7 +3562,10 @@
3561
3562
  repairBtn = el.findChild(".repair-btn"),
3562
3563
  _simplifiedXX, // saved simplified intersections, for repair
3563
3564
  _unsimplifiedXX, // saved unsimplified intersection data, for performance
3564
- _disabled = false;
3565
+ _disabled = false,
3566
+ _on = false;
3567
+
3568
+ el.findChild('.close-btn').on('click', dismissForever);
3565
3569
 
3566
3570
  gui.on('simplify_drag_start', function() {
3567
3571
  if (intersectionsAreOn()) {
@@ -3570,19 +3574,20 @@
3570
3574
  });
3571
3575
 
3572
3576
  gui.on('simplify_drag_end', function() {
3573
- updateAsync();
3577
+ updateSync('simplify_drag_end');
3574
3578
  });
3575
3579
 
3576
3580
  checkBtn.on('click', function() {
3577
3581
  checkBtn.hide();
3578
- refreshSync();
3582
+ _on = true;
3583
+ updateSync();
3579
3584
  });
3580
3585
 
3581
3586
  repairBtn.on('click', function() {
3582
3587
  var e = model.getActiveLayer();
3583
3588
  if (!_simplifiedXX || !e.dataset.arcs) return;
3584
- var xx = _simplifiedXX = internal.repairIntersections(e.dataset.arcs, _simplifiedXX);
3585
- showIntersections(xx, e.layer, e.dataset.arcs);
3589
+ _simplifiedXX = internal.repairIntersections(e.dataset.arcs, _simplifiedXX);
3590
+ showIntersections(_simplifiedXX, e.layer, e.dataset.arcs);
3586
3591
  repairBtn.hide();
3587
3592
  model.updated({repair: true});
3588
3593
  gui.session.simplificationRepair();
@@ -3593,7 +3598,8 @@
3593
3598
  reset(); // need this?
3594
3599
  return;
3595
3600
  }
3596
- var needRefresh = e.flags.simplify_method || e.flags.simplify || e.flags.repair;
3601
+ var needRefresh = e.flags.simplify_method || e.flags.simplify ||
3602
+ e.flags.repair || e.flags.clean;
3597
3603
  if (needRefresh) {
3598
3604
  updateAsync();
3599
3605
  } else if (e.flags.simplify_amount) {
@@ -3608,17 +3614,18 @@
3608
3614
  });
3609
3615
 
3610
3616
  function intersectionsAreOn() {
3611
- return !!(_simplifiedXX || _unsimplifiedXX);
3617
+ return _on && !_disabled;
3612
3618
  }
3613
3619
 
3614
- function clearSavedData() {
3620
+ function turnOff() {
3621
+ hide();
3622
+ _on = false;
3615
3623
  _simplifiedXX = null;
3616
3624
  _unsimplifiedXX = null;
3617
3625
  }
3618
3626
 
3619
3627
  function reset() {
3620
- clearSavedData();
3621
- hide();
3628
+ turnOff();
3622
3629
  if (_disabled) {
3623
3630
  return;
3624
3631
  }
@@ -3633,8 +3640,7 @@
3633
3640
 
3634
3641
  function dismissForever() {
3635
3642
  _disabled = true;
3636
- clearSavedData();
3637
- hide();
3643
+ turnOff();
3638
3644
  }
3639
3645
 
3640
3646
  function hide() {
@@ -3645,12 +3651,11 @@
3645
3651
  // Update intersection display, after a short delay so map can redraw after previous
3646
3652
  // operation (e.g. simplification change)
3647
3653
  function updateAsync() {
3648
- if (intersectionsAreOn()) {
3649
- setTimeout(refreshSync, 10);
3650
- }
3654
+ setTimeout(updateSync, 10);
3651
3655
  }
3652
3656
 
3653
- function refreshSync() {
3657
+ function updateSync(action) {
3658
+ if (!intersectionsAreOn()) return;
3654
3659
  var e = model.getActiveLayer();
3655
3660
  var arcs = e.dataset && e.dataset.arcs;
3656
3661
  var intersectionOpts = {
@@ -3661,13 +3666,14 @@
3661
3666
  return;
3662
3667
  }
3663
3668
  if (arcs.getRetainedInterval() > 0) {
3669
+ // simplification
3664
3670
  _simplifiedXX = internal.findSegmentIntersections(arcs, intersectionOpts);
3665
3671
  } else {
3666
3672
  // no simplification
3667
- _simplifiedXX = null; // clear old simplified XX
3668
- if (!_unsimplifiedXX) {
3669
- // save intersections at 0 simplification, to avoid recalculating
3670
- // every time the simplification slider is set to 100% or the layer is selected at 100%
3673
+ _simplifiedXX = null; // clear any old simplified XX
3674
+ if (_unsimplifiedXX && action == 'simplify_drag_end') {
3675
+ // re-use previously generated intersection data (optimization)
3676
+ } else {
3671
3677
  _unsimplifiedXX = internal.findSegmentIntersections(arcs, intersectionOpts);
3672
3678
  }
3673
3679
  }
@@ -3675,7 +3681,7 @@
3675
3681
  }
3676
3682
 
3677
3683
  function showIntersections(xx, lyr, arcs) {
3678
- var pointLyr, count = 0;
3684
+ var pointLyr, count = 0, html;
3679
3685
  el.show();
3680
3686
  readout.show();
3681
3687
  checkBtn.hide();
@@ -3685,12 +3691,13 @@
3685
3691
  }
3686
3692
  if (count == 0) {
3687
3693
  map.setIntersectionLayer(null);
3688
- readout.html('<span class="icon black"></span>No self-intersections');
3694
+ html = '<span class="icon black"></span>No self-intersections';
3689
3695
  } else {
3690
3696
  map.setIntersectionLayer(pointLyr, {layers:[pointLyr]});
3691
- readout.html(utils$1.format('<span class="icon"></span>%s line intersection%s <img class="close-btn" src="images/close.png">', count, utils$1.pluralSuffix(count)));
3692
- readout.findChild('.close-btn').on('click', dismissForever);
3697
+ html = utils$1.format('<span class="icon"></span>%s line intersection%s', count, utils$1.pluralSuffix(count));
3693
3698
  }
3699
+ readout.html(html);
3700
+
3694
3701
  if (_simplifiedXX && count > 0) {
3695
3702
  repairBtn.show();
3696
3703
  } else {
@@ -5367,6 +5374,14 @@
5367
5374
  else console.error(msg);
5368
5375
  }
5369
5376
 
5377
+ function truncateString(str, maxLen) {
5378
+ maxLen = maxLen || 80;
5379
+ if (str.length > maxLen) {
5380
+ str = str.substring(0, maxLen - 3).trimEnd() + '...';
5381
+ }
5382
+ return str;
5383
+ }
5384
+
5370
5385
  var uniqCount = 0;
5371
5386
  function getUniqueName(prefix) {
5372
5387
  return (prefix || "__id_") + (++uniqCount);
package/www/mapshaper.js CHANGED
@@ -1,6 +1,6 @@
1
1
  (function () {
2
2
 
3
- var VERSION = "0.6.54";
3
+ var VERSION = "0.6.56";
4
4
 
5
5
 
6
6
  var utils = /*#__PURE__*/Object.freeze({
@@ -1403,6 +1403,14 @@
1403
1403
  else console.error(msg);
1404
1404
  }
1405
1405
 
1406
+ function truncateString(str, maxLen) {
1407
+ maxLen = maxLen || 80;
1408
+ if (str.length > maxLen) {
1409
+ str = str.substring(0, maxLen - 3).trimEnd() + '...';
1410
+ }
1411
+ return str;
1412
+ }
1413
+
1406
1414
  var Logging = /*#__PURE__*/Object.freeze({
1407
1415
  __proto__: null,
1408
1416
  getLoggingSetter: getLoggingSetter,
@@ -1424,7 +1432,8 @@
1424
1432
  formatColumns: formatColumns,
1425
1433
  formatStringsAsGrid: formatStringsAsGrid,
1426
1434
  formatLogArgs: formatLogArgs,
1427
- logArgs: logArgs
1435
+ logArgs: logArgs,
1436
+ truncateString: truncateString
1428
1437
  });
1429
1438
 
1430
1439
  function Transform() {
@@ -14209,6 +14218,87 @@
14209
14218
  };
14210
14219
  }
14211
14220
 
14221
+ // Return array of variables on the left side of assignment operations
14222
+ // @hasDot (bool) Return property assignments via dot notation
14223
+ function getAssignedVars(exp, hasDot) {
14224
+ var rxp = /[a-z_$][.a-z0-9_$]*(?= *=[^>=])/ig; // ignore arrow functions and comparisons
14225
+ var matches = exp.match(rxp) || [];
14226
+ var f = function(s) {
14227
+ var i = s.indexOf('.');
14228
+ return hasDot ? i > -1 : i == -1;
14229
+ };
14230
+ var vars = utils.uniq(matches.filter(f));
14231
+ return vars;
14232
+ }
14233
+
14234
+ // Return array of objects with properties assigned via dot notation
14235
+ // e.g. 'd.value = 45' -> ['d']
14236
+ // export function getAssignmentObjects(exp) {
14237
+ // var matches = getAssignedVars(exp, true),
14238
+ // names = [];
14239
+ // matches.forEach(function(s) {
14240
+ // var match = /^([^.]+)\.[^.]+$/.exec(s);
14241
+ // var name = match ? match[1] : null;
14242
+ // if (name && name != 'this') {
14243
+ // names.push(name);
14244
+ // }
14245
+ // });
14246
+ // return utils.uniq(names);
14247
+ // }
14248
+
14249
+ function getExpressionFunction(exp, opts) {
14250
+ var func = compileExpressionToFunction(exp, opts);
14251
+ return function(rec, ctx) {
14252
+ var val;
14253
+ try {
14254
+ val = func.call(ctx.$, rec, ctx);
14255
+ } catch(e) {
14256
+ stop(e.name, "in expression [" + exp + "]:", e.message);
14257
+ }
14258
+ return val;
14259
+ };
14260
+ }
14261
+
14262
+ function compileExpressionToFunction(exp, opts) {
14263
+ // $$ added to avoid duplication with data field variables (an error condition)
14264
+ var functionBody, func;
14265
+ if (opts.returns) {
14266
+ // functionBody = 'return ' + functionBody;
14267
+ functionBody = 'var $$retn = ' + exp + '; return $$retn;';
14268
+ } else {
14269
+ functionBody = exp;
14270
+ }
14271
+ functionBody = 'with($$env){with($$record){ ' + functionBody + '}}';
14272
+ try {
14273
+ func = new Function('$$record,$$env', functionBody);
14274
+ } catch(e) {
14275
+ // if (opts.quiet) throw e;
14276
+ stop(e.name, 'in expression [' + exp + ']');
14277
+ }
14278
+ return func;
14279
+ }
14280
+
14281
+ function getBaseContext(ctx) {
14282
+ ctx = ctx || {};
14283
+ // Mask global properties (is this effective/worth doing?)
14284
+ ctx.globalThis = void 0; // some globals are not iterable
14285
+ (function() {
14286
+ for (var key in this) {
14287
+ ctx[key] = void 0;
14288
+ }
14289
+ }());
14290
+ ctx.console = console;
14291
+ return ctx;
14292
+ }
14293
+
14294
+ var Expressions = /*#__PURE__*/Object.freeze({
14295
+ __proto__: null,
14296
+ getAssignedVars: getAssignedVars,
14297
+ getExpressionFunction: getExpressionFunction,
14298
+ compileExpressionToFunction: compileExpressionToFunction,
14299
+ getBaseContext: getBaseContext
14300
+ });
14301
+
14212
14302
  // Compiled expression returns a value
14213
14303
  function compileValueExpression(exp, lyr, arcs, opts) {
14214
14304
  opts = opts || {};
@@ -14216,7 +14306,6 @@
14216
14306
  return compileFeatureExpression(exp, lyr, arcs, opts);
14217
14307
  }
14218
14308
 
14219
-
14220
14309
  function compileFeaturePairFilterExpression(exp, lyr, arcs) {
14221
14310
  var func = compileFeaturePairExpression(exp, lyr, arcs);
14222
14311
  return function(idA, idB) {
@@ -14232,13 +14321,16 @@
14232
14321
  var exp = cleanExpression(rawExp);
14233
14322
  // don't add layer data to the context
14234
14323
  // (fields are not added to the pair expression context)
14235
- var ctx = getExpressionContext({});
14324
+ var ctx = getFeatureExpressionContext({});
14236
14325
  var getA = getProxyFactory(lyr, arcs);
14237
14326
  var getB = getProxyFactory(lyr, arcs);
14238
14327
  var vars = getAssignedVars(exp);
14239
14328
  var functionBody = "with($$env){with($$record){return " + exp + "}}";
14240
14329
  var func;
14241
14330
 
14331
+ // protect global object from assigned values
14332
+ nullifyUnsetProperties(vars, ctx);
14333
+
14242
14334
  try {
14243
14335
  func = new Function("$$record,$$env", functionBody);
14244
14336
  } catch(e) {
@@ -14246,9 +14338,6 @@
14246
14338
  stop(e.name, "in expression [" + exp + "]");
14247
14339
  }
14248
14340
 
14249
- // protect global object from assigned values
14250
- nullifyUnsetProperties(vars, ctx);
14251
-
14252
14341
  function getProxyFactory(lyr, arcs) {
14253
14342
  var records = lyr.data ? lyr.data.getRecords() : [];
14254
14343
  var getFeatureById = initFeatureProxy(lyr, arcs);
@@ -14284,12 +14373,12 @@
14284
14373
  };
14285
14374
  }
14286
14375
 
14287
- function compileFeatureExpression(rawExp, lyr, arcs, opts_) {
14288
- var opts = utils.extend({}, opts_),
14376
+ function compileFeatureExpression(rawExp, lyr, arcs, optsArg) {
14377
+ var opts = optsArg || {},
14378
+ ctx = opts.context || {},
14289
14379
  exp = cleanExpression(rawExp || ''),
14290
14380
  mutable = !opts.no_assign, // block assignment expressions
14291
- vars = getAssignedVars(exp),
14292
- func, records;
14381
+ vars = getAssignedVars(exp);
14293
14382
 
14294
14383
  if (mutable && vars.length > 0 && !lyr.data) {
14295
14384
  initDataTable(lyr);
@@ -14297,110 +14386,45 @@
14297
14386
 
14298
14387
  if (!mutable) {
14299
14388
  // protect global object from assigned values
14300
- opts.context = opts.context || {};
14301
- nullifyUnsetProperties(vars, opts.context);
14389
+ nullifyUnsetProperties(vars, ctx);
14302
14390
  }
14303
14391
 
14304
- records = lyr.data ? lyr.data.getRecords() : [];
14305
- func = getExpressionFunction(exp, lyr, arcs, opts);
14392
+ var records = lyr.data ? lyr.data.getRecords() : [];
14393
+ var getFeatureById = initFeatureProxy(lyr, arcs, opts);
14394
+ var layerOnlyProxy = addLayerGetters({}, lyr, arcs);
14395
+ var func = getExpressionFunction(exp, opts);
14396
+ ctx = getFeatureExpressionContext(lyr, ctx, opts);
14306
14397
 
14307
- // @destRec (optional) substitute for records[recId] (used by -calc)
14398
+ // recId: index of a data record in the records array.
14399
+ // destRec: (optional argument, used by -calc) an object used to capture assignments
14400
+ // By default, assignments are captured by records[recId]
14401
+ //
14308
14402
  return function(recId, destRec) {
14309
- var record;
14403
+ var rec;
14310
14404
  if (destRec) {
14311
- record = destRec;
14405
+ rec = destRec;
14312
14406
  } else {
14313
- record = records[recId] || (records[recId] = {});
14314
- }
14407
+ rec = records[recId] || (records[recId] = {});
14408
+ }
14409
+ // Assigning feature/layer proxy to '$' ... ctx.$ is also exposed as 'this'
14410
+ // in the expression context.
14411
+ ctx.$ = recId >= 0 ? getFeatureById(recId) : layerOnlyProxy;
14412
+ // "_" is used as an alias for the expression context, so functions can still
14413
+ // be used when masked by variables of the same name.
14414
+ ctx._ = ctx;
14415
+ // Expose data properties using "d", like d3 does. (data propertries are
14416
+ // also available as "this.properties")
14417
+ ctx.d = rec || null;
14315
14418
 
14316
- // initialize new fields to null so assignments work
14317
14419
  if (mutable) {
14318
- nullifyUnsetProperties(vars, record);
14319
- }
14320
- return func(record, recId);
14321
- };
14322
- }
14323
-
14324
- // Return array of variables on the left side of assignment operations
14325
- // @hasDot (bool) Return property assignments via dot notation
14326
- function getAssignedVars(exp, hasDot) {
14327
- var rxp = /[a-z_$][.a-z0-9_$]*(?= *=[^>=])/ig; // ignore arrow functions and comparisons
14328
- var matches = exp.match(rxp) || [];
14329
- var f = function(s) {
14330
- var i = s.indexOf('.');
14331
- return hasDot ? i > -1 : i == -1;
14332
- };
14333
- var vars = utils.uniq(matches.filter(f));
14334
- return vars;
14335
- }
14336
-
14337
- // Return array of objects with properties assigned via dot notation
14338
- // e.g. 'd.value = 45' -> ['d']
14339
- function getAssignmentObjects(exp) {
14340
- var matches = getAssignedVars(exp, true),
14341
- names = [];
14342
- matches.forEach(function(s) {
14343
- var match = /^([^.]+)\.[^.]+$/.exec(s);
14344
- var name = match ? match[1] : null;
14345
- if (name && name != 'this') {
14346
- names.push(name);
14347
- }
14348
- });
14349
- return utils.uniq(names);
14350
- }
14351
-
14352
- function compileExpressionToFunction(exp, opts) {
14353
- // $$ added to avoid duplication with data field variables (an error condition)
14354
- var functionBody, func;
14355
- if (opts.returns) {
14356
- // functionBody = 'return ' + functionBody;
14357
- functionBody = 'var $$retn = ' + exp + '; return $$retn;';
14358
- } else {
14359
- functionBody = exp;
14360
- }
14361
- functionBody = 'with($$env){with($$record){ ' + functionBody + '}}';
14362
- try {
14363
- func = new Function('$$record,$$env', functionBody);
14364
- } catch(e) {
14365
- // if (opts.quiet) throw e;
14366
- stop(e.name, 'in expression [' + exp + ']');
14367
- }
14368
- return func;
14369
- }
14370
-
14371
- function getExpressionFunction(exp, lyr, arcs, opts) {
14372
- var getFeatureById = initFeatureProxy(lyr, arcs, opts);
14373
- var layerOnlyProxy = addLayerGetters({}, lyr, arcs);
14374
- var ctx = getExpressionContext(lyr, opts.context, opts);
14375
- var func = compileExpressionToFunction(exp, opts);
14376
- return function(rec, i) {
14377
- var val;
14378
- // Assigning feature/layer proxy to '$' -- maybe this should be removed,
14379
- // since it is also exposed as "this".
14380
- // (kludge) i is undefined in calc expressions ... we still
14381
- // may need layer data (but not single-feature data)
14382
- ctx.$ = i >= 0 ? getFeatureById(i) : layerOnlyProxy;
14383
- ctx._ = ctx; // provide access to functions when masked by variable names
14384
- ctx.d = rec || null; // expose data properties a la d3 (also exposed as this.properties)
14385
- try {
14386
- val = func.call(ctx.$, rec, ctx);
14387
- } catch(e) {
14388
- // if (opts.quiet) throw e;
14389
- stop(e.name, "in expression [" + exp + "]:", e.message);
14420
+ // initialize assigned variables to rec.null so rec can capture them
14421
+ nullifyUnsetProperties(vars, rec);
14390
14422
  }
14391
- return val;
14423
+ return func(rec, ctx);
14392
14424
  };
14393
14425
  }
14394
14426
 
14395
- function nullifyUnsetProperties(vars, obj) {
14396
- for (var i=0; i<vars.length; i++) {
14397
- if (vars[i] in obj === false) {
14398
- obj[vars[i]] = null;
14399
- }
14400
- }
14401
- }
14402
-
14403
- function getExpressionContext(lyr, mixins, opts) {
14427
+ function getFeatureExpressionContext(lyr, mixins, opts) {
14404
14428
  var defs = getStashedVar('defs');
14405
14429
  var env = getBaseContext();
14406
14430
  var ctx = {};
@@ -14446,29 +14470,20 @@
14446
14470
  }, ctx);
14447
14471
  }
14448
14472
 
14449
- function getBaseContext(ctx) {
14450
- ctx = ctx || {};
14451
- // Mask global properties (is this effective/worth doing?)
14452
- ctx.globalThis = void 0; // some globals are not iterable
14453
- (function() {
14454
- for (var key in this) {
14455
- ctx[key] = void 0;
14473
+ function nullifyUnsetProperties(vars, obj) {
14474
+ for (var i=0; i<vars.length; i++) {
14475
+ if (vars[i] in obj === false) {
14476
+ obj[vars[i]] = null;
14456
14477
  }
14457
- }());
14458
- ctx.console = console;
14459
- return ctx;
14478
+ }
14460
14479
  }
14461
14480
 
14462
- var Expressions = /*#__PURE__*/Object.freeze({
14481
+ var FeatureExpressions = /*#__PURE__*/Object.freeze({
14463
14482
  __proto__: null,
14464
14483
  compileValueExpression: compileValueExpression,
14465
14484
  compileFeaturePairFilterExpression: compileFeaturePairFilterExpression,
14466
14485
  compileFeaturePairExpression: compileFeaturePairExpression,
14467
- compileFeatureExpression: compileFeatureExpression,
14468
- getAssignedVars: getAssignedVars,
14469
- getAssignmentObjects: getAssignmentObjects,
14470
- compileExpressionToFunction: compileExpressionToFunction,
14471
- getBaseContext: getBaseContext
14486
+ compileFeatureExpression: compileFeatureExpression
14472
14487
  });
14473
14488
 
14474
14489
  function getMode(values) {
@@ -25221,11 +25236,12 @@ ${svg}
25221
25236
  describe: 'use field values to calculate data island weights'
25222
25237
  });
25223
25238
 
25224
- parser.command('external')
25225
- .option('module', {
25226
- DEFAULT: true,
25227
- describe: 'name of Node module containing the command'
25228
- });
25239
+ // replaced by -require
25240
+ // parser.command('external')
25241
+ // .option('module', {
25242
+ // DEFAULT: true,
25243
+ // describe: 'name of Node module containing the command'
25244
+ // });
25229
25245
 
25230
25246
  parser.command('filter-points')
25231
25247
  // .describe('remove points that are not part of a group')
@@ -25311,17 +25327,17 @@ ${svg}
25311
25327
  .option('no-replace', noReplaceOpt);
25312
25328
 
25313
25329
  parser.command('require')
25314
- .describe('require a Node module for use in -each expressions')
25330
+ .describe('require a Node module or ES module to use in JS expressions')
25315
25331
  .option('module', {
25316
25332
  DEFAULT: true,
25317
- describe: 'name of Node module or path to module file'
25333
+ describe: 'name of installed module or path to module file'
25318
25334
  })
25319
25335
  .option('alias', {
25320
25336
  describe: 'Set the module name to an alias'
25321
- })
25322
- .option('init', {
25323
- describe: 'JS expression to run after the module loads'
25324
25337
  });
25338
+ // .option('init', {
25339
+ // describe: 'JS expression to run after the module loads'
25340
+ // });
25325
25341
 
25326
25342
  parser.command('rotate')
25327
25343
  // .describe('apply d3-style 3-axis rotation to a lat-long dataset')
@@ -35318,7 +35334,6 @@ ${svg}
35318
35334
  if (targets.length === 0 && targetId) {
35319
35335
  stop('Layer not found:', targetId);
35320
35336
  }
35321
- // var vars = getAssignedVars(exp);
35322
35337
  var defs = getStashedVar('defs') || {};
35323
35338
 
35324
35339
  var ctx;
@@ -41983,8 +41998,8 @@ ${svg}
41983
41998
  return true;
41984
41999
  }
41985
42000
 
41986
- cmd.require = async function(targets, opts) {
41987
- var defs = getStashedVar('defs');
42001
+ cmd.require = async function(opts) {
42002
+ var globals = getStashedVar('defs');
41988
42003
  var moduleFile, moduleName, mod;
41989
42004
  if (!opts.module) {
41990
42005
  stop("Missing module name or path to module");
@@ -42000,25 +42015,33 @@ ${svg}
42000
42015
  moduleFile = require$1('path').join(process.cwd(), moduleFile);
42001
42016
  }
42002
42017
  try {
42003
- mod = require$1(moduleFile || moduleName);
42018
+ // import CJS and ES modules
42019
+ mod = await import(moduleFile || moduleName);
42020
+ if (mod.default) {
42021
+ mod = mod.default;
42022
+ }
42004
42023
  if (typeof mod == 'function') {
42005
- // -require now includes the functionality of the old -external command
42024
+ // assuming that functions are mapshpaper command generators...
42025
+ // this MUST be changed asap.
42006
42026
  var retn = mod(api);
42007
42027
  if (retn && isValidExternalCommand(retn)) {
42008
42028
  cmd.registerCommand(retn.name, retn);
42009
42029
  }
42010
42030
  }
42011
42031
  } catch(e) {
42012
- stop('Unable to load external module:', e.message, getErrorDetail(e));
42032
+ if (!mod) {
42033
+ stop('Unable to load external module:', e.message, getErrorDetail(e));
42034
+ }
42013
42035
  }
42014
42036
  if (moduleName || opts.alias) {
42015
- defs[opts.alias || moduleName] = mod;
42037
+ globals[opts.alias || moduleName] = mod;
42016
42038
  } else {
42017
- Object.assign(defs, mod);
42018
- }
42019
- if (opts.init) {
42020
- await evalTemplateExpression(opts.init, targets);
42039
+ Object.assign(globals, mod);
42021
42040
  }
42041
+ // instead of an init expression, you could use -run <expression>
42042
+ // if (opts.init) {
42043
+ // await evalTemplateExpression(opts.init, targets);
42044
+ // }
42022
42045
  };
42023
42046
 
42024
42047
  // Parse an array or a string of command line tokens into an array of
@@ -42123,7 +42146,8 @@ ${svg}
42123
42146
  stop('Expected a string containing mapshaper commands; received:', tmp);
42124
42147
  }
42125
42148
  if (tmp) {
42126
- message(`command: [${tmp}]`);
42149
+ // truncate message (command might include a large GeoJSON string in an -i command)
42150
+ message(`command: [${truncateString(tmp, 150)}]`);
42127
42151
  commands = parseCommands(tmp);
42128
42152
 
42129
42153
  // TODO: remove duplication with mapshaper-run-commands.mjs
@@ -44473,9 +44497,9 @@ ${svg}
44473
44497
  } else if (name == 'explode') {
44474
44498
  outputLayers = applyCommandToEachLayer(cmd.explodeFeatures, targetLayers, arcs, opts);
44475
44499
 
44476
- } else if (name == 'external') {
44477
- // -require now incorporates -external
44478
- cmd.require(targets, opts);
44500
+ // -require now incorporates functionality of -external
44501
+ // } else if (name == 'external') {
44502
+ // cmd.require(targets, opts);
44479
44503
 
44480
44504
  } else if (name == 'filter') {
44481
44505
  outputLayers = applyCommandToEachLayer(cmd.filterFeatures, targetLayers, arcs, opts);
@@ -44617,7 +44641,7 @@ ${svg}
44617
44641
  cmd.renameLayers(targetLayers, opts.names, job.catalog);
44618
44642
 
44619
44643
  } else if (name == 'require') {
44620
- cmd.require(targets, opts);
44644
+ await cmd.require(opts);
44621
44645
 
44622
44646
  } else if (name == 'rotate') {
44623
44647
  targets.forEach(function(targ) {
@@ -45445,6 +45469,7 @@ ${svg}
45445
45469
  Explode,
45446
45470
  Export,
45447
45471
  Expressions,
45472
+ FeatureExpressions,
45448
45473
  FileExport,
45449
45474
  FileImport,
45450
45475
  FilenameUtils,
package/www/page.css CHANGED
@@ -959,10 +959,6 @@ img.close-btn:hover,
959
959
  left: 13px;
960
960
  }
961
961
 
962
- .intersection-count {
963
- vertical-align: middle;
964
- }
965
-
966
962
  .intersection-check {
967
963
  display: none;
968
964
  }
@@ -979,13 +975,13 @@ img.close-btn:hover,
979
975
  background-color: black;
980
976
  }
981
977
 
982
- .intersection-count .close-btn {
978
+ .intersection-display .close-btn {
983
979
  width: 16px;
984
980
  height: 16px;
985
981
  cursor: pointer;
986
982
  position: relative;
987
983
  top: 4px;
988
- margin-left: 2px;
984
+ margin-left: 1px;
989
985
  }
990
986
 
991
987
  /*.intersection-display .text-btn.disabled {