From c2fc590a63a3b86cb4995d2453aaa7153740e4c4 Mon Sep 17 00:00:00 2001 From: Just van den Broecke Date: Mon, 9 Mar 2020 17:33:37 +0100 Subject: [PATCH 1/4] #107 FeatureInfoWindow working with multiple Layers - added Dutch Castles Layer --- src/WguAppTemplate.vue | 9 ++- src/components/FeatureInfoWindow.vue | 67 +++++++++++++------ static/app-conf.json | 56 +++++++++++++++- .../components/FeatureInfoWindow.spec.js | 9 +-- 4 files changed, 111 insertions(+), 30 deletions(-) diff --git a/src/WguAppTemplate.vue b/src/WguAppTemplate.vue index 5570dc78..d7d9b0b2 100644 --- a/src/WguAppTemplate.vue +++ b/src/WguAppTemplate.vue @@ -33,6 +33,8 @@ :color="baseColor" :draggable="moduleWin.draggable" :initPos="moduleWin.initPos" + :title="moduleWin.title" + :icon="moduleWin.icon" /> @@ -63,6 +65,7 @@ import LayerListWin from './components/layerlist/LayerListWin' import InfoClickWin from './components/infoclick/InfoClickWin' import MapLoadingStatus from './components/progress/MapLoadingStatus' + import FeatureInfoWindow from './components/FeatureInfoWindow' export default { name: 'wgu-app-tpl', @@ -74,7 +77,8 @@ 'wgu-measuretool-win': MeasureWin, 'wgu-layerlist-win': LayerListWin, 'wgu-infoclick-win': InfoClickWin, - 'wgu-maploading-status': MapLoadingStatus + 'wgu-maploading-status': MapLoadingStatus, + 'wgu-feature-info-window-win': FeatureInfoWindow }, data () { return { @@ -121,7 +125,8 @@ moduleWins.push({ type: key + '-win', draggable: moduleOpts.draggable, - initPos: moduleOpts.initPos + initPos: moduleOpts.initPos, + title: moduleOpts.title }); } } diff --git a/src/components/FeatureInfoWindow.vue b/src/components/FeatureInfoWindow.vue index 4d458ce9..4a3509ef 100644 --- a/src/components/FeatureInfoWindow.vue +++ b/src/components/FeatureInfoWindow.vue @@ -10,16 +10,17 @@ {{icon}} {{title}} + close - +

{{attributes[titleProp]}}

- More info... + {{infoUrlText}} @@ -31,34 +32,53 @@ import { WguEventBus } from '../WguEventBus.js'; import { DraggableWin } from '../directives/DraggableWin.js'; export default { - name: 'wgu-feature-info-window', + name: 'wgu-feature-info-window-win', directives: { DraggableWin }, props: { - layerId: {type: String, required: true}, - imageProp: {type: String, required: false}, - titleProp: {type: String, required: false}, - icon: {type: String, required: false}, - title: {type: String, required: false} + icon: {type: String, required: false, default: 'info'}, + title: {type: String, required: false, default: 'Feature Info'} }, data () { return { - // will be filled in mounted + // will be filled in mounted and when feature clicked feature: null, attributes: null, - left: '300px', - top: '200px' + left: null, + top: null, + titleProp: null, + imageProp: null, + infoUrlProp: null, + infoUrlText: null, + imageHeight: null } }, mounted () { + const config = this.$appConfig.modules['wgu-feature-info-window'] || {}; + this.layers = config.layers; + this.left = config.initPos ? this.initPos.left + 'px' : '300px'; + this.top = config.initPos ? this.initPos.top + 'px' : '200px'; var me = this; // listen to selection events of connected layer and apply attributes WguEventBus.$on('map-selectionchange', function (layerId, selected, deselected) { - if (me.layerId === layerId) { - me.setFeature(selected[0]); + if (selected.length === 0) { + return; } + const layer = me.findLayer(layerId); + if (!layer) { + return; + } + // me = {...layer}; TODO How to use Object Spread + me.layerId = layer.layerId; + me.titleProp = layer.titleProp; + me.imageProp = layer.imageProp; + me.imageHeight = layer.imageHeight || '200px'; + me.infoUrlProp = layer.infoUrlProp; + me.infoUrlText = layer.infoUrlText || 'More info...'; + + me.setFeature(selected[0]); }); }, methods: { @@ -67,13 +87,20 @@ export default { * @param {ol.Feature} feature The new feature */ setFeature (feature) { - if (feature) { - this.feature = feature; - this.attributes = feature.getProperties(); - } else { - this.feature = null; - this.attributes = null; - } + this.feature = feature; + this.attributes = this.feature ? this.feature.getProperties() : null; + }, + /** + * Find a layer in our target Layer collection by layer name (layerId). + * @param {layerId} layerId layer name + */ + findLayer (layerId) { + const targetLayerArr = this.layers.filter(layer => layer.layerId === layerId); + return targetLayerArr.length > 0 ? targetLayerArr[0] : null; + }, + onWinXClose: function () { + // this.feature.deselected; TODO: how to deselect Feature on Map? + this.setFeature(null); } } diff --git a/static/app-conf.json b/static/app-conf.json index 6af2b2aa..1e96ec03 100644 --- a/static/app-conf.json +++ b/static/app-conf.json @@ -55,7 +55,40 @@ "fillColor": "rgba(207, 16, 32, 0.6)" } }, - + { + "type": "VECTOR", + "lid": "dutch_windmills", + "name": "Dutch Windmills", + "url": "https://demo.pygeoapi.io/master/collections/dutch_windmills/items", + "formatConfig": { + }, + "format": "GeoJSON", + "visible": true, + "selectable": true, + "style": { + "radius": 4, + "strokeColor": "orange", + "strokeWidth": 2, + "fillColor": "rgba(155,153,51,0.5)" + } + }, + { + "type": "VECTOR", + "lid": "dutch_castles", + "name": "Dutch Castles", + "url": "https://demo.pygeoapi.io/master/collections/dutch_castles/items", + "formatConfig": { + }, + "format": "GeoJSON", + "visible": true, + "selectable": true, + "style": { + "radius": 4, + "strokeColor": "blue", + "strokeWidth": 2, + "fillColor": "rgba(155,153,51,0.5)" + } + }, { "type": "WMS", "lid": "ahocevar-wms", @@ -129,7 +162,26 @@ "wgu-helpwin": { "target": "toolbar", "darkLayout": true + }, + "wgu-feature-info-window": { + "win": true, + "draggable": true, + "layers": [ + { + "layerId": "dutch_windmills", + "title": "Dutch Windmills", + "titleProp": "NAAM", + "imageProp": "FOTO_GROOT", + "infoUrlProp": "INFOLINK" + }, + { + "layerId": "dutch_castles", + "title": "Dutch Castles", + "titleProp": "naam", + "imageProp": "foto_groot", + "infoUrlProp": "info_link" + } + ] } } - } diff --git a/test/unit/specs/components/FeatureInfoWindow.spec.js b/test/unit/specs/components/FeatureInfoWindow.spec.js index 2e6d034a..57a31152 100644 --- a/test/unit/specs/components/FeatureInfoWindow.spec.js +++ b/test/unit/specs/components/FeatureInfoWindow.spec.js @@ -17,11 +17,8 @@ describe('InfoWindow.vue', () => { }); it('has correct default props', () => { - expect(vm.layerId).to.equal(undefined); - expect(vm.imageProp).to.equal(undefined); - expect(vm.titleProp).to.equal(undefined); - expect(vm.icon).to.equal(undefined); - expect(vm.title).to.equal(undefined); + expect(vm.icon).to.equal('info'); + expect(vm.title).to.equal('Feature Info'); }); }); @@ -51,7 +48,7 @@ describe('InfoWindow.vue', () => { it('setFeature resets if no feature passed', () => { vm.setFeature(); - expect(vm.feature).to.equal(null); + expect(vm.feature).to.equal(undefined); expect(vm.attributes).to.equal(null); }); From 9be3406c74c8f8d3a9672c20f2319b20675180b0 Mon Sep 17 00:00:00 2001 From: Just van den Broecke Date: Mon, 9 Mar 2020 22:43:07 +0100 Subject: [PATCH 2/4] #107 FeatureInfoWindow more config options and projected example and POI icons --- src/WguAppTemplate.vue | 5 ++- src/components/FeatureInfoWindow.vue | 53 +++++++++++++----------- static/app-conf-projected.json | 58 +++++++++++++++++++++++++++ static/app-conf.json | 24 +++++------ static/icon/README.md | 8 ++++ static/icon/castle.png | Bin 0 -> 2532 bytes static/icon/castle2.png | Bin 0 -> 1168 bytes static/icon/windmill2.png | Bin 0 -> 779 bytes 8 files changed, 111 insertions(+), 37 deletions(-) create mode 100644 static/icon/README.md create mode 100644 static/icon/castle.png create mode 100644 static/icon/castle2.png create mode 100644 static/icon/windmill2.png diff --git a/src/WguAppTemplate.vue b/src/WguAppTemplate.vue index d7d9b0b2..c3bdd1b6 100644 --- a/src/WguAppTemplate.vue +++ b/src/WguAppTemplate.vue @@ -33,6 +33,7 @@ :color="baseColor" :draggable="moduleWin.draggable" :initPos="moduleWin.initPos" + :width="moduleWin.width" :title="moduleWin.title" :icon="moduleWin.icon" /> @@ -126,7 +127,9 @@ type: key + '-win', draggable: moduleOpts.draggable, initPos: moduleOpts.initPos, - title: moduleOpts.title + title: moduleOpts.title, + width: moduleOpts.width, + icon: moduleOpts.icon }); } } diff --git a/src/components/FeatureInfoWindow.vue b/src/components/FeatureInfoWindow.vue index 4a3509ef..f9fdb74b 100644 --- a/src/components/FeatureInfoWindow.vue +++ b/src/components/FeatureInfoWindow.vue @@ -2,23 +2,22 @@ + v-bind:style="{ left: left, top: top, width: width }" > - + {{icon}} {{title}} close - - -
-

{{attributes[titleProp]}}

-
+ + +

{{attributes[titleProp]}}

+ {{attributes[descProp]}} {{infoUrlText}} @@ -38,20 +37,25 @@ export default { }, props: { icon: {type: String, required: false, default: 'info'}, - title: {type: String, required: false, default: 'Feature Info'} + color: {type: String, required: false, default: 'red darken-3'}, + draggable: {type: Boolean, required: false, default: true} }, data () { return { - // will be filled in mounted and when feature clicked + // will be filled in when mounted and when feature clicked feature: null, attributes: null, + width: null, left: null, top: null, + title: null, titleProp: null, imageProp: null, + descProp: null, infoUrlProp: null, infoUrlText: null, - imageHeight: null + imageHeight: null, + imageWidth: null } }, mounted () { @@ -59,26 +63,29 @@ export default { this.layers = config.layers; this.left = config.initPos ? this.initPos.left + 'px' : '300px'; this.top = config.initPos ? this.initPos.top + 'px' : '200px'; - var me = this; + this.width = config.width ? config.width + 'px' : '350px'; // listen to selection events of connected layer and apply attributes - WguEventBus.$on('map-selectionchange', function (layerId, selected, deselected) { + WguEventBus.$on('map-selectionchange', (layerId, selected, deselected) => { if (selected.length === 0) { return; } - const layer = me.findLayer(layerId); + const layer = this.findLayer(layerId); if (!layer) { return; } - // me = {...layer}; TODO How to use Object Spread - me.layerId = layer.layerId; - me.titleProp = layer.titleProp; - me.imageProp = layer.imageProp; - me.imageHeight = layer.imageHeight || '200px'; - me.infoUrlProp = layer.infoUrlProp; - me.infoUrlText = layer.infoUrlText || 'More info...'; + // {...layer}; TODO How to use Object Spread + this.layerId = layer.layerId; + this.title = layer.title || layer.titleProp || 'Feature Info'; + this.titleProp = layer.titleProp; + this.descProp = layer.descProp; + this.imageProp = layer.imageProp; + this.imageHeight = layer.imageHeight; + this.imageWidth = layer.imageWidth; + this.infoUrlProp = layer.infoUrlProp; + this.infoUrlText = layer.infoUrlText || 'More info...'; - me.setFeature(selected[0]); + this.setFeature(selected[0]); }); }, methods: { @@ -103,7 +110,6 @@ export default { this.setFeature(null); } } - } @@ -112,7 +118,6 @@ export default { .wgu-feature-infowindow.info-card { position: absolute; - width: 300px; background-color: white; } diff --git a/static/app-conf-projected.json b/static/app-conf-projected.json index c578352e..e1530c4d 100644 --- a/static/app-conf-projected.json +++ b/static/app-conf-projected.json @@ -28,6 +28,42 @@ ], "mapLayers": [ + { + "type": "VECTOR", + "lid": "dutch_windmills", + "name": "Dutch Windmills", + "url": "https://demo.pygeoapi.io/master/collections/dutch_windmills/items", + "formatConfig": { + "dataProjection": "EPSG:4326" + }, + "format": "GeoJSON", + "visible": true, + "selectable": true, + "style": { + "iconUrl": "./static/icon/windmill2.png", + "anchor": [0.5, 37], + "anchorXUnits": "fraction", + "anchorYUnits": "pixels" + } + }, + { + "type": "VECTOR", + "lid": "dutch_castles", + "name": "Dutch Castles", + "url": "https://demo.pygeoapi.io/master/collections/dutch_castles/items", + "formatConfig": { + "dataProjection": "EPSG:4326" + }, + "format": "GeoJSON", + "visible": true, + "selectable": true, + "style": { + "iconUrl": "./static/icon/castle2.png", + "anchor": [0.5, 37], + "anchorXUnits": "fraction", + "anchorYUnits": "pixels" + } + }, { "type": "WMS", "lid": "pdok-natura2000-wms", @@ -93,6 +129,28 @@ "wgu-helpwin": { "target": "toolbar", "darkLayout": true + }, + "wgu-feature-info-window": { + "win": true, + "draggable": true, + "width": 360, + "icon": "info", + "layers": [ + { + "layerId": "dutch_windmills", + "title": "Dutch Windmills", + "titleProp": "NAAM", + "imageProp": "FOTO_GROOT", + "infoUrlProp": "INFOLINK" + }, + { + "layerId": "dutch_castles", + "title": "Dutch Castles", + "titleProp": "naam", + "imageProp": "foto_groot", + "infoUrlProp": "info_link" + } + ] } } diff --git a/static/app-conf.json b/static/app-conf.json index 1e96ec03..59e77ac8 100644 --- a/static/app-conf.json +++ b/static/app-conf.json @@ -66,10 +66,10 @@ "visible": true, "selectable": true, "style": { - "radius": 4, - "strokeColor": "orange", - "strokeWidth": 2, - "fillColor": "rgba(155,153,51,0.5)" + "iconUrl": "./static/icon/windmill2.png", + "anchor": [0.5, 37], + "anchorXUnits": "fraction", + "anchorYUnits": "pixels" } }, { @@ -83,10 +83,10 @@ "visible": true, "selectable": true, "style": { - "radius": 4, - "strokeColor": "blue", - "strokeWidth": 2, - "fillColor": "rgba(155,153,51,0.5)" + "iconUrl": "./static/icon/castle2.png", + "anchor": [0.5, 37], + "anchorXUnits": "fraction", + "anchorYUnits": "pixels" } }, { @@ -104,7 +104,6 @@ "visible": false, "displayInLayerList": true }, - { "type": "VECTORTILE", "name": "Vector Tile Layer", @@ -117,7 +116,6 @@ "fillColor": "rgba(20,20,20,0.1)" } }, - { "type": "OSM", "lid": "osm-bg", @@ -126,7 +124,6 @@ "visible": true, "displayInLayerList": true } - ], "modules": { @@ -166,13 +163,16 @@ "wgu-feature-info-window": { "win": true, "draggable": true, + "width": 360, + "icon": "info", "layers": [ { "layerId": "dutch_windmills", "title": "Dutch Windmills", "titleProp": "NAAM", "imageProp": "FOTO_GROOT", - "infoUrlProp": "INFOLINK" + "infoUrlProp": "INFOLINK", + "imageWidth": 360 }, { "layerId": "dutch_castles", diff --git a/static/icon/README.md b/static/icon/README.md new file mode 100644 index 00000000..6ea13dc7 --- /dev/null +++ b/static/icon/README.md @@ -0,0 +1,8 @@ +# Icons + +* castle.png from: https://openlayers.org/en/latest/examples/data/icon.png + +Main source and credits: https://mapicons.mapsmarker.com/ + +* castle2.png by: https://mapicons.mapsmarker.com/author/matthias.stasiak +* windmill2.png by: https://mapicons.mapsmarker.com/author/matthias.stasiak diff --git a/static/icon/castle.png b/static/icon/castle.png new file mode 100644 index 0000000000000000000000000000000000000000..ed886623d54cc7972175302fad216a541dd349c3 GIT binary patch literal 2532 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 Date: Wed, 11 Mar 2020 16:47:44 +0100 Subject: [PATCH 3/4] #107 #110 fix failing Unit Test --- src/components/FeatureInfoWindow.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/FeatureInfoWindow.vue b/src/components/FeatureInfoWindow.vue index f9fdb74b..92b013fa 100644 --- a/src/components/FeatureInfoWindow.vue +++ b/src/components/FeatureInfoWindow.vue @@ -48,7 +48,7 @@ export default { width: null, left: null, top: null, - title: null, + title: 'Feature Info', titleProp: null, imageProp: null, descProp: null, From e20465f837aa4e9108a9ddc541c7a778b665f310 Mon Sep 17 00:00:00 2001 From: Just van den Broecke Date: Mon, 16 Mar 2020 16:00:46 +0100 Subject: [PATCH 4/4] #107 FeatureInfoWindow: regexp layer filter and Feature Select Style --- src/components/FeatureInfoWindow.vue | 7 ++++++- src/components/ol/Map.vue | 3 ++- src/factory/Layer.js | 1 + static/app-conf-projected.json | 12 ++++++++++++ static/app-conf.json | 18 ++++++++++++++++++ static/icon/castle2-select.png | Bin 0 -> 745 bytes static/icon/windmill2-select.png | Bin 0 -> 780 bytes 7 files changed, 39 insertions(+), 2 deletions(-) create mode 100644 static/icon/castle2-select.png create mode 100644 static/icon/windmill2-select.png diff --git a/src/components/FeatureInfoWindow.vue b/src/components/FeatureInfoWindow.vue index 92b013fa..19cf4c92 100644 --- a/src/components/FeatureInfoWindow.vue +++ b/src/components/FeatureInfoWindow.vue @@ -43,6 +43,7 @@ export default { data () { return { // will be filled in when mounted and when feature clicked + layers: null, feature: null, attributes: null, width: null, @@ -61,6 +62,10 @@ export default { mounted () { const config = this.$appConfig.modules['wgu-feature-info-window'] || {}; this.layers = config.layers; + if (this.layers) { + // Using a regular expression to Match layers + this.layers.forEach(layer => { layer.layerId = new RegExp(layer.layerId) }); + } this.left = config.initPos ? this.initPos.left + 'px' : '300px'; this.top = config.initPos ? this.initPos.top + 'px' : '200px'; this.width = config.width ? config.width + 'px' : '350px'; @@ -102,7 +107,7 @@ export default { * @param {layerId} layerId layer name */ findLayer (layerId) { - const targetLayerArr = this.layers.filter(layer => layer.layerId === layerId); + const targetLayerArr = this.layers.filter(layer => layerId.match(layer.layerId)); return targetLayerArr.length > 0 ? targetLayerArr[0] : null; }, onWinXClose: function () { diff --git a/src/components/ol/Map.vue b/src/components/ol/Map.vue index 0f778465..41067a3f 100644 --- a/src/components/ol/Map.vue +++ b/src/components/ol/Map.vue @@ -120,7 +120,8 @@ export default { // if layer is selectable register a select interaction if (lConf.selectable) { const selectClick = new SelectInteraction({ - layers: [layer] + layers: [layer], + style: layer.get('styleSelected') || undefined }); // forward an event if feature selection changes selectClick.on('select', function (evt) { diff --git a/src/factory/Layer.js b/src/factory/Layer.js index 073f3067..0ce02fb2 100644 --- a/src/factory/Layer.js +++ b/src/factory/Layer.js @@ -146,6 +146,7 @@ export const LayerFactory = { attributions: lConf.attributions }), style: OlStyleFactory.getInstance(lConf.style), + styleSelected: OlStyleFactory.getInstance(lConf.styleSelected), hoverable: lConf.hoverable, hoverAttribute: lConf.hoverAttribute }); diff --git a/static/app-conf-projected.json b/static/app-conf-projected.json index 29728433..4cc5a497 100644 --- a/static/app-conf-projected.json +++ b/static/app-conf-projected.json @@ -44,6 +44,12 @@ "anchor": [0.5, 37], "anchorXUnits": "fraction", "anchorYUnits": "pixels" + }, + "styleSelected": { + "iconUrl": "./static/icon/windmill2-select.png", + "anchor": [0.5, 37], + "anchorXUnits": "fraction", + "anchorYUnits": "pixels" } }, { @@ -62,6 +68,12 @@ "anchor": [0.5, 37], "anchorXUnits": "fraction", "anchorYUnits": "pixels" + }, + "styleSelected": { + "iconUrl": "./static/icon/castle2-select.png", + "anchor": [0.5, 37], + "anchorXUnits": "fraction", + "anchorYUnits": "pixels" } }, { diff --git a/static/app-conf.json b/static/app-conf.json index f1fd0884..fb65e72f 100644 --- a/static/app-conf.json +++ b/static/app-conf.json @@ -70,6 +70,12 @@ "anchor": [0.5, 37], "anchorXUnits": "fraction", "anchorYUnits": "pixels" + }, + "styleSelected": { + "iconUrl": "./static/icon/windmill2-select.png", + "anchor": [0.5, 37], + "anchorXUnits": "fraction", + "anchorYUnits": "pixels" } }, { @@ -87,6 +93,12 @@ "anchor": [0.5, 37], "anchorXUnits": "fraction", "anchorYUnits": "pixels" + }, + "styleSelected": { + "iconUrl": "./static/icon/castle2-select.png", + "anchor": [0.5, 37], + "anchorXUnits": "fraction", + "anchorYUnits": "pixels" } }, { @@ -195,6 +207,12 @@ "titleProp": "naam", "imageProp": "foto_groot", "infoUrlProp": "info_link" + }, + { + "layerId": "Shops", + "title": "Shops Dannstadt", + "titleProp": "name", + "descProp": "shop" } ] } diff --git a/static/icon/castle2-select.png b/static/icon/castle2-select.png new file mode 100644 index 0000000000000000000000000000000000000000..ee926177a43483d6c8d07fdf898690039e88b623 GIT binary patch literal 745 zcmVMgE7|{H9UiZm`34u#47u z5=GHxBn)=qwSl#W1I2rqJX0pyP4gBXjYjW*c-Ayo-c+{xm|9u*`uZAxG)-5dsIxj3 zpPiinaD05cK7cBlPNy$^-{0SVEWmg?24FZG0&sG2(ma51zfY!@?W^0ra`so<+!ekQ zU^bh*+Bh1Gn9XLd)|wEMjTL)mfcbo0y0~h*%3MNM3UGLMSh~1u+&4dp_U>11omui+yREep|h)tYhCx&hM?&3qoX5wy&eFI#e&n*)5^83;c^baU@%~BZx5vu zN-4rHWH1=GZhs$u?Z!^0^J?B6`;ZX$to02+=B(75Ww7)>YBjpS4!8M@ll#Ij^!h{U z20P~RSyS<^T#5m0ycpzHHFDVa?bDU%1P{#+UI-gN9mjt zCVzoj;9-NM2V$1x5>hnSrI`ZITK^>BO$Z|%MbS4IGWk_3&0-*PDNdii;kDM6b)K-q z4|thd)y3%><+57J^IRAp}h zR6uMRPXPAGAMg-&1}K5p5{OHgI}p)3A8{{$0z^kzOQsT*u7C6q_Xe;aOj4Rh)jVQ} bk2t^+y*XSLfA7|I00000NkvXXu0mjfWz1M% literal 0 HcmV?d00001 diff --git a/static/icon/windmill2-select.png b/static/icon/windmill2-select.png new file mode 100644 index 0000000000000000000000000000000000000000..3c413638447abcf6b8175a1659ab47e2c969bd5b GIT binary patch literal 780 zcmV+n1M~ceP)J$K9YUB`L~n zGB@}f2V&p}c#wIjyKD%&WsDhC41N@Zy95T=i>{mCwJUD-&YDg*xcoC zdk`Lk3}3tm3mm!G5<}y?{v+6&9Tf9M-&SZbu`={XPIkXJ_oU+iSsL z4F_yEz_{P%b~IW7FMB;_IFxiCub5Pj&aQAM;XqL(+wjv)#~BWe4osqGxhu6hEB4!M z24To)r^9xuRhyjlN{fb{P5 zkFy*o19cXV7g-KysNkYo(n&yi_bz|v3Uv~Y4i}5pNkir_%&L4nX7+_-=ifetAHE6m zE|H>3sA$baK;rV_yh~`+T23UeNWsh+9Bl69z8B_M>uUMI=B_?2nI5n0QVejoy=VWh zve4IZiCCCP&G-E}&;-6v(3qT$FZdn(bAtV79rNqxXXctTCK2!-c-&y&K+K|DLYfA< zHS++BF@J!SA`~73!FTye>nq)w#X#cHoG#ztjWJh6PFV00-qu!rbGo8E*V%60{$`1= z;9q5znrB-;c6(kFBCNrpPMRWOWQ(xiZGk_^h!vC