Часть функционала перенесена из карты в приложение - JS
This commit is contained in:
parent
f4472d1762
commit
46f6497228
271
public/js/app.js
271
public/js/app.js
|
|
@ -170,3 +170,274 @@ window.addEventListener('popstate', function(e)
|
||||||
function getTime() {
|
function getTime() {
|
||||||
return Math.floor(Date.now() / 1000);
|
return Math.floor(Date.now() / 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function showRandomPoint()
|
||||||
|
{
|
||||||
|
roundIndex = Math.floor(Math.random() * points.length);
|
||||||
|
runner = 0;
|
||||||
|
for (var key in points)
|
||||||
|
{
|
||||||
|
if (runner++ >= roundIndex)
|
||||||
|
return showInfo(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Загружает с сервера список категорий точек.
|
||||||
|
* @returns {Boolean}
|
||||||
|
*/
|
||||||
|
function initCategories()
|
||||||
|
{
|
||||||
|
$.ajax({
|
||||||
|
url: "/json/categories/",
|
||||||
|
success: function (data) {
|
||||||
|
for (var k in data) {
|
||||||
|
categories[data[k]['id']] = L.icon({
|
||||||
|
iconUrl: data[k]['icon'],
|
||||||
|
iconSize: [32, 37],
|
||||||
|
iconAnchor: [16, 37],
|
||||||
|
popupAnchor: [0, 1]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
initPoints();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Производит поиск по адресу или координатам, введённым в соответствующее поле.
|
||||||
|
* @returns {undefined}
|
||||||
|
*/
|
||||||
|
function searchAdderess()
|
||||||
|
{
|
||||||
|
$.ajax({
|
||||||
|
url: "/json/geocoding",
|
||||||
|
data: {
|
||||||
|
search: $('#addressField').val()
|
||||||
|
},
|
||||||
|
success: function (data)
|
||||||
|
{
|
||||||
|
if (data.lat && data.lng)
|
||||||
|
{
|
||||||
|
myMap.setView([data.lat, data.lng], defaultZoom);
|
||||||
|
L.popup()
|
||||||
|
.setLatLng([data.lat, data.lng])
|
||||||
|
.setContent('Координаты: lat:' + data.lat + ' lng:' + data.lng)
|
||||||
|
.openOn(myMap);
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
alert('Ничего не найдено.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Активирет добавление точки - ждёт выбор координат, меняет курсор на прицел.
|
||||||
|
* @returns {Boolean}
|
||||||
|
*/
|
||||||
|
function activateAddPoint()
|
||||||
|
{
|
||||||
|
$('#addPointButton').toggleClass('active');
|
||||||
|
if ($('#addPointButton').hasClass('active'))
|
||||||
|
{
|
||||||
|
$('.extraImage', '#imgsContainer').remove();
|
||||||
|
addNewImage();
|
||||||
|
$('#map').css('cursor', 'crosshair');
|
||||||
|
setStatus(statusHunting)
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$('#map').css('cursor', 'arrow');
|
||||||
|
setStatus(statusReady)
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Отправляет данные о точке на сервер.
|
||||||
|
* @returns {Boolean}
|
||||||
|
*/
|
||||||
|
function addPoint()
|
||||||
|
{
|
||||||
|
$('.form-group').removeClass('has-error');
|
||||||
|
if (status != statusSendingToServer)
|
||||||
|
{
|
||||||
|
setStatus(statusSendingToServer)
|
||||||
|
id = $('#addPointId').length ? $('#addPointId').val() : 0;
|
||||||
|
hasImages = false;
|
||||||
|
$("input[name='imgs[]']", '#addPointForm').each(function () {
|
||||||
|
if ($(this).val().length > 10)
|
||||||
|
hasImages = true;
|
||||||
|
});
|
||||||
|
$("input[name='photos[]']", '#addPointForm').each(function () {
|
||||||
|
if ($(this).val().length > 5)
|
||||||
|
hasImages = true;
|
||||||
|
})
|
||||||
|
$.ajax({
|
||||||
|
type: "POST",
|
||||||
|
url: "/json/addpoint/",
|
||||||
|
data: {
|
||||||
|
name: $('#addPointName').val(),
|
||||||
|
img: hasImages ? 1 : 0,
|
||||||
|
description: $('#addPointDescription').val(),
|
||||||
|
categoryId: $('#addPointCategoryId').val(),
|
||||||
|
source: $('#addPointSource').val(),
|
||||||
|
lat: $('#addPointLat').val(),
|
||||||
|
lng: $('#addPointLng').val(),
|
||||||
|
id: id
|
||||||
|
},
|
||||||
|
success: function (data) {
|
||||||
|
if ($("input[name='photos[]']").length > 0 || $("input[name='imgs[]']").length > 0)
|
||||||
|
{
|
||||||
|
$('<input type="hidden" id="addPointId" name="id"/>').appendTo('#addPointForm').val(data);
|
||||||
|
$('#addPointForm').submit();
|
||||||
|
}
|
||||||
|
|
||||||
|
text = id ? 'Точка успешно отредактирована!' : 'Точка успешно добавлена!';
|
||||||
|
if (id)
|
||||||
|
{
|
||||||
|
markers.removeLayer(points[id]);
|
||||||
|
}
|
||||||
|
|
||||||
|
text = '<center><img src="/img/loading.gif" style="height: 89px; width: 89px;" /><br/><br/><b style="font-size: 1.2em;">Подождите пожалуйста!</b><br/>Изображения загружаются на сайт...</center>'
|
||||||
|
balloon = L.popup()
|
||||||
|
.setLatLng([$('#addPointLat').val(), $('#addPointLng').val()])
|
||||||
|
.setContent(text)
|
||||||
|
.openOn(myMap);
|
||||||
|
// setTimeout(function () {
|
||||||
|
// balloon._close();
|
||||||
|
// delete balloon;
|
||||||
|
// }, 2000);
|
||||||
|
|
||||||
|
obj = {};
|
||||||
|
obj.id = data;
|
||||||
|
obj.name = $('#addPointName').val();
|
||||||
|
obj.lat = $('#addPointLat').val();
|
||||||
|
obj.lng = $('#addPointLng').val();
|
||||||
|
obj.categoryIcon = categories[$('#addPointCategoryId').val()].icon;
|
||||||
|
obj.categoryId = $('#addPointCategoryId').val();
|
||||||
|
|
||||||
|
setTimeout(function () {
|
||||||
|
markers.addLayer(constructPoint(obj));
|
||||||
|
}, 2000);
|
||||||
|
|
||||||
|
$('#addPointModal').modal('hide');
|
||||||
|
|
||||||
|
// Clear form
|
||||||
|
$('#addPointForm input').val('');
|
||||||
|
$('#addPointForm textarea').val('');
|
||||||
|
$('.form-group').removeClass('has-error');
|
||||||
|
$('#addPointButton').removeClass('active');
|
||||||
|
$('#addPointId').remove();
|
||||||
|
$('#map').css('cursor', 'arrow');
|
||||||
|
setStatus(statusReady);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
error: function (data) {
|
||||||
|
response = data.responseJSON;
|
||||||
|
message = '';
|
||||||
|
for (var k in response) {
|
||||||
|
if (typeof response[k] !== 'function') {
|
||||||
|
if (k == 1)
|
||||||
|
$('#addPointName').parent().addClass('has-error');
|
||||||
|
else
|
||||||
|
if (k == 2)
|
||||||
|
{
|
||||||
|
$('.extraImage', '#addPointForm').addClass('has-error');
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if (k == 3)
|
||||||
|
$('#addPointDescription').parent().addClass('has-error');
|
||||||
|
else
|
||||||
|
message += response[k] + '; ';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (message != '')
|
||||||
|
alert(message);
|
||||||
|
|
||||||
|
resetStatus();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
alert('Точка добавляется, нужно немного подождать.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Включает режим редактирования точки.
|
||||||
|
* @param int id
|
||||||
|
* @returns {undefined}
|
||||||
|
*/
|
||||||
|
function editPoint(id)
|
||||||
|
{
|
||||||
|
$('#addPointId').remove();
|
||||||
|
$('<input type="hidden" id="addPointId" name="id"/>').appendTo('#addPointForm').val(id);
|
||||||
|
$('#addPointName').val(pointsSources[id].name);
|
||||||
|
$('#addPointDescription').val(pointsSources[id].description);
|
||||||
|
$("#addPointCategoryId option").attr('selected', null);
|
||||||
|
$("#addPointCategoryId option[value='" + pointsSources[id].categoryId + "']").attr('selected', 'selected');
|
||||||
|
$('#addPointSource').val(pointsSources[id].source);
|
||||||
|
$('#addPointLat').val(pointsSources[id].lat);
|
||||||
|
$('#addPointLng').val(pointsSources[id].lng);
|
||||||
|
|
||||||
|
$('.extraImage', '#imgsContainer').remove();
|
||||||
|
if (pointsSources[id].images != undefined && pointsSources[id].images.length > 0)
|
||||||
|
{
|
||||||
|
for (var i = 0; i < pointsSources[id].images.length; i++)
|
||||||
|
{
|
||||||
|
addNewImage(pointsSources[id].images[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
addNewImage(pointsSources[id].img);
|
||||||
|
}
|
||||||
|
|
||||||
|
closePopup();
|
||||||
|
$('#addPointModal').modal('show');
|
||||||
|
setStatus(statusEdit);
|
||||||
|
}
|
||||||
|
|
||||||
|
function editSetNewCoords()
|
||||||
|
{
|
||||||
|
$('#addPointModal').modal('hide');
|
||||||
|
$('#map').css('cursor', 'crosshair');
|
||||||
|
setStatus(statusReHunting)
|
||||||
|
}
|
||||||
|
|
||||||
|
function closePopup()
|
||||||
|
{
|
||||||
|
if (myMap._popup)
|
||||||
|
myMap._popup._close();
|
||||||
|
}
|
||||||
|
|
||||||
|
function filter()
|
||||||
|
{
|
||||||
|
var selected = new Array();
|
||||||
|
$('.filterSelector:checked').each(function (i, e) {
|
||||||
|
selected.push($(e).val());
|
||||||
|
});
|
||||||
|
|
||||||
|
for (var key in points)
|
||||||
|
{
|
||||||
|
if (selected.length == 0 || points[key].options.categoryId == undefined || selected.indexOf(points[key].options.categoryId) != -1)
|
||||||
|
{
|
||||||
|
markers.addLayer(points[key]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
markers.removeLayer(points[key]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
||||||
273
public/js/map.js
273
public/js/map.js
|
|
@ -113,9 +113,9 @@ function init(lat, lng) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Создаёт точку для карту - Placemark.
|
* Создаёт точку для карты - Placemark.
|
||||||
* @param {Array} data
|
* @param {Array} data
|
||||||
* @returns {ymaps.Placemark}
|
* @returns {Array}
|
||||||
*/
|
*/
|
||||||
function constructPoint(data)
|
function constructPoint(data)
|
||||||
{
|
{
|
||||||
|
|
@ -240,250 +240,6 @@ function showInfo(id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function showRandomPoint()
|
|
||||||
{
|
|
||||||
roundIndex = Math.floor(Math.random() * points.length);
|
|
||||||
runner = 0;
|
|
||||||
for (var key in points)
|
|
||||||
{
|
|
||||||
if (runner++ >= roundIndex)
|
|
||||||
return showInfo(key);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Загружает с сервера список категорий точек.
|
|
||||||
* @returns {Boolean}
|
|
||||||
*/
|
|
||||||
function initCategories()
|
|
||||||
{
|
|
||||||
$.ajax({
|
|
||||||
url: "/json/categories/",
|
|
||||||
success: function (data) {
|
|
||||||
for (var k in data) {
|
|
||||||
categories[data[k]['id']] = L.icon({
|
|
||||||
iconUrl: data[k]['icon'],
|
|
||||||
iconSize: [32, 37],
|
|
||||||
iconAnchor: [16, 37],
|
|
||||||
popupAnchor: [0, 1]
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
initPoints();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Производит поиск по адресу или координатам, введённым в соответствующее поле.
|
|
||||||
* @returns {undefined}
|
|
||||||
*/
|
|
||||||
function searchAdderess()
|
|
||||||
{
|
|
||||||
$.ajax({
|
|
||||||
url: "/json/geocoding",
|
|
||||||
data: {
|
|
||||||
search: $('#addressField').val()
|
|
||||||
},
|
|
||||||
success: function (data)
|
|
||||||
{
|
|
||||||
if (data.lat && data.lng)
|
|
||||||
{
|
|
||||||
myMap.setView([data.lat, data.lng], defaultZoom);
|
|
||||||
L.popup()
|
|
||||||
.setLatLng([data.lat, data.lng])
|
|
||||||
.setContent('Координаты: lat:' + data.lat + ' lng:' + data.lng)
|
|
||||||
.openOn(myMap);
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
alert('Ничего не найдено.');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Активирет добавление точки - ждёт выбор координат, меняет курсор на прицел.
|
|
||||||
* @returns {Boolean}
|
|
||||||
*/
|
|
||||||
function activateAddPoint()
|
|
||||||
{
|
|
||||||
$('#addPointButton').toggleClass('active');
|
|
||||||
if ($('#addPointButton').hasClass('active'))
|
|
||||||
{
|
|
||||||
$('.extraImage', '#imgsContainer').remove();
|
|
||||||
addNewImage();
|
|
||||||
$('#map').css('cursor', 'crosshair');
|
|
||||||
setStatus(statusHunting)
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$('#map').css('cursor', 'arrow');
|
|
||||||
setStatus(statusReady)
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Отправляет данные о точке на сервер.
|
|
||||||
* @returns {Boolean}
|
|
||||||
*/
|
|
||||||
function addPoint()
|
|
||||||
{
|
|
||||||
$('.form-group').removeClass('has-error');
|
|
||||||
if (status != statusSendingToServer)
|
|
||||||
{
|
|
||||||
setStatus(statusSendingToServer)
|
|
||||||
id = $('#addPointId').length ? $('#addPointId').val() : 0;
|
|
||||||
hasImages = false;
|
|
||||||
$("input[name='imgs[]']", '#addPointForm').each(function () {
|
|
||||||
if ($(this).val().length > 10)
|
|
||||||
hasImages = true;
|
|
||||||
});
|
|
||||||
$("input[name='photos[]']", '#addPointForm').each(function () {
|
|
||||||
if ($(this).val().length > 5)
|
|
||||||
hasImages = true;
|
|
||||||
})
|
|
||||||
$.ajax({
|
|
||||||
type: "POST",
|
|
||||||
url: "/json/addpoint/",
|
|
||||||
data: {
|
|
||||||
name: $('#addPointName').val(),
|
|
||||||
img: hasImages ? 1 : 0,
|
|
||||||
description: $('#addPointDescription').val(),
|
|
||||||
categoryId: $('#addPointCategoryId').val(),
|
|
||||||
source: $('#addPointSource').val(),
|
|
||||||
lat: $('#addPointLat').val(),
|
|
||||||
lng: $('#addPointLng').val(),
|
|
||||||
id: id
|
|
||||||
},
|
|
||||||
success: function (data) {
|
|
||||||
if ($("input[name='photos[]']").length > 0 || $("input[name='imgs[]']").length > 0)
|
|
||||||
{
|
|
||||||
$('<input type="hidden" id="addPointId" name="id"/>').appendTo('#addPointForm').val(data);
|
|
||||||
$('#addPointForm').submit();
|
|
||||||
}
|
|
||||||
|
|
||||||
text = id ? 'Точка успешно отредактирована!' : 'Точка успешно добавлена!';
|
|
||||||
if (id)
|
|
||||||
{
|
|
||||||
markers.removeLayer(points[id]);
|
|
||||||
}
|
|
||||||
|
|
||||||
text = '<center><img src="/img/loading.gif" style="height: 89px; width: 89px;" /><br/><br/><b style="font-size: 1.2em;">Подождите пожалуйста!</b><br/>Изображения загружаются на сайт...</center>'
|
|
||||||
balloon = L.popup()
|
|
||||||
.setLatLng([$('#addPointLat').val(), $('#addPointLng').val()])
|
|
||||||
.setContent(text)
|
|
||||||
.openOn(myMap);
|
|
||||||
// setTimeout(function () {
|
|
||||||
// balloon._close();
|
|
||||||
// delete balloon;
|
|
||||||
// }, 2000);
|
|
||||||
|
|
||||||
obj = {};
|
|
||||||
obj.id = data;
|
|
||||||
obj.name = $('#addPointName').val();
|
|
||||||
obj.lat = $('#addPointLat').val();
|
|
||||||
obj.lng = $('#addPointLng').val();
|
|
||||||
obj.categoryIcon = categories[$('#addPointCategoryId').val()].icon;
|
|
||||||
obj.categoryId = $('#addPointCategoryId').val();
|
|
||||||
|
|
||||||
setTimeout(function () {
|
|
||||||
markers.addLayer(constructPoint(obj));
|
|
||||||
}, 2000);
|
|
||||||
|
|
||||||
$('#addPointModal').modal('hide');
|
|
||||||
|
|
||||||
// Clear form
|
|
||||||
$('#addPointForm input').val('');
|
|
||||||
$('#addPointForm textarea').val('');
|
|
||||||
$('.form-group').removeClass('has-error');
|
|
||||||
$('#addPointButton').removeClass('active');
|
|
||||||
$('#addPointId').remove();
|
|
||||||
$('#map').css('cursor', 'arrow');
|
|
||||||
setStatus(statusReady);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
},
|
|
||||||
error: function (data) {
|
|
||||||
response = data.responseJSON;
|
|
||||||
message = '';
|
|
||||||
for (var k in response) {
|
|
||||||
if (typeof response[k] !== 'function') {
|
|
||||||
if (k == 1)
|
|
||||||
$('#addPointName').parent().addClass('has-error');
|
|
||||||
else
|
|
||||||
if (k == 2)
|
|
||||||
{
|
|
||||||
$('.extraImage', '#addPointForm').addClass('has-error');
|
|
||||||
}
|
|
||||||
else
|
|
||||||
if (k == 3)
|
|
||||||
$('#addPointDescription').parent().addClass('has-error');
|
|
||||||
else
|
|
||||||
message += response[k] + '; ';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (message != '')
|
|
||||||
alert(message);
|
|
||||||
|
|
||||||
resetStatus();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
alert('Точка добавляется, нужно немного подождать.');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Включает режим редактирования точки.
|
|
||||||
* @param int id
|
|
||||||
* @returns {undefined}
|
|
||||||
*/
|
|
||||||
function editPoint(id)
|
|
||||||
{
|
|
||||||
$('#addPointId').remove();
|
|
||||||
$('<input type="hidden" id="addPointId" name="id"/>').appendTo('#addPointForm').val(id);
|
|
||||||
$('#addPointName').val(pointsSources[id].name);
|
|
||||||
$('#addPointDescription').val(pointsSources[id].description);
|
|
||||||
$("#addPointCategoryId option").attr('selected', null);
|
|
||||||
$("#addPointCategoryId option[value='" + pointsSources[id].categoryId + "']").attr('selected', 'selected');
|
|
||||||
$('#addPointSource').val(pointsSources[id].source);
|
|
||||||
$('#addPointLat').val(pointsSources[id].lat);
|
|
||||||
$('#addPointLng').val(pointsSources[id].lng);
|
|
||||||
|
|
||||||
$('.extraImage', '#imgsContainer').remove();
|
|
||||||
if (pointsSources[id].images != undefined && pointsSources[id].images.length > 0)
|
|
||||||
{
|
|
||||||
for (var i = 0; i < pointsSources[id].images.length; i++)
|
|
||||||
{
|
|
||||||
addNewImage(pointsSources[id].images[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
addNewImage(pointsSources[id].img);
|
|
||||||
}
|
|
||||||
|
|
||||||
closePopup();
|
|
||||||
$('#addPointModal').modal('show');
|
|
||||||
setStatus(statusEdit);
|
|
||||||
}
|
|
||||||
|
|
||||||
function editSetNewCoords()
|
|
||||||
{
|
|
||||||
$('#addPointModal').modal('hide');
|
|
||||||
$('#map').css('cursor', 'crosshair');
|
|
||||||
setStatus(statusReHunting)
|
|
||||||
}
|
|
||||||
|
|
||||||
function setLayer(name)
|
function setLayer(name)
|
||||||
{
|
{
|
||||||
if (layer)
|
if (layer)
|
||||||
|
|
@ -496,28 +252,3 @@ function setLayer(name)
|
||||||
$.cookie('mapLayer', layer);
|
$.cookie('mapLayer', layer);
|
||||||
}
|
}
|
||||||
|
|
||||||
function closePopup()
|
|
||||||
{
|
|
||||||
if (myMap._popup)
|
|
||||||
myMap._popup._close();
|
|
||||||
}
|
|
||||||
|
|
||||||
function filter()
|
|
||||||
{
|
|
||||||
var selected = new Array();
|
|
||||||
$('.filterSelector:checked').each(function (i, e) {
|
|
||||||
selected.push($(e).val());
|
|
||||||
});
|
|
||||||
|
|
||||||
for (var key in points)
|
|
||||||
{
|
|
||||||
if (selected.length == 0 || points[key].options.categoryId == undefined || selected.indexOf(points[key].options.categoryId) != -1)
|
|
||||||
{
|
|
||||||
markers.addLayer(points[key]);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
markers.removeLayer(points[key]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue