commit 19ec350ca9c3a2ec9da6ee3823f3b0a09efe3eaa Author: Jonny Barnes <jonny@jonnybarnes.uk> Date: Tue Nov 22 16:07:42 2016 +0000 Update changelog commit 73428d3d94c659e5e4431b6740ba10dc2a609e44 Author: Jonny Barnes <jonny@jonnybarnes.uk> Date: Tue Nov 22 16:03:37 2016 +0000 output of gulp compress commit 4bb8038e787e35b5d38be9d63600b10bb9d75a07 Author: Jonny Barnes <jonny@jonnybarnes.uk> Date: Tue Nov 22 16:03:11 2016 +0000 import Guzzle’s ClientException namespace commit 4bcb676bb95274da2422023fefa88b8d246b7f97 Author: Jonny Barnes <jonny@jonnybarnes.uk> Date: Tue Nov 22 16:02:24 2016 +0000 Update manual testing token commit d902de76f00b4f3bba94ce6528f87e43f6c113f9 Author: Jonny Barnes <jonny@jonnybarnes.uk> Date: Tue Nov 22 16:01:52 2016 +0000 output of gulp js-assets commit 0a495956e4f540aae0d1515229dd29c30c76fd64 Author: Jonny Barnes <jonny@jonnybarnes.uk> Date: Tue Nov 22 16:01:27 2016 +0000 Update new note page to use Mapbox GL JS commit bf22004256179c9487c668eb77785a9bc90227bc Author: Jonny Barnes <jonny@jonnybarnes.uk> Date: Mon Nov 21 18:47:59 2016 +0000 output of gulp js-assets commit 22ed61cb853d98a4638754d44f042841e2b4495c Author: Jonny Barnes <jonny@jonnybarnes.uk> Date: Mon Nov 21 18:47:06 2016 +0000 Attempting to use mapbox gl on the newnote page commit 47fd891f1b3f0da59d10e937f7ed11f3b603c4af Author: Jonny Barnes <jonny@jonnybarnes.uk> Date: Sat Nov 19 17:21:53 2016 +0000 gulp derived assets commit 19e83f33b1c8c7a90a74d0ad17a6cace8761bcef Author: Jonny Barnes <jonny@jonnybarnes.uk> Date: Sat Nov 19 17:21:16 2016 +0000 Move .map styles into mapbox.scss commit 3d848d59126032671907a1e354cf121441d9a6e3 Author: Jonny Barnes <jonny@jonnybarnes.uk> Date: Sat Nov 19 17:12:51 2016 +0000 gulp derived assets commit 9e51e8690ac8b782bc56663e7ec682837b27d4a1 Author: Jonny Barnes <jonny@jonnybarnes.uk> Date: Sat Nov 19 17:12:32 2016 +0000 Link to mapbox-gl files commit 296b5fd7770f2a1c5c26ed4efedd99a7a0ad0bed Author: Jonny Barnes <jonny@jonnybarnes.uk> Date: Sat Nov 19 17:12:08 2016 +0000 Use mapbox gl to add maps to notes commit bd031df6e969b7af741730acabe41465f68bd3a1 Author: Jonny Barnes <jonny@jonnybarnes.uk> Date: Sat Nov 19 17:11:27 2016 +0000 Update sass to style mapbox gl maps commit a7cd5e6eaa9510b5c9de672b6d5ed6917dabd7c6 Author: Jonny Barnes <jonny@jonnybarnes.uk> Date: Fri Nov 18 16:19:45 2016 +0000 output of gulp compress commit fe63c7ed394d62cd0e47a9ef718d9629d8643e71 Author: Jonny Barnes <jonny@jonnybarnes.uk> Date: Fri Nov 18 16:18:47 2016 +0000 output of gulp sass commit 15ac4012681635753a4b1f52d81f7f9e24830eb4 Author: Jonny Barnes <jonny@jonnybarnes.uk> Date: Fri Nov 18 16:18:05 2016 +0000 Add a dividing line between notes and bio on the homepage commit 5ada66b1a01ae57359145eb757cab65769400f1e Author: Jonny Barnes <jonny@jonnybarnes.uk> Date: Fri Nov 18 16:12:01 2016 +0000 output of gulp sass commit 86adf97c3831c3310683a25c2671c7560700de1a Author: Jonny Barnes <jonny@jonnybarnes.uk> Date: Fri Nov 18 16:11:33 2016 +0000 Resize note metadata for spacial flow commit 3f3fc51ea8df8206d5b13512295ac09827bb2ede Author: Jonny Barnes <jonny@jonnybarnes.uk> Date: Fri Nov 18 15:37:21 2016 +0000 output of gulp sass commit df6f7f827641dc4deca621d099357757f760ece4 Author: Jonny Barnes <jonny@jonnybarnes.uk> Date: Fri Nov 18 15:36:51 2016 +0000 Use system UI fonts commit b71950275ddaf274b26195694a07c1b58f746725 Author: Jonny Barnes <jonny@jonnybarnes.uk> Date: Fri Nov 18 15:31:30 2016 +0000 output of gulp compress commit 5ff5d73a803b9bcc4e2f314946c1d757dcabae67 Author: Jonny Barnes <jonny@jonnybarnes.uk> Date: Fri Nov 18 15:30:12 2016 +0000 output of gulp js-assets commit d8ff563569223bddc836ab9f8fc7c43970273b44 Author: Jonny Barnes <jonny@jonnybarnes.uk> Date: Fri Nov 18 15:29:27 2016 +0000 use containing divs in new place section of form commit 3cbf3083612210cdd7609c930737cf7a698ec024 Author: Jonny Barnes <jonny@jonnybarnes.uk> Date: Fri Nov 18 14:39:27 2016 +0000 gulp sass output commit 239b742a355a397f5b84377b26b2d7a4254bd50e Author: Jonny Barnes <jonny@jonnybarnes.uk> Date: Fri Nov 18 14:38:52 2016 +0000 Better spacing of form elements on mobile commit a20279e3f4216b87ff59ed4e507b6de9e212db9f Author: Jonny Barnes <jonny@jonnybarnes.uk> Date: Fri Nov 18 13:41:31 2016 +0000 Derived assets commit 86ebd05472498814084e86fb0c2d674633f00096 Author: Jonny Barnes <jonny@jonnybarnes.uk> Date: Fri Nov 18 13:40:42 2016 +0000 Use containing divs for flex layout commit 00e0e6f3f462ca575e92209a86ada67b7f5ff757 Author: Jonny Barnes <jonny@jonnybarnes.uk> Date: Thu Nov 17 14:38:39 2016 +0000 Correct scss according to stylelint commit 6dd8ff4d13c3ab83c6a811501b817c45b89338ce Author: Jonny Barnes <jonny@jonnybarnes.uk> Date: Thu Nov 17 14:33:46 2016 +0000 Get stylelint working commit 9b9a64defd9335014b46070e2b92a392929f4aa5 Author: Jonny Barnes <jonny@jonnybarnes.uk> Date: Thu Nov 17 09:48:28 2016 +0000 Add missing new-line to match style commit 2521446f32420047d6d5f7372f4f7afc17200a1c Author: Jonny Barnes <jonny@jonnybarnes.uk> Date: Tue Nov 15 13:16:45 2016 +0000 Add logging during an error, improve the error message commit 095507bec225992aac510a2ca852f65c197f0298 Author: Jonny Barnes <jonny@jonnybarnes.uk> Date: Tue Nov 15 13:15:59 2016 +0000 Update test token commit 374ef70fecaedf041f12a57688ed9596e25a2ce6 Author: Jonny Barnes <jonny@jonnybarnes.uk> Date: Tue Nov 15 13:15:16 2016 +0000 Remove typekit for now commit f5671ad435732ddb3288a2e02de7631a6acb4183 Author: Jonny Barnes <jonny@jonnybarnes.uk> Date: Fri Nov 11 16:06:01 2016 +0000 Better designed new note form commit f38df507b85502e733fa38e970cd584f7d79bca1 Author: Jonny Barnes <jonny@jonnybarnes.uk> Date: Fri Nov 11 13:28:21 2016 +0000 More styling, use normal pagination, improve bio commit 077076d4f92014d488bca5d4dbbab5af913e6cf0 Author: Jonny Barnes <jonny@jonnybarnes.uk> Date: Fri Nov 11 00:05:56 2016 +0000 Use an anchor for permalinks, re-word projects page commit 37c6e862b693c2bfd3a39654a533627e0f73fd1a Author: Jonny Barnes <jonny@jonnybarnes.uk> Date: Thu Nov 10 23:58:54 2016 +0000 The resulting CSS files commit 1a3b6d7064b1b67238ffd3909d6d1ae54a4f78e1 Author: Jonny Barnes <jonny@jonnybarnes.uk> Date: Thu Nov 10 23:31:53 2016 +0000 Sass for very basic redesign commit e5d9e9d41b50d7f316fcae9bae75863aa09a7d63 Author: Jonny Barnes <jonny@jonnybarnes.uk> Date: Thu Nov 10 23:00:35 2016 +0000 Use app.(s)css commit 231c5292e68220f588e9d300975bb19dfea20b4f Author: Jonny Barnes <jonny@jonnybarnes.uk> Date: Thu Nov 10 22:59:50 2016 +0000 Restructure homepage to show notes, also show bio when on '/', but note '/notes' commit 11a272b2a3050297dd84105a6c70adc937a0c409 Author: Jonny Barnes <jonny@jonnybarnes.uk> Date: Thu Nov 10 17:49:30 2016 +0000 Set my homepage to the stream of notes commit 2e46ccad4038be64b5007f15dabee0321061fe98 Author: Jonny Barnes <jonny@jonnybarnes.uk> Date: Tue Nov 8 23:58:11 2016 +0000 Drop sanitize.css and use normalize.css instead, also fix compress method commit 8082403d7464a873691fabab07ae4f6116993cdf Author: Jonny Barnes <jonny@jonnybarnes.uk> Date: Tue Nov 8 23:48:35 2016 +0000 Sort out yarn dependencies commit 8ef7137d160ae8577e42ab1fd19e957aa37cf08b Author: Jonny Barnes <jonny@jonnybarnes.uk> Date: Tue Nov 8 23:39:49 2016 +0000 Remove the compiled css commit 8284cdf838f5222eff87c942f119d6000a1b6fc6 Author: Jonny Barnes <jonny@jonnybarnes.uk> Date: Tue Nov 8 23:16:27 2016 +0000 Remove sass files
313 lines
14 KiB
JavaScript
313 lines
14 KiB
JavaScript
/* global mapboxgl, alertify */
|
||
if ('geolocation' in navigator) {
|
||
var button = document.querySelector('#locate');
|
||
if (button.addEventListener) {
|
||
//if we have javascript, event listeners and geolocation, make the locate
|
||
//button clickable and add event
|
||
button.disabled = false;
|
||
button.addEventListener('click', getLocation);
|
||
}
|
||
}
|
||
|
||
function getLocation() {
|
||
navigator.geolocation.getCurrentPosition(function (position) {
|
||
//the locate button has been clicked so add the places/map
|
||
addPlacesMap(position.coords.latitude, position.coords.longitude, position.coords.accuracy);
|
||
});
|
||
}
|
||
|
||
function addPlacesMap(latitude, longitude, uncertainty) {
|
||
//get the nearby places
|
||
fetch('/places/near/' + latitude + '/' + longitude + '?u=' + uncertainty, {
|
||
credentials: 'same-origin',
|
||
method: 'get'
|
||
}).then(function (response) {
|
||
return response.json();
|
||
}).then(function (j) {
|
||
if (j.error == true) {
|
||
alertify.reset();
|
||
alertify.error(j.error_description);
|
||
}
|
||
if (j.places.length > 0) {
|
||
var i;
|
||
var places = [];
|
||
for (i = 0; i < j.places.length; ++i) {
|
||
var latlng = parseLocation(j.places[i].location);
|
||
var name = j.places[i].name;
|
||
var uri = j.places[i].uri;
|
||
places.push([name, uri, latlng[0], latlng[1]]);
|
||
}
|
||
//add a map with the nearby places
|
||
addMap(latitude, longitude, places);
|
||
} else {
|
||
//add a map with just current location
|
||
addMap(latitude, longitude);
|
||
}
|
||
}).catch(function (err) {
|
||
console.error(err);
|
||
});
|
||
}
|
||
|
||
function addMap(latitude, longitude, places) {
|
||
//make places null if not supplied
|
||
if (arguments.length == 2) {
|
||
places = null;
|
||
}
|
||
// the form has a fieldset element that we are actually targetting
|
||
var form = document.querySelector('.note-ui');
|
||
var mapDiv = document.createElement('div');
|
||
mapDiv.classList.add('map');
|
||
//add the map div
|
||
form.appendChild(mapDiv);
|
||
//set up the mapbox gl map
|
||
mapboxgl.accessToken = 'pk.eyJ1Ijoiam9ubnliYXJuZXMiLCJhIjoiY2l2cDhjYW04MDAwcjJ0cG1uZnhqcm82ayJ9.qA2zeVA-nsoMh9IFrd5KQw';
|
||
var map = new mapboxgl.Map({
|
||
container: mapDiv,
|
||
style: 'mapbox://styles/mapbox/streets-v9',
|
||
center: [longitude, latitude],
|
||
zoom: 15
|
||
});
|
||
//create the current location marker
|
||
var el = document.createElement('div');
|
||
el.classList.add('marker');
|
||
//create the map style menu
|
||
var mapMenu = document.createElement('div');
|
||
mapMenu.classList.add('map-menu');
|
||
var streetsInput = document.createElement('input');
|
||
streetsInput.setAttribute('id', 'streets');
|
||
streetsInput.setAttribute('type', 'radio');
|
||
streetsInput.setAttribute('name', 'toggle');
|
||
streetsInput.setAttribute('value', 'streets');
|
||
streetsInput.setAttribute('checked', 'checked');
|
||
streetsInput.addEventListener('click', function () {
|
||
map.setStyle('mapbox://styles/mapbox/streets-v9');
|
||
});
|
||
var streetsLabel = document.createElement('label');
|
||
streetsLabel.setAttribute('for', 'streets');
|
||
streetsLabel.appendChild(document.createTextNode('Streets'));
|
||
var satelliteInput = document.createElement('input');
|
||
satelliteInput.setAttribute('id', 'satellite');
|
||
satelliteInput.setAttribute('type', 'radio');
|
||
satelliteInput.setAttribute('name', 'toggle');
|
||
satelliteInput.setAttribute('value', 'streets');
|
||
satelliteInput.addEventListener('click', function () {
|
||
map.setStyle('mapbox://styles/mapbox/satellite-v9');
|
||
});
|
||
var satelliteLabel = document.createElement('label');
|
||
satelliteLabel.setAttribute('for', 'satellite');
|
||
satelliteLabel.appendChild(document.createTextNode('Satellite'));
|
||
mapMenu.appendChild(streetsInput);
|
||
mapMenu.appendChild(streetsLabel);
|
||
mapMenu.appendChild(satelliteInput);
|
||
mapMenu.appendChild(satelliteLabel);
|
||
//add the map menu
|
||
mapDiv.appendChild(mapMenu);
|
||
//add a marker for the current location
|
||
new mapboxgl.Marker(el, {offset: [-10, -20]}).setLngLat([longitude, latitude]).addTo(map);
|
||
//create containing div for flexbox
|
||
var containingDiv = document.createElement('div');
|
||
//create the <select> element and give it a no location default
|
||
var selectEl = document.createElement('select');
|
||
selectEl.setAttribute('name', 'location');
|
||
var noLocation = document.createElement('option');
|
||
noLocation.setAttribute('value', 'no-location');
|
||
noLocation.appendChild(document.createTextNode('Don’t send location'));
|
||
selectEl.appendChild(noLocation);
|
||
var geoLocation = document.createElement('option');
|
||
geoLocation.setAttribute('selected', 'selected');
|
||
geoLocation.setAttribute('id', 'option-coords');
|
||
geoLocation.setAttribute('value', 'geo:' + latitude + ',' + longitude);
|
||
geoLocation.dataset.latitude = latitude;
|
||
geoLocation.dataset.longitude = longitude;
|
||
geoLocation.appendChild(document.createTextNode('Send co-ordinates'));
|
||
selectEl.appendChild(geoLocation);
|
||
containingDiv.appendChild(selectEl);
|
||
form.insertBefore(containingDiv, mapDiv);
|
||
if (places !== null) {
|
||
//add the places both to the map and <select>
|
||
places.forEach(function (item) {
|
||
var option = document.createElement('option');
|
||
option.setAttribute('value', item[1]);
|
||
var text = document.createTextNode(item[0]);
|
||
option.appendChild(text);
|
||
option.dataset.latitude = item[2];
|
||
option.dataset.longitude = item[3];
|
||
selectEl.appendChild(option);
|
||
var placeMarkerIcon = document.createElement('div');
|
||
placeMarkerIcon.classList.add('marker');
|
||
new mapboxgl.Marker(placeMarkerIcon, {offset: [-10, -20]}).setLngLat([item[3], item[2]]).addTo(map);
|
||
placeMarkerIcon.addEventListener('click', function () {
|
||
map.flyTo({
|
||
center: [
|
||
item[3],
|
||
item[2]
|
||
]
|
||
});
|
||
selectPlace(item[1]);
|
||
});
|
||
});
|
||
//add an event listener
|
||
selectEl.addEventListener('change', function () {
|
||
if (selectEl.value !== 'no-location') {
|
||
var placeLat = selectEl[selectEl.selectedIndex].dataset.latitude;
|
||
var placeLon = selectEl[selectEl.selectedIndex].dataset.longitude;
|
||
map.flyTo({
|
||
center: [
|
||
placeLon,
|
||
placeLat
|
||
]
|
||
});
|
||
}
|
||
});
|
||
}
|
||
//add a button to add a new place
|
||
var newLocButton = document.createElement('button');
|
||
newLocButton.setAttribute('type', 'button');
|
||
newLocButton.setAttribute('id', 'create-new-place');
|
||
newLocButton.appendChild(document.createTextNode('Create New Place?'));
|
||
//the event listener
|
||
newLocButton.addEventListener('click', function() {
|
||
//add the form elements
|
||
var nameDiv = document.createElement('div');
|
||
var nameLabel = document.createElement('label');
|
||
nameLabel.setAttribute('for', 'place-name');
|
||
nameLabel.classList.add('place-label');
|
||
nameLabel.appendChild(document.createTextNode('Place Name:'));
|
||
var nameEl = document.createElement('input');
|
||
nameEl.setAttribute('placeholder', 'Name');
|
||
nameEl.setAttribute('name', 'place-name');
|
||
nameEl.setAttribute('id', 'place-name');
|
||
nameEl.setAttribute('type', 'text');
|
||
nameDiv.appendChild(nameLabel);
|
||
nameDiv.appendChild(nameEl);
|
||
var descDiv = document.createElement('div');
|
||
var descLabel = document.createElement('label');
|
||
descLabel.setAttribute('for', 'place-description');
|
||
descLabel.classList.add('place-label');
|
||
descLabel.appendChild(document.createTextNode('Place Description:'));
|
||
var descEl = document.createElement('input');
|
||
descEl.setAttribute('placeholder', 'Description');
|
||
descEl.setAttribute('name', 'place-description');
|
||
descEl.setAttribute('id', 'place-description');
|
||
descEl.setAttribute('type', 'text');
|
||
descDiv.appendChild(descLabel);
|
||
descDiv.appendChild(descEl);
|
||
var latDiv = document.createElement('div');
|
||
var latLabel = document.createElement('label');
|
||
latLabel.setAttribute('for', 'place-latitude');
|
||
latLabel.classList.add('place-label');
|
||
latLabel.appendChild(document.createTextNode('Place Latitude:'));
|
||
var latEl = document.createElement('input');
|
||
latEl.setAttribute('name', 'place-latitude');
|
||
latEl.setAttribute('id', 'place-latitude');
|
||
latEl.setAttribute('type', 'text');
|
||
latEl.value = getLatitudeFromMapbox(map.getCenter());
|
||
latDiv.appendChild(latLabel);
|
||
latDiv.appendChild(latEl);
|
||
var lonDiv = document.createElement('div');
|
||
var lonLabel = document.createElement('label');
|
||
lonLabel.setAttribute('for', 'place-longitude');
|
||
lonLabel.classList.add('place-label');
|
||
lonLabel.appendChild(document.createTextNode('Place Longitude:'));
|
||
var lonEl = document.createElement('input');
|
||
lonEl.setAttribute('name', 'place-longitude');
|
||
lonEl.setAttribute('id', 'place-longitude');
|
||
lonEl.setAttribute('type', 'text');
|
||
lonEl.value = getLongitudeFromMapbox(map.getCenter());
|
||
lonDiv.appendChild(lonLabel);
|
||
lonDiv.appendChild(lonEl);
|
||
var placeSubmit = document.createElement('button');
|
||
placeSubmit.setAttribute('id', 'place-submit');
|
||
placeSubmit.setAttribute('value', 'Submit New Place');
|
||
placeSubmit.setAttribute('name', 'place-submit');
|
||
placeSubmit.setAttribute('type', 'button');
|
||
placeSubmit.appendChild(document.createTextNode('Submit New Place'));
|
||
form.appendChild(nameDiv);
|
||
form.appendChild(descDiv);
|
||
form.appendChild(latDiv);
|
||
form.appendChild(lonDiv);
|
||
form.appendChild(placeSubmit);
|
||
//the event listener for the new place form
|
||
placeSubmit.addEventListener('click', function () {
|
||
//create the form data to send
|
||
var formData = new FormData();
|
||
formData.append('place-name', document.querySelector('#place-name').value);
|
||
formData.append('place-description', document.querySelector('#place-description').value);
|
||
formData.append('place-latitude', document.querySelector('#place-latitude').value);
|
||
formData.append('place-longitude', document.querySelector('#place-longitude').value);
|
||
//post the new place
|
||
fetch('/places/new', {
|
||
//send cookies with the request
|
||
credentials: 'same-origin',
|
||
method: 'post',
|
||
body: formData
|
||
})
|
||
.then(function (response) {
|
||
return response.json();
|
||
})
|
||
.then(function (placeJson) {
|
||
if (placeJson.error == true) {
|
||
throw new Error(placeJson.error_description);
|
||
}
|
||
//remove un-needed form elements
|
||
//iterate through labels and remove parent div elements
|
||
var labels = document.querySelectorAll('.place-label');
|
||
for (var i = 0; i < labels.length; ++i) {
|
||
form.removeChild(labels[i].parentNode);
|
||
}
|
||
form.removeChild(document.querySelector('#place-submit'));
|
||
var newPlaceButton = document.querySelector('#create-new-place');
|
||
//in order to remove a DOM Node, you need to run removeChild on the parent Node
|
||
newPlaceButton.parentNode.removeChild(newPlaceButton);
|
||
//add place marker
|
||
var newOption = document.createElement('option');
|
||
newOption.setAttribute('value', placeJson.uri);
|
||
newOption.appendChild(document.createTextNode(placeJson.name));
|
||
newOption.dataset.latitude = placeJson.latitude;
|
||
newOption.dataset.longitude = placeJson.longitude;
|
||
selectEl.appendChild(newOption);
|
||
var newPlaceMarkerIcon = document.createElement('div');
|
||
newPlaceMarkerIcon.classList.add('marker');
|
||
var newPlaceMarker = new mapboxgl.Marker(newPlaceMarkerIcon, {offset: [-10, -20]}).setLngLat([placeJson.longitude, placeJson.latitude]).addTo(map);
|
||
map.flyTo({center: [placeJson.longitude, placeJson.latitude]});
|
||
|
||
newPlaceMarkerIcon.addEventListener('click', function () {
|
||
map.flyTo({center: [placeJson.longitude, placeJson.latitude]});
|
||
selectPlace(placeJson.uri);
|
||
});
|
||
//make selected
|
||
selectPlace(placeJson.uri);
|
||
}).catch(function (placeError) {
|
||
alertify.reset();
|
||
alertify.error(placeError);
|
||
});
|
||
});
|
||
});
|
||
containingDiv.appendChild(newLocButton);
|
||
}
|
||
|
||
function parseLocation(point) {
|
||
var re = /\((.*)\)/;
|
||
var resultArray = re.exec(point);
|
||
var location = resultArray[1].split(' ');
|
||
|
||
return [location[1], location[0]];
|
||
}
|
||
|
||
function selectPlace(uri) {
|
||
document.querySelector('select [value="' + uri + '"]').selected = true;
|
||
}
|
||
|
||
function getLatitudeFromMapbox(lnglat) {
|
||
var resultArray = /\((.*)\)/.exec(lnglat);
|
||
var location = resultArray[1].split(' ');
|
||
|
||
return location[1];
|
||
}
|
||
|
||
function getLongitudeFromMapbox(lnglat) {
|
||
var resultArray = /\((.*)\)/.exec(lnglat);
|
||
var location = resultArray[1].split(' ');
|
||
|
||
return location[0].replace(',', '');
|
||
}
|