dgeoutils 2.4.6 → 2.4.9

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.
@@ -1,11 +1,13 @@
1
1
  import { DLine } from './DLine';
2
2
  import { DPolygon } from './DPolygon';
3
+ import { Point } from 'geojson';
3
4
  export declare const EARTH_RADIUS_IN_METERS = 6371008.8;
4
5
  export declare type DCoord = [number, number] | [number, number, number];
5
6
  export interface LatLng {
6
7
  lat: number;
7
8
  lng?: number;
8
9
  lon?: number;
10
+ alt?: number;
9
11
  }
10
12
  export declare const HALF_PI_IN_DEGREE = 90;
11
13
  export declare const PI_IN_DEGREE = 180;
@@ -25,14 +27,15 @@ export declare class DPoint {
25
27
  constructor(x: number, y: number);
26
28
  constructor(x: number, y: number, z?: number);
27
29
  static zero(): DPoint;
28
- static parse(c: LatLng | number[] | DCoord): DPoint;
30
+ static parse(c: LatLng | number[] | DCoord | Point, format?: string): DPoint;
29
31
  static parseFromWKT(wkt: string): DPoint;
30
32
  static random(): DPoint;
31
33
  static getTileFromQuadKey(quadKey: string): DPoint;
32
34
  getTileFromCoords(zoom?: number): DPoint;
33
35
  getQuadKeyFromTile(zoom?: number): string;
34
36
  getCoordsFromTile(zoom?: number): DPoint;
35
- toCoords(): DCoord;
37
+ toCoords(format?: string): DCoord;
38
+ toGeoJSON(format?: string): Point;
36
39
  findLine(p: DPoint): DLine;
37
40
  findInnerAngle(p1: DPoint, p3: DPoint): number;
38
41
  toString(): string;
@@ -99,6 +102,10 @@ export declare class DPoint {
99
102
  get yPoint(): DPoint;
100
103
  get wPoint(): DPoint;
101
104
  get hPoint(): DPoint;
105
+ get lat(): number;
106
+ get lng(): number;
107
+ get lon(): number;
108
+ get alt(): number | undefined;
102
109
  simple(xKey?: string, yKey?: string): {
103
110
  [key: string]: number;
104
111
  };
@@ -57,13 +57,34 @@ var DPoint = (function () {
57
57
  DPoint.zero = function () {
58
58
  return new DPoint();
59
59
  };
60
- DPoint.parse = function (c) {
61
- var _a = c, lat = _a.lat, lon = _a.lon, _b = _a.lng, lng = _b === void 0 ? lon : _b;
60
+ DPoint.parse = function (c, format) {
61
+ if (format === void 0) { format = 'xyz'; }
62
+ var _a = c, lat = _a.lat, lon = _a.lon, _b = _a.lng, lng = _b === void 0 ? lon : _b, alt = _a.alt;
62
63
  if (lat && lng) {
63
- return new DPoint(lat, lng, 0);
64
+ return new DPoint(lng, lat, alt !== null && alt !== void 0 ? alt : 0);
64
65
  }
65
- var _c = __read(c, 3), x = _c[0], y = _c[1], z = _c[2];
66
- return new DPoint(x, y, z);
66
+ var t = c;
67
+ if (c.type === 'Point') {
68
+ t = c.coordinates;
69
+ }
70
+ return format.replace(/[^x-z]/gmiu, '')
71
+ .split('')
72
+ .reduce(function (a, k, index) {
73
+ var _a, _b;
74
+ switch (k) {
75
+ case 'x':
76
+ a.x = (_a = t[index]) !== null && _a !== void 0 ? _a : 0;
77
+ break;
78
+ case 'y':
79
+ a.y = (_b = t[index]) !== null && _b !== void 0 ? _b : 0;
80
+ break;
81
+ case 'z':
82
+ a.z = t[index];
83
+ break;
84
+ default:
85
+ }
86
+ return a;
87
+ }, new DPoint());
67
88
  };
68
89
  DPoint.parseFromWKT = function (wkt) {
69
90
  var regexp = /POINT \((?<data>(?:(?!\)).)*?)\)$/miu;
@@ -134,11 +155,23 @@ var DPoint = (function () {
134
155
  var y = exports.PI_IN_DEGREE / Math.PI * Math.atan((Math.exp(n) - Math.exp(-n)) / 2);
135
156
  return new DPoint(x, y, zoom);
136
157
  };
137
- DPoint.prototype.toCoords = function () {
138
- if (this.z === undefined) {
139
- return [this.x, this.y];
140
- }
141
- return [this.x, this.y, this.z];
158
+ DPoint.prototype.toCoords = function (format) {
159
+ var _this = this;
160
+ if (format === void 0) { format = 'xyz'; }
161
+ return format.replace(/[^x-z]/gmiu, '').split('')
162
+ .map(function (k) { return ({
163
+ x: _this.x,
164
+ y: _this.y,
165
+ z: _this.z
166
+ })[k]; })
167
+ .filter(function (r) { return r !== undefined; });
168
+ };
169
+ DPoint.prototype.toGeoJSON = function (format) {
170
+ if (format === void 0) { format = 'xyz'; }
171
+ return {
172
+ type: 'Point',
173
+ coordinates: this.toCoords(format)
174
+ };
142
175
  };
143
176
  DPoint.prototype.findLine = function (p) {
144
177
  (0, utils_1.checkFunction)('findLine')
@@ -562,6 +595,34 @@ var DPoint = (function () {
562
595
  enumerable: false,
563
596
  configurable: true
564
597
  });
598
+ Object.defineProperty(DPoint.prototype, "lat", {
599
+ get: function () {
600
+ return this.y;
601
+ },
602
+ enumerable: false,
603
+ configurable: true
604
+ });
605
+ Object.defineProperty(DPoint.prototype, "lng", {
606
+ get: function () {
607
+ return this.x;
608
+ },
609
+ enumerable: false,
610
+ configurable: true
611
+ });
612
+ Object.defineProperty(DPoint.prototype, "lon", {
613
+ get: function () {
614
+ return this.x;
615
+ },
616
+ enumerable: false,
617
+ configurable: true
618
+ });
619
+ Object.defineProperty(DPoint.prototype, "alt", {
620
+ get: function () {
621
+ return this.z;
622
+ },
623
+ enumerable: false,
624
+ configurable: true
625
+ });
565
626
  DPoint.prototype.simple = function (xKey, yKey) {
566
627
  var _a;
567
628
  if (xKey === void 0) { xKey = 'x'; }
@@ -3,12 +3,13 @@ import { DCoord, DPoint, LatLng } from './DPoint';
3
3
  import { DLine } from './DLine';
4
4
  import { DPolygonLoop } from './DPolygonLoop';
5
5
  import { True } from './utils';
6
+ import { LineString, Polygon, Geometry as GeoJsonGeometry, Feature, FeatureCollection } from 'geojson';
7
+ interface DeepArray<T> extends Array<T | DeepArray<T>> {
8
+ }
6
9
  export declare const MIN_POINTS_IN_VALID_POLYGON = 3;
7
10
  export declare class DPolygon {
8
11
  private pPoints;
9
- properties: {
10
- [key: string]: any;
11
- };
12
+ properties: Record<string, any>;
12
13
  holes: DPolygon[];
13
14
  private searchStore;
14
15
  constructor(pPoints?: DPoint[]);
@@ -93,10 +94,14 @@ export declare class DPolygon {
93
94
  onBorder(p: DPoint): boolean;
94
95
  nextStart(): DPolygon;
95
96
  removeDuplicates(): DPolygon;
96
- static parse(a: LatLng[]): DPolygon;
97
- static parse(a: number[][]): DPolygon;
98
- static parse(a: DCoord[]): DPolygon;
99
- toArrayOfCoords(): DCoord[];
97
+ static toGeoJSONFeatureCollection(polygons: DPolygon[], format?: string): FeatureCollection<LineString | Polygon, Record<string, any>>;
98
+ static parse(a: LatLng[], format?: string): DPolygon;
99
+ static parse(a: number[][], format?: string): DPolygon;
100
+ static parse(a: DCoord[], format?: string): DPolygon;
101
+ static parse(a: GeoJsonGeometry | Feature | FeatureCollection<LineString | Polygon>, format?: string): DPolygon | DeepArray<DPolygon>;
102
+ toArrayOfCoords(format?: string): DCoord[];
103
+ toGeoJSONFeature(format?: string): Feature<LineString | Polygon, Record<string, any>>;
104
+ toGeoJSON(format?: string): LineString | Polygon;
100
105
  divideToPieces(piecesCount: number, withAltitude?: boolean): DPolygon;
101
106
  prepareToFastSearch(): void;
102
107
  fastHas({ x, y, z }: DPoint): boolean;
@@ -122,3 +127,4 @@ export declare class DPolygon {
122
127
  private getJSTSGeometry;
123
128
  private simpleLogicFunction;
124
129
  }
130
+ export {};
@@ -1,4 +1,15 @@
1
1
  "use strict";
2
+ var __assign = (this && this.__assign) || function () {
3
+ __assign = Object.assign || function(t) {
4
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
5
+ s = arguments[i];
6
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7
+ t[p] = s[p];
8
+ }
9
+ return t;
10
+ };
11
+ return __assign.apply(this, arguments);
12
+ };
2
13
  var __generator = (this && this.__generator) || function (thisArg, body) {
3
14
  var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
4
15
  return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
@@ -955,11 +966,96 @@ var DPolygon = (function () {
955
966
  }
956
967
  return this;
957
968
  };
958
- DPolygon.parse = function (a) {
959
- return new DPolygon(a.map(function (r) { return DPoint_1.DPoint.parse(r); }));
969
+ DPolygon.toGeoJSONFeatureCollection = function (polygons, format) {
970
+ if (format === void 0) { format = 'xyz'; }
971
+ return {
972
+ type: 'FeatureCollection',
973
+ features: polygons.map(function (polygon) { return polygon.toGeoJSONFeature(format); })
974
+ };
960
975
  };
961
- DPolygon.prototype.toArrayOfCoords = function () {
962
- return this.mapArray(function (r) { return r.toCoords(); });
976
+ DPolygon.parse = function (a, format) {
977
+ if (format === void 0) { format = 'xyz'; }
978
+ if (a.type) {
979
+ switch (a.type) {
980
+ case 'FeatureCollection':
981
+ return a.features.reduce(function (ak, f) {
982
+ var t = DPolygon.parse(f, format);
983
+ if (Array.isArray(t)) {
984
+ ak.push.apply(ak, __spreadArray([], __read(t), false));
985
+ }
986
+ else {
987
+ ak.push(t);
988
+ }
989
+ return ak;
990
+ }, []);
991
+ case 'Feature': {
992
+ var t = DPolygon.parse(a.geometry, format);
993
+ t.properties = __assign(__assign({}, a.properties), { id: a.id });
994
+ return t;
995
+ }
996
+ case 'LineString':
997
+ case 'MultiPoint':
998
+ return new DPolygon(a.coordinates.map(function (c) { return DPoint_1.DPoint.parse(c, format); }));
999
+ case 'Polygon':
1000
+ return a.coordinates.reduce(function (ak, line, index) {
1001
+ if (index === 0) {
1002
+ ak.points = line.map(function (c) { return DPoint_1.DPoint.parse(c, format); });
1003
+ }
1004
+ else {
1005
+ ak.holes.push(new DPolygon(line.map(function (c) { return DPoint_1.DPoint.parse(c, format); })));
1006
+ }
1007
+ return ak;
1008
+ }, new DPolygon());
1009
+ case 'MultiLineString':
1010
+ return a.coordinates.reduce(function (ak, line) {
1011
+ ak.push(new DPolygon(line.map(function (c) { return DPoint_1.DPoint.parse(c, format); })));
1012
+ return ak;
1013
+ }, []);
1014
+ case 'MultiPolygon':
1015
+ return a.coordinates.reduce(function (ak, coordinates) {
1016
+ ak.push(DPolygon.parse({
1017
+ type: 'Polygon',
1018
+ coordinates: coordinates
1019
+ }, format));
1020
+ return ak;
1021
+ }, []);
1022
+ case 'GeometryCollection':
1023
+ return a.geometries.reduce(function (ak, line) {
1024
+ ak.push(DPolygon.parse(line, format));
1025
+ return ak;
1026
+ }, []);
1027
+ default:
1028
+ }
1029
+ }
1030
+ return new DPolygon(a
1031
+ .map(function (r) { return DPoint_1.DPoint.parse(r, format); }));
1032
+ };
1033
+ DPolygon.prototype.toArrayOfCoords = function (format) {
1034
+ if (format === void 0) { format = 'xyz'; }
1035
+ return this.mapArray(function (r) { return r.toCoords(format); });
1036
+ };
1037
+ DPolygon.prototype.toGeoJSONFeature = function (format) {
1038
+ if (format === void 0) { format = 'xyz'; }
1039
+ return {
1040
+ type: 'Feature',
1041
+ properties: __assign({}, this.properties),
1042
+ geometry: this.toGeoJSON(format)
1043
+ };
1044
+ };
1045
+ DPolygon.prototype.toGeoJSON = function (format) {
1046
+ if (format === void 0) { format = 'xyz'; }
1047
+ if (this.closed) {
1048
+ return {
1049
+ type: 'Polygon',
1050
+ coordinates: __spreadArray([
1051
+ this.toArrayOfCoords(format)
1052
+ ], __read(this.holes.map(function (h) { return h.toArrayOfCoords(format); })), false)
1053
+ };
1054
+ }
1055
+ return {
1056
+ type: 'LineString',
1057
+ coordinates: this.toArrayOfCoords(format)
1058
+ };
963
1059
  };
964
1060
  DPolygon.prototype.divideToPieces = function (piecesCount, withAltitude) {
965
1061
  var e_13, _a;
@@ -25,13 +25,33 @@ export class DPoint {
25
25
  static zero() {
26
26
  return new DPoint();
27
27
  }
28
- static parse(c) {
29
- const { lat, lon, lng = lon } = c;
28
+ static parse(c, format = 'xyz') {
29
+ const { lat, lon, lng = lon, alt } = c;
30
30
  if (lat && lng) {
31
- return new DPoint(lat, lng, 0);
31
+ return new DPoint(lng, lat, alt !== null && alt !== void 0 ? alt : 0);
32
32
  }
33
- const [x, y, z] = c;
34
- return new DPoint(x, y, z);
33
+ let t = c;
34
+ if (c.type === 'Point') {
35
+ t = c.coordinates;
36
+ }
37
+ return format.replace(/[^x-z]/gmiu, '')
38
+ .split('')
39
+ .reduce((a, k, index) => {
40
+ var _a, _b;
41
+ switch (k) {
42
+ case 'x':
43
+ a.x = (_a = t[index]) !== null && _a !== void 0 ? _a : 0;
44
+ break;
45
+ case 'y':
46
+ a.y = (_b = t[index]) !== null && _b !== void 0 ? _b : 0;
47
+ break;
48
+ case 'z':
49
+ a.z = t[index];
50
+ break;
51
+ default:
52
+ }
53
+ return a;
54
+ }, new DPoint());
35
55
  }
36
56
  static parseFromWKT(wkt) {
37
57
  const regexp = /POINT \((?<data>(?:(?!\)).)*?)\)$/miu;
@@ -99,11 +119,20 @@ export class DPoint {
99
119
  const y = PI_IN_DEGREE / Math.PI * Math.atan((Math.exp(n) - Math.exp(-n)) / 2);
100
120
  return new DPoint(x, y, zoom);
101
121
  }
102
- toCoords() {
103
- if (this.z === undefined) {
104
- return [this.x, this.y];
105
- }
106
- return [this.x, this.y, this.z];
122
+ toCoords(format = 'xyz') {
123
+ return format.replace(/[^x-z]/gmiu, '').split('')
124
+ .map((k) => ({
125
+ x: this.x,
126
+ y: this.y,
127
+ z: this.z
128
+ })[k])
129
+ .filter((r) => r !== undefined);
130
+ }
131
+ toGeoJSON(format = 'xyz') {
132
+ return {
133
+ type: 'Point',
134
+ coordinates: this.toCoords(format)
135
+ };
107
136
  }
108
137
  findLine(p) {
109
138
  checkFunction('findLine')
@@ -466,6 +495,18 @@ export class DPoint {
466
495
  get hPoint() {
467
496
  return this.yPoint;
468
497
  }
498
+ get lat() {
499
+ return this.y;
500
+ }
501
+ get lng() {
502
+ return this.x;
503
+ }
504
+ get lon() {
505
+ return this.x;
506
+ }
507
+ get alt() {
508
+ return this.z;
509
+ }
469
510
  simple(xKey = 'x', yKey = 'y') {
470
511
  return {
471
512
  [xKey]: this.x,
@@ -618,11 +618,92 @@ export class DPolygon {
618
618
  }
619
619
  return this;
620
620
  }
621
- static parse(a) {
622
- return new DPolygon(a.map((r) => DPoint.parse(r)));
621
+ static toGeoJSONFeatureCollection(polygons, format = 'xyz') {
622
+ return {
623
+ type: 'FeatureCollection',
624
+ features: polygons.map((polygon) => polygon.toGeoJSONFeature(format))
625
+ };
626
+ }
627
+ static parse(a, format = 'xyz') {
628
+ if (a.type) {
629
+ switch (a.type) {
630
+ case 'FeatureCollection':
631
+ return a.features.reduce((ak, f) => {
632
+ const t = DPolygon.parse(f, format);
633
+ if (Array.isArray(t)) {
634
+ ak.push(...t);
635
+ }
636
+ else {
637
+ ak.push(t);
638
+ }
639
+ return ak;
640
+ }, []);
641
+ case 'Feature': {
642
+ const t = DPolygon.parse(a.geometry, format);
643
+ t.properties = Object.assign(Object.assign({}, a.properties), { id: a.id });
644
+ return t;
645
+ }
646
+ case 'LineString':
647
+ case 'MultiPoint':
648
+ return new DPolygon(a.coordinates.map((c) => DPoint.parse(c, format)));
649
+ case 'Polygon':
650
+ return a.coordinates.reduce((ak, line, index) => {
651
+ if (index === 0) {
652
+ ak.points = line.map((c) => DPoint.parse(c, format));
653
+ }
654
+ else {
655
+ ak.holes.push(new DPolygon(line.map((c) => DPoint.parse(c, format))));
656
+ }
657
+ return ak;
658
+ }, new DPolygon());
659
+ case 'MultiLineString':
660
+ return a.coordinates.reduce((ak, line) => {
661
+ ak.push(new DPolygon(line.map((c) => DPoint.parse(c, format))));
662
+ return ak;
663
+ }, []);
664
+ case 'MultiPolygon':
665
+ return a.coordinates.reduce((ak, coordinates) => {
666
+ ak.push(DPolygon.parse({
667
+ type: 'Polygon',
668
+ coordinates
669
+ }, format));
670
+ return ak;
671
+ }, []);
672
+ case 'GeometryCollection':
673
+ return a.geometries.reduce((ak, line) => {
674
+ ak.push(DPolygon.parse(line, format));
675
+ return ak;
676
+ }, []);
677
+ default:
678
+ }
679
+ }
680
+ return new DPolygon(a
681
+ .map((r) => DPoint.parse(r, format)));
623
682
  }
624
- toArrayOfCoords() {
625
- return this.mapArray((r) => r.toCoords());
683
+ toArrayOfCoords(format = 'xyz') {
684
+ return this.mapArray((r) => r.toCoords(format));
685
+ }
686
+ toGeoJSONFeature(format = 'xyz') {
687
+ return {
688
+ type: 'Feature',
689
+ properties: Object.assign({}, this.properties),
690
+ geometry: this.toGeoJSON(format)
691
+ };
692
+ }
693
+ toGeoJSON(format = 'xyz') {
694
+ if (this.closed) {
695
+ return {
696
+ type: 'Polygon',
697
+ coordinates: [
698
+ this.toArrayOfCoords(format),
699
+ ...this.holes.map((h) => h.toArrayOfCoords(format))
700
+ ]
701
+ };
702
+ }
703
+ return {
704
+ type: 'LineString',
705
+ coordinates: this.toArrayOfCoords(format)
706
+ };
626
707
  }
627
708
  divideToPieces(piecesCount, withAltitude = false) {
628
709
  const { fullLength } = this;
@@ -54,13 +54,34 @@ var DPoint = (function () {
54
54
  DPoint.zero = function () {
55
55
  return new DPoint();
56
56
  };
57
- DPoint.parse = function (c) {
58
- var _a = c, lat = _a.lat, lon = _a.lon, _b = _a.lng, lng = _b === void 0 ? lon : _b;
57
+ DPoint.parse = function (c, format) {
58
+ if (format === void 0) { format = 'xyz'; }
59
+ var _a = c, lat = _a.lat, lon = _a.lon, _b = _a.lng, lng = _b === void 0 ? lon : _b, alt = _a.alt;
59
60
  if (lat && lng) {
60
- return new DPoint(lat, lng, 0);
61
+ return new DPoint(lng, lat, alt !== null && alt !== void 0 ? alt : 0);
61
62
  }
62
- var _c = __read(c, 3), x = _c[0], y = _c[1], z = _c[2];
63
- return new DPoint(x, y, z);
63
+ var t = c;
64
+ if (c.type === 'Point') {
65
+ t = c.coordinates;
66
+ }
67
+ return format.replace(/[^x-z]/gmiu, '')
68
+ .split('')
69
+ .reduce(function (a, k, index) {
70
+ var _a, _b;
71
+ switch (k) {
72
+ case 'x':
73
+ a.x = (_a = t[index]) !== null && _a !== void 0 ? _a : 0;
74
+ break;
75
+ case 'y':
76
+ a.y = (_b = t[index]) !== null && _b !== void 0 ? _b : 0;
77
+ break;
78
+ case 'z':
79
+ a.z = t[index];
80
+ break;
81
+ default:
82
+ }
83
+ return a;
84
+ }, new DPoint());
64
85
  };
65
86
  DPoint.parseFromWKT = function (wkt) {
66
87
  var regexp = /POINT \((?<data>(?:(?!\)).)*?)\)$/miu;
@@ -131,11 +152,23 @@ var DPoint = (function () {
131
152
  var y = PI_IN_DEGREE / Math.PI * Math.atan((Math.exp(n) - Math.exp(-n)) / 2);
132
153
  return new DPoint(x, y, zoom);
133
154
  };
134
- DPoint.prototype.toCoords = function () {
135
- if (this.z === undefined) {
136
- return [this.x, this.y];
137
- }
138
- return [this.x, this.y, this.z];
155
+ DPoint.prototype.toCoords = function (format) {
156
+ var _this = this;
157
+ if (format === void 0) { format = 'xyz'; }
158
+ return format.replace(/[^x-z]/gmiu, '').split('')
159
+ .map(function (k) { return ({
160
+ x: _this.x,
161
+ y: _this.y,
162
+ z: _this.z
163
+ })[k]; })
164
+ .filter(function (r) { return r !== undefined; });
165
+ };
166
+ DPoint.prototype.toGeoJSON = function (format) {
167
+ if (format === void 0) { format = 'xyz'; }
168
+ return {
169
+ type: 'Point',
170
+ coordinates: this.toCoords(format)
171
+ };
139
172
  };
140
173
  DPoint.prototype.findLine = function (p) {
141
174
  checkFunction('findLine')
@@ -559,6 +592,34 @@ var DPoint = (function () {
559
592
  enumerable: false,
560
593
  configurable: true
561
594
  });
595
+ Object.defineProperty(DPoint.prototype, "lat", {
596
+ get: function () {
597
+ return this.y;
598
+ },
599
+ enumerable: false,
600
+ configurable: true
601
+ });
602
+ Object.defineProperty(DPoint.prototype, "lng", {
603
+ get: function () {
604
+ return this.x;
605
+ },
606
+ enumerable: false,
607
+ configurable: true
608
+ });
609
+ Object.defineProperty(DPoint.prototype, "lon", {
610
+ get: function () {
611
+ return this.x;
612
+ },
613
+ enumerable: false,
614
+ configurable: true
615
+ });
616
+ Object.defineProperty(DPoint.prototype, "alt", {
617
+ get: function () {
618
+ return this.z;
619
+ },
620
+ enumerable: false,
621
+ configurable: true
622
+ });
562
623
  DPoint.prototype.simple = function (xKey, yKey) {
563
624
  var _a;
564
625
  if (xKey === void 0) { xKey = 'x'; }