@artstesh/maps 4.1.23 → 4.1.25
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/esm2020/map/map-plate/features/polygons/polygons.component.mjs +6 -2
- package/dist/esm2020/map/map-plate/layers/feature-layer/feature-layer.settings.mjs +13 -1
- package/dist/esm2020/map/map-plate/map-plate.component.mjs +5 -1
- package/dist/esm2020/map/messages/events/map-feature-hovered.event.mjs +21 -0
- package/dist/esm2020/map/messages/events/map-pointer-move.event.mjs +20 -0
- package/dist/esm2020/map/messages/executors/polygon-self-intersection.executor.mjs +9 -0
- package/dist/esm2020/map/messages/index.mjs +4 -1
- package/dist/esm2020/map/models/map.constants.mjs +2 -1
- package/dist/esm2020/map/services/feature.service.mjs +53 -2
- package/dist/esm2020/map/services/map-feature.service.mjs +22 -2
- package/dist/esm2020/map/services/message-registrator.service.mjs +8 -2
- package/dist/esm2020/src/map/map-plate/features/polygons/polygons.component.mjs +6 -2
- package/dist/esm2020/src/map/map-plate/layers/feature-layer/feature-layer.settings.mjs +13 -1
- package/dist/esm2020/src/map/map-plate/map-plate.component.mjs +5 -1
- package/dist/esm2020/src/map/messages/events/map-feature-hovered.event.mjs +21 -0
- package/dist/esm2020/src/map/messages/events/map-pointer-move.event.mjs +20 -0
- package/dist/esm2020/src/map/messages/executors/polygon-self-intersection.executor.mjs +9 -0
- package/dist/esm2020/src/map/messages/index.mjs +4 -1
- package/dist/esm2020/src/map/models/map.constants.mjs +2 -1
- package/dist/esm2020/src/map/services/feature.service.mjs +53 -2
- package/dist/esm2020/src/map/services/map-feature.service.mjs +22 -2
- package/dist/esm2020/src/map/services/message-registrator.service.mjs +8 -2
- package/dist/fesm2015/maps-components-src-map.mjs +143 -6
- package/dist/fesm2015/maps-components-src-map.mjs.map +1 -1
- package/dist/fesm2015/maps-components.mjs +143 -6
- package/dist/fesm2015/maps-components.mjs.map +1 -1
- package/dist/fesm2020/maps-components-src-map.mjs +143 -6
- package/dist/fesm2020/maps-components-src-map.mjs.map +1 -1
- package/dist/fesm2020/maps-components.mjs +143 -6
- package/dist/fesm2020/maps-components.mjs.map +1 -1
- package/dist/map/map-plate/layers/feature-layer/feature-layer.settings.d.ts +22 -0
- package/dist/map/messages/events/map-feature-hovered.event.d.ts +19 -0
- package/dist/map/messages/events/map-pointer-move.event.d.ts +17 -0
- package/dist/map/messages/executors/polygon-self-intersection.executor.d.ts +7 -0
- package/dist/map/messages/index.d.ts +3 -0
- package/dist/map/models/map.constants.d.ts +1 -0
- package/dist/map/services/feature.service.d.ts +5 -0
- package/dist/map/services/map-feature.service.d.ts +1 -0
- package/dist/src/map/map-plate/layers/feature-layer/feature-layer.settings.d.ts +22 -0
- package/dist/src/map/messages/events/map-feature-hovered.event.d.ts +19 -0
- package/dist/src/map/messages/events/map-pointer-move.event.d.ts +17 -0
- package/dist/src/map/messages/executors/polygon-self-intersection.executor.d.ts +7 -0
- package/dist/src/map/messages/index.d.ts +3 -0
- package/dist/src/map/models/map.constants.d.ts +1 -0
- package/dist/src/map/services/feature.service.d.ts +5 -0
- package/dist/src/map/services/map-feature.service.d.ts +1 -0
- package/package.json +1 -1
|
@@ -3,7 +3,7 @@ import { Component, Injectable, ChangeDetectionStrategy, Input, ViewChild, NgMod
|
|
|
3
3
|
import * as i4 from '@angular/common';
|
|
4
4
|
import { CommonModule } from '@angular/common';
|
|
5
5
|
import { Feature, Collection } from 'ol';
|
|
6
|
-
import { Point } from 'ol/geom';
|
|
6
|
+
import { Point, LineString } from 'ol/geom';
|
|
7
7
|
import { GeoJSON, WKT } from 'ol/format';
|
|
8
8
|
import { getCenter, createEmpty, extend } from 'ol/extent';
|
|
9
9
|
import Polygon, { circular, fromExtent } from 'ol/geom/Polygon';
|
|
@@ -13,15 +13,15 @@ import { PostboyGenericMessage, PostboyCallbackMessage, PostboyExecutor, Postboy
|
|
|
13
13
|
import { Draw, Modify, Translate, defaults } from 'ol/interaction';
|
|
14
14
|
import { createRegularPolygon, createBox } from 'ol/interaction/Draw';
|
|
15
15
|
import * as Sphere from 'ol/sphere';
|
|
16
|
+
import { Subject, combineLatest } from 'rxjs';
|
|
17
|
+
import { first, debounceTime, filter, auditTime } from 'rxjs/operators';
|
|
16
18
|
import { Dictionary } from '@artstesh/collections';
|
|
17
|
-
import { first, filter, auditTime } from 'rxjs/operators';
|
|
18
19
|
import { Vector, XYZ } from 'ol/source';
|
|
19
20
|
import TileLayer from 'ol/layer/Tile';
|
|
20
21
|
import OSM from 'ol/source/OSM';
|
|
21
22
|
import { Vector as Vector$1 } from 'ol/layer';
|
|
22
23
|
import { bbox } from 'ol/loadingstrategy';
|
|
23
24
|
import Cluster from 'ol/source/Cluster';
|
|
24
|
-
import { combineLatest } from 'rxjs';
|
|
25
25
|
import Map from 'ol/Map';
|
|
26
26
|
import View from 'ol/View';
|
|
27
27
|
import Overlay from 'ol/Overlay';
|
|
@@ -194,7 +194,8 @@ IdGenerator.collection = 'ABCDEFGHIJKLMNOPQRSTUVWXTZ0123456789'.split('');
|
|
|
194
194
|
class MapConstants {
|
|
195
195
|
}
|
|
196
196
|
MapConstants.FeatureInfo = 'f-info';
|
|
197
|
-
MapConstants.DrawingLayerId = '93a981756ec7';
|
|
197
|
+
MapConstants.DrawingLayerId = '93a981756ec7';
|
|
198
|
+
MapConstants.FeatureLayerName = 'L-253';
|
|
198
199
|
|
|
199
200
|
class MarkerModel {
|
|
200
201
|
constructor(lat, lng, id, info) {
|
|
@@ -518,6 +519,45 @@ class MapMoveEndEvent extends PostboyGenericMessage {
|
|
|
518
519
|
}
|
|
519
520
|
MapMoveEndEvent.ID = 'd210ec7e-032f-4ce8-8a39-7b816519eaae';
|
|
520
521
|
|
|
522
|
+
/**
|
|
523
|
+
* Represents an event that is triggered when the pointer moves on a map.
|
|
524
|
+
* This class extends PostboyGenericMessage.
|
|
525
|
+
*
|
|
526
|
+
* It contains information about the coordinates of the pointer when the event occurs.
|
|
527
|
+
*/
|
|
528
|
+
class MapPointerMoveEvent extends PostboyGenericMessage {
|
|
529
|
+
/**
|
|
530
|
+
* Constructor for initializing an instance with a given point.
|
|
531
|
+
*
|
|
532
|
+
* @param {Array<number>} point - An array representing the coordinates of the point.
|
|
533
|
+
*/
|
|
534
|
+
constructor(point) {
|
|
535
|
+
super();
|
|
536
|
+
this.point = point;
|
|
537
|
+
}
|
|
538
|
+
}
|
|
539
|
+
MapPointerMoveEvent.ID = '193cb41d-2489-45cc-b349-59c3ec18ed72';
|
|
540
|
+
|
|
541
|
+
/**
|
|
542
|
+
* Represents an event triggered when a map feature is hovered over.
|
|
543
|
+
* This event contains information about the hovered feature and its associated layer.
|
|
544
|
+
* Extends the PostboyGenericMessage class.
|
|
545
|
+
*/
|
|
546
|
+
class MapFeatureHoveredEvent extends PostboyGenericMessage {
|
|
547
|
+
/**
|
|
548
|
+
* Constructs an instance of the class.
|
|
549
|
+
*
|
|
550
|
+
* @param {Feature|null} feature - The feature associated with this instance. Can be null.
|
|
551
|
+
* @param {string|null} layer - The layer associated with this instance. Can be null.
|
|
552
|
+
*/
|
|
553
|
+
constructor(feature, layer) {
|
|
554
|
+
super();
|
|
555
|
+
this.feature = feature;
|
|
556
|
+
this.layer = layer;
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
MapFeatureHoveredEvent.ID = 'eb9b032a-1616-4823-a628-0fd8ffc3b57a';
|
|
560
|
+
|
|
521
561
|
/**
|
|
522
562
|
* A class responsible for executing filtering of geographical features
|
|
523
563
|
* based on a specific geographical point (latitude and longitude).
|
|
@@ -586,6 +626,14 @@ class GetMapPositionExecutor extends PostboyExecutor {
|
|
|
586
626
|
}
|
|
587
627
|
GetMapPositionExecutor.ID = '52c95689-d09b-4082-ba58-9183ea96a213';
|
|
588
628
|
|
|
629
|
+
class PolygonSelfIntersectionExecutor extends PostboyGenericMessage {
|
|
630
|
+
constructor(polygon) {
|
|
631
|
+
super();
|
|
632
|
+
this.polygon = polygon;
|
|
633
|
+
}
|
|
634
|
+
}
|
|
635
|
+
PolygonSelfIntersectionExecutor.ID = 'a4ef116d-fe40-4e92-9d4a-653f8b398c62';
|
|
636
|
+
|
|
589
637
|
/**
|
|
590
638
|
* Class representing a query to get features within a specified geographical area.
|
|
591
639
|
* The query optionally takes a set of layer names to ignore during the operation.
|
|
@@ -723,6 +771,20 @@ class FeatureService {
|
|
|
723
771
|
return 0;
|
|
724
772
|
return Sphere.getArea(g, { projection: 'EPSG:4326' });
|
|
725
773
|
}
|
|
774
|
+
static polygonSelfIntersects(feature) {
|
|
775
|
+
if (feature.getGeometry().getType() !== 'Polygon')
|
|
776
|
+
return false;
|
|
777
|
+
let intersections = 0;
|
|
778
|
+
const segments = FeatureService.getSegmentsFromCoordinates(feature.getGeometry());
|
|
779
|
+
for (let i = 0; i < segments.length; i++) {
|
|
780
|
+
for (let z = i + 1; z < segments.length; z++) {
|
|
781
|
+
if (!intersections && this.segmentIntersection(segments[i].getCoordinates(), segments[z].getCoordinates())) {
|
|
782
|
+
intersections++;
|
|
783
|
+
}
|
|
784
|
+
}
|
|
785
|
+
}
|
|
786
|
+
return intersections !== 0;
|
|
787
|
+
}
|
|
726
788
|
static booleanIntersects(g1, g2) {
|
|
727
789
|
if (g2.getType() === 'Point')
|
|
728
790
|
return g1.intersectsCoordinate(g2.getCoordinates());
|
|
@@ -732,6 +794,43 @@ class FeatureService {
|
|
|
732
794
|
return g1.intersectsCoordinate(g2.getInteriorPoint().getCoordinates());
|
|
733
795
|
return false;
|
|
734
796
|
}
|
|
797
|
+
static getSegmentsFromCoordinates(geom) {
|
|
798
|
+
if (!geom)
|
|
799
|
+
return [];
|
|
800
|
+
const coords = geom.getCoordinates();
|
|
801
|
+
const line = new LineString(coords[0]);
|
|
802
|
+
const segments = [];
|
|
803
|
+
line.forEachSegment((s1, s2) => {
|
|
804
|
+
const l = new LineString([s1, s2]);
|
|
805
|
+
l.scale(0.999); // bug of the OL, as I see
|
|
806
|
+
segments.push(l);
|
|
807
|
+
});
|
|
808
|
+
return segments;
|
|
809
|
+
}
|
|
810
|
+
static segmentIntersection(s1, s2) {
|
|
811
|
+
const a = s1[0], b = s1[1], c = s2[0], d = s2[1];
|
|
812
|
+
const o1 = this.orientation(a, b, c);
|
|
813
|
+
const o2 = this.orientation(a, b, d);
|
|
814
|
+
const o3 = this.orientation(c, d, a);
|
|
815
|
+
const o4 = this.orientation(c, d, b);
|
|
816
|
+
return ((o1 != o2 && o3 != o4) ||
|
|
817
|
+
(o1 == 0 && this.onSegment(a, d, b)) ||
|
|
818
|
+
(o2 == 0 && this.onSegment(a, d, b)) ||
|
|
819
|
+
(o3 == 0 && this.onSegment(d, a, d)) ||
|
|
820
|
+
(o4 == 0 && this.onSegment(d, b, d)));
|
|
821
|
+
}
|
|
822
|
+
static orientation(p, q, r) {
|
|
823
|
+
const val = (q[1] - p[1]) * (r[0] - q[0]) - (q[0] - p[0]) * (r[1] - q[1]);
|
|
824
|
+
if (val == 0)
|
|
825
|
+
return 0; // collinear
|
|
826
|
+
return val > 0 ? 1 : 2; // clock or counterclock wise
|
|
827
|
+
}
|
|
828
|
+
static onSegment(p, q, r) {
|
|
829
|
+
return (q[0] <= (p[0] > r[0] ? p[0] : r[0]) &&
|
|
830
|
+
q[0] >= (p[0] < r[0] ? p[0] : r[0]) &&
|
|
831
|
+
q[1] <= (p[1] > r[1] ? p[1] : r[1]) &&
|
|
832
|
+
q[1] >= (p[1] < r[1] ? p[1] : r[1]));
|
|
833
|
+
}
|
|
735
834
|
}
|
|
736
835
|
|
|
737
836
|
class GenerateDrawExecutor extends PostboyExecutor {
|
|
@@ -932,6 +1031,7 @@ class MapFeatureService {
|
|
|
932
1031
|
this.observeMapRender();
|
|
933
1032
|
this.observeFitToFeatures();
|
|
934
1033
|
this.observeFitToPolygons();
|
|
1034
|
+
this.observePointerMove();
|
|
935
1035
|
}
|
|
936
1036
|
observeMapRender() {
|
|
937
1037
|
this.postboy.sub(MapRenderedEvent).subscribe((m) => {
|
|
@@ -940,6 +1040,22 @@ class MapFeatureService {
|
|
|
940
1040
|
this.postboy.fire(this.fitPolygonsWaiting);
|
|
941
1041
|
});
|
|
942
1042
|
}
|
|
1043
|
+
observePointerMove() {
|
|
1044
|
+
this.postboy.sub(MapPointerMoveEvent).subscribe((ev) => {
|
|
1045
|
+
if (!this.map)
|
|
1046
|
+
return;
|
|
1047
|
+
let featureFound = false;
|
|
1048
|
+
this.map.forEachFeatureAtPixel(ev.point, (f) => {
|
|
1049
|
+
if (f instanceof Feature) {
|
|
1050
|
+
this.postboy.fire(new MapFeatureHoveredEvent(f, f.get(MapConstants.FeatureLayerName)));
|
|
1051
|
+
featureFound = true;
|
|
1052
|
+
}
|
|
1053
|
+
return true;
|
|
1054
|
+
});
|
|
1055
|
+
if (!featureFound)
|
|
1056
|
+
this.postboy.fire(new MapFeatureHoveredEvent(null, null));
|
|
1057
|
+
});
|
|
1058
|
+
}
|
|
943
1059
|
observeFitToFeatures() {
|
|
944
1060
|
this.postboy.sub(FitToFeaturesCommand).subscribe((cmd) => {
|
|
945
1061
|
this.fitToGeometries(cmd.features.map((f) => f.getGeometry()), cmd.zoomAfter);
|
|
@@ -1234,6 +1350,8 @@ class MessageRegistratorService extends PostboyAbstractRegistrator {
|
|
|
1234
1350
|
this.recordSubject(CancelDrawingCommand);
|
|
1235
1351
|
this.recordSubject(StartDrawingCommand);
|
|
1236
1352
|
this.recordSubject(GetLayerQuery);
|
|
1353
|
+
this.recordSubject(MapFeatureHoveredEvent);
|
|
1354
|
+
this.recordWithPipe(MapPointerMoveEvent, new Subject(), (s) => s.pipe(debounceTime(150)));
|
|
1237
1355
|
this.recordSubject(DrawingFinishedEvent);
|
|
1238
1356
|
this.recordSubject(GetFeaturesInAreaQuery);
|
|
1239
1357
|
this.recordSubject(DrawSelectionAreaCommand);
|
|
@@ -1246,6 +1364,7 @@ class MessageRegistratorService extends PostboyAbstractRegistrator {
|
|
|
1246
1364
|
this.recordExecutor(FilterFeaturesInAreaExecutor, (e) => FeatureService.filterFeaturesInArea(e));
|
|
1247
1365
|
this.recordExecutor(FilterFeaturesInPointExecutor, (e) => FeatureService.filterFeaturesInPoint(e));
|
|
1248
1366
|
this.recordExecutor(CalculateAreaExecutor, (e) => FeatureService.calculateArea(e.polygon?.feature?.getGeometry()));
|
|
1367
|
+
this.recordExecutor(PolygonSelfIntersectionExecutor, (e) => FeatureService.polygonSelfIntersects(e.polygon.feature));
|
|
1249
1368
|
this.recordExecutor(GenerateDrawExecutor, (e) => DrawingGenerationService.getDraw(e));
|
|
1250
1369
|
this.recordExecutor(GenerateZoomControlExecutor, (e) => ZoomControlFactory.build(e.settings));
|
|
1251
1370
|
this.recordExecutor(GetMapPositionExecutor, () => this.state.getMapPosition());
|
|
@@ -1590,6 +1709,7 @@ class FeatureLayerSettings {
|
|
|
1590
1709
|
result.minZoom = model.minZoom;
|
|
1591
1710
|
result.zIndex = model.zIndex;
|
|
1592
1711
|
result.style = model.style;
|
|
1712
|
+
result.featureHoverStyle = model.featureHoverStyle;
|
|
1593
1713
|
return result;
|
|
1594
1714
|
}
|
|
1595
1715
|
/**
|
|
@@ -1638,6 +1758,15 @@ class FeatureLayerSettings {
|
|
|
1638
1758
|
setStyle(style) {
|
|
1639
1759
|
return FeatureLayerSettings.copy({ ...this, style });
|
|
1640
1760
|
}
|
|
1761
|
+
/**
|
|
1762
|
+
* Sets the style to apply to features when they are hovered over.
|
|
1763
|
+
*
|
|
1764
|
+
* @param {Style | StyleFunction} featureHoverStyle - The style or style function to use for hovered features.
|
|
1765
|
+
* @return {FeatureLayerSettings} A new instance of FeatureLayerSettings with the updated hover style.
|
|
1766
|
+
*/
|
|
1767
|
+
setFeatureHoverStyle(featureHoverStyle) {
|
|
1768
|
+
return FeatureLayerSettings.copy({ ...this, featureHoverStyle });
|
|
1769
|
+
}
|
|
1641
1770
|
/**
|
|
1642
1771
|
* Checks if the given FeatureLayerSettings object is identical to the current object.
|
|
1643
1772
|
*
|
|
@@ -1655,6 +1784,8 @@ class FeatureLayerSettings {
|
|
|
1655
1784
|
return false;
|
|
1656
1785
|
if (this.style !== model.style)
|
|
1657
1786
|
return false;
|
|
1787
|
+
if (this.featureHoverStyle !== model.featureHoverStyle)
|
|
1788
|
+
return false;
|
|
1658
1789
|
return true;
|
|
1659
1790
|
}
|
|
1660
1791
|
}
|
|
@@ -2051,6 +2182,9 @@ class MapPlateComponent extends DestructibleComponent {
|
|
|
2051
2182
|
this.map.updateSize();
|
|
2052
2183
|
this.postboy.fire(new MapRenderedEvent(this.map));
|
|
2053
2184
|
});
|
|
2185
|
+
this.map.on('pointermove', (ev) => {
|
|
2186
|
+
this.postboy.fire(new MapPointerMoveEvent(ev.pixel));
|
|
2187
|
+
});
|
|
2054
2188
|
this.setOsm();
|
|
2055
2189
|
}
|
|
2056
2190
|
setOsm() {
|
|
@@ -2262,7 +2396,10 @@ class PolygonsComponent extends DestructibleComponent {
|
|
|
2262
2396
|
putPolygons() {
|
|
2263
2397
|
if (!this._polygons)
|
|
2264
2398
|
return;
|
|
2265
|
-
this.postboy.fire(new PlaceLayerFeaturesCommand(this.layerName, this._polygons.map((m) =>
|
|
2399
|
+
this.postboy.fire(new PlaceLayerFeaturesCommand(this.layerName, this._polygons.map((m) => {
|
|
2400
|
+
m.feature.set(MapConstants.FeatureLayerName, this.layerName);
|
|
2401
|
+
return m.feature;
|
|
2402
|
+
})));
|
|
2266
2403
|
}
|
|
2267
2404
|
}
|
|
2268
2405
|
PolygonsComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: PolygonsComponent, deps: [{ token: MapPostboyService }], target: i0.ɵɵFactoryTarget.Component });
|
|
@@ -2698,5 +2835,5 @@ class StringifyFeatureHelper {
|
|
|
2698
2835
|
* Generated bundle index. Do not edit.
|
|
2699
2836
|
*/
|
|
2700
2837
|
|
|
2701
|
-
export { AddControlCommand, CalculateAreaExecutor, CancelDrawingCommand, CancelFeatureModificationCommand, CloseTooltipCommand, ClusterLayerComponent, ClusterLayerSettings, DrawSelectionAreaCommand, DrawingType, FeatureLayerComponent, FeatureLayerSettings, FeatureOutputFormat, FilterFeaturesInAreaExecutor, FilterFeaturesInPointExecutor, FitToFeaturesCommand, FitToPolygonsCommand, GetFeaturesInAreaQuery, GetFeaturesInPointQuery, GetMapPositionExecutor, MapClickEvent, MapConstants, MapControl, MapControlZoomComponent, MapLyrs, MapLyrsLabel, MapModule, MapMoveEndEvent, MapPlateComponent, MapPostboyService, MapRenderedEvent, MapSettings, MarkerModel, MarkerStyleHelper, MarkersComponent, MessageRegistratorService, ModifyFeatureCommand, OsmTileLayerComponent, PolygonModel, PolygonStyleHelper, PolygonsComponent, RemoveControlCommand, SetMapCenterCommand, StartDrawingCommand, StringifyFeatureHelper, TextStyleHelper, TileLayerComponent, TileLayerSettings, TooltipComponent, TooltipSettings, ZoomControlSettings };
|
|
2838
|
+
export { AddControlCommand, CalculateAreaExecutor, CancelDrawingCommand, CancelFeatureModificationCommand, CloseTooltipCommand, ClusterLayerComponent, ClusterLayerSettings, DrawSelectionAreaCommand, DrawingType, FeatureLayerComponent, FeatureLayerSettings, FeatureOutputFormat, FilterFeaturesInAreaExecutor, FilterFeaturesInPointExecutor, FitToFeaturesCommand, FitToPolygonsCommand, GetFeaturesInAreaQuery, GetFeaturesInPointQuery, GetMapPositionExecutor, MapClickEvent, MapConstants, MapControl, MapControlZoomComponent, MapFeatureHoveredEvent, MapLyrs, MapLyrsLabel, MapModule, MapMoveEndEvent, MapPlateComponent, MapPointerMoveEvent, MapPostboyService, MapRenderedEvent, MapSettings, MarkerModel, MarkerStyleHelper, MarkersComponent, MessageRegistratorService, ModifyFeatureCommand, OsmTileLayerComponent, PolygonModel, PolygonSelfIntersectionExecutor, PolygonStyleHelper, PolygonsComponent, RemoveControlCommand, SetMapCenterCommand, StartDrawingCommand, StringifyFeatureHelper, TextStyleHelper, TileLayerComponent, TileLayerSettings, TooltipComponent, TooltipSettings, ZoomControlSettings };
|
|
2702
2839
|
//# sourceMappingURL=maps-components.mjs.map
|