@esri/solutions-components 0.7.9 → 0.7.10

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. package/dist/cjs/basemap-gallery_7.cjs.entry.js +1 -1
  2. package/dist/cjs/calcite-alert_3.cjs.entry.js +1 -1
  3. package/dist/cjs/calcite-combobox_6.cjs.entry.js +1 -1
  4. package/dist/cjs/card-manager_3.cjs.entry.js +134 -17
  5. package/dist/cjs/{downloadUtils-95e4a5b2.js → downloadUtils-8f50633d.js} +2 -2
  6. package/dist/cjs/{index.es-a88403f8.js → index.es-140aa937.js} +2 -2
  7. package/dist/cjs/map-select-tools_3.cjs.entry.js +2 -2
  8. package/dist/cjs/{mapViewUtils-b7d9e71c.js → mapViewUtils-569e9644.js} +17 -0
  9. package/dist/cjs/public-notification.cjs.entry.js +2 -2
  10. package/dist/collection/components/layer-table/layer-table.js +133 -16
  11. package/dist/collection/components/map-picker/map-picker.js +1 -1
  12. package/dist/collection/demos/crowdsource-manager.html +2 -2
  13. package/dist/collection/utils/queryUtils.js +16 -0
  14. package/dist/collection/utils/queryUtils.ts +21 -0
  15. package/dist/components/layer-table2.js +133 -16
  16. package/dist/components/map-picker2.js +1 -1
  17. package/dist/components/map-select-tools2.js +1 -1
  18. package/dist/components/queryUtils.js +17 -1
  19. package/dist/components/refine-selection2.js +1 -1
  20. package/dist/esm/basemap-gallery_7.entry.js +1 -1
  21. package/dist/esm/calcite-alert_3.entry.js +1 -1
  22. package/dist/esm/calcite-combobox_6.entry.js +1 -1
  23. package/dist/esm/card-manager_3.entry.js +134 -17
  24. package/dist/esm/{downloadUtils-83dd2143.js → downloadUtils-9dee8bc0.js} +2 -2
  25. package/dist/esm/{index.es-0c98e2f3.js → index.es-54e86c8e.js} +2 -2
  26. package/dist/esm/map-select-tools_3.entry.js +2 -2
  27. package/dist/esm/{mapViewUtils-3ff1c264.js → mapViewUtils-066602d5.js} +17 -1
  28. package/dist/esm/public-notification.entry.js +2 -2
  29. package/dist/solutions-components/demos/crowdsource-manager.html +2 -2
  30. package/dist/solutions-components/{p-a9bbd352.entry.js → p-13bfc206.entry.js} +1 -1
  31. package/dist/solutions-components/{p-d6050d57.js → p-1bdd64a0.js} +2 -2
  32. package/dist/solutions-components/{p-b7e2c75b.js → p-531d91d6.js} +1 -1
  33. package/dist/solutions-components/{p-dcd6e7b9.entry.js → p-6656c53e.entry.js} +1 -1
  34. package/dist/solutions-components/{p-a5d924a9.entry.js → p-683cded6.entry.js} +1 -1
  35. package/dist/solutions-components/{p-95ebc2e5.entry.js → p-c2b20b85.entry.js} +1 -1
  36. package/dist/solutions-components/p-c7ff24df.entry.js +6 -0
  37. package/dist/solutions-components/{p-b030a151.js → p-dfdb8411.js} +1 -1
  38. package/dist/solutions-components/p-ffae568b.entry.js +6 -0
  39. package/dist/solutions-components/solutions-components.esm.js +1 -1
  40. package/dist/solutions-components/utils/queryUtils.ts +21 -0
  41. package/dist/types/components/layer-table/layer-table.d.ts +40 -1
  42. package/dist/types/utils/queryUtils.d.ts +11 -0
  43. package/package.json +1 -1
  44. package/dist/solutions-components/p-c556ed60.entry.js +0 -6
  45. package/dist/solutions-components/p-c9b4d52f.entry.js +0 -6
@@ -525,7 +525,7 @@ const MapPicker = class {
525
525
  * @protected
526
526
  */
527
527
  _getMapNameList(show) {
528
- const listClass = show ? "map-list" : "display-none";
528
+ const listClass = show ? "map-list border-bottom-1" : "display-none";
529
529
  return (index.h("div", { class: listClass }, index.h("calcite-list", { id: "mapList", ref: (el) => this._list = el, selectionAppearance: "border", selectionMode: "single" }, this.mapInfos.map(mapInfo => {
530
530
  return (index.h("calcite-list-item", { label: mapInfo.name, onClick: () => this._webMapSelected(mapInfo), selected: mapInfo.id === this._loadedId, value: mapInfo.id }));
531
531
  }))));
@@ -17,7 +17,7 @@ const t9n = require('./t9n-0556abcb.js');
17
17
  const resources = require('./resources-222ad22c.js');
18
18
  const loadModules = require('./loadModules-46d14e81.js');
19
19
  const locale$1 = require('./locale-9db09b63.js');
20
- const mapViewUtils = require('./mapViewUtils-b7d9e71c.js');
20
+ const mapViewUtils = require('./mapViewUtils-569e9644.js');
21
21
  require('./guid-1a466ca6.js');
22
22
  require('./resources-6c60363a.js');
23
23
  require('./key-b8c05387.js');
@@ -26,7 +26,7 @@ const debounce = require('./debounce-30afab47.js');
26
26
  const conditionalSlot = require('./conditionalSlot-63e11cba.js');
27
27
  const key = require('./key-b8c05387.js');
28
28
  const locale$1 = require('./locale-9db09b63.js');
29
- const mapViewUtils = require('./mapViewUtils-b7d9e71c.js');
29
+ const mapViewUtils = require('./mapViewUtils-569e9644.js');
30
30
  const publicNotificationStore = require('./publicNotificationStore-3a17c2f4.js');
31
31
  require('./resources-6c60363a.js');
32
32
  require('./browser-9a43b900.js');
@@ -9,9 +9,9 @@ Object.defineProperty(exports, '__esModule', { value: true });
9
9
 
10
10
  const index = require('./index-b8a649fc.js');
11
11
  const locale = require('./locale-9db09b63.js');
12
- const mapViewUtils = require('./mapViewUtils-b7d9e71c.js');
12
+ const mapViewUtils = require('./mapViewUtils-569e9644.js');
13
13
  const loadModules = require('./loadModules-46d14e81.js');
14
- const downloadUtils = require('./downloadUtils-95e4a5b2.js');
14
+ const downloadUtils = require('./downloadUtils-8f50633d.js');
15
15
  require('./esri-loader-a91c0ec1.js');
16
16
  require('./_commonjsHelpers-384729db.js');
17
17
  require('./interfaces-7cd0a48a.js');
@@ -116,6 +116,10 @@ const LayerTable = class {
116
116
  * number[]: A list of all IDs for the current layer
117
117
  */
118
118
  this._allIds = [];
119
+ /**
120
+ * boolean: When true the ctrl key is currently pressed
121
+ */
122
+ this._ctrlIsPressed = false;
119
123
  /**
120
124
  * boolean: When true the default global id provided via url param has been honored and should now be ignored
121
125
  */
@@ -124,6 +128,14 @@ const LayerTable = class {
124
128
  * boolean: When true the default OID provided via url param has been honored and should now be ignored
125
129
  */
126
130
  this._defaultOidHonored = false;
131
+ /**
132
+ * boolean: When true the shift key is currently pressed
133
+ */
134
+ this._shiftIsPressed = false;
135
+ /**
136
+ * boolean: When true any onChange handeling will be skipped
137
+ */
138
+ this._skipOnChange = false;
127
139
  /**
128
140
  * bool: When true the table is being sorted
129
141
  */
@@ -328,6 +340,8 @@ const LayerTable = class {
328
340
  async componentDidLoad() {
329
341
  this._resizeObserver.observe(this._toolbar);
330
342
  document.onclick = (e) => this._handleDocumentClick(e);
343
+ document.onkeydown = (e) => this._handleKeyDown(e);
344
+ document.onkeyup = (e) => this._handleKeyUp(e);
331
345
  }
332
346
  /**
333
347
  * Called after the component is rendered
@@ -807,18 +821,8 @@ const LayerTable = class {
807
821
  this._initColumnsInfo();
808
822
  this._checkEditEnabled();
809
823
  await this._table.when(() => {
810
- this._table.highlightIds.on("change", () => {
811
- // https://github.com/Esri/solutions-components/issues/365
812
- this._selectedIndexes = this._table.highlightIds.toArray().reverse();
813
- if (this._showOnlySelected) {
814
- if (this._featuresSelected()) {
815
- this._table.filterBySelection();
816
- }
817
- else {
818
- this._toggleShowSelected();
819
- }
820
- }
821
- this.featureSelectionChange.emit(this._selectedIndexes);
824
+ this._table.highlightIds.on("change", (evt) => {
825
+ void this._handleOnChange(evt);
822
826
  });
823
827
  this.reactiveUtils.watch(() => this._table.activeSortOrders, (sortOrders) => {
824
828
  var _a, _b, _c, _d;
@@ -828,6 +832,93 @@ const LayerTable = class {
828
832
  });
829
833
  }
830
834
  }
835
+ async _handleOnChange(evt) {
836
+ const ids = [...this._table.highlightIds.toArray()];
837
+ if (!this._skipOnChange) {
838
+ if (!this._ctrlIsPressed && !this._shiftIsPressed) {
839
+ if (this._selectedIndexes.length > 0) {
840
+ this._skipOnChange = true;
841
+ // only readd in specific case where we have multiple selected and then click one of the currently selected
842
+ const reAdd = this._selectedIndexes.length > 1 && evt.removed.length === 1;
843
+ const newIndexes = reAdd ? evt.removed : ids.filter(id => this._selectedIndexes.indexOf(id) < 0);
844
+ this._clearSelection();
845
+ this._selectedIndexes = [...newIndexes];
846
+ if (newIndexes.length > 0) {
847
+ this._table.highlightIds.add(newIndexes[0]);
848
+ }
849
+ }
850
+ else {
851
+ // https://github.com/Esri/solutions-components/issues/365
852
+ this._selectedIndexes = ids.reverse();
853
+ }
854
+ }
855
+ else if (this._ctrlIsPressed) {
856
+ this._selectedIndexes = ids.reverse();
857
+ }
858
+ else if (this._shiftIsPressed) {
859
+ this._skipOnChange = true;
860
+ this._previousCurrentId = this._currentId;
861
+ this._currentId = [...this._table.highlightIds.toArray()].reverse()[0];
862
+ if (this._previousCurrentId !== this._currentId) {
863
+ // query the layer based on current sort and filters then grab between the current id and previous id
864
+ const orderBy = this._table.activeSortOrders.reduce((prev, cur) => {
865
+ prev.push(`${cur.fieldName} ${cur.direction}`);
866
+ return prev;
867
+ }, []);
868
+ const oids = await mapViewUtils.queryFeatureIds(this._layer, this._layer.definitionExpression, orderBy);
869
+ let isBetween = false;
870
+ const _start = this._table.viewModel.getObjectIdIndex(this._previousCurrentId);
871
+ const _end = this._table.viewModel.getObjectIdIndex(this._currentId);
872
+ const startIndex = _start < _end ? _start : _end;
873
+ const endIndex = _end > _start ? _end : _start;
874
+ this._selectedIndexes = oids.reduce((prev, cur) => {
875
+ const id = cur;
876
+ const index = this._table.viewModel.getObjectIdIndex(id);
877
+ if ((id === this._currentId || id === this._previousCurrentId)) {
878
+ isBetween = !isBetween;
879
+ if (prev.indexOf(id) < 0) {
880
+ prev.push(id);
881
+ }
882
+ }
883
+ // The oids are sorted so after we have reached the start or end oid add all ids even if the index is -1.
884
+ // Index of -1 will occur for features between the start and and oid if
885
+ // you select a row then scroll faster than the FeatureTable loads the data to select the next id
886
+ if (isBetween && prev.indexOf(id) < 0) {
887
+ prev.push(id);
888
+ }
889
+ // Also add index based check.
890
+ // In some cases the FeatureTable and Layer query will have differences in how null/undefined field values are sorted
891
+ if ((this._selectedIndexes.indexOf(id) > -1 || (index >= startIndex && index <= endIndex)) && prev.indexOf(id) < 0 && index > -1) {
892
+ prev.push(id);
893
+ }
894
+ return prev;
895
+ }, []);
896
+ this._table.highlightIds.addMany(this._selectedIndexes.filter(i => ids.indexOf(i) < 0));
897
+ }
898
+ }
899
+ this._finishOnChange();
900
+ }
901
+ else {
902
+ this._skipOnChange = false;
903
+ }
904
+ this._currentId = [...this._table.highlightIds.toArray()].reverse()[0];
905
+ }
906
+ /**
907
+ * Handle any updates after a selection change has occured and emit the results
908
+ *
909
+ * @returns void
910
+ */
911
+ _finishOnChange() {
912
+ if (this._showOnlySelected) {
913
+ if (this._featuresSelected()) {
914
+ this._table.filterBySelection();
915
+ }
916
+ else {
917
+ this._toggleShowSelected();
918
+ }
919
+ }
920
+ this.featureSelectionChange.emit(this._selectedIndexes);
921
+ }
831
922
  /**
832
923
  * Reset basic table props
833
924
  *
@@ -963,6 +1054,24 @@ const LayerTable = class {
963
1054
  }
964
1055
  }
965
1056
  }
1057
+ /**
1058
+ * Keep track of key down for ctrl and shift
1059
+ *
1060
+ * @returns void
1061
+ */
1062
+ _handleKeyDown(e) {
1063
+ this._ctrlIsPressed = e.ctrlKey;
1064
+ this._shiftIsPressed = e.shiftKey;
1065
+ }
1066
+ /**
1067
+ * Keep track of key up for ctrl and shift
1068
+ *
1069
+ * @returns void
1070
+ */
1071
+ _handleKeyUp(e) {
1072
+ this._ctrlIsPressed = e.ctrlKey;
1073
+ this._shiftIsPressed = e.shiftKey;
1074
+ }
966
1075
  /**
967
1076
  * Show filter component in modal
968
1077
  *
@@ -970,15 +1079,19 @@ const LayerTable = class {
970
1079
  */
971
1080
  _filterModal() {
972
1081
  var _a, _b, _c;
973
- return (index.h("calcite-modal", { "aria-labelledby": "modal-title", kind: "brand", onCalciteModalClose: () => this._closeFilter(), open: this._filterOpen, widthScale: "s" }, index.h("div", { class: "display-flex align-center", id: "modal-title", slot: "header" }, (_b = (_a = this._translations) === null || _a === void 0 ? void 0 : _a.filter) === null || _b === void 0 ? void 0 : _b.replace("{{title}}", (_c = this._layer) === null || _c === void 0 ? void 0 : _c.title)), index.h("div", { slot: "content" }, index.h("instant-apps-filter-list", { autoUpdateUrl: false, closeBtn: true, closeBtnOnClick: () => this._closeFilter(), layerExpressions: this._layerExpressions, ref: (el) => this._filterList = el, view: this.mapView }))));
1082
+ return (index.h("calcite-modal", { "aria-labelledby": "modal-title", kind: "brand", onCalciteModalClose: async () => this._closeFilter(), open: this._filterOpen, widthScale: "s" }, index.h("div", { class: "display-flex align-center", id: "modal-title", slot: "header" }, (_b = (_a = this._translations) === null || _a === void 0 ? void 0 : _a.filter) === null || _b === void 0 ? void 0 : _b.replace("{{title}}", (_c = this._layer) === null || _c === void 0 ? void 0 : _c.title)), index.h("div", { slot: "content" }, index.h("instant-apps-filter-list", { autoUpdateUrl: false, closeBtn: true, closeBtnOnClick: async () => this._closeFilter(), layerExpressions: this._layerExpressions, ref: (el) => this._filterList = el, view: this.mapView }))));
974
1083
  }
975
1084
  /**
976
1085
  * Close the filter modal
977
1086
  *
978
1087
  * @returns void
979
1088
  */
980
- _closeFilter() {
981
- this._filterOpen = false;
1089
+ async _closeFilter() {
1090
+ if (this._filterOpen) {
1091
+ // reset allIds
1092
+ this._allIds = await mapViewUtils.queryAllIds(this._layer);
1093
+ this._filterOpen = false;
1094
+ }
982
1095
  }
983
1096
  /**
984
1097
  * Show delete confirmation message
@@ -1051,8 +1164,10 @@ const LayerTable = class {
1051
1164
  _selectAll() {
1052
1165
  const ids = this._allIds;
1053
1166
  this._table.highlightIds.removeAll();
1167
+ this._skipOnChange = true;
1054
1168
  this._table.highlightIds.addMany(ids);
1055
1169
  this._selectedIndexes = ids;
1170
+ this._finishOnChange();
1056
1171
  }
1057
1172
  /**
1058
1173
  * Toggle the show only selected flag
@@ -1112,8 +1227,10 @@ const LayerTable = class {
1112
1227
  }
1113
1228
  return prev;
1114
1229
  }, []).sort((a, b) => a - b);
1230
+ this._skipOnChange = true;
1115
1231
  this._table.highlightIds.addMany(ids);
1116
1232
  this._selectedIndexes = ids;
1233
+ this._finishOnChange();
1117
1234
  }
1118
1235
  /**
1119
1236
  * Export all selected rows as CSV
@@ -8,7 +8,7 @@
8
8
  const _commonjsHelpers = require('./_commonjsHelpers-384729db.js');
9
9
  const index = require('./index-b8a649fc.js');
10
10
  const loadModules = require('./loadModules-46d14e81.js');
11
- const mapViewUtils = require('./mapViewUtils-b7d9e71c.js');
11
+ const mapViewUtils = require('./mapViewUtils-569e9644.js');
12
12
  require('./solution-resource-abec7452.js');
13
13
  require('./index-f64944ad.js');
14
14
  const restHelpersGet = require('./restHelpersGet-e0737480.js');
@@ -1510,7 +1510,7 @@ function(t){var e=function(t){for(var e=t.length,r=new Uint8Array(e),n=0;n<e;n++
1510
1510
  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
1511
1511
  * ====================================================================
1512
1512
  */
1513
- function(t){function e(){return (n.canvg?Promise.resolve(n.canvg):Promise.resolve().then(function () { return require('./index.es-a88403f8.js'); })).catch((function(t){return Promise.reject(new Error("Could not load canvg: "+t))})).then((function(t){return t.default?t.default:t}))}E.API.addSvgAsImage=function(t,r,n,i,o,s,c,u){if(isNaN(r)||isNaN(n))throw a.error("jsPDF.addSvgAsImage: Invalid coordinates",arguments),new Error("Invalid coordinates passed to jsPDF.addSvgAsImage");if(isNaN(i)||isNaN(o))throw a.error("jsPDF.addSvgAsImage: Invalid measurements",arguments),new Error("Invalid measurements (width and/or height) passed to jsPDF.addSvgAsImage");var h=document.createElement("canvas");h.width=i,h.height=o;var l=h.getContext("2d");l.fillStyle="#fff",l.fillRect(0,0,h.width,h.height);var f={ignoreMouse:!0,ignoreAnimation:!0,ignoreDimensions:!0},d=this;return e().then((function(e){return e.fromString(l,t,f)}),(function(){return Promise.reject(new Error("Could not load canvg."))})).then((function(t){return t.render(f)})).then((function(){d.addImage(h.toDataURL("image/jpeg",1),r,n,i,o,c,u);}))};}(),E.API.putTotalPages=function(t){var e,r=0;parseInt(this.internal.getFont().id.substr(1),10)<15?(e=new RegExp(t,"g"),r=this.internal.getNumberOfPages()):(e=new RegExp(this.pdfEscape16(t,this.internal.getFont()),"g"),r=this.pdfEscape16(this.internal.getNumberOfPages()+"",this.internal.getFont()));for(var n=1;n<=this.internal.getNumberOfPages();n++)for(var i=0;i<this.internal.pages[n].length;i++)this.internal.pages[n][i]=this.internal.pages[n][i].replace(e,r);return this},E.API.viewerPreferences=function(e,r){var n;e=e||{},r=r||!1;var i,a,o,s={HideToolbar:{defaultValue:!1,value:!1,type:"boolean",explicitSet:!1,valueSet:[!0,!1],pdfVersion:1.3},HideMenubar:{defaultValue:!1,value:!1,type:"boolean",explicitSet:!1,valueSet:[!0,!1],pdfVersion:1.3},HideWindowUI:{defaultValue:!1,value:!1,type:"boolean",explicitSet:!1,valueSet:[!0,!1],pdfVersion:1.3},FitWindow:{defaultValue:!1,value:!1,type:"boolean",explicitSet:!1,valueSet:[!0,!1],pdfVersion:1.3},CenterWindow:{defaultValue:!1,value:!1,type:"boolean",explicitSet:!1,valueSet:[!0,!1],pdfVersion:1.3},DisplayDocTitle:{defaultValue:!1,value:!1,type:"boolean",explicitSet:!1,valueSet:[!0,!1],pdfVersion:1.4},NonFullScreenPageMode:{defaultValue:"UseNone",value:"UseNone",type:"name",explicitSet:!1,valueSet:["UseNone","UseOutlines","UseThumbs","UseOC"],pdfVersion:1.3},Direction:{defaultValue:"L2R",value:"L2R",type:"name",explicitSet:!1,valueSet:["L2R","R2L"],pdfVersion:1.3},ViewArea:{defaultValue:"CropBox",value:"CropBox",type:"name",explicitSet:!1,valueSet:["MediaBox","CropBox","TrimBox","BleedBox","ArtBox"],pdfVersion:1.4},ViewClip:{defaultValue:"CropBox",value:"CropBox",type:"name",explicitSet:!1,valueSet:["MediaBox","CropBox","TrimBox","BleedBox","ArtBox"],pdfVersion:1.4},PrintArea:{defaultValue:"CropBox",value:"CropBox",type:"name",explicitSet:!1,valueSet:["MediaBox","CropBox","TrimBox","BleedBox","ArtBox"],pdfVersion:1.4},PrintClip:{defaultValue:"CropBox",value:"CropBox",type:"name",explicitSet:!1,valueSet:["MediaBox","CropBox","TrimBox","BleedBox","ArtBox"],pdfVersion:1.4},PrintScaling:{defaultValue:"AppDefault",value:"AppDefault",type:"name",explicitSet:!1,valueSet:["AppDefault","None"],pdfVersion:1.6},Duplex:{defaultValue:"",value:"none",type:"name",explicitSet:!1,valueSet:["Simplex","DuplexFlipShortEdge","DuplexFlipLongEdge","none"],pdfVersion:1.7},PickTrayByPDFSize:{defaultValue:!1,value:!1,type:"boolean",explicitSet:!1,valueSet:[!0,!1],pdfVersion:1.7},PrintPageRange:{defaultValue:"",value:"",type:"array",explicitSet:!1,valueSet:null,pdfVersion:1.7},NumCopies:{defaultValue:1,value:1,type:"integer",explicitSet:!1,valueSet:null,pdfVersion:1.7}},c=Object.keys(s),u=[],h=0,l=0,f=0;function d(t,e){var r,n=!1;for(r=0;r<t.length;r+=1)t[r]===e&&(n=!0);return n}if(void 0===this.internal.viewerpreferences&&(this.internal.viewerpreferences={},this.internal.viewerpreferences.configuration=JSON.parse(JSON.stringify(s)),this.internal.viewerpreferences.isSubscribed=!1),n=this.internal.viewerpreferences.configuration,"reset"===e||!0===r){var p=c.length;for(f=0;f<p;f+=1)n[c[f]].value=n[c[f]].defaultValue,n[c[f]].explicitSet=!1;}if("object"===t(e))for(a in e)if(o=e[a],d(c,a)&&void 0!==o){if("boolean"===n[a].type&&"boolean"==typeof o)n[a].value=o;else if("name"===n[a].type&&d(n[a].valueSet,o))n[a].value=o;else if("integer"===n[a].type&&Number.isInteger(o))n[a].value=o;else if("array"===n[a].type){for(h=0;h<o.length;h+=1)if(i=!0,1===o[h].length&&"number"==typeof o[h][0])u.push(String(o[h]-1));else if(o[h].length>1){for(l=0;l<o[h].length;l+=1)"number"!=typeof o[h][l]&&(i=!1);!0===i&&u.push([o[h][0]-1,o[h][1]-1].join(" "));}n[a].value="["+u.join(" ")+"]";}else n[a].value=n[a].defaultValue;n[a].explicitSet=!0;}return !1===this.internal.viewerpreferences.isSubscribed&&(this.internal.events.subscribe("putCatalog",(function(){var t,e=[];for(t in n)!0===n[t].explicitSet&&("name"===n[t].type?e.push("/"+t+" /"+n[t].value):e.push("/"+t+" "+n[t].value));0!==e.length&&this.internal.write("/ViewerPreferences\n<<\n"+e.join("\n")+"\n>>");})),this.internal.viewerpreferences.isSubscribed=!0),this.internal.viewerpreferences.configuration=n,this},
1513
+ function(t){function e(){return (n.canvg?Promise.resolve(n.canvg):Promise.resolve().then(function () { return require('./index.es-140aa937.js'); })).catch((function(t){return Promise.reject(new Error("Could not load canvg: "+t))})).then((function(t){return t.default?t.default:t}))}E.API.addSvgAsImage=function(t,r,n,i,o,s,c,u){if(isNaN(r)||isNaN(n))throw a.error("jsPDF.addSvgAsImage: Invalid coordinates",arguments),new Error("Invalid coordinates passed to jsPDF.addSvgAsImage");if(isNaN(i)||isNaN(o))throw a.error("jsPDF.addSvgAsImage: Invalid measurements",arguments),new Error("Invalid measurements (width and/or height) passed to jsPDF.addSvgAsImage");var h=document.createElement("canvas");h.width=i,h.height=o;var l=h.getContext("2d");l.fillStyle="#fff",l.fillRect(0,0,h.width,h.height);var f={ignoreMouse:!0,ignoreAnimation:!0,ignoreDimensions:!0},d=this;return e().then((function(e){return e.fromString(l,t,f)}),(function(){return Promise.reject(new Error("Could not load canvg."))})).then((function(t){return t.render(f)})).then((function(){d.addImage(h.toDataURL("image/jpeg",1),r,n,i,o,c,u);}))};}(),E.API.putTotalPages=function(t){var e,r=0;parseInt(this.internal.getFont().id.substr(1),10)<15?(e=new RegExp(t,"g"),r=this.internal.getNumberOfPages()):(e=new RegExp(this.pdfEscape16(t,this.internal.getFont()),"g"),r=this.pdfEscape16(this.internal.getNumberOfPages()+"",this.internal.getFont()));for(var n=1;n<=this.internal.getNumberOfPages();n++)for(var i=0;i<this.internal.pages[n].length;i++)this.internal.pages[n][i]=this.internal.pages[n][i].replace(e,r);return this},E.API.viewerPreferences=function(e,r){var n;e=e||{},r=r||!1;var i,a,o,s={HideToolbar:{defaultValue:!1,value:!1,type:"boolean",explicitSet:!1,valueSet:[!0,!1],pdfVersion:1.3},HideMenubar:{defaultValue:!1,value:!1,type:"boolean",explicitSet:!1,valueSet:[!0,!1],pdfVersion:1.3},HideWindowUI:{defaultValue:!1,value:!1,type:"boolean",explicitSet:!1,valueSet:[!0,!1],pdfVersion:1.3},FitWindow:{defaultValue:!1,value:!1,type:"boolean",explicitSet:!1,valueSet:[!0,!1],pdfVersion:1.3},CenterWindow:{defaultValue:!1,value:!1,type:"boolean",explicitSet:!1,valueSet:[!0,!1],pdfVersion:1.3},DisplayDocTitle:{defaultValue:!1,value:!1,type:"boolean",explicitSet:!1,valueSet:[!0,!1],pdfVersion:1.4},NonFullScreenPageMode:{defaultValue:"UseNone",value:"UseNone",type:"name",explicitSet:!1,valueSet:["UseNone","UseOutlines","UseThumbs","UseOC"],pdfVersion:1.3},Direction:{defaultValue:"L2R",value:"L2R",type:"name",explicitSet:!1,valueSet:["L2R","R2L"],pdfVersion:1.3},ViewArea:{defaultValue:"CropBox",value:"CropBox",type:"name",explicitSet:!1,valueSet:["MediaBox","CropBox","TrimBox","BleedBox","ArtBox"],pdfVersion:1.4},ViewClip:{defaultValue:"CropBox",value:"CropBox",type:"name",explicitSet:!1,valueSet:["MediaBox","CropBox","TrimBox","BleedBox","ArtBox"],pdfVersion:1.4},PrintArea:{defaultValue:"CropBox",value:"CropBox",type:"name",explicitSet:!1,valueSet:["MediaBox","CropBox","TrimBox","BleedBox","ArtBox"],pdfVersion:1.4},PrintClip:{defaultValue:"CropBox",value:"CropBox",type:"name",explicitSet:!1,valueSet:["MediaBox","CropBox","TrimBox","BleedBox","ArtBox"],pdfVersion:1.4},PrintScaling:{defaultValue:"AppDefault",value:"AppDefault",type:"name",explicitSet:!1,valueSet:["AppDefault","None"],pdfVersion:1.6},Duplex:{defaultValue:"",value:"none",type:"name",explicitSet:!1,valueSet:["Simplex","DuplexFlipShortEdge","DuplexFlipLongEdge","none"],pdfVersion:1.7},PickTrayByPDFSize:{defaultValue:!1,value:!1,type:"boolean",explicitSet:!1,valueSet:[!0,!1],pdfVersion:1.7},PrintPageRange:{defaultValue:"",value:"",type:"array",explicitSet:!1,valueSet:null,pdfVersion:1.7},NumCopies:{defaultValue:1,value:1,type:"integer",explicitSet:!1,valueSet:null,pdfVersion:1.7}},c=Object.keys(s),u=[],h=0,l=0,f=0;function d(t,e){var r,n=!1;for(r=0;r<t.length;r+=1)t[r]===e&&(n=!0);return n}if(void 0===this.internal.viewerpreferences&&(this.internal.viewerpreferences={},this.internal.viewerpreferences.configuration=JSON.parse(JSON.stringify(s)),this.internal.viewerpreferences.isSubscribed=!1),n=this.internal.viewerpreferences.configuration,"reset"===e||!0===r){var p=c.length;for(f=0;f<p;f+=1)n[c[f]].value=n[c[f]].defaultValue,n[c[f]].explicitSet=!1;}if("object"===t(e))for(a in e)if(o=e[a],d(c,a)&&void 0!==o){if("boolean"===n[a].type&&"boolean"==typeof o)n[a].value=o;else if("name"===n[a].type&&d(n[a].valueSet,o))n[a].value=o;else if("integer"===n[a].type&&Number.isInteger(o))n[a].value=o;else if("array"===n[a].type){for(h=0;h<o.length;h+=1)if(i=!0,1===o[h].length&&"number"==typeof o[h][0])u.push(String(o[h]-1));else if(o[h].length>1){for(l=0;l<o[h].length;l+=1)"number"!=typeof o[h][l]&&(i=!1);!0===i&&u.push([o[h][0]-1,o[h][1]-1].join(" "));}n[a].value="["+u.join(" ")+"]";}else n[a].value=n[a].defaultValue;n[a].explicitSet=!0;}return !1===this.internal.viewerpreferences.isSubscribed&&(this.internal.events.subscribe("putCatalog",(function(){var t,e=[];for(t in n)!0===n[t].explicitSet&&("name"===n[t].type?e.push("/"+t+" /"+n[t].value):e.push("/"+t+" "+n[t].value));0!==e.length&&this.internal.write("/ViewerPreferences\n<<\n"+e.join("\n")+"\n>>");})),this.internal.viewerpreferences.isSubscribed=!0),this.internal.viewerpreferences.configuration=n,this},
1514
1514
  /** ====================================================================
1515
1515
  * @license
1516
1516
  * jsPDF XMP metadata plugin
@@ -6,11 +6,11 @@
6
6
  'use strict';
7
7
 
8
8
  const _commonjsHelpers = require('./_commonjsHelpers-384729db.js');
9
- const downloadUtils = require('./downloadUtils-95e4a5b2.js');
9
+ const downloadUtils = require('./downloadUtils-8f50633d.js');
10
10
  require('./index-b8a649fc.js');
11
11
  require('./loadModules-46d14e81.js');
12
12
  require('./esri-loader-a91c0ec1.js');
13
- require('./mapViewUtils-b7d9e71c.js');
13
+ require('./mapViewUtils-569e9644.js');
14
14
  require('./interfaces-7cd0a48a.js');
15
15
  require('./solution-resource-abec7452.js');
16
16
  require('./index-f64944ad.js');
@@ -9,11 +9,11 @@ Object.defineProperty(exports, '__esModule', { value: true });
9
9
 
10
10
  const index = require('./index-b8a649fc.js');
11
11
  const loadModules = require('./loadModules-46d14e81.js');
12
- const mapViewUtils = require('./mapViewUtils-b7d9e71c.js');
12
+ const mapViewUtils = require('./mapViewUtils-569e9644.js');
13
13
  const interfaces = require('./interfaces-7cd0a48a.js');
14
14
  const publicNotificationStore = require('./publicNotificationStore-3a17c2f4.js');
15
15
  const locale = require('./locale-9db09b63.js');
16
- const downloadUtils = require('./downloadUtils-95e4a5b2.js');
16
+ const downloadUtils = require('./downloadUtils-8f50633d.js');
17
17
  require('./esri-loader-a91c0ec1.js');
18
18
  require('./_commonjsHelpers-384729db.js');
19
19
  require('./index-22bb61da.js');
@@ -126,6 +126,22 @@ async function queryFeaturesByGeometry(start, layer, geometry, featuresCollectio
126
126
  queryFeaturesByGeometry(start += num, layer, geometry, featuresCollection) :
127
127
  Promise.resolve(featuresCollection);
128
128
  }
129
+ /**
130
+ * Query the layer for feature ids that match the provided where clause.
131
+ * If no where clause is provided all features will be returned.
132
+ *
133
+ * @param layer the layer to retrieve features from
134
+ * @param where the where clause for the query
135
+ * @param orderBy any sort order to apply to the query
136
+ *
137
+ * @returns Promise with the ids from the layer that match the where and are sorted as defined by orderBy
138
+ */
139
+ async function queryFeatureIds(layer, where, orderBy) {
140
+ const query = layer.createQuery();
141
+ query.where = where ? where : "1=1";
142
+ query.orderByFields = orderBy;
143
+ return await layer.queryObjectIds(query);
144
+ }
129
145
  /**
130
146
  * Query the layer for the extent of features with the provided OIDs
131
147
  *
@@ -444,6 +460,7 @@ exports.goToSelection = goToSelection;
444
460
  exports.highlightAllFeatures = highlightAllFeatures;
445
461
  exports.highlightFeatures = highlightFeatures;
446
462
  exports.queryAllIds = queryAllIds;
463
+ exports.queryFeatureIds = queryFeatureIds;
447
464
  exports.queryFeaturesByGeometry = queryFeaturesByGeometry;
448
465
  exports.queryFeaturesByGlobalID = queryFeaturesByGlobalID;
449
466
  exports.queryFeaturesByID = queryFeaturesByID;
@@ -10,10 +10,10 @@ Object.defineProperty(exports, '__esModule', { value: true });
10
10
  const index = require('./index-b8a649fc.js');
11
11
  const interfaces = require('./interfaces-7cd0a48a.js');
12
12
  const loadModules = require('./loadModules-46d14e81.js');
13
- const mapViewUtils = require('./mapViewUtils-b7d9e71c.js');
13
+ const mapViewUtils = require('./mapViewUtils-569e9644.js');
14
14
  const publicNotificationStore = require('./publicNotificationStore-3a17c2f4.js');
15
15
  const locale = require('./locale-9db09b63.js');
16
- const downloadUtils = require('./downloadUtils-95e4a5b2.js');
16
+ const downloadUtils = require('./downloadUtils-8f50633d.js');
17
17
  require('./esri-loader-a91c0ec1.js');
18
18
  require('./_commonjsHelpers-384729db.js');
19
19
  require('./index-22bb61da.js');
@@ -22,7 +22,7 @@ import { Host, h } from "@stencil/core";
22
22
  import { loadModules } from "../../utils/loadModules";
23
23
  import { getLocaleComponentStrings } from "../../utils/locale";
24
24
  import { getLayerOrTable, goToSelection } from "../../utils/mapViewUtils";
25
- import { queryAllIds, queryFeaturesByGlobalID } from "../../utils/queryUtils";
25
+ import { queryAllIds, queryFeatureIds, queryFeaturesByGlobalID } from "../../utils/queryUtils";
26
26
  import * as downloadUtils from "../../utils/downloadUtils";
27
27
  import "@esri/instant-apps-components/dist/components/instant-apps-social-share";
28
28
  export class LayerTable {
@@ -31,6 +31,10 @@ export class LayerTable {
31
31
  * number[]: A list of all IDs for the current layer
32
32
  */
33
33
  this._allIds = [];
34
+ /**
35
+ * boolean: When true the ctrl key is currently pressed
36
+ */
37
+ this._ctrlIsPressed = false;
34
38
  /**
35
39
  * boolean: When true the default global id provided via url param has been honored and should now be ignored
36
40
  */
@@ -39,6 +43,14 @@ export class LayerTable {
39
43
  * boolean: When true the default OID provided via url param has been honored and should now be ignored
40
44
  */
41
45
  this._defaultOidHonored = false;
46
+ /**
47
+ * boolean: When true the shift key is currently pressed
48
+ */
49
+ this._shiftIsPressed = false;
50
+ /**
51
+ * boolean: When true any onChange handeling will be skipped
52
+ */
53
+ this._skipOnChange = false;
42
54
  /**
43
55
  * bool: When true the table is being sorted
44
56
  */
@@ -243,6 +255,8 @@ export class LayerTable {
243
255
  async componentDidLoad() {
244
256
  this._resizeObserver.observe(this._toolbar);
245
257
  document.onclick = (e) => this._handleDocumentClick(e);
258
+ document.onkeydown = (e) => this._handleKeyDown(e);
259
+ document.onkeyup = (e) => this._handleKeyUp(e);
246
260
  }
247
261
  /**
248
262
  * Called after the component is rendered
@@ -722,18 +736,8 @@ export class LayerTable {
722
736
  this._initColumnsInfo();
723
737
  this._checkEditEnabled();
724
738
  await this._table.when(() => {
725
- this._table.highlightIds.on("change", () => {
726
- // https://github.com/Esri/solutions-components/issues/365
727
- this._selectedIndexes = this._table.highlightIds.toArray().reverse();
728
- if (this._showOnlySelected) {
729
- if (this._featuresSelected()) {
730
- this._table.filterBySelection();
731
- }
732
- else {
733
- this._toggleShowSelected();
734
- }
735
- }
736
- this.featureSelectionChange.emit(this._selectedIndexes);
739
+ this._table.highlightIds.on("change", (evt) => {
740
+ void this._handleOnChange(evt);
737
741
  });
738
742
  this.reactiveUtils.watch(() => this._table.activeSortOrders, (sortOrders) => {
739
743
  var _a, _b, _c, _d;
@@ -743,6 +747,93 @@ export class LayerTable {
743
747
  });
744
748
  }
745
749
  }
750
+ async _handleOnChange(evt) {
751
+ const ids = [...this._table.highlightIds.toArray()];
752
+ if (!this._skipOnChange) {
753
+ if (!this._ctrlIsPressed && !this._shiftIsPressed) {
754
+ if (this._selectedIndexes.length > 0) {
755
+ this._skipOnChange = true;
756
+ // only readd in specific case where we have multiple selected and then click one of the currently selected
757
+ const reAdd = this._selectedIndexes.length > 1 && evt.removed.length === 1;
758
+ const newIndexes = reAdd ? evt.removed : ids.filter(id => this._selectedIndexes.indexOf(id) < 0);
759
+ this._clearSelection();
760
+ this._selectedIndexes = [...newIndexes];
761
+ if (newIndexes.length > 0) {
762
+ this._table.highlightIds.add(newIndexes[0]);
763
+ }
764
+ }
765
+ else {
766
+ // https://github.com/Esri/solutions-components/issues/365
767
+ this._selectedIndexes = ids.reverse();
768
+ }
769
+ }
770
+ else if (this._ctrlIsPressed) {
771
+ this._selectedIndexes = ids.reverse();
772
+ }
773
+ else if (this._shiftIsPressed) {
774
+ this._skipOnChange = true;
775
+ this._previousCurrentId = this._currentId;
776
+ this._currentId = [...this._table.highlightIds.toArray()].reverse()[0];
777
+ if (this._previousCurrentId !== this._currentId) {
778
+ // query the layer based on current sort and filters then grab between the current id and previous id
779
+ const orderBy = this._table.activeSortOrders.reduce((prev, cur) => {
780
+ prev.push(`${cur.fieldName} ${cur.direction}`);
781
+ return prev;
782
+ }, []);
783
+ const oids = await queryFeatureIds(this._layer, this._layer.definitionExpression, orderBy);
784
+ let isBetween = false;
785
+ const _start = this._table.viewModel.getObjectIdIndex(this._previousCurrentId);
786
+ const _end = this._table.viewModel.getObjectIdIndex(this._currentId);
787
+ const startIndex = _start < _end ? _start : _end;
788
+ const endIndex = _end > _start ? _end : _start;
789
+ this._selectedIndexes = oids.reduce((prev, cur) => {
790
+ const id = cur;
791
+ const index = this._table.viewModel.getObjectIdIndex(id);
792
+ if ((id === this._currentId || id === this._previousCurrentId)) {
793
+ isBetween = !isBetween;
794
+ if (prev.indexOf(id) < 0) {
795
+ prev.push(id);
796
+ }
797
+ }
798
+ // The oids are sorted so after we have reached the start or end oid add all ids even if the index is -1.
799
+ // Index of -1 will occur for features between the start and and oid if
800
+ // you select a row then scroll faster than the FeatureTable loads the data to select the next id
801
+ if (isBetween && prev.indexOf(id) < 0) {
802
+ prev.push(id);
803
+ }
804
+ // Also add index based check.
805
+ // In some cases the FeatureTable and Layer query will have differences in how null/undefined field values are sorted
806
+ if ((this._selectedIndexes.indexOf(id) > -1 || (index >= startIndex && index <= endIndex)) && prev.indexOf(id) < 0 && index > -1) {
807
+ prev.push(id);
808
+ }
809
+ return prev;
810
+ }, []);
811
+ this._table.highlightIds.addMany(this._selectedIndexes.filter(i => ids.indexOf(i) < 0));
812
+ }
813
+ }
814
+ this._finishOnChange();
815
+ }
816
+ else {
817
+ this._skipOnChange = false;
818
+ }
819
+ this._currentId = [...this._table.highlightIds.toArray()].reverse()[0];
820
+ }
821
+ /**
822
+ * Handle any updates after a selection change has occured and emit the results
823
+ *
824
+ * @returns void
825
+ */
826
+ _finishOnChange() {
827
+ if (this._showOnlySelected) {
828
+ if (this._featuresSelected()) {
829
+ this._table.filterBySelection();
830
+ }
831
+ else {
832
+ this._toggleShowSelected();
833
+ }
834
+ }
835
+ this.featureSelectionChange.emit(this._selectedIndexes);
836
+ }
746
837
  /**
747
838
  * Reset basic table props
748
839
  *
@@ -878,6 +969,24 @@ export class LayerTable {
878
969
  }
879
970
  }
880
971
  }
972
+ /**
973
+ * Keep track of key down for ctrl and shift
974
+ *
975
+ * @returns void
976
+ */
977
+ _handleKeyDown(e) {
978
+ this._ctrlIsPressed = e.ctrlKey;
979
+ this._shiftIsPressed = e.shiftKey;
980
+ }
981
+ /**
982
+ * Keep track of key up for ctrl and shift
983
+ *
984
+ * @returns void
985
+ */
986
+ _handleKeyUp(e) {
987
+ this._ctrlIsPressed = e.ctrlKey;
988
+ this._shiftIsPressed = e.shiftKey;
989
+ }
881
990
  /**
882
991
  * Show filter component in modal
883
992
  *
@@ -885,15 +994,19 @@ export class LayerTable {
885
994
  */
886
995
  _filterModal() {
887
996
  var _a, _b, _c;
888
- return (h("calcite-modal", { "aria-labelledby": "modal-title", kind: "brand", onCalciteModalClose: () => this._closeFilter(), open: this._filterOpen, widthScale: "s" }, h("div", { class: "display-flex align-center", id: "modal-title", slot: "header" }, (_b = (_a = this._translations) === null || _a === void 0 ? void 0 : _a.filter) === null || _b === void 0 ? void 0 : _b.replace("{{title}}", (_c = this._layer) === null || _c === void 0 ? void 0 : _c.title)), h("div", { slot: "content" }, h("instant-apps-filter-list", { autoUpdateUrl: false, closeBtn: true, closeBtnOnClick: () => this._closeFilter(), layerExpressions: this._layerExpressions, ref: (el) => this._filterList = el, view: this.mapView }))));
997
+ return (h("calcite-modal", { "aria-labelledby": "modal-title", kind: "brand", onCalciteModalClose: async () => this._closeFilter(), open: this._filterOpen, widthScale: "s" }, h("div", { class: "display-flex align-center", id: "modal-title", slot: "header" }, (_b = (_a = this._translations) === null || _a === void 0 ? void 0 : _a.filter) === null || _b === void 0 ? void 0 : _b.replace("{{title}}", (_c = this._layer) === null || _c === void 0 ? void 0 : _c.title)), h("div", { slot: "content" }, h("instant-apps-filter-list", { autoUpdateUrl: false, closeBtn: true, closeBtnOnClick: async () => this._closeFilter(), layerExpressions: this._layerExpressions, ref: (el) => this._filterList = el, view: this.mapView }))));
889
998
  }
890
999
  /**
891
1000
  * Close the filter modal
892
1001
  *
893
1002
  * @returns void
894
1003
  */
895
- _closeFilter() {
896
- this._filterOpen = false;
1004
+ async _closeFilter() {
1005
+ if (this._filterOpen) {
1006
+ // reset allIds
1007
+ this._allIds = await queryAllIds(this._layer);
1008
+ this._filterOpen = false;
1009
+ }
897
1010
  }
898
1011
  /**
899
1012
  * Show delete confirmation message
@@ -966,8 +1079,10 @@ export class LayerTable {
966
1079
  _selectAll() {
967
1080
  const ids = this._allIds;
968
1081
  this._table.highlightIds.removeAll();
1082
+ this._skipOnChange = true;
969
1083
  this._table.highlightIds.addMany(ids);
970
1084
  this._selectedIndexes = ids;
1085
+ this._finishOnChange();
971
1086
  }
972
1087
  /**
973
1088
  * Toggle the show only selected flag
@@ -1027,8 +1142,10 @@ export class LayerTable {
1027
1142
  }
1028
1143
  return prev;
1029
1144
  }, []).sort((a, b) => a - b);
1145
+ this._skipOnChange = true;
1030
1146
  this._table.highlightIds.addMany(ids);
1031
1147
  this._selectedIndexes = ids;
1148
+ this._finishOnChange();
1032
1149
  }
1033
1150
  /**
1034
1151
  * Export all selected rows as CSV
@@ -132,7 +132,7 @@ export class MapPicker {
132
132
  * @protected
133
133
  */
134
134
  _getMapNameList(show) {
135
- const listClass = show ? "map-list" : "display-none";
135
+ const listClass = show ? "map-list border-bottom-1" : "display-none";
136
136
  return (h("div", { class: listClass }, h("calcite-list", { id: "mapList", ref: (el) => this._list = el, selectionAppearance: "border", selectionMode: "single" }, this.mapInfos.map(mapInfo => {
137
137
  return (h("calcite-list-item", { label: mapInfo.name, onClick: () => this._webMapSelected(mapInfo), selected: mapInfo.id === this._loadedId, value: mapInfo.id }));
138
138
  }))));
@@ -94,10 +94,10 @@
94
94
  operator: " AND ",
95
95
  expressions: [
96
96
  {
97
- definitionExpression: "OBJECTID > 700",
97
+ definitionExpression: "OBJECTID > 690",
98
98
  id: 1701793260225,
99
99
  index: 0,
100
- name: "greater than 700",
100
+ name: "greater than 690",
101
101
  active: false
102
102
  }
103
103
  ]
@@ -165,6 +165,22 @@ export async function queryFeaturesByGeometry(start, layer, geometry, featuresCo
165
165
  queryFeaturesByGeometry(start += num, layer, geometry, featuresCollection) :
166
166
  Promise.resolve(featuresCollection);
167
167
  }
168
+ /**
169
+ * Query the layer for feature ids that match the provided where clause.
170
+ * If no where clause is provided all features will be returned.
171
+ *
172
+ * @param layer the layer to retrieve features from
173
+ * @param where the where clause for the query
174
+ * @param orderBy any sort order to apply to the query
175
+ *
176
+ * @returns Promise with the ids from the layer that match the where and are sorted as defined by orderBy
177
+ */
178
+ export async function queryFeatureIds(layer, where, orderBy) {
179
+ const query = layer.createQuery();
180
+ query.where = where ? where : "1=1";
181
+ query.orderByFields = orderBy;
182
+ return await layer.queryObjectIds(query);
183
+ }
168
184
  /**
169
185
  * Query the layer for the extent of features with the provided OIDs
170
186
  *