v0.0.1
13
web/Dockerfile
Normal file
@@ -0,0 +1,13 @@
|
||||
FROM node:20.18
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY package.json package-lock.json ./
|
||||
|
||||
RUN npm install
|
||||
|
||||
COPY . .
|
||||
|
||||
EXPOSE 4002
|
||||
|
||||
CMD npm start
|
||||
4
web/config.js
Normal file
@@ -0,0 +1,4 @@
|
||||
const CONFIG = {
|
||||
"api": "https://sheep-service.com/api/",
|
||||
"wss": "wss://sheep-service.com/ws"
|
||||
}
|
||||
551
web/css/main.css
Normal file
@@ -0,0 +1,551 @@
|
||||
@import url('https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;700&display=swap');
|
||||
|
||||
@media (prefers-color-scheme: light) {
|
||||
:root {
|
||||
/* PrimaryColor */
|
||||
--PrimaryColor: #28a55a;
|
||||
--PrimaryColor: #f2bd53;
|
||||
--PrimaryColorText: #2e2e2e;
|
||||
/* BGColor */
|
||||
--ColorThemes0: #fbfbfb;
|
||||
--ColorThemes1: #f3f3f3;
|
||||
--ColorThemes2: #e5e5df;
|
||||
/* TextColor */
|
||||
--ColorThemes3: #313131;
|
||||
|
||||
--ColorAnimation: linear-gradient(90deg, #f3f3f3, #efefef, #f3f3f3);
|
||||
|
||||
--shadow-l1: 0px 2px 4px rgba(0, 0, 0, 0.02), 0px 0px 2px rgba(0, 0, 0, 0.04), 0px 0px 1px rgba(0, 0, 0, 0.04);
|
||||
--border-radius: 15px;
|
||||
|
||||
|
||||
--CardAnimation: linear-gradient(to right, #fbfbfb 0%, #fbfbfb 30%, #d8d8d8 45%, #d8d8d8 50%, #fbfbfb 60%, #fbfbfb 100%);
|
||||
}
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:root {
|
||||
/* PrimaryColor */
|
||||
--PrimaryColor: #28a55a;
|
||||
--PrimaryColor: #cb9e44;
|
||||
--PrimaryColorText: #2e2e2e;
|
||||
/* BGColor */
|
||||
--ColorThemes0: #1c1c19;
|
||||
--ColorThemes1: #21221d;
|
||||
--ColorThemes2: #3a3a39;
|
||||
/* TextColor */
|
||||
--ColorThemes3: #f3f3f3;
|
||||
|
||||
--ColorAnimation: linear-gradient(90deg, #21221d, #242520, #21221d);
|
||||
|
||||
--shadow-l1: 0px 4px 8px rgba(0, 0, 0, 0.04), 0px 0px 2px rgba(0, 0, 0, 0.06), 0px 0px 1px rgba(0, 0, 0, 0.04);
|
||||
--border-radius: 15px;
|
||||
|
||||
|
||||
|
||||
--CardAnimation: linear-gradient(to right, #1c1c19 0%, #1c1c19 30%, #252525 45%, #252525 50%, #1c1c19 60%, #1c1c19 100%);
|
||||
}
|
||||
}
|
||||
|
||||
* {
|
||||
border: 0;
|
||||
padding: 0;
|
||||
font-family: 'Roboto', sans-serif;
|
||||
margin: 0;
|
||||
font-weight: 300;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
*:disabled {
|
||||
opacity: 0.6 !important;
|
||||
cursor: no-drop !important;
|
||||
}
|
||||
|
||||
@media (min-width: 800px) {
|
||||
* {
|
||||
scroll-snap-type: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
@media (pointer:fine) {
|
||||
::-webkit-scrollbar {
|
||||
width: 7px;
|
||||
height: 7px;
|
||||
background-color: #f9f9fd;
|
||||
border-radius: var(--border-radius);
|
||||
background: 0;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
background: var(--PrimaryColor);
|
||||
border-radius: var(--border-radius);
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-track {
|
||||
background: 0;
|
||||
border: 0;
|
||||
margin: 0;
|
||||
border-radius: var(--border-radius);
|
||||
}
|
||||
}
|
||||
|
||||
a {
|
||||
text-decoration: none;
|
||||
font-size: 15px;
|
||||
font-weight: 700;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: var(--ColorThemes2);
|
||||
color: var(--ColorThemes3);
|
||||
/* transition: .3s ease; */
|
||||
}
|
||||
|
||||
/* Стили для анимации обновления страници свайпом */
|
||||
@keyframes fade-in {
|
||||
from {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
to {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes fade-out {
|
||||
from {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
to {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
select {
|
||||
-moz-appearance: none;
|
||||
-webkit-appearance: none;
|
||||
appearance: none;
|
||||
appearance: none;
|
||||
background-image: url(data:image/svg+xml;charset=US-ASCII,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22292.4%22%20height%3D%22292.4%22%3E%3Cpath%20fill%3D%22%23F2BD53%22%20d%3D%22M287%2069.4a17.6%2017.6%200%200%200-13-5.4H18.4c-5%200-9.3%201.8-12.9%205.4A17.6%2017.6%200%200%200%200%2082.2c0%205%201.8%209.3%205.4%2012.9l128%20127.9c3.6%203.6%207.8%205.4%2012.8%205.4s9.2-1.8%2012.8-5.4L287%2095c3.5-3.5%205.4-7.8%205.4-12.8%200-5-1.9-9.2-5.5-12.8z%22%2F%3E%3C%2Fsvg%3E);
|
||||
background-repeat: no-repeat;
|
||||
background-position: right 0.7rem top 50%;
|
||||
background-size: 0.65rem auto;
|
||||
}
|
||||
|
||||
.hold-button{
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
|
||||
.custom-checkbox {
|
||||
position: absolute;
|
||||
z-index: -1;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.custom-checkbox+label {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.custom-checkbox+label::before {
|
||||
content: '';
|
||||
display: inline-block;
|
||||
width: 25px;
|
||||
height: 25px;
|
||||
flex-shrink: 0;
|
||||
flex-grow: 0;
|
||||
border: 1px solid #adb5bd;
|
||||
border-radius: 10px;
|
||||
margin-right: 0.5em;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center center;
|
||||
background-size: 50% 50%;
|
||||
}
|
||||
|
||||
.custom-checkbox:checked+label::before {
|
||||
border-color: var(--PrimaryColor);
|
||||
background-color: var(--PrimaryColor);
|
||||
background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%23fff' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26 2.974 7.25 8 2.193z'/%3e%3c/svg%3e");
|
||||
}
|
||||
|
||||
.custom-checkbox:not(:disabled):not(:checked)+label:hover::before {
|
||||
border-color: var(--PrimaryColor);
|
||||
}
|
||||
|
||||
.custom-checkbox:not(:disabled):active+label::before {
|
||||
background-color: var(--PrimaryColor);
|
||||
border-color: var(--PrimaryColor);
|
||||
}
|
||||
|
||||
.custom-checkbox:focus:not(:checked)+label::before {
|
||||
border-color: var(--PrimaryColor);
|
||||
}
|
||||
|
||||
.custom-checkbox:disabled+label::before {
|
||||
background-color: #e9ecef;
|
||||
}
|
||||
|
||||
#swipe_updater {
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#swipe_block {
|
||||
width: calc(100% - 252px);
|
||||
margin-left: 252px;
|
||||
height: 50px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: flex-end;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
#swipe_icon {
|
||||
width: 20px;
|
||||
fill: var(--ColorThemes3);
|
||||
transform: rotate(0deg);
|
||||
position: absolute;
|
||||
margin-top: -45px;
|
||||
top: -45px;
|
||||
background: var(--ColorThemes2);
|
||||
border: 2px solid var(--ColorThemes3);
|
||||
border-radius: 50%;
|
||||
padding: 10px;
|
||||
display: flex;
|
||||
overflow: hidden;
|
||||
height: 0;
|
||||
opacity: 0;
|
||||
transition: height 0ms 400ms, opacity 400ms 0ms;
|
||||
}
|
||||
|
||||
#swipe_icon[data-state="active"] {
|
||||
height: 20px;
|
||||
opacity: 1;
|
||||
transition: height 0ms 0ms, opacity 400ms 0ms;
|
||||
}
|
||||
|
||||
@media (max-width: 1100px) {
|
||||
#swipe_block {
|
||||
width: calc(100% - 122px);
|
||||
margin-left: 122px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 700px) {
|
||||
#swipe_block {
|
||||
width: 100%;
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* Уведомление и кнопка обновления приложения */
|
||||
#update_banner {
|
||||
height: 55px;
|
||||
transition: .3s ease;
|
||||
}
|
||||
|
||||
#update_banner .content {
|
||||
margin: 0 auto;
|
||||
max-width: 300px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
#update_banner .headline {
|
||||
font-weight: 800;
|
||||
font-size: 15px;
|
||||
color: var(--PrimaryColorText);
|
||||
font-family: 'Roboto', sans-serif;
|
||||
}
|
||||
|
||||
#update_banner .subhead {
|
||||
font-size: 13px;
|
||||
text-align: center;
|
||||
color: var(--PrimaryColorText);
|
||||
font-family: 'Roboto', sans-serif;
|
||||
}
|
||||
|
||||
#update_banner[data-state="noupdate"] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#update_banner[data-state="updateavailable"] {
|
||||
display: block;
|
||||
cursor: pointer;
|
||||
background-color: var(--PrimaryColor);
|
||||
color: var(--PrimaryColorText);
|
||||
transition: .3s ease;
|
||||
opacity: 0.95;
|
||||
z-index: 9999;
|
||||
position: fixed;
|
||||
width: 300px;
|
||||
margin: 10px;
|
||||
padding: 5px;
|
||||
border-radius: 25px;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
#update_banner_icon {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#update_banner_icon svg {
|
||||
padding: 0px 50px;
|
||||
width: 25px;
|
||||
margin: -4px;
|
||||
fill: var(--PrimaryColorText);
|
||||
}
|
||||
|
||||
@media (max-width: 700px) {
|
||||
#update_banner[data-state="updateavailable"] {
|
||||
width: calc(100% - 30px);
|
||||
}
|
||||
}
|
||||
|
||||
/* Стили для меню */
|
||||
#navigation {
|
||||
position: fixed;
|
||||
width: 230px;
|
||||
height: calc(100vh - 60px);
|
||||
min-height: 510px;
|
||||
background: var(--ColorThemes2);
|
||||
padding: 36px 10px;
|
||||
-webkit-transition: width .2s ease 0s;
|
||||
-o-transition: width .2s ease 0s;
|
||||
transition: width .2s ease 0s;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
#navigation>nav {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 290px;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
#navigation>nav>li {
|
||||
width: 180px;
|
||||
height: 50px;
|
||||
list-style-type: none;
|
||||
position: relative;
|
||||
-webkit-transition: all .2s ease 0s;
|
||||
-o-transition: all .2s ease 0s;
|
||||
transition: all .2s ease 0s;
|
||||
z-index: 1;
|
||||
margin: 5px;
|
||||
}
|
||||
|
||||
#navigation>nav>li>div {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: nowrap;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
height: 50px;
|
||||
padding: 0 10px;
|
||||
border-radius: var(--border-radius);
|
||||
-webkit-transition: all .2s ease 0s;
|
||||
-o-transition: all .2s ease 0s;
|
||||
transition: all .2s ease 0s;
|
||||
opacity: 0.8;
|
||||
cursor: pointer;
|
||||
border: 2px;
|
||||
border: 2px solid var(--ColorThemes2);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
#navigation>nav>li>div[data-state="active"] {
|
||||
background: var(--ColorThemes3);
|
||||
border: 2px solid var(--ColorThemes3);
|
||||
box-shadow: var(--shadow-l1);
|
||||
}
|
||||
|
||||
#navigation>nav>li:has(div[data-state="active"]) {
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
#navigation>nav>li>div>svg {
|
||||
width: 25px;
|
||||
height: 25px;
|
||||
min-width: 25px;
|
||||
min-height: 25px;
|
||||
fill: var(--ColorThemes3);
|
||||
}
|
||||
|
||||
#navigation>nav>li>div[data-state="active"] svg {
|
||||
fill: var(--ColorThemes2);
|
||||
}
|
||||
|
||||
#navigation>nav>li>div>b {
|
||||
margin-left: 15px;
|
||||
font-size: 14px;
|
||||
font-weight: 300;
|
||||
color: var(--ColorThemes3);
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
#navigation>nav>li>div[data-state="active"] b {
|
||||
color: var(--ColorThemes2);
|
||||
}
|
||||
|
||||
#navigation>nav>li>a {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
top: 2px;
|
||||
}
|
||||
|
||||
|
||||
@media (hover: hover) {
|
||||
#navigation>nav>li:hover {
|
||||
transform: scale(1.01);
|
||||
}
|
||||
|
||||
#navigation>nav>li:hover>div {
|
||||
border: 2px solid var(--ColorThemes3);
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 1100px) {
|
||||
#navigation {
|
||||
width: 100px;
|
||||
}
|
||||
|
||||
#navigation>nav>li {
|
||||
width: 50px;
|
||||
}
|
||||
|
||||
#navigation>nav>li>div {
|
||||
width: 30px;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
#navigation>nav>li>div>b {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
#app {
|
||||
background: var(--ColorThemes0);
|
||||
position: absolute;
|
||||
margin-top: 40px;
|
||||
margin-left: 250px;
|
||||
padding: 5px;
|
||||
width: calc(100% - 250px - 10px);
|
||||
min-height: calc(100% - 50px);
|
||||
border-radius: 20px 0 0 0;
|
||||
-webkit-transition: all .2sease 0s;
|
||||
-o-transition: all .2s ease 0s;
|
||||
transition: all .2sease 0s;
|
||||
box-shadow: var(--shadow-l1);
|
||||
display: flex;
|
||||
}
|
||||
|
||||
@media (max-width: 1100px) {
|
||||
#app {
|
||||
margin-left: 120px;
|
||||
width: calc(100% - 130px);
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 700px),
|
||||
(max-height: 540px) {
|
||||
body {
|
||||
background: var(--ColorThemes0);
|
||||
}
|
||||
|
||||
#navigation {
|
||||
width: 100%;
|
||||
height: 60px;
|
||||
min-height: 60px;
|
||||
padding: 0;
|
||||
z-index: 99999990;
|
||||
bottom: -1px;
|
||||
border: 0;
|
||||
margin: 0;
|
||||
box-shadow: 0px 24px 32px rgba(0, 0, 0, .09), 0px 16px 24px rgba(0, 0, 0, .09), 0px 4px 8px rgba(0, 0, 0, .09), 0px 0px 1px rgba(0, 0, 0, .09);
|
||||
}
|
||||
|
||||
#navigation>nav {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
height: 100%;
|
||||
justify-content: space-around;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
#navigation>nav>li {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
#navigation>nav>li:hover {
|
||||
transform: scale(1.0);
|
||||
}
|
||||
|
||||
#navigation>nav>li:hover>div {
|
||||
border: 0;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
#navigation>nav>li>div {
|
||||
width: 100%;
|
||||
height: 40px;
|
||||
padding: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
border: 0;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
#navigation>nav>li>div>span {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#navigation>nav>li>div[data-state="active"] {
|
||||
background: 0;
|
||||
border: 0;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
#navigation>nav>li>div[data-state="active"]>svg {
|
||||
fill: var(--PrimaryColor);
|
||||
}
|
||||
|
||||
#navigation>nav>li>button {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#navigation[data-state="ios"] {
|
||||
height: 70px;
|
||||
}
|
||||
|
||||
#navigation[data-state="ios"]>nav {
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
#app {
|
||||
margin-left: 0px;
|
||||
width: 100%;
|
||||
border-radius: 0;
|
||||
padding: 0;
|
||||
margin-top: 0;
|
||||
padding-bottom: 80px;
|
||||
height: auto;
|
||||
}
|
||||
}
|
||||
94
web/fonts/PT_Mono/OFL.txt
Normal file
@@ -0,0 +1,94 @@
|
||||
Copyright (c) 2011, ParaType Ltd. (http://www.paratype.com/public),
|
||||
with Reserved Font Names "PT Sans", "PT Serif", "PT Mono" and "ParaType".
|
||||
|
||||
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||
This license is copied below, and is also available with a FAQ at:
|
||||
http://scripts.sil.org/OFL
|
||||
|
||||
|
||||
-----------------------------------------------------------
|
||||
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||
-----------------------------------------------------------
|
||||
|
||||
PREAMBLE
|
||||
The goals of the Open Font License (OFL) are to stimulate worldwide
|
||||
development of collaborative font projects, to support the font creation
|
||||
efforts of academic and linguistic communities, and to provide a free and
|
||||
open framework in which fonts may be shared and improved in partnership
|
||||
with others.
|
||||
|
||||
The OFL allows the licensed fonts to be used, studied, modified and
|
||||
redistributed freely as long as they are not sold by themselves. The
|
||||
fonts, including any derivative works, can be bundled, embedded,
|
||||
redistributed and/or sold with any software provided that any reserved
|
||||
names are not used by derivative works. The fonts and derivatives,
|
||||
however, cannot be released under any other type of license. The
|
||||
requirement for fonts to remain under this license does not apply
|
||||
to any document created using the fonts or their derivatives.
|
||||
|
||||
DEFINITIONS
|
||||
"Font Software" refers to the set of files released by the Copyright
|
||||
Holder(s) under this license and clearly marked as such. This may
|
||||
include source files, build scripts and documentation.
|
||||
|
||||
"Reserved Font Name" refers to any names specified as such after the
|
||||
copyright statement(s).
|
||||
|
||||
"Original Version" refers to the collection of Font Software components as
|
||||
distributed by the Copyright Holder(s).
|
||||
|
||||
"Modified Version" refers to any derivative made by adding to, deleting,
|
||||
or substituting -- in part or in whole -- any of the components of the
|
||||
Original Version, by changing formats or by porting the Font Software to a
|
||||
new environment.
|
||||
|
||||
"Author" refers to any designer, engineer, programmer, technical
|
||||
writer or other person who contributed to the Font Software.
|
||||
|
||||
PERMISSION & CONDITIONS
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
||||
redistribute, and sell modified and unmodified copies of the Font
|
||||
Software, subject to the following conditions:
|
||||
|
||||
1) Neither the Font Software nor any of its individual components,
|
||||
in Original or Modified Versions, may be sold by itself.
|
||||
|
||||
2) Original or Modified Versions of the Font Software may be bundled,
|
||||
redistributed and/or sold with any software, provided that each copy
|
||||
contains the above copyright notice and this license. These can be
|
||||
included either as stand-alone text files, human-readable headers or
|
||||
in the appropriate machine-readable metadata fields within text or
|
||||
binary files as long as those fields can be easily viewed by the user.
|
||||
|
||||
3) No Modified Version of the Font Software may use the Reserved Font
|
||||
Name(s) unless explicit written permission is granted by the corresponding
|
||||
Copyright Holder. This restriction only applies to the primary font name as
|
||||
presented to the users.
|
||||
|
||||
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
||||
Software shall not be used to promote, endorse or advertise any
|
||||
Modified Version, except to acknowledge the contribution(s) of the
|
||||
Copyright Holder(s) and the Author(s) or with their explicit written
|
||||
permission.
|
||||
|
||||
5) The Font Software, modified or unmodified, in part or in whole,
|
||||
must be distributed entirely under this license, and must not be
|
||||
distributed under any other license. The requirement for fonts to
|
||||
remain under this license does not apply to any document created
|
||||
using the Font Software.
|
||||
|
||||
TERMINATION
|
||||
This license becomes null and void if any of the above conditions are
|
||||
not met.
|
||||
|
||||
DISCLAIMER
|
||||
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||
OTHER DEALINGS IN THE FONT SOFTWARE.
|
||||
BIN
web/fonts/PT_Mono/PTMono-Regular.ttf
Normal file
96
web/fonts/UbuntuMono/UFL.txt
Normal file
@@ -0,0 +1,96 @@
|
||||
-------------------------------
|
||||
UBUNTU FONT LICENCE Version 1.0
|
||||
-------------------------------
|
||||
|
||||
PREAMBLE
|
||||
This licence allows the licensed fonts to be used, studied, modified and
|
||||
redistributed freely. The fonts, including any derivative works, can be
|
||||
bundled, embedded, and redistributed provided the terms of this licence
|
||||
are met. The fonts and derivatives, however, cannot be released under
|
||||
any other licence. The requirement for fonts to remain under this
|
||||
licence does not require any document created using the fonts or their
|
||||
derivatives to be published under this licence, as long as the primary
|
||||
purpose of the document is not to be a vehicle for the distribution of
|
||||
the fonts.
|
||||
|
||||
DEFINITIONS
|
||||
"Font Software" refers to the set of files released by the Copyright
|
||||
Holder(s) under this licence and clearly marked as such. This may
|
||||
include source files, build scripts and documentation.
|
||||
|
||||
"Original Version" refers to the collection of Font Software components
|
||||
as received under this licence.
|
||||
|
||||
"Modified Version" refers to any derivative made by adding to, deleting,
|
||||
or substituting -- in part or in whole -- any of the components of the
|
||||
Original Version, by changing formats or by porting the Font Software to
|
||||
a new environment.
|
||||
|
||||
"Copyright Holder(s)" refers to all individuals and companies who have a
|
||||
copyright ownership of the Font Software.
|
||||
|
||||
"Substantially Changed" refers to Modified Versions which can be easily
|
||||
identified as dissimilar to the Font Software by users of the Font
|
||||
Software comparing the Original Version with the Modified Version.
|
||||
|
||||
To "Propagate" a work means to do anything with it that, without
|
||||
permission, would make you directly or secondarily liable for
|
||||
infringement under applicable copyright law, except executing it on a
|
||||
computer or modifying a private copy. Propagation includes copying,
|
||||
distribution (with or without modification and with or without charging
|
||||
a redistribution fee), making available to the public, and in some
|
||||
countries other activities as well.
|
||||
|
||||
PERMISSION & CONDITIONS
|
||||
This licence does not grant any rights under trademark law and all such
|
||||
rights are reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of the Font Software, to propagate the Font Software, subject to
|
||||
the below conditions:
|
||||
|
||||
1) Each copy of the Font Software must contain the above copyright
|
||||
notice and this licence. These can be included either as stand-alone
|
||||
text files, human-readable headers or in the appropriate machine-
|
||||
readable metadata fields within text or binary files as long as those
|
||||
fields can be easily viewed by the user.
|
||||
|
||||
2) The font name complies with the following:
|
||||
(a) The Original Version must retain its name, unmodified.
|
||||
(b) Modified Versions which are Substantially Changed must be renamed to
|
||||
avoid use of the name of the Original Version or similar names entirely.
|
||||
(c) Modified Versions which are not Substantially Changed must be
|
||||
renamed to both (i) retain the name of the Original Version and (ii) add
|
||||
additional naming elements to distinguish the Modified Version from the
|
||||
Original Version. The name of such Modified Versions must be the name of
|
||||
the Original Version, with "derivative X" where X represents the name of
|
||||
the new work, appended to that name.
|
||||
|
||||
3) The name(s) of the Copyright Holder(s) and any contributor to the
|
||||
Font Software shall not be used to promote, endorse or advertise any
|
||||
Modified Version, except (i) as required by this licence, (ii) to
|
||||
acknowledge the contribution(s) of the Copyright Holder(s) or (iii) with
|
||||
their explicit written permission.
|
||||
|
||||
4) The Font Software, modified or unmodified, in part or in whole, must
|
||||
be distributed entirely under this licence, and must not be distributed
|
||||
under any other licence. The requirement for fonts to remain under this
|
||||
licence does not affect any document created using the Font Software,
|
||||
except any version of the Font Software extracted from a document
|
||||
created using the Font Software may only be distributed under this
|
||||
licence.
|
||||
|
||||
TERMINATION
|
||||
This licence becomes null and void if any of the above conditions are
|
||||
not met.
|
||||
|
||||
DISCLAIMER
|
||||
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
|
||||
COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER
|
||||
DEALINGS IN THE FONT SOFTWARE.
|
||||
BIN
web/fonts/UbuntuMono/UbuntuMono-Bold.ttf
Normal file
BIN
web/fonts/UbuntuMono/UbuntuMono-BoldItalic.ttf
Normal file
BIN
web/fonts/UbuntuMono/UbuntuMono-Italic.ttf
Normal file
BIN
web/fonts/UbuntuMono/UbuntuMono-Regular.ttf
Normal file
41
web/img/0.svg
Normal file
@@ -0,0 +1,41 @@
|
||||
<svg xmlns:dc="http://purl.org/dc/elements/1.1/" inkscape:export-ydpi="96" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:osb="http://www.openswatchbook.org/uri/2009/osb" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" inkscape:export-xdpi="96" width="48" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" height="48" xmlns:svg="http://www.w3.org/2000/svg" style="fill:none;stroke:none;" viewBox="0 0 48 48" version="1.1">
|
||||
<defs/>
|
||||
<sodipodi:namedview pagecolor="#ffffff" inkscape:pagecheckerboard="true" borderlayer="true" bordercolor="#666666" inkscape:document-units="px"/>
|
||||
<title>synchronize-cloud</title>
|
||||
<g inkscape:groupmode="layer" id="MainComposition_a4ec5bcbf1d44168962622fcea8276bf" inkscape:label="synchronize-cloud">
|
||||
<g inkscape:groupmode="layer" transform="matrix(1, 0, 0, 1, 0, 0)" opacity="1" id="Layer_9907dd6ff6004617bd3a525195c313f2" inkscape:label="arrows">
|
||||
<g transform="translate(24 29)">
|
||||
<g transform="rotate(0)">
|
||||
<g transform="scale(1 1)">
|
||||
<g transform="translate(-24 -29)">
|
||||
<g opacity="1" id="Group_2cb26585a6274aff82b52d6629f47ff3" inkscape:label="Group 1">
|
||||
<g transform="matrix(1, 0, 0, 1, 18.772, 33.991)" opacity="1" id="Stroke_eac34415491147c99ffc4335fed73f62" stroke="#000000" stroke-width="3" stroke-opacity="1" inkscape:label="Group 4">
|
||||
<path sodipodi:nodetypes="ccc" d="M -2.708,2.491 C -2.708,2.491 -2.273,-2.49 -2.273,-2.49 -2.273,-2.49 2.708,-2.055 2.708,-2.055" style="fill:none;stroke-dasharray:none;stroke-linecap:round;stroke-linejoin:round;">
|
||||
<animate calcMode="spline" repeatCount="indefinite" attributeName="d" dur="1.166667" begin="0.000000" keyTimes="0; 0.107143; 0.178571; 0.821429; 0.892857; 1" keySplines="0 0 1 1; 0.333000 0.000000 0.667000 1.000000; 0.167000 0.167000 0.833000 0.833000; 0.333000 0.000000 0.667000 1.000000; 0.000000 0.000000 0.000000 0.000000" values="M -2.708,2.491 C -2.708,2.491 -2.273,-2.49 -2.273,-2.49 -2.273,-2.49 2.708,-2.055 2.708,-2.055; M -2.708,2.491 C -2.708,2.491 -2.273,-2.49 -2.273,-2.49 -2.273,-2.49 2.708,-2.055 2.708,-2.055; M -1.771,-2.28 C -1.771,-2.28 -1.761,-2.279 -1.761,-2.279 -1.761,-2.279 -1.78,-2.283 -1.78,-2.283; M -1.768,-2.281 C -1.768,-2.281 -1.758,-2.28 -1.758,-2.28 -1.758,-2.28 -1.778,-2.284 -1.778,-2.284; M -2.708,2.491 C -2.708,2.491 -2.273,-2.49 -2.273,-2.49 -2.273,-2.49 2.708,-2.055 2.708,-2.055; M -2.708,2.491 C -2.708,2.491 -2.273,-2.49 -2.273,-2.49 -2.273,-2.49 2.708,-2.055 2.708,-2.055"/>
|
||||
</path>
|
||||
</g>
|
||||
<g transform="matrix(1, 0, 0, 1, 24.037, 34)" opacity="1" id="Stroke_808239d21b7e4a859d5a99d0baf98e17" stroke="#000000" stroke-width="3" stroke-opacity="1" inkscape:label="Group 3">
|
||||
<path sodipodi:nodetypes="ccc" d="M 7.036,-2.5 C 6.006,0.413 3.228,2.5 -0.036,2.5 -3.227,2.5 -5.953,0.507 -7.036,-2.303" style="fill:none;stroke-dasharray:none;stroke-linecap:round;stroke-linejoin:round;"/>
|
||||
</g>
|
||||
<g transform="matrix(1, 0, 0, 1, 29.227, 24.009)" opacity="1" id="Stroke_c1f02aae6dea4564b6abe25c038848fe" stroke="#000000" stroke-width="3" stroke-opacity="1" inkscape:label="Group 2">
|
||||
<path sodipodi:nodetypes="ccc" d="M 2.708,-2.49 C 2.708,-2.49 2.273,2.491 2.273,2.491 2.273,2.491 -2.708,2.055 -2.708,2.055" style="fill:none;stroke-dasharray:none;stroke-linecap:round;stroke-linejoin:round;">
|
||||
<animate calcMode="spline" repeatCount="indefinite" attributeName="d" dur="1.166667" begin="0.000000" keyTimes="0; 0.107143; 0.178571; 0.821429; 0.892857; 1" keySplines="0 0 1 1; 0.333000 0.000000 0.667000 1.000000; 0.167000 0.167000 0.833000 0.833000; 0.333000 0.000000 0.667000 1.000000; 0.000000 0.000000 0.000000 0.000000" values="M 2.708,-2.49 C 2.708,-2.49 2.273,2.491 2.273,2.491 2.273,2.491 -2.708,2.055 -2.708,2.055; M 2.708,-2.49 C 2.708,-2.49 2.273,2.491 2.273,2.491 2.273,2.491 -2.708,2.055 -2.708,2.055; M 1.775,2.301 C 1.775,2.301 1.775,2.298 1.775,2.298 1.775,2.298 1.777,2.29 1.777,2.29; M 1.767,2.292 C 1.767,2.292 1.767,2.289 1.767,2.289 1.767,2.289 1.768,2.281 1.768,2.281; M 2.708,-2.49 C 2.708,-2.49 2.273,2.491 2.273,2.491 2.273,2.491 -2.708,2.055 -2.708,2.055; M 2.708,-2.49 C 2.708,-2.49 2.273,2.491 2.273,2.491 2.273,2.491 -2.708,2.055 -2.708,2.055"/>
|
||||
</path>
|
||||
</g>
|
||||
<g transform="matrix(1, 0, 0, 1, 23.963, 24)" opacity="1" id="Stroke_b8202dc468474015b6784aeccf30c7fe" stroke="#000000" stroke-width="3" stroke-opacity="1" inkscape:label="Group 1">
|
||||
<path sodipodi:nodetypes="ccc" d="M -7.036,2.5 C -6.006,-0.413 -3.229,-2.5 0.036,-2.5 3.228,-2.5 5.953,-0.507 7.036,2.303" style="fill:none;stroke-dasharray:none;stroke-linecap:round;stroke-linejoin:round;"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
<animateTransform calcMode="spline" repeatCount="indefinite" attributeName="transform" dur="1.166667" begin="0.000000" type="rotate" keyTimes="0; 0.107143; 0.821429; 0.892857; 1" keySplines="0 0 1 1; 0.333000 0.000000 0.667000 1.000000; 0.333000 0.000000 0.667000 1.000000; 0.000000 0.000000 0.000000 0.000000" values="0; 0; 380; 360; 360"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
<g inkscape:groupmode="layer" transform="matrix(1, 0, 0, 1, 0, 0)" opacity="1" id="Layer_27939f0fe5ec41fa8de333c2fda4c3f8" inkscape:label="cloud">
|
||||
<g fill-opacity="1" transform="matrix(1, 0, 0, 1, 24, 22.5)" opacity="1" id="Fill_2eda0ab38e6f42adb64be815c093c02c" fill="#000000" inkscape:label="Group 1">
|
||||
<path sodipodi:nodetypes="ccccccccccccccccccccccccc" d="M 15,-2.5 C 15,-2.5 14.42,-2.5 14.42,-2.5 13.67,-9.79 7.49,-15.5 0,-15.5 -7.49,-15.5 -13.67,-9.79 -14.42,-2.5 -14.42,-2.5 -15,-2.5 -15,-2.5 -19.96,-2.5 -24,1.54 -24,6.5 -24,11.46 -19.96,15.5 -15,15.5 -15,15.5 -12.17,15.5 -12.17,15.5 -12.38,14.91 -12.48,14.26 -12.42,13.59 -12.42,13.59 -12.32,12.5 -12.32,12.5 -12.32,12.5 -15,12.5 -15,12.5 -18.31,12.5 -21,9.81 -21,6.5 -21,3.19 -18.31,0.5 -15,0.5 -15,0.5 -13,0.5 -13,0.5 -12.17,0.5 -11.5,-0.17 -11.5,-1 -11.5,-7.34 -6.34,-12.5 0,-12.5 6.34,-12.5 11.5,-7.34 11.5,-1 11.5,-0.17 12.17,0.5 13,0.5 13,0.5 15,0.5 15,0.5 18.31,0.5 21,3.19 21,6.5 21,9.81 18.31,12.5 15,12.5 15,12.5 10.38,12.5 10.38,12.5 9.73,13.64 8.89,14.66 7.92,15.5 7.92,15.5 15,15.5 15,15.5 19.96,15.5 24,11.46 24,6.5 24,1.54 19.96,-2.5 15,-2.5 Z" style=""/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 6.9 KiB |
BIN
web/img/1.gif
Normal file
|
After Width: | Height: | Size: 16 KiB |
1
web/img/1.json
Normal file
6
web/img/1.svg
Normal file
|
After Width: | Height: | Size: 30 KiB |
BIN
web/img/2.gif
Normal file
|
After Width: | Height: | Size: 16 KiB |
BIN
web/img/IconKitchen.zip
Normal file
BIN
web/img/apple-touch-icon.png
Normal file
|
After Width: | Height: | Size: 5.2 KiB |
BIN
web/img/badge.png
Normal file
|
After Width: | Height: | Size: 3.2 KiB |
BIN
web/img/favicon.ico
Normal file
|
After Width: | Height: | Size: 5.1 KiB |
BIN
web/img/icon-192-maskable.png
Normal file
|
After Width: | Height: | Size: 5.6 KiB |
BIN
web/img/icon-192.png
Normal file
|
After Width: | Height: | Size: 6.8 KiB |
BIN
web/img/icon-512-maskable.png
Normal file
|
After Width: | Height: | Size: 20 KiB |
BIN
web/img/icon-512.png
Normal file
|
After Width: | Height: | Size: 23 KiB |
BIN
web/img/icons/info.gif
Normal file
|
After Width: | Height: | Size: 5.5 KiB |
1
web/img/icons/info.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg fill="#1A1A1A" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48" width="100px" height="100px"><path d="M 24 4 C 12.972066 4 4 12.972074 4 24 C 4 35.027926 12.972066 44 24 44 C 35.027934 44 44 35.027926 44 24 C 44 12.972074 35.027934 4 24 4 z M 24 7 C 33.406615 7 41 14.593391 41 24 C 41 33.406609 33.406615 41 24 41 C 14.593385 41 7 33.406609 7 24 C 7 14.593391 14.593385 7 24 7 z M 24 14 A 2 2 0 0 0 24 18 A 2 2 0 0 0 24 14 z M 23.976562 20.978516 A 1.50015 1.50015 0 0 0 22.5 22.5 L 22.5 33.5 A 1.50015 1.50015 0 1 0 25.5 33.5 L 25.5 22.5 A 1.50015 1.50015 0 0 0 23.976562 20.978516 z"/></svg>
|
||||
|
After Width: | Height: | Size: 606 B |
BIN
web/img/map/1.jpg
Normal file
|
After Width: | Height: | Size: 110 KiB |
3
web/img/sheep.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 30 30">
|
||||
<path fill="#f2bd53" d="M 13 5 C 11.828237 5 10.793477 5.4713326 9.9394531 6.1503906 C 9.6361713 6.0843037 9.3462112 6 9 6 C 6.2504839 6 4 8.2504839 4 11 C 4 11.08059 4.0124881 11.1121 4.0175781 11.181641 C 2.9210459 12.039325 2.1098117 13.257229 2.0175781 14.726562 L 1.1054688 16.552734 A 1.0001165 1.0001165 0 0 0 2.7675781 17.640625 C 3.2526418 18.411838 3.9424236 19.03683 4.7597656 19.449219 L 5 19.675781 L 5 25 A 1.0001 1.0001 0 1 0 7 25 L 7 19.246094 A 1.0001 1.0001 0 0 0 6.6875 18.519531 L 6.046875 17.914062 A 1.0001 1.0001 0 0 0 5.7714844 17.728516 C 4.7470246 17.266071 4.0294077 16.259842 4.0039062 15.064453 A 1.0001 1.0001 0 0 0 4.0039062 14.939453 C 4.0261116 13.839378 4.6387768 12.906535 5.5429688 12.398438 A 1.0001 1.0001 0 0 0 6.0449219 11.394531 C 6.0183372 11.193412 6 11.068889 6 11 C 6 9.3315161 7.3315161 8 9 8 C 9.2766049 8 9.5584058 8.0531018 9.8652344 8.1464844 A 1.0001 1.0001 0 0 0 10.867188 7.8925781 C 11.414334 7.3394013 12.160136 7 13 7 C 13.943745 7 14.765257 7.4389147 15.322266 8.1289062 A 1.0001 1.0001 0 0 0 16.578125 8.3789062 C 17.019891 8.1381558 17.492971 8 18 8 C 19.125679 8 20.081212 8.6201548 20.599609 9.5390625 A 1.0001 1.0001 0 0 0 21.353516 10.039062 C 22.531272 10.179159 23.485346 10.980923 23.841797 12.068359 C 22.824708 11.859395 21.724766 12.146328 20.935547 12.935547 C 19.687547 14.183547 19.687547 16.207078 20.935547 17.455078 C 21.055851 17.575382 21.216262 17.686732 21.376953 17.796875 C 20.836332 18.524365 19.985264 19 19 19 C 18.492971 19 18.019891 18.861844 17.578125 18.621094 A 1.0001 1.0001 0 0 0 16.322266 18.871094 C 15.765471 19.56158 14.944275 20 14 20 C 13.291552 20 12.65587 19.746025 12.128906 19.320312 A 1.0001 1.0001 0 0 0 10.871094 19.320312 C 10.34413 19.746025 9.7084483 20 9 20 A 1.0001 1.0001 0 1 0 9 22 L 9 25 A 1.0001 1.0001 0 1 0 11 25 L 11 21.505859 C 11.170848 21.422563 11.337991 21.33349 11.5 21.236328 C 12.238737 21.67937 13.068046 22 14 22 C 14.730164 22 15.395058 21.803876 16 21.498047 L 16 25 A 1.0001 1.0001 0 1 0 18 25 L 18 20.806641 C 18.316031 20.913616 18.640829 21 19 21 C 19.343981 21 19.67546 20.953638 20 20.886719 L 20 25 A 1.0001 1.0001 0 1 0 22 25 L 22 20 A 1.0001 1.0001 0 0 0 22 19.974609 C 22.486448 19.603854 22.905789 19.152819 23.228516 18.630859 C 24.642494 19.048643 26.176371 19.140035 26.658203 18.658203 C 27.339744 17.976663 26.884402 15.198742 25.958984 13.625 A 1.0001 1.0001 0 0 0 25.966797 13.570312 C 25.987917 13.383949 26 13.19371 26 13 C 26 10.589178 24.248068 8.6335533 21.970703 8.171875 C 21.067822 6.9086944 19.672766 6 18 6 C 17.386577 6 16.866243 6.2341923 16.335938 6.4355469 C 15.448182 5.6006824 14.319642 5 13 5 z M 17.421875 12.279297 C 17.32925 12.296094 17.237609 12.342875 17.162109 12.421875 C 16.614109 12.997875 16 13.891 16 15 C 16 15.567 16.471922 16.023047 17.044922 15.998047 C 17.590922 15.974047 18 15.481547 18 14.935547 L 18 12.763672 C 18 12.435922 17.69975 12.228906 17.421875 12.279297 z M 23 14 C 23.552 14 24 14.448 24 15 C 24 15.552 23.552 16 23 16 C 22.448 16 22 15.552 22 15 C 22 14.448 22.448 14 23 14 z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.1 KiB |
223
web/index.html
Normal file
@@ -0,0 +1,223 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<!-- <meta name="viewport" content="width=device-width, initial-scale=1.0" /> -->
|
||||
<meta
|
||||
name="viewport"
|
||||
content="user-scalable=no, initial-scale=1.0, maximum-scale=1.0"
|
||||
/>
|
||||
|
||||
<!-- Start Single Page Apps for GitHub Pages -->
|
||||
<script>
|
||||
(function(){
|
||||
var redirect = sessionStorage.redirect;
|
||||
delete sessionStorage.redirect;
|
||||
if (redirect && redirect != location.href) {
|
||||
history.replaceState(null, null, redirect);
|
||||
}
|
||||
})();
|
||||
</script>
|
||||
<!-- End Single Page Apps for GitHub Pages -->
|
||||
|
||||
<title>Sheep Service</title>
|
||||
|
||||
<link rel="icon" href="/img/favicon.ico" sizes="any" />
|
||||
<link rel="apple-touch-icon" href="/img/apple-touch-icon.png" />
|
||||
|
||||
<link rel="manifest" href="/manifest.json" />
|
||||
|
||||
<meta
|
||||
name="theme-color"
|
||||
content="#e5e5df"
|
||||
media="(prefers-color-scheme: light)"
|
||||
/>
|
||||
<meta
|
||||
name="theme-color"
|
||||
content="#252523"
|
||||
media="(prefers-color-scheme: dark)"
|
||||
/>
|
||||
|
||||
<!-- Конфигурация SW -->
|
||||
<script src="/sw.js"></script>
|
||||
|
||||
<link rel="stylesheet" href="/css/main.css" />
|
||||
|
||||
<script src="/config.js" defer></script>
|
||||
|
||||
<script src="/lib/router/router.js" defer></script>
|
||||
<script src="/lib/router/routes.js" defer></script>
|
||||
|
||||
<!-- Подключение стилей Leaflet.js -->
|
||||
<link rel="stylesheet" href="/lib/components/leaflet/leaflet.css" />
|
||||
<script src="/lib/components/leaflet/leaflet.js"></script>
|
||||
|
||||
<link rel="stylesheet" href="/lib/components/geoman/leaflet-geoman.css" />
|
||||
<script src="/lib/components/geoman/leaflet-geoman.min.js"></script>
|
||||
|
||||
<script src="/lib/components/turf.min.js" defer></script>
|
||||
|
||||
<script src="/lib/components/clipboard.js" defer></script>
|
||||
<script src="/lib/components/colorGroup.js" defer></script>
|
||||
<script src="/lib/components/makeid.js" defer></script>
|
||||
<script src="/lib/components/swipeUpdater.js" defer></script>
|
||||
<script src="/lib/components/detectBrowser.js" defer></script>
|
||||
<script src="/lib/components/detectOS.js" defer></script>
|
||||
<script src="/lib/components/formattedDate.js" defer></script>
|
||||
|
||||
<script src="/lib/pages/home/script.js" defer></script>
|
||||
<link href="/lib/pages/home/style.css" rel="stylesheet" />
|
||||
|
||||
<script src="/lib/pages/territory/script.js" defer></script>
|
||||
<link href="/lib/pages/territory/style.css" rel="stylesheet" />
|
||||
|
||||
<script src="/lib/pages/territory_manager/script.js" defer></script>
|
||||
<link href="/lib/pages/territory_manager/style.css" rel="stylesheet" />
|
||||
|
||||
<script src="/lib/pages/card/script.js" defer></script>
|
||||
<link href="/lib/pages/card/style.css" rel="stylesheet" />
|
||||
|
||||
<script src="/lib/pages/options/script.js" defer></script>
|
||||
<link href="/lib/pages/options/style.css" rel="stylesheet" />
|
||||
|
||||
<script src="/lib/pages/sheeps/script.js" defer></script>
|
||||
<link href="/lib/pages/sheeps/style.css" rel="stylesheet" />
|
||||
|
||||
<script src="/lib/pages/constructor/script.js" defer></script>
|
||||
<link href="/lib/pages/constructor/style.css" rel="stylesheet" />
|
||||
|
||||
<script src="/lib/pages/editor/script.js" defer></script>
|
||||
<link href="/lib/pages/editor/style.css" rel="stylesheet" />
|
||||
|
||||
<script src="/lib/pages/stand/script.js" defer></script>
|
||||
<link href="/lib/pages/stand/style.css" rel="stylesheet" />
|
||||
|
||||
<script src="/lib/app.js" defer></script>
|
||||
</head>
|
||||
<body>
|
||||
<!-- Кнопка сповіщення та оновлення додатків -->
|
||||
<div id="update_banner" data-state="noupdate">
|
||||
<div class="content">
|
||||
<div class="headline"></div>
|
||||
<div class="subhead"></div>
|
||||
<div id="update_banner_icon">
|
||||
<svg
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
version="1.0"
|
||||
width="64px"
|
||||
height="64px"
|
||||
viewBox="0 0 128 128"
|
||||
xml:space="preserve"
|
||||
>
|
||||
<g>
|
||||
<path
|
||||
d="M64 9.75A54.25 54.25 0 0 0 9.75 64H0a64 64 0 0 1 128 0h-9.75A54.25 54.25 0 0 0 64 9.75z"
|
||||
></path>
|
||||
<animateTransform
|
||||
attributeName="transform"
|
||||
type="rotate"
|
||||
from="0 64 64"
|
||||
to="360 64 64"
|
||||
dur="1400ms"
|
||||
repeatCount="indefinite"
|
||||
></animateTransform>
|
||||
</g>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Анімація оновлення сторінки свайпом -->
|
||||
<div id="swipe_updater">
|
||||
<div id="swipe_block">
|
||||
<svg
|
||||
id="swipe_icon"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 448 512"
|
||||
data-state="active"
|
||||
>
|
||||
<path
|
||||
d="M413.1 222.5l22.2 22.2c9.4 9.4 9.4 24.6 0 33.9L241 473c-9.4 9.4-24.6 9.4-33.9 0L12.7 278.6c-9.4-9.4-9.4-24.6 0-33.9l22.2-22.2c9.5-9.5 25-9.3 34.3.4L184 343.4V56c0-13.3 10.7-24 24-24h32c13.3 0 24 10.7 24 24v287.4l114.8-120.5c9.3-9.8 24.8-10 34.3-.4z"
|
||||
></path>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Меню застосунку -->
|
||||
<div id="navigation">
|
||||
<nav>
|
||||
<li>
|
||||
<div id="nav-home">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
||||
<path
|
||||
d="M9 2H4C2.897 2 2 2.897 2 4v7c0 1.103.897 2 2 2h5c1.103 0 2-.897 2-2V4C11 2.897 10.103 2 9 2zM20 2h-5c-1.103 0-2 .897-2 2v3c0 1.103.897 2 2 2h5c1.103 0 2-.897 2-2V4C22 2.897 21.103 2 20 2zM9 15H4c-1.103 0-2 .897-2 2v3c0 1.103.897 2 2 2h5c1.103 0 2-.897 2-2v-3C11 15.897 10.103 15 9 15zM20 11h-5c-1.103 0-2 .897-2 2v7c0 1.103.897 2 2 2h5c1.103 0 2-.897 2-2v-7C22 11.897 21.103 11 20 11z"
|
||||
/>
|
||||
</svg>
|
||||
<b>Головна</b>
|
||||
</div>
|
||||
<a href="/" data-route></a>
|
||||
</li>
|
||||
<li id="li-territory" style="display: none;">
|
||||
<div id="nav-territory">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 30 30">
|
||||
<path
|
||||
d="M24 2H14c-.55 0-1 .45-1 1v4l3.6 2.7c.25.19.4.49.4.8V14h8V3C25 2.45 24.55 2 24 2zM15.5 7C15.22 7 15 6.78 15 6.5v-2C15 4.22 15.22 4 15.5 4h2C17.78 4 18 4.22 18 4.5v2C18 6.78 17.78 7 17.5 7h-1.17H15.5zM23 4.5v2C23 6.78 22.78 7 22.5 7h-2C20.22 7 20 6.78 20 6.5v-2C20 4.22 20.22 4 20.5 4h2C22.78 4 23 4.22 23 4.5zM22.5 12h-2c-.28 0-.5-.22-.5-.5v-2C20 9.22 20.22 9 20.5 9h2C22.78 9 23 9.22 23 9.5v2C23 11.78 22.78 12 22.5 12zM1 11.51V27c0 .55.45 1 1 1h12c.55 0 1-.45 1-1V11.51c0-.32-.16-.62-.42-.81l-6-4.28C8.41 6.29 8.2 6.23 8 6.23S7.59 6.29 7.42 6.42l-6 4.28C1.16 10.89 1 11.19 1 11.51zM6.5 20h-2C4.22 20 4 19.78 4 19.5v-2C4 17.22 4.22 17 4.5 17h2C6.78 17 7 17.22 7 17.5v2C7 19.78 6.78 20 6.5 20zM7 22.5v2C7 24.78 6.78 25 6.5 25h-2C4.22 25 4 24.78 4 24.5v-2C4 22.22 4.22 22 4.5 22h2C6.78 22 7 22.22 7 22.5zM6.5 15h-2C4.22 15 4 14.78 4 14.5v-2C4 12.22 4.22 12 4.5 12h2C6.78 12 7 12.22 7 12.5v2C7 14.78 6.78 15 6.5 15zM9.5 17h2c.28 0 .5.22.5.5v2c0 .28-.22.5-.5.5h-2C9.22 20 9 19.78 9 19.5v-2C9 17.22 9.22 17 9.5 17zM9 14.5v-2C9 12.22 9.22 12 9.5 12h2c.28 0 .5.22.5.5v2c0 .28-.22.5-.5.5h-2C9.22 15 9 14.78 9 14.5zM9.5 22h2c.28 0 .5.22.5.5v2c0 .28-.22.5-.5.5h-2C9.22 25 9 24.78 9 24.5v-2C9 22.22 9.22 22 9.5 22zM17 17v10c0 .55.45 1 1 1h10c.55 0 1-.45 1-1V17c0-.55-.45-1-1-1H18C17.45 16 17 16.45 17 17zM19.5 18h2c.28 0 .5.22.5.5v2c0 .28-.22.5-.5.5h-2c-.28 0-.5-.22-.5-.5v-2C19 18.22 19.22 18 19.5 18zM27 18.5v2c0 .28-.22.5-.5.5h-2c-.28 0-.5-.22-.5-.5v-2c0-.28.22-.5.5-.5h2C26.78 18 27 18.22 27 18.5zM26.5 26h-2c-.28 0-.5-.22-.5-.5v-2c0-.28.22-.5.5-.5h2c.28 0 .5.22.5.5v2C27 25.78 26.78 26 26.5 26zM19.5 23h2c.28 0 .5.22.5.5v2c0 .28-.22.5-.5.5h-2c-.28 0-.5-.22-.5-.5v-2C19 23.22 19.22 23 19.5 23z"
|
||||
/>
|
||||
</svg>
|
||||
<b>Території</b>
|
||||
</div>
|
||||
<a href="/territory" data-route></a>
|
||||
</li>
|
||||
<li id="li-sheeps" style="display: none;">
|
||||
<div id="nav-sheeps">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
|
||||
<path
|
||||
d="M 42.5 14 C 37.813 14 34 18.038 34 23 C 34 27.962 37.813 32 42.5 32 C 47.187 32 51 27.962 51 23 C 51 18.038 47.187 14 42.5 14 z M 21.5 17 C 16.813 17 13 21.038 13 26 C 13 30.962 16.813 35 21.5 35 C 26.187 35 30 30.962 30 26 C 30 21.038 26.187 17 21.5 17 z M 42.5 18 C 44.981 18 47 20.243 47 23 C 47 25.757 44.981 28 42.5 28 C 40.019 28 38 25.757 38 23 C 38 20.243 40.019 18 42.5 18 z M 42.498047 34.136719 C 37.579021 34.136719 33.07724 35.947963 30.054688 38.962891 C 27.67058 37.796576 24.915421 37.136719 22 37.136719 C 14.956 37.136719 8.8129375 40.942422 6.7109375 46.607422 C 5.7409375 49.220422 7.7121406 52 10.494141 52 L 33.505859 52 C 35.43112 52 36.95694 50.674804 37.404297 49 L 53.431641 49 C 56.437641 49 59.121453 45.844281 57.564453 42.613281 C 55.084453 37.463281 49.169047 34.136719 42.498047 34.136719 z M 42.5 38.136719 C 47.565 38.136719 52.171937 40.633609 53.960938 44.349609 C 54.119938 44.687609 53.741687 45 53.429688 45 L 36.544922 45 C 35.777257 43.585465 34.746773 42.317451 33.503906 41.234375 C 35.78496 39.306575 39.034912 38.136719 42.5 38.136719 z"
|
||||
/>
|
||||
</svg>
|
||||
<b>Вісники</b>
|
||||
</div>
|
||||
<a href="/sheeps" data-route></a>
|
||||
</li>
|
||||
<li id="li-schedule" style="display: none;">
|
||||
<div id="nav-schedule">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
|
||||
<path
|
||||
d="M47 23c3.314 0 6 2.686 6 6v17c0 3.309-2.691 6-6 6H17c-3.309 0-6-2.691-6-6V29c0-3.314 2.686-6 6-6H47zM22 45v-2c0-.552-.448-1-1-1h-2c-.552 0-1 .448-1 1v2c0 .552.448 1 1 1h2C21.552 46 22 45.552 22 45zM22 38v-2c0-.552-.448-1-1-1h-2c-.552 0-1 .448-1 1v2c0 .552.448 1 1 1h2C21.552 39 22 38.552 22 38zM30 45v-2c0-.552-.448-1-1-1h-2c-.552 0-1 .448-1 1v2c0 .552.448 1 1 1h2C29.552 46 30 45.552 30 45zM30 38v-2c0-.552-.448-1-1-1h-2c-.552 0-1 .448-1 1v2c0 .552.448 1 1 1h2C29.552 39 30 38.552 30 38zM30 31v-2c0-.552-.448-1-1-1h-2c-.552 0-1 .448-1 1v2c0 .552.448 1 1 1h2C29.552 32 30 31.552 30 31zM38 45v-2c0-.552-.448-1-1-1h-2c-.552 0-1 .448-1 1v2c0 .552.448 1 1 1h2C37.552 46 38 45.552 38 45zM38 38v-2c0-.552-.448-1-1-1h-2c-.552 0-1 .448-1 1v2c0 .552.448 1 1 1h2C37.552 39 38 38.552 38 38zM38 31v-2c0-.552-.448-1-1-1h-2c-.552 0-1 .448-1 1v2c0 .552.448 1 1 1h2C37.552 32 38 31.552 38 31zM46 38v-2c0-.552-.448-1-1-1h-2c-.552 0-1 .448-1 1v2c0 .552.448 1 1 1h2C45.552 39 46 38.552 46 38zM46 31v-2c0-.552-.448-1-1-1h-2c-.552 0-1 .448-1 1v2c0 .552.448 1 1 1h2C45.552 32 46 31.552 46 31zM17 20c-2.308 0-4.407.876-6 2.305V18c0-3.309 2.691-6 6-6h30c3.309 0 6 2.691 6 6v4.305C51.407 20.876 49.308 20 47 20H17z"
|
||||
/>
|
||||
</svg>
|
||||
<b>Графік зібрань</b>
|
||||
</div>
|
||||
<a href="/schedule" data-route></a>
|
||||
</li>
|
||||
<li id="li-stand" style="display: none;">
|
||||
<div id="nav-stand">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 30 30">
|
||||
<path
|
||||
d="M 6.9707031 4 C 6.8307031 4 6.6807813 4.039375 6.5507812 4.109375 L 2.5507812 6.109375 C 2.0607813 6.349375 1.859375 6.9492188 2.109375 7.4492188 C 2.349375 7.9392188 2.9492187 8.140625 3.4492188 7.890625 L 6.4902344 6.3691406 L 12.5 20.650391 C 12.73 21.180391 13.040156 21.650547 13.410156 22.060547 C 12.040156 22.340547 11 23.56 11 25 C 11 26.65 12.35 28 14 28 C 15.65 28 17 26.65 17 25 C 17 24.52 16.869922 24.070156 16.669922 23.660156 C 17.479922 23.740156 18.319141 23.639062 19.119141 23.289062 L 26.400391 20.099609 C 26.910391 19.889609 27.159219 19.310781 26.949219 18.800781 C 26.749219 18.290781 26.160391 18.040234 25.650391 18.240234 C 25.630391 18.250234 25.619609 18.259531 25.599609 18.269531 L 18.320312 21.460938 C 16.770312 22.130938 14.999609 21.429141 14.349609 19.869141 L 7.9199219 4.609375 C 7.7599219 4.229375 7.3807031 3.99 6.9707031 4 z M 21.359375 8.0605469 C 21.229375 8.0605469 21.100703 8.090625 20.970703 8.140625 L 13.609375 11.269531 C 13.099375 11.479531 12.860078 12.070078 13.080078 12.580078 L 16.029297 19.179688 C 16.249297 19.689688 16.829844 19.930937 17.339844 19.710938 L 24.710938 16.589844 C 25.210938 16.369844 25.450234 15.789297 25.240234 15.279297 L 22.279297 8.6699219 C 22.119297 8.2899219 21.749375 8.0605469 21.359375 8.0605469 z M 14 24 C 14.56 24 15 24.44 15 25 C 15 25.56 14.56 26 14 26 C 13.44 26 13 25.56 13 25 C 13 24.44 13.44 24 14 24 z"
|
||||
/>
|
||||
</svg>
|
||||
<b>Графік стенду</b>
|
||||
</div>
|
||||
<a href="/stand" data-route></a>
|
||||
</li>
|
||||
<li>
|
||||
<div id="nav-options">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 172 172">
|
||||
<path
|
||||
d="M75.18001,14.33333c-3.43283,0 -6.36736,2.42659 -7.02669,5.79492l-2.39355,12.28971c-5.8821,2.22427 -11.32102,5.33176 -16.097,9.25228l-11.78581,-4.05924c-3.2465,-1.118 -6.81841,0.22441 -8.53841,3.19141l-10.80599,18.72852c-1.71283,2.97417 -1.08945,6.74999 1.49772,9.00033l9.44824,8.21647c-0.49137,3.0197 -0.81185,6.09382 -0.81185,9.25228c0,3.15846 0.32048,6.23258 0.81185,9.25228l-9.44824,8.21647c-2.58717,2.25033 -3.21055,6.02616 -1.49772,9.00032l10.80599,18.72852c1.71283,2.97417 5.29191,4.31623 8.53841,3.2054l11.78581,-4.05924c4.77441,3.91806 10.21756,7.01501 16.097,9.23828l2.39355,12.28972c0.65933,3.36833 3.59386,5.79492 7.02669,5.79492h21.63998c3.43283,0 6.36735,-2.42659 7.02669,-5.79492l2.39356,-12.28972c5.88211,-2.22427 11.32102,-5.33176 16.097,-9.25227l11.78581,4.05924c3.2465,1.118 6.81841,-0.21724 8.53841,-3.1914l10.80599,-18.74252c1.71284,-2.97417 1.08945,-6.73599 -1.49772,-8.98633l-9.44824,-8.21647c0.49137,-3.0197 0.81185,-6.09382 0.81185,-9.25228c0,-3.15846 -0.32048,-6.23258 -0.81185,-9.25228l9.44824,-8.21647c2.58717,-2.25033 3.21056,-6.02616 1.49772,-9.00033l-10.80599,-18.72852c-1.71283,-2.97417 -5.29191,-4.31624 -8.53841,-3.2054l-11.78581,4.05924c-4.7744,-3.91806 -10.21755,-7.01501 -16.097,-9.23828l-2.39356,-12.28971c-0.65933,-3.36833 -3.59385,-5.79492 -7.02669,-5.79492zM86,57.33333c15.83117,0 28.66667,12.8355 28.66667,28.66667c0,15.83117 -12.8355,28.66667 -28.66667,28.66667c-15.83117,0 -28.66667,-12.8355 -28.66667,-28.66667c0,-15.83117 12.8355,-28.66667 28.66667,-28.66667z"
|
||||
></path>
|
||||
</svg>
|
||||
<b>Опції</b>
|
||||
</div>
|
||||
<a href="/options" data-route></a>
|
||||
</li>
|
||||
</nav>
|
||||
</div>
|
||||
|
||||
<!-- Блок контенту застосунка -->
|
||||
<div id="app"></div>
|
||||
</body>
|
||||
</html>
|
||||
303
web/js/app.js
Normal file
@@ -0,0 +1,303 @@
|
||||
let socket, username;
|
||||
|
||||
let listEntrances = []
|
||||
let listApartment = []
|
||||
|
||||
let statusD = document.getElementById("status");
|
||||
let hashD = document.getElementById("hash");
|
||||
|
||||
const urlParams = new URLSearchParams(window.location.search);
|
||||
const share_hash = urlParams.get('share_hash');
|
||||
|
||||
let house = urlParams.get('id') ?? 81;
|
||||
let entrance = 1;
|
||||
let group_number = 1;
|
||||
|
||||
const api = "https://sheep-service.com";
|
||||
const wss = "wss://sheep-service.com/ws";
|
||||
|
||||
// let color_status = [
|
||||
// "#000000",
|
||||
// "#C16917",
|
||||
// "#b10202",
|
||||
// "#3d3d3d",
|
||||
// "#11734b",
|
||||
// "#6cc5fc",
|
||||
// "#5a3286"
|
||||
// ];
|
||||
|
||||
// let color_status = [
|
||||
// ["#ffffff", "#000000"],
|
||||
// ["#e7af32", "#ffffff"],
|
||||
// ["#fc2a2a", "#ffffff"],
|
||||
// ["#3d3d3d", "#ffffff"],
|
||||
// ["#11a568", "#ffffff"],
|
||||
// ["#6cc5fc", "#ffffff"],
|
||||
// ["#b381eb", "#ffffff"]
|
||||
// ];
|
||||
|
||||
let color_status = [
|
||||
["#ffffff", "#eaebef"],
|
||||
["#fbf1e0", "#ff8300"],
|
||||
["#fce3e2", "#ff0000"],
|
||||
["#e2e0e0", "#3d3d3d"],
|
||||
["#d5e9dd", "#11a568"],
|
||||
["#d7ebfa", "#3fb4fc"],
|
||||
["#e8dbf5", "#b381eb"]
|
||||
];
|
||||
|
||||
function makeid(length) {
|
||||
let result = '';
|
||||
const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
||||
const charactersLength = characters.length;
|
||||
let counter = 0;
|
||||
while (counter < length) {
|
||||
result += characters.charAt(Math.floor(Math.random() * charactersLength));
|
||||
counter += 1;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function start(name) {
|
||||
if (!hash) return;
|
||||
|
||||
|
||||
hashD.innerText = `HASH: ${name}`
|
||||
username = name;
|
||||
|
||||
socket = new WebSocket(`${wss}?share_hash=${share_hash}`);
|
||||
|
||||
let user_hash = localStorage.getItem('hash') ?? share_hash;
|
||||
|
||||
socket.onopen = function (e) {
|
||||
console.log("[WebSocket | open] Соединение установлено");
|
||||
statusD.innerText = "WebSocket | open";
|
||||
|
||||
const message = {
|
||||
event: 'connection',
|
||||
id: getTimeInSeconds(),
|
||||
date: getTimeInSeconds(),
|
||||
hash: user_hash,
|
||||
username: name,
|
||||
data: {
|
||||
id: 1,
|
||||
entrance_id: 1,
|
||||
apartment_number: "1",
|
||||
group_number: 1,
|
||||
status: 1,
|
||||
description: "",
|
||||
created_at: 1727541827,
|
||||
updated_at: 1727541827
|
||||
}
|
||||
}
|
||||
|
||||
socket.send(JSON.stringify(message))
|
||||
};
|
||||
|
||||
socket.onmessage = function (event) {
|
||||
let data = JSON.parse(event.data)
|
||||
|
||||
if (data.event == 'connection') {
|
||||
if (data.username == username) return
|
||||
|
||||
console.log(`Добавлен новый пользователь по имени ${data.username}`);
|
||||
} else if (data.event == 'message') {
|
||||
update(data);
|
||||
|
||||
if (data.username == username) return
|
||||
|
||||
console.log(`${data.username} пишет: `, data.data);
|
||||
}
|
||||
};
|
||||
|
||||
socket.onclose = function (event) {
|
||||
if (event.wasClean) {
|
||||
statusD.innerText = "WebSocket | close"
|
||||
console.log(`[WebSocket | close] Соединение закрыто чисто, код=${event.code} причина=${event.reason}`);
|
||||
} else {
|
||||
statusD.innerText = "WebSocket | close"
|
||||
console.log('[WebSocket | close] Соединение прервано');
|
||||
|
||||
// setTimeout(function() {
|
||||
// start(username);
|
||||
// }, 1000);
|
||||
|
||||
const result = confirm(`З'єднання розірвано! Перепідключитись?`);
|
||||
if (result) {
|
||||
getEntrances();
|
||||
start(username);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
socket.onerror = function (error) {
|
||||
console.log(`[WebSocket | error]`);
|
||||
statusD.innerText = "WebSocket | error"
|
||||
};
|
||||
}
|
||||
|
||||
function mess(entrance_number, id, date_type) {
|
||||
console.log(id, listApartment[entrance_number]);
|
||||
|
||||
const pos = listApartment[entrance_number].map(e => e.id).indexOf(id);
|
||||
let apartment = listApartment[entrance_number][pos];
|
||||
|
||||
console.log(pos, apartment);
|
||||
|
||||
|
||||
let status = document.getElementById(`status_${id}`);
|
||||
let description = document.getElementById(`description_${id}`);
|
||||
let date = new Date(document.getElementById(`date_${id}`).value);
|
||||
const timestamp = date.getTime();
|
||||
|
||||
apartment.description = description.value;
|
||||
apartment.status = Number(status.value);
|
||||
apartment.updated_at = date_type ? getTimeInSeconds(timestamp) : getTimeInSeconds(),
|
||||
|
||||
|
||||
status.style.backgroundColor = color_status[status.value][0];
|
||||
status.style.color = color_status[status.value][1];
|
||||
status.style.border = `1px solid ${color_status[status.value][1]}`;
|
||||
|
||||
let user_hash = localStorage.getItem('hash') ?? share_hash;
|
||||
|
||||
let message = {
|
||||
event: 'message',
|
||||
id: getTimeInSeconds(),
|
||||
date: getTimeInSeconds(),
|
||||
hash: user_hash,
|
||||
username: username,
|
||||
data: {
|
||||
id: apartment.id,
|
||||
entrance_id: apartment.entrance_id,
|
||||
apartment_number: apartment.apartment_number,
|
||||
group_number: apartment.group_number,
|
||||
status: apartment.status,
|
||||
description: apartment.description,
|
||||
updated_at: apartment.updated_at,
|
||||
}
|
||||
}
|
||||
|
||||
socket.send(JSON.stringify(message));
|
||||
|
||||
sort(apartment.id, apartment.entrance_id);
|
||||
}
|
||||
|
||||
function update(message) {
|
||||
if (!document.getElementById(`status_${message.data.id}`)) return;
|
||||
|
||||
let now = new Date(message.data.updated_at);
|
||||
now.setMinutes(now.getMinutes() - now.getTimezoneOffset());
|
||||
|
||||
document.getElementById(`status_${message.data.id}`).style.backgroundColor = color_status[message.data.status][0];
|
||||
document.getElementById(`status_${message.data.id}`).style.color = color_status[message.data.status][1];
|
||||
document.getElementById(`status_${message.data.id}`).style.border = `1px solid ${color_status[message.data.status][1]}`;
|
||||
|
||||
document.getElementById(`status_${message.data.id}`).value = message.data.status;
|
||||
document.getElementById(`description_${message.data.id}`).value = message.data.description;
|
||||
document.getElementById(`date_${message.data.id}`).value = now.toISOString().slice(0, 16);
|
||||
}
|
||||
|
||||
function getEntrances(house_id = house) {
|
||||
let url = `${api}/api/house/${house_id}/entrances?share_hash=${share_hash}`;
|
||||
fetch(url)
|
||||
.then(function (response) {
|
||||
return response.json();
|
||||
})
|
||||
.then(function (data) {
|
||||
listEntrances = data;
|
||||
document.getElementById('list').innerHTML = "";
|
||||
|
||||
for (let i = 0; i < listEntrances.length; i++) {
|
||||
const element = listEntrances[i];
|
||||
|
||||
let status = () => {
|
||||
if (element.history.name == "Групова") return '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M 12 1 C 9.1277778 1 6.7189086 3.0461453 6.1230469 5.7871094 L 8.078125 6.2128906 C 8.4822632 4.3538547 10.072222 3 12 3 C 14.27619 3 16 4.7238095 16 7 L 16 8 L 6 8 C 4.9069372 8 4 8.9069372 4 10 L 4 20 C 4 21.093063 4.9069372 22 6 22 L 18 22 C 19.093063 22 20 21.093063 20 20 L 20 10 C 20 8.9069372 19.093063 8 18 8 L 18 7 C 18 3.6761905 15.32381 1 12 1 z M 6 10 L 18 10 L 18 20 L 6 20 L 6 10 z M 12 13 C 10.9 13 10 13.9 10 15 C 10 16.1 10.9 17 12 17 C 13.1 17 14 16.1 14 15 C 14 13.9 13.1 13 12 13 z"/></svg>'
|
||||
else return '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"> <path d="M 12 1 C 8.6761905 1 6 3.6761905 6 7 L 6 8 C 4.9069372 8 4 8.9069372 4 10 L 4 20 C 4 21.093063 4.9069372 22 6 22 L 18 22 C 19.093063 22 20 21.093063 20 20 L 20 10 C 20 8.9069372 19.093063 8 18 8 L 18 7 C 18 3.6761905 15.32381 1 12 1 z M 12 3 C 14.27619 3 16 4.7238095 16 7 L 16 8 L 8 8 L 8 7 C 8 4.7238095 9.7238095 3 12 3 z M 6 10 L 18 10 L 18 20 L 6 20 L 6 10 z M 12 13 C 10.9 13 10 13.9 10 15 C 10 16.1 10.9 17 12 17 C 13.1 17 14 16.1 14 15 C 14 13.9 13.1 13 12 13 z"/></svg>'
|
||||
}
|
||||
|
||||
document.getElementById('list').innerHTML += `
|
||||
<details ${element.history.name == "Групова" ? "open" : "disabled"}>
|
||||
<summary>
|
||||
<p>${element.title}</p>
|
||||
${status()}
|
||||
</summary>
|
||||
<div id="apartments_${element.id}" class="apartments_list">
|
||||
|
||||
</div>
|
||||
</details>
|
||||
`;
|
||||
getApartment(element.id, element.entrance_number);
|
||||
|
||||
console.log(element);
|
||||
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
function getApartment(entrance_id, entrance_number) {
|
||||
let url = `${api}/api/apartment/${entrance_id}?share_hash=${share_hash}`;
|
||||
fetch(url)
|
||||
.then(function (response) {
|
||||
return response.json();
|
||||
})
|
||||
.then(function (data) {
|
||||
listApartment[entrance_number] = data;
|
||||
|
||||
data.sort((a, b) => a.apartment_number - b.apartment_number);
|
||||
|
||||
data.sort((a, b) => a.updated_at - b.updated_at);
|
||||
|
||||
for (let i = 0; i < data.length; i++) {
|
||||
const element = data[i];
|
||||
|
||||
let now = new Date(element.updated_at);
|
||||
now.setMinutes(now.getMinutes() - now.getTimezoneOffset());
|
||||
now = now.toISOString().slice(0, 16)
|
||||
|
||||
document.getElementById(`apartments_${entrance_id}`).innerHTML += `
|
||||
<div id="card_${element.id}">
|
||||
<span>кв.${element.title}</span>
|
||||
<select id="status_${element.id}" onchange="mess(${entrance_number}, ${element.id})" style="background-color: ${color_status[element.status][0]}; color: ${color_status[element.status][1]}; border: 1px solid ${color_status[element.status][1]};" ${element.status == 2 ? "disabled" : ""}>
|
||||
<option value="0" ${element.status == 0 ? "selected" : ""}></option>
|
||||
<option value="1" ${element.status == 1 ? "selected" : ""}>Відмова</option>
|
||||
<option value="2" ${element.status == 2 ? "selected" : ""}>Не заходити (Груба відмова)</option>
|
||||
<option value="3" ${element.status == 3 ? "selected" : ""}>Нема домофона</option>
|
||||
<option value="4" ${element.status == 4 ? "selected" : ""}>Повторна відвідина</option>
|
||||
<option value="5" ${element.status == 5 ? "selected" : ""}>Немає вдома</option>
|
||||
<option value="6" ${element.status == 6 ? "selected" : ""}>Свідки Єгови</option>
|
||||
</select>
|
||||
<input onchange="mess(${entrance_number}, ${element.id})" type="text" name="description" id="description_${element.id}" placeholder="Нотатки..." value="${element.description ?? ""}" ${element.status == 2 ? "disabled" : ""}>
|
||||
<input onchange="mess(${entrance_number}, ${element.id}, true)" type="datetime-local" name="date" id="date_${element.id}" placeholder="Дата" value="${element.updated_at ? now : ""}" ${element.status == 2 ? "disabled" : ""} style="max-width: 170px;">
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
function sort(id, entrance_id) {
|
||||
let child = document.getElementById(`card_${id}`);
|
||||
|
||||
document.getElementById(`apartments_${entrance_id}`).removeChild(child);
|
||||
|
||||
document.getElementById(`apartments_${entrance_id}`).append(child);
|
||||
|
||||
child.style.border = "1px solid var(--PrimaryColor)";
|
||||
}
|
||||
|
||||
function getTimeInSeconds(time = Date.now()) {
|
||||
// Если время больше 10 знаков (это значит, что время в миллисекундах)
|
||||
if (time.toString().length < 10) {
|
||||
// Округляем до секунд, убирая последние 3 цифры (миллисекунды)
|
||||
time = Math.floor(time * 1000);
|
||||
}
|
||||
|
||||
return time;
|
||||
}
|
||||
|
||||
getEntrances();
|
||||
start(makeid(6));
|
||||
|
||||
|
||||
116
web/lib/app.js
Normal file
@@ -0,0 +1,116 @@
|
||||
let USER = {};
|
||||
|
||||
// Определение ID главного блока
|
||||
let app = document.getElementById('app');
|
||||
|
||||
// Конфигурация роутера
|
||||
Router.config({ mode: 'history' });
|
||||
|
||||
async function appReload() {
|
||||
|
||||
location.reload();
|
||||
|
||||
// Router.navigate(window.location.pathname, false).check();
|
||||
|
||||
// // Закрытие старого соединения WebSocket
|
||||
// if (socket) socket.close(1000, "Перезапуск соединения");
|
||||
// listEntrances = []
|
||||
// listApartment = []
|
||||
}
|
||||
|
||||
const Rotation = async () => {
|
||||
const result = confirm(`Ви бажаєте провести ротацію територій між групами?`);
|
||||
|
||||
if (result) {
|
||||
let rotationButton = document.getElementById('rotationButton-title');
|
||||
rotationButton.innerText = "Зачекайте";
|
||||
|
||||
let uuid = localStorage.getItem("uuid");
|
||||
|
||||
const URL = `${CONFIG.api}rotation`;
|
||||
await fetch(URL, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
"Content-Type": "application/json, text/plain, */*",
|
||||
"Authorization": uuid
|
||||
}
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
console.log(data);
|
||||
rotationButton.innerText = 'Ротація завершилась успішно!';
|
||||
|
||||
Territory.house.setHTML();
|
||||
Territory.homestead.setHTML();
|
||||
|
||||
setTimeout(() => {
|
||||
rotationButton.innerText = "Провести ротацію";
|
||||
}, 3000);
|
||||
})
|
||||
.catch(err => {
|
||||
console.log(err);
|
||||
rotationButton.innerText = "Помилка ротації!";
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// Функция загрузки приложения
|
||||
window.addEventListener('load', async function () {
|
||||
console.log('[OS] ', detectOS());
|
||||
if (window.matchMedia('(display-mode: standalone)').matches) {
|
||||
if (detectOS() == 'Android') {
|
||||
document.getElementById('navigation').dataset.state = '';
|
||||
} else if (detectOS() == 'iOS') {
|
||||
document.getElementById('navigation').dataset.state = 'ios';
|
||||
localStorage.setItem('backToTop', 'false');
|
||||
} else if (detectOS() == 'MacOS') {
|
||||
document.getElementById('navigation').dataset.state = 'ios';
|
||||
localStorage.setItem('backToTop', 'false');
|
||||
} else {
|
||||
document.getElementById('navigation').dataset.state = '';
|
||||
}
|
||||
}
|
||||
|
||||
let userInput = () => {
|
||||
let h = prompt("Введіть ваше посилання з UUID:");
|
||||
if (h) {
|
||||
h = h.replace("https://sheep-service.com/?uuid=", "");
|
||||
h = h.replace("https://sheep-service.com?uuid=", "");
|
||||
h = h.replace("https://sheep-service.com?/hash=", "");
|
||||
h = h.replace("https://sheep-service.com?hash=", "");
|
||||
|
||||
localStorage.setItem("uuid", h)
|
||||
return h;
|
||||
}
|
||||
};
|
||||
|
||||
const urlParams = new URLSearchParams(window.location.search);
|
||||
if (urlParams.get('uuid')) {
|
||||
localStorage.setItem("uuid", urlParams.get('uuid'))
|
||||
}
|
||||
if (urlParams.get('hash')) {
|
||||
localStorage.setItem("uuid", urlParams.get('hash'))
|
||||
}
|
||||
|
||||
let uuid = localStorage.getItem("uuid") ? localStorage.getItem("uuid") : userInput();
|
||||
if (uuid) {
|
||||
const URL = `${CONFIG.api}auth`;
|
||||
USER = await fetch(URL, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
"Content-Type": "application/json, text/plain, */*",
|
||||
"Authorization": uuid
|
||||
}
|
||||
}).then((response) => response.json());
|
||||
|
||||
console.log("USER Info: ", USER);
|
||||
|
||||
|
||||
if (USER.administrator.uuid || USER.moderator.uuid) document.getElementById("li-sheeps").style.display = "";
|
||||
if (USER.administrator.uuid || (USER.moderator.uuid && USER.moderator.can_add_schedule)) document.getElementById("li-schedule").style.display = "";
|
||||
if (USER.administrator.uuid || (USER.moderator.uuid && USER.moderator.can_manager_territory)) document.getElementById("li-territory").style.display = "";
|
||||
if (USER.administrator.uuid || USER.can_view_stand) document.getElementById("li-stand").style.display = "";
|
||||
}
|
||||
|
||||
Router.check().listen();
|
||||
});
|
||||
5
web/lib/components/clipboard.js
Normal file
@@ -0,0 +1,5 @@
|
||||
clipboard = (text) => {
|
||||
navigator.clipboard.writeText(text)
|
||||
.then(() => console.log("Текст скопійовано!"))
|
||||
.catch(err => console.error(err))
|
||||
}
|
||||
20
web/lib/components/colorGroup.js
Normal file
@@ -0,0 +1,20 @@
|
||||
let colorGroup = (number) => {
|
||||
switch (number) {
|
||||
case 1:
|
||||
return "#c1ae4d"
|
||||
case 2:
|
||||
return "#93c14d"
|
||||
case 3:
|
||||
return "#4dc1a7"
|
||||
case 4:
|
||||
return "#4d90c1"
|
||||
case 5:
|
||||
return "#654dc1"
|
||||
case 6:
|
||||
return "#c14db7"
|
||||
case 7:
|
||||
return "#c1734d"
|
||||
default:
|
||||
return "#C14D4D"
|
||||
}
|
||||
}
|
||||
35
web/lib/components/detectBrowser.js
Normal file
@@ -0,0 +1,35 @@
|
||||
detectBrowser = () => {
|
||||
const userAgent = navigator.userAgent;
|
||||
let browser = "unkown";
|
||||
// Detect browser name
|
||||
browser = (/ucbrowser/i).test(userAgent) ? 'UCBrowser' : browser;
|
||||
browser = (/edg/i).test(userAgent) ? 'Edge' : browser;
|
||||
browser = (/googlebot/i).test(userAgent) ? 'GoogleBot' : browser;
|
||||
browser = (/chromium/i).test(userAgent) ? 'Chromium' : browser;
|
||||
browser = (/firefox|fxios/i).test(userAgent) && !(/seamonkey/i).test(userAgent) ? 'Firefox' : browser;
|
||||
browser = (/; msie|trident/i).test(userAgent) && !(/ucbrowser/i).test(userAgent) ? 'IE' : browser;
|
||||
browser = (/chrome|crios/i).test(userAgent) && !(/opr|opera|chromium|edg|ucbrowser|googlebot/i).test(userAgent) ? 'Chrome' : browser;;
|
||||
browser = (/safari/i).test(userAgent) && !(/chromium|edg|ucbrowser|chrome|crios|opr|opera|fxios|firefox/i).test(userAgent) ? 'Safari' : browser;
|
||||
browser = (/opr|opera/i).test(userAgent) ? 'Opera' : browser;
|
||||
|
||||
// detect browser version
|
||||
switch (browser) {
|
||||
case 'UCBrowser': return `${browser}/${browserVersion(userAgent,/(ucbrowser)\/([\d\.]+)/i)}`;
|
||||
case 'Edge': return `${browser}/${browserVersion(userAgent,/(edge|edga|edgios|edg)\/([\d\.]+)/i)}`;
|
||||
case 'GoogleBot': return `${browser}/${browserVersion(userAgent,/(googlebot)\/([\d\.]+)/i)}`;
|
||||
case 'Chromium': return `${browser}/${browserVersion(userAgent,/(chromium)\/([\d\.]+)/i)}`;
|
||||
case 'Firefox': return `${browser}/${browserVersion(userAgent,/(firefox|fxios)\/([\d\.]+)/i)}`;
|
||||
case 'Chrome': return `${browser}/${browserVersion(userAgent,/(chrome|crios)\/([\d\.]+)/i)}`;
|
||||
case 'Safari': return `${browser}/${browserVersion(userAgent,/(safari)\/([\d\.]+)/i)}`;
|
||||
case 'Opera': return `${browser}/${browserVersion(userAgent,/(opera|opr)\/([\d\.]+)/i)}`;
|
||||
case 'IE': const version = browserVersion(userAgent,/(trident)\/([\d\.]+)/i);
|
||||
// IE version is mapped using trident version
|
||||
// IE/8.0 = Trident/4.0, IE/9.0 = Trident/5.0
|
||||
return version ? `${browser}/${parseFloat(version) + 4.0}` : `${browser}/7.0`;
|
||||
default: return `unknown/0.0.0.0`;
|
||||
}
|
||||
}
|
||||
|
||||
browserVersion = (userAgent,regex) => {
|
||||
return userAgent.match(regex) ? userAgent.match(regex)[2] : null;
|
||||
}
|
||||
12
web/lib/components/detectOS.js
Normal file
@@ -0,0 +1,12 @@
|
||||
function detectOS() {
|
||||
const platform = navigator.platform.toLowerCase(),
|
||||
iosPlatforms = ['iphone', 'ipad', 'ipod', 'ipod touch'];
|
||||
|
||||
if (platform.includes('mac')) return 'MacOS';
|
||||
if (iosPlatforms.includes(platform)) return 'iOS';
|
||||
if (platform.includes('win')) return 'Windows';
|
||||
if (/android/.test(navigator.userAgent.toLowerCase())) return 'Android';
|
||||
if (/linux/.test(platform)) return 'Linux';
|
||||
|
||||
return 'unknown';
|
||||
}
|
||||
9
web/lib/components/formattedDate.js
Normal file
@@ -0,0 +1,9 @@
|
||||
let formattedDate = (unix_timestamp) => {
|
||||
if(!unix_timestamp) return
|
||||
|
||||
let date = new Date(unix_timestamp);
|
||||
let year = date.getFullYear() >= 10 ? date.getFullYear() : "0" + date.getFullYear();
|
||||
let month = (date.getMonth() + 1) >= 10 ? (date.getMonth() + 1) : "0" + (date.getMonth() + 1);
|
||||
let weekday = date.getDate() >= 10 ? date.getDate() : "0" + date.getDate();
|
||||
return weekday + '.' + month + '.' + year;
|
||||
}
|
||||
283
web/lib/components/geoman/leaflet-geoman.css
Normal file
@@ -0,0 +1,283 @@
|
||||
.marker-icon,
|
||||
.marker-icon:focus {
|
||||
background-color: #ffffff;
|
||||
border: 1px solid #3388ff;
|
||||
border-radius: 50%;
|
||||
margin: -4px 0 0 -4px !important;
|
||||
width: 6px !important;
|
||||
height: 6px !important;
|
||||
outline: 0;
|
||||
transition: opacity ease 0.3s;
|
||||
}
|
||||
|
||||
.marker-icon-middle,
|
||||
.marker-icon-middle:focus {
|
||||
opacity: 0.7;
|
||||
margin: -6px 0 0 -6px !important;
|
||||
width: 10px !important;
|
||||
height: 10px !important;
|
||||
}
|
||||
|
||||
.leaflet-pm-draggable {
|
||||
cursor: move !important;
|
||||
}
|
||||
|
||||
.cursor-marker {
|
||||
cursor: crosshair;
|
||||
pointer-events: none;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.cursor-marker.visible {
|
||||
opacity: 1 !important;
|
||||
}
|
||||
|
||||
.leaflet-pm-invalid {
|
||||
stroke: red;
|
||||
transition: fill ease 0s, stroke ease 0s;
|
||||
}
|
||||
|
||||
.rect-style-marker,
|
||||
.rect-start-marker {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.rect-style-marker.visible,
|
||||
.rect-start-marker.visible {
|
||||
opacity: 1 !important;
|
||||
}
|
||||
|
||||
.vertexmarker-disabled {
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
.pm-text-marker {
|
||||
width: 0;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
.pm-textarea {
|
||||
background-color: #fff;
|
||||
color: #000;
|
||||
resize: none;
|
||||
border: none;
|
||||
outline: 0;
|
||||
cursor: pointer;
|
||||
border-radius: 3px;
|
||||
padding-left: 7px;
|
||||
padding-bottom: 0;
|
||||
padding-top: 4px;
|
||||
}
|
||||
|
||||
.leaflet-pm-draggable .pm-textarea {
|
||||
cursor: move;
|
||||
}
|
||||
|
||||
.pm-textarea:focus,
|
||||
.pm-textarea:focus-within,
|
||||
.pm-textarea:focus-visible,
|
||||
.pm-textarea:active {
|
||||
border: 2px solid #000;
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
.pm-textarea.pm-disabled {
|
||||
border: none;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.pm-textarea.pm-hasfocus {
|
||||
cursor: auto;
|
||||
}
|
||||
|
||||
.leaflet-pm-toolbar {
|
||||
}
|
||||
|
||||
.leaflet-pm-toolbar .leaflet-buttons-control-button {
|
||||
padding: 5px;
|
||||
box-sizing: border-box;
|
||||
position: relative;
|
||||
z-index: 3;
|
||||
}
|
||||
|
||||
.leaflet-pm-toolbar
|
||||
.leaflet-pm-actions-container
|
||||
a.leaflet-pm-action:first-child:not(.pos-right),
|
||||
.leaflet-pm-toolbar
|
||||
.leaflet-pm-actions-container
|
||||
a.leaflet-pm-action:last-child.pos-right {
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
.leaflet-pm-toolbar .button-container a.leaflet-buttons-control-button {
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
.leaflet-pm-toolbar
|
||||
.button-container:last-child
|
||||
a.leaflet-buttons-control-button {
|
||||
border-radius: 0 0 2px 2px;
|
||||
}
|
||||
|
||||
.leaflet-pm-toolbar
|
||||
.button-container:first-child
|
||||
a.leaflet-buttons-control-button {
|
||||
border-radius: 2px 2px 0 0;
|
||||
}
|
||||
|
||||
.leaflet-pm-toolbar
|
||||
.button-container:last-child
|
||||
a.leaflet-buttons-control-button {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.leaflet-pm-toolbar .control-fa-icon {
|
||||
font-size: 19px;
|
||||
line-height: 24px;
|
||||
}
|
||||
|
||||
.leaflet-pm-toolbar .control-icon {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
box-sizing: border-box;
|
||||
background-size: contain;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center center;
|
||||
}
|
||||
|
||||
.leaflet-pm-toolbar .leaflet-pm-icon-marker {
|
||||
background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB3aWR0aD0iMjRweCIgaGVpZ2h0PSIyNHB4IiB2aWV3Qm94PSIwIDAgMjQgMjQiIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+CiAgICA8IS0tIEdlbmVyYXRvcjogU2tldGNoIDUyLjUgKDY3NDY5KSAtIGh0dHA6Ly93d3cuYm9oZW1pYW5jb2RpbmcuY29tL3NrZXRjaCAtLT4KICAgIDx0aXRsZT5BdG9tcy9JY29ucy9Ub29scy9NYXJrZXI8L3RpdGxlPgogICAgPGRlc2M+Q3JlYXRlZCB3aXRoIFNrZXRjaC48L2Rlc2M+CiAgICA8ZGVmcz4KICAgICAgICA8cGF0aCBkPSJNMTUuNSwyNC44NzgyOTU5IEMxNS4yOTA5MjAxLDI0Ljg3NzIyMTkgMTUuMTc0NDg1NywyNC44NDY3ODE3IDE0LjY1OTA4NjYsMjQuMjM1NDE2MyBDMTAuMjE5Njk1NSwxOS40MTE4MDU0IDgsMTUuNTAxNDM5MiA4LDEyLjUwNDMxNzcgQzgsOC4zNTk3OTc0NiAxMS4zNTc4NjQ0LDUgMTUuNSw1IEMxOS42NDIxMzU2LDUgMjMsOC4zNTk3OTc0NiAyMywxMi41MDQzMTc3IEMyMywxNyAxOC4yODc4MjE3LDIxLjkyNjgzNzggMTYuMzMzNjYwMSwyNC4yNDQwMTg2IEMxNS44MjI0NjIyLDI0Ljg1MDE4MDIgMTUuNzA5MDc5OSwyNC44NzkzNjk5IDE1LjUsMjQuODc4Mjk1OSBaIE0xNS41LDE1LjUzMjY5NDggQzE3LjI3NTIwMSwxNS41MzI2OTQ4IDE4LjcxNDI4NTcsMTQuMTE4MDAwNCAxOC43MTQyODU3LDEyLjM3Mjg4NjQgQzE4LjcxNDI4NTcsMTAuNjI3NzcyMyAxNy4yNzUyMDEsOS4yMTMwNzc5MiAxNS41LDkuMjEzMDc3OTIgQzEzLjcyNDc5OSw5LjIxMzA3NzkyIDEyLjI4NTcxNDMsMTAuNjI3NzcyMyAxMi4yODU3MTQzLDEyLjM3Mjg4NjQgQzEyLjI4NTcxNDMsMTQuMTE4MDAwNCAxMy43MjQ3OTksMTUuNTMyNjk0OCAxNS41LDE1LjUzMjY5NDggWiIgaWQ9InBhdGgtMSI+PC9wYXRoPgogICAgPC9kZWZzPgogICAgPGcgaWQ9IlN5bWJvbHMiIHN0cm9rZT0ibm9uZSIgc3Ryb2tlLXdpZHRoPSIxIiBmaWxsPSJub25lIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiPgogICAgICAgIDxnIGlkPSJBdG9tcy9JY29ucy9Ub29scy9NYXJrZXIiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0zLjAwMDAwMCwgLTMuMDAwMDAwKSI+CiAgICAgICAgICAgIDxtYXNrIGlkPSJtYXNrLTIiIGZpbGw9IndoaXRlIj4KICAgICAgICAgICAgICAgIDx1c2UgeGxpbms6aHJlZj0iI3BhdGgtMSI+PC91c2U+CiAgICAgICAgICAgIDwvbWFzaz4KICAgICAgICAgICAgPHVzZSBpZD0iTWFzayIgZmlsbD0iIzVCNUI1QiIgZmlsbC1ydWxlPSJub256ZXJvIiB4bGluazpocmVmPSIjcGF0aC0xIj48L3VzZT4KICAgICAgICA8L2c+CiAgICA8L2c+Cjwvc3ZnPg==);
|
||||
}
|
||||
.leaflet-pm-toolbar .leaflet-pm-icon-polygon {
|
||||
background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCI+CiAgPGRlZnM+CiAgICA8cGF0aCBpZD0icG9seWdvbi1hIiBkPSJNMTkuNDIwNjg5Miw5LjE2NTA5NzI1IEMxOS4xNTIzNjgxLDguNjY5OTI5MTQgMTksOC4xMDI3NTgzMSAxOSw3LjUgQzE5LDUuNTY3MDAzMzggMjAuNTY3MDAzNCw0IDIyLjUsNCBDMjQuNDMyOTk2Niw0IDI2LDUuNTY3MDAzMzggMjYsNy41IEMyNiw5LjI2MzIzNTk1IDI0LjY5NjE0NzEsMTAuNzIxOTQwNyAyMywxMC45NjQ1NTU2IEwyMywxOS4wMzU0NDQ0IEMyNC42OTYxNDcxLDE5LjI3ODA1OTMgMjYsMjAuNzM2NzY0IDI2LDIyLjUgQzI2LDI0LjQzMjk5NjYgMjQuNDMyOTk2NiwyNiAyMi41LDI2IEMyMC43MzY3NjQsMjYgMTkuMjc4MDU5MywyNC42OTYxNDcxIDE5LjAzNTQ0NDQsMjMgTDEwLjk2NDU1NTYsMjMgQzEwLjcyMTk0MDcsMjQuNjk2MTQ3MSA5LjI2MzIzNTk1LDI2IDcuNSwyNiBDNS41NjcwMDMzOCwyNiA0LDI0LjQzMjk5NjYgNCwyMi41IEM0LDIwLjU2NzAwMzQgNS41NjcwMDMzOCwxOSA3LjUsMTkgQzguMTAyNzU4MzEsMTkgOC42Njk5MjkxNCwxOS4xNTIzNjgxIDkuMTY1MDk3MjUsMTkuNDIwNjg5MiBMMTkuNDIwNjg5Miw5LjE2NTA5NzI1IFogTTIwLjgzNDkwNzMsMTAuNTc5MzA2MyBMMTAuNTc5MzEwOCwyMC44MzQ5MDI3IEMxMC42MDg2NzMxLDIwLjg4OTA4ODggMTAuNjM2NjQ2OSwyMC45NDQxMzcyIDEwLjY2MzE4NDQsMjEgTDE5LjMzNjgxNTYsMjEgQzE5LjY4MjU3NzUsMjAuMjcyMTU0IDIwLjI3MjE1NCwxOS42ODI1Nzc1IDIxLDE5LjMzNjgxNTYgTDIxLDEwLjY2MzE4NDQgQzIwLjk0NDEzNzIsMTAuNjM2NjQ2OSAyMC44ODkwODg4LDEwLjYwODY3MzEgMjAuODM0OTAyNywxMC41NzkzMTA4IFogTTIyLjUsOSBDMjMuMzI4NDI3MSw5IDI0LDguMzI4NDI3MTIgMjQsNy41IEMyNCw2LjY3MTU3Mjg4IDIzLjMyODQyNzEsNiAyMi41LDYgQzIxLjY3MTU3MjksNiAyMSw2LjY3MTU3Mjg4IDIxLDcuNSBDMjEsOC4zMjg0MjcxMiAyMS42NzE1NzI5LDkgMjIuNSw5IFogTTIyLjUsMjQgQzIzLjMyODQyNzEsMjQgMjQsMjMuMzI4NDI3MSAyNCwyMi41IEMyNCwyMS42NzE1NzI5IDIzLjMyODQyNzEsMjEgMjIuNSwyMSBDMjEuNjcxNTcyOSwyMSAyMSwyMS42NzE1NzI5IDIxLDIyLjUgQzIxLDIzLjMyODQyNzEgMjEuNjcxNTcyOSwyNCAyMi41LDI0IFogTTcuNSwyNCBDOC4zMjg0MjcxMiwyNCA5LDIzLjMyODQyNzEgOSwyMi41IEM5LDIxLjY3MTU3MjkgOC4zMjg0MjcxMiwyMSA3LjUsMjEgQzYuNjcxNTcyODgsMjEgNiwyMS42NzE1NzI5IDYsMjIuNSBDNiwyMy4zMjg0MjcxIDYuNjcxNTcyODgsMjQgNy41LDI0IFoiLz4KICA8L2RlZnM+CiAgPGcgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMyAtMykiPgogICAgPG1hc2sgaWQ9InBvbHlnb24tYiIgZmlsbD0iI2ZmZiI+CiAgICAgIDx1c2UgeGxpbms6aHJlZj0iI3BvbHlnb24tYSIvPgogICAgPC9tYXNrPgogICAgPHVzZSBmaWxsPSIjNUI1QjVCIiBmaWxsLXJ1bGU9Im5vbnplcm8iIHhsaW5rOmhyZWY9IiNwb2x5Z29uLWEiLz4KICAgIDxnIGZpbGw9IiM1QjVCNUIiIG1hc2s9InVybCgjcG9seWdvbi1iKSI+CiAgICAgIDxyZWN0IHdpZHRoPSIzMCIgaGVpZ2h0PSIzMCIvPgogICAgPC9nPgogIDwvZz4KPC9zdmc+Cg==);
|
||||
}
|
||||
.leaflet-pm-toolbar .leaflet-pm-icon-polyline {
|
||||
background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCI+CiAgPGRlZnM+CiAgICA8cGF0aCBpZD0ibGluZS1hIiBkPSJNOS4xNjUwOTcyNSwxOS40MjA2ODkyIEwxOC40MjA2ODkyLDEwLjE2NTA5NzMgQzE4LjE1MjM2ODEsOS42Njk5MjkxNCAxOCw5LjEwMjc1ODMxIDE4LDguNSBDMTgsNi41NjcwMDMzOCAxOS41NjcwMDM0LDUgMjEuNSw1IEMyMy40MzI5OTY2LDUgMjUsNi41NjcwMDMzOCAyNSw4LjUgQzI1LDEwLjQzMjk5NjYgMjMuNDMyOTk2NiwxMiAyMS41LDEyIEMyMC44OTcyNDE3LDEyIDIwLjMzMDA3MDksMTEuODQ3NjMxOSAxOS44MzQ5MDI3LDExLjU3OTMxMDggTDEwLjU3OTMxMDgsMjAuODM0OTAyNyBDMTAuODQ3NjMxOSwyMS4zMzAwNzA5IDExLDIxLjg5NzI0MTcgMTEsMjIuNSBDMTEsMjQuNDMyOTk2NiA5LjQzMjk5NjYyLDI2IDcuNSwyNiBDNS41NjcwMDMzOCwyNiA0LDI0LjQzMjk5NjYgNCwyMi41IEM0LDIwLjU2NzAwMzQgNS41NjcwMDMzOCwxOSA3LjUsMTkgQzguMTAyNzU4MzEsMTkgOC42Njk5MjkxNCwxOS4xNTIzNjgxIDkuMTY1MDk3MjUsMTkuNDIwNjg5MiBaIE0yMS41LDEwIEMyMi4zMjg0MjcxLDEwIDIzLDkuMzI4NDI3MTIgMjMsOC41IEMyMyw3LjY3MTU3Mjg4IDIyLjMyODQyNzEsNyAyMS41LDcgQzIwLjY3MTU3MjksNyAyMCw3LjY3MTU3Mjg4IDIwLDguNSBDMjAsOS4zMjg0MjcxMiAyMC42NzE1NzI5LDEwIDIxLjUsMTAgWiBNNy41LDI0IEM4LjMyODQyNzEyLDI0IDksMjMuMzI4NDI3MSA5LDIyLjUgQzksMjEuNjcxNTcyOSA4LjMyODQyNzEyLDIxIDcuNSwyMSBDNi42NzE1NzI4OCwyMSA2LDIxLjY3MTU3MjkgNiwyMi41IEM2LDIzLjMyODQyNzEgNi42NzE1NzI4OCwyNCA3LjUsMjQgWiIvPgogIDwvZGVmcz4KICA8ZyBmaWxsPSJub25lIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0zIC0zKSI+CiAgICA8bWFzayBpZD0ibGluZS1iIiBmaWxsPSIjZmZmIj4KICAgICAgPHVzZSB4bGluazpocmVmPSIjbGluZS1hIi8+CiAgICA8L21hc2s+CiAgICA8dXNlIGZpbGw9IiM1QjVCNUIiIGZpbGwtcnVsZT0ibm9uemVybyIgeGxpbms6aHJlZj0iI2xpbmUtYSIvPgogICAgPGcgZmlsbD0iIzVCNUI1QiIgbWFzaz0idXJsKCNsaW5lLWIpIj4KICAgICAgPHJlY3Qgd2lkdGg9IjMwIiBoZWlnaHQ9IjMwIi8+CiAgICA8L2c+CiAgPC9nPgo8L3N2Zz4K);
|
||||
}
|
||||
.leaflet-pm-toolbar .leaflet-pm-icon-circle {
|
||||
background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB3aWR0aD0iMjRweCIgaGVpZ2h0PSIyNHB4IiB2aWV3Qm94PSIwIDAgMjQgMjQiIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+CiAgICA8IS0tIEdlbmVyYXRvcjogU2tldGNoIDUyLjUgKDY3NDY5KSAtIGh0dHA6Ly93d3cuYm9oZW1pYW5jb2RpbmcuY29tL3NrZXRjaCAtLT4KICAgIDx0aXRsZT5BdG9tcy9JY29ucy9Ub29scy9DaXJjbGU8L3RpdGxlPgogICAgPGRlc2M+Q3JlYXRlZCB3aXRoIFNrZXRjaC48L2Rlc2M+CiAgICA8ZGVmcz4KICAgICAgICA8cGF0aCBkPSJNMTguMjg5Nzc1MSw2Ljc4NjAyMjc1IEMxOC44OTI0MTMxLDYuMjk0NjQ5ODEgMTkuNjYxNzk3LDYgMjAuNSw2IEMyMi40MzI5OTY2LDYgMjQsNy41NjcwMDMzOCAyNCw5LjUgQzI0LDEwLjMzODIwMyAyMy43MDUzNTAyLDExLjEwNzU4NjkgMjMuMjEzOTc3MiwxMS43MTAyMjQ5IEMyMy43MTk1OTksMTIuODcxMjA1MyAyNCwxNC4xNTI4NTcxIDI0LDE1LjUgQzI0LDIwLjc0NjcwNTEgMTkuNzQ2NzA1MSwyNSAxNC41LDI1IEM5LjI1MzI5NDg4LDI1IDUsMjAuNzQ2NzA1MSA1LDE1LjUgQzUsMTAuMjUzMjk0OSA5LjI1MzI5NDg4LDYgMTQuNSw2IEMxNS44NDcxNDI5LDYgMTcuMTI4Nzk0Nyw2LjI4MDQwMDk4IDE4LjI4OTc3NTEsNi43ODYwMjI3NSBaIE0xNy4xNTA0MjI4LDguNDgxNzU4NiBDMTYuMzI2MzU4MSw4LjE3MDM5MjM2IDE1LjQzMzA3NzcsOCAxNC41LDggQzEwLjM1Nzg2NDQsOCA3LDExLjM1Nzg2NDQgNywxNS41IEM3LDE5LjY0MjEzNTYgMTAuMzU3ODY0NCwyMyAxNC41LDIzIEMxOC42NDIxMzU2LDIzIDIyLDE5LjY0MjEzNTYgMjIsMTUuNSBDMjIsMTQuNTY2OTIyMyAyMS44Mjk2MDc2LDEzLjY3MzY0MTkgMjEuNTE4MjQxNCwxMi44NDk1NzcyIEMyMS4xOTYwMzgzLDEyLjk0NzM5NjggMjAuODU0MTYyMiwxMyAyMC41LDEzIEMxOC41NjcwMDM0LDEzIDE3LDExLjQzMjk5NjYgMTcsOS41IEMxNyw5LjE0NTgzNzc4IDE3LjA1MjYwMzIsOC44MDM5NjE2OSAxNy4xNTA0MjI4LDguNDgxNzU4NiBaIE0xNC41LDE3IEMxMy42NzE1NzI5LDE3IDEzLDE2LjMyODQyNzEgMTMsMTUuNSBDMTMsMTQuNjcxNTcyOSAxMy42NzE1NzI5LDE0IDE0LjUsMTQgQzE1LjMyODQyNzEsMTQgMTYsMTQuNjcxNTcyOSAxNiwxNS41IEMxNiwxNi4zMjg0MjcxIDE1LjMyODQyNzEsMTcgMTQuNSwxNyBaIE0yMC41LDExIEMyMS4zMjg0MjcxLDExIDIyLDEwLjMyODQyNzEgMjIsOS41IEMyMiw4LjY3MTU3Mjg4IDIxLjMyODQyNzEsOCAyMC41LDggQzE5LjY3MTU3MjksOCAxOSw4LjY3MTU3Mjg4IDE5LDkuNSBDMTksMTAuMzI4NDI3MSAxOS42NzE1NzI5LDExIDIwLjUsMTEgWiIgaWQ9InBhdGgtMSI+PC9wYXRoPgogICAgPC9kZWZzPgogICAgPGcgaWQ9IlN5bWJvbHMiIHN0cm9rZT0ibm9uZSIgc3Ryb2tlLXdpZHRoPSIxIiBmaWxsPSJub25lIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiPgogICAgICAgIDxnIGlkPSJBdG9tcy9JY29ucy9Ub29scy9DaXJjbGUiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0zLjAwMDAwMCwgLTMuMDAwMDAwKSI+CiAgICAgICAgICAgIDxtYXNrIGlkPSJtYXNrLTIiIGZpbGw9IndoaXRlIj4KICAgICAgICAgICAgICAgIDx1c2UgeGxpbms6aHJlZj0iI3BhdGgtMSI+PC91c2U+CiAgICAgICAgICAgIDwvbWFzaz4KICAgICAgICAgICAgPHVzZSBpZD0iTWFzayIgZmlsbD0iIzVCNUI1QiIgZmlsbC1ydWxlPSJub256ZXJvIiB4bGluazpocmVmPSIjcGF0aC0xIj48L3VzZT4KICAgICAgICAgICAgPGcgaWQ9IkF0b21zL0NvbG9yL0dyZXkiIG1hc2s9InVybCgjbWFzay0yKSIgZmlsbD0iIzVCNUI1QiI+CiAgICAgICAgICAgICAgICA8cmVjdCBpZD0iUmVjdGFuZ2xlIiB4PSIwIiB5PSIwIiB3aWR0aD0iMzAiIGhlaWdodD0iMzAiPjwvcmVjdD4KICAgICAgICAgICAgPC9nPgogICAgICAgIDwvZz4KICAgIDwvZz4KPC9zdmc+);
|
||||
}
|
||||
.leaflet-pm-toolbar .leaflet-pm-icon-circle-marker {
|
||||
background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KCjxzdmcgdmlld0JveD0iMCAwIDEwMCAxMDAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgc3Ryb2tlPSIjNUI1QjVCIiBzdHJva2Utd2lkdGg9IjgiCiAgICAgZmlsbD0ibm9uZSI+CjxjaXJjbGUgY3g9IjUwIiBjeT0iNTAiIHI9IjM1Ii8+CiAgPGNpcmNsZSBjeD0iNTAiIGN5PSI1MCIgcj0iMyIgZmlsbD0iIzVCNUI1QiIvPgo8L3N2Zz4=);
|
||||
}
|
||||
.leaflet-pm-toolbar .leaflet-pm-icon-rectangle {
|
||||
background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCI+CiAgPGRlZnM+CiAgICA8cGF0aCBpZD0icmVjdGFuZ2xlLWEiIGQ9Ik0yMywxMC45NjQ1NTU2IEwyMywxOS4wMzU0NDQ0IEMyNC42OTYxNDcxLDE5LjI3ODA1OTMgMjYsMjAuNzM2NzY0IDI2LDIyLjUgQzI2LDI0LjQzMjk5NjYgMjQuNDMyOTk2NiwyNiAyMi41LDI2IEMyMC43MzY3NjQsMjYgMTkuMjc4MDU5MywyNC42OTYxNDcxIDE5LjAzNTQ0NDQsMjMgTDEwLjk2NDU1NTYsMjMgQzEwLjcyMTk0MDcsMjQuNjk2MTQ3MSA5LjI2MzIzNTk1LDI2IDcuNSwyNiBDNS41NjcwMDMzOCwyNiA0LDI0LjQzMjk5NjYgNCwyMi41IEM0LDIwLjczNjc2NCA1LjMwMzg1MjkzLDE5LjI3ODA1OTMgNywxOS4wMzU0NDQ0IEw3LDEwLjk2NDU1NTYgQzUuMzAzODUyOTMsMTAuNzIxOTQwNyA0LDkuMjYzMjM1OTUgNCw3LjUgQzQsNS41NjcwMDMzOCA1LjU2NzAwMzM4LDQgNy41LDQgQzkuMjYzMjM1OTUsNCAxMC43MjE5NDA3LDUuMzAzODUyOTMgMTAuOTY0NTU1Niw3IEwxOS4wMzU0NDQ0LDcgQzE5LjI3ODA1OTMsNS4zMDM4NTI5MyAyMC43MzY3NjQsNCAyMi41LDQgQzI0LjQzMjk5NjYsNCAyNiw1LjU2NzAwMzM4IDI2LDcuNSBDMjYsOS4yNjMyMzU5NSAyNC42OTYxNDcxLDEwLjcyMTk0MDcgMjMsMTAuOTY0NTU1NiBaIE0yMSwxMC42NjMxODQ0IEMyMC4yNzIxNTQsMTAuMzE3NDIyNSAxOS42ODI1Nzc1LDkuNzI3ODQ1OTggMTkuMzM2ODE1Niw5IEwxMC42NjMxODQ0LDkgQzEwLjMxNzQyMjUsOS43Mjc4NDU5OCA5LjcyNzg0NTk4LDEwLjMxNzQyMjUgOSwxMC42NjMxODQ0IEw5LDE5LjMzNjgxNTYgQzkuNzI3ODQ1OTgsMTkuNjgyNTc3NSAxMC4zMTc0MjI1LDIwLjI3MjE1NCAxMC42NjMxODQ0LDIxIEwxOS4zMzY4MTU2LDIxIEMxOS42ODI1Nzc1LDIwLjI3MjE1NCAyMC4yNzIxNTQsMTkuNjgyNTc3NSAyMSwxOS4zMzY4MTU2IEwyMSwxMC42NjMxODQ0IFogTTcuNSw5IEM4LjMyODQyNzEyLDkgOSw4LjMyODQyNzEyIDksNy41IEM5LDYuNjcxNTcyODggOC4zMjg0MjcxMiw2IDcuNSw2IEM2LjY3MTU3Mjg4LDYgNiw2LjY3MTU3Mjg4IDYsNy41IEM2LDguMzI4NDI3MTIgNi42NzE1NzI4OCw5IDcuNSw5IFogTTIyLjUsOSBDMjMuMzI4NDI3MSw5IDI0LDguMzI4NDI3MTIgMjQsNy41IEMyNCw2LjY3MTU3Mjg4IDIzLjMyODQyNzEsNiAyMi41LDYgQzIxLjY3MTU3MjksNiAyMSw2LjY3MTU3Mjg4IDIxLDcuNSBDMjEsOC4zMjg0MjcxMiAyMS42NzE1NzI5LDkgMjIuNSw5IFogTTIyLjUsMjQgQzIzLjMyODQyNzEsMjQgMjQsMjMuMzI4NDI3MSAyNCwyMi41IEMyNCwyMS42NzE1NzI5IDIzLjMyODQyNzEsMjEgMjIuNSwyMSBDMjEuNjcxNTcyOSwyMSAyMSwyMS42NzE1NzI5IDIxLDIyLjUgQzIxLDIzLjMyODQyNzEgMjEuNjcxNTcyOSwyNCAyMi41LDI0IFogTTcuNSwyNCBDOC4zMjg0MjcxMiwyNCA5LDIzLjMyODQyNzEgOSwyMi41IEM5LDIxLjY3MTU3MjkgOC4zMjg0MjcxMiwyMSA3LjUsMjEgQzYuNjcxNTcyODgsMjEgNiwyMS42NzE1NzI5IDYsMjIuNSBDNiwyMy4zMjg0MjcxIDYuNjcxNTcyODgsMjQgNy41LDI0IFoiLz4KICA8L2RlZnM+CiAgPGcgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMyAtMykiPgogICAgPG1hc2sgaWQ9InJlY3RhbmdsZS1iIiBmaWxsPSIjZmZmIj4KICAgICAgPHVzZSB4bGluazpocmVmPSIjcmVjdGFuZ2xlLWEiLz4KICAgIDwvbWFzaz4KICAgIDx1c2UgZmlsbD0iIzVCNUI1QiIgZmlsbC1ydWxlPSJub256ZXJvIiB4bGluazpocmVmPSIjcmVjdGFuZ2xlLWEiLz4KICAgIDxnIGZpbGw9IiM1QjVCNUIiIG1hc2s9InVybCgjcmVjdGFuZ2xlLWIpIj4KICAgICAgPHJlY3Qgd2lkdGg9IjMwIiBoZWlnaHQ9IjMwIi8+CiAgICA8L2c+CiAgPC9nPgo8L3N2Zz4K);
|
||||
}
|
||||
.leaflet-pm-toolbar .leaflet-pm-icon-delete {
|
||||
background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB3aWR0aD0iMjRweCIgaGVpZ2h0PSIyNHB4IiB2aWV3Qm94PSIwIDAgMjQgMjQiIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+CiAgICA8IS0tIEdlbmVyYXRvcjogU2tldGNoIDUyLjUgKDY3NDY5KSAtIGh0dHA6Ly93d3cuYm9oZW1pYW5jb2RpbmcuY29tL3NrZXRjaCAtLT4KICAgIDx0aXRsZT5BdG9tcy9JY29ucy9Ub29scy9FcmFzZXI8L3RpdGxlPgogICAgPGRlc2M+Q3JlYXRlZCB3aXRoIFNrZXRjaC48L2Rlc2M+CiAgICA8ZGVmcz4KICAgICAgICA8cGF0aCBkPSJNMTcuNzg3NDIxOSwxOC40ODEyNTUyIEwxMS42NDgwMDc5LDEzLjM0OTgxODQgTDYuNDA0NjYwMDksMTkuMzgxNjAwMSBMMTAuNTUzOTE1NiwyMi45ODg0OTI5IEwxMy44NjkzNCwyMi45ODg0OTI5IEwxNy43ODc0MjE5LDE4LjQ4MTI1NTIgWiBNMTYuNTA3NDI1MiwyMi45ODg0OTI5IEwyNi4wMDAwMDAyLDIyLjk4ODQ5MjkgTDI2LjAwMDAwMDIsMjQuOTg4NDkyOSBMMTAuMDAwMDAwMiwyNC45ODg0OTI5IEw5LjgwNzA4MzEzLDI0Ljk4ODQ5MjkgTDUuMDkyNTQyMDQsMjAuODkxMDE5MiBDNC4yNTg5MTI4NSwyMC4xNjYzNTY0IDQuMTcwNTc4MTQsMTguOTAzMTExMiA0Ljg5NTI0MDkzLDE4LjA2OTQ4MiBMMTYuMDQ4MjQ0NCw1LjIzOTQxOTE2IEMxNi43NzI5MDcyLDQuNDA1Nzg5OTggMTguMDM2MTUyNSw0LjMxNzQ1NTI2IDE4Ljg2OTc4MTYsNS4wNDIxMTgwNiBMMjQuOTA3NDU4MywxMC4yOTA1OTAzIEMyNS43NDEwODc1LDExLjAxNTI1MzEgMjUuODI5NDIyMiwxMi4yNzg0OTgzIDI1LjEwNDc1OTQsMTMuMTEyMTI3NSBMMTYuNTA3NDI1MiwyMi45ODg0OTI5IFoiIGlkPSJwYXRoLTEiPjwvcGF0aD4KICAgIDwvZGVmcz4KICAgIDxnIGlkPSJTeW1ib2xzIiBzdHJva2U9Im5vbmUiIHN0cm9rZS13aWR0aD0iMSIgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIj4KICAgICAgICA8ZyBpZD0iQXRvbXMvSWNvbnMvVG9vbHMvRXJhc2VyIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMy4wMDAwMDAsIC0zLjAwMDAwMCkiPgogICAgICAgICAgICA8bWFzayBpZD0ibWFzay0yIiBmaWxsPSJ3aGl0ZSI+CiAgICAgICAgICAgICAgICA8dXNlIHhsaW5rOmhyZWY9IiNwYXRoLTEiPjwvdXNlPgogICAgICAgICAgICA8L21hc2s+CiAgICAgICAgICAgIDx1c2UgaWQ9IkNvbWJpbmVkLVNoYXBlIiBmaWxsPSIjNUI1QjVCIiBmaWxsLXJ1bGU9Im5vbnplcm8iIHhsaW5rOmhyZWY9IiNwYXRoLTEiPjwvdXNlPgogICAgICAgIDwvZz4KICAgIDwvZz4KPC9zdmc+);
|
||||
}
|
||||
.leaflet-pm-toolbar .leaflet-pm-icon-edit {
|
||||
background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCI+CiAgPGRlZnM+CiAgICA8cGF0aCBpZD0iZWRpdF9hbmNob3ItYSIgZD0iTTEzLjUsMTEgQzExLjU2NzAwMzQsMTEgMTAsOS40MzI5OTY2MiAxMCw3LjUgQzEwLDUuNTY3MDAzMzggMTEuNTY3MDAzNCw0IDEzLjUsNCBDMTUuNDMyOTk2Niw0IDE3LDUuNTY3MDAzMzggMTcsNy41IEMxNyw5LjQzMjk5NjYyIDE1LjQzMjk5NjYsMTEgMTMuNSwxMSBaIE0xMy41LDkgQzE0LjMyODQyNzEsOSAxNSw4LjMyODQyNzEyIDE1LDcuNSBDMTUsNi42NzE1NzI4OCAxNC4zMjg0MjcxLDYgMTMuNSw2IEMxMi42NzE1NzI5LDYgMTIsNi42NzE1NzI4OCAxMiw3LjUgQzEyLDguMzI4NDI3MTIgMTIuNjcxNTcyOSw5IDEzLjUsOSBaIE0xMi4wMDAyODg5LDcuNTI5NzM4OTMgQzEyLjAxMjU5ODMsOC4xNjI3MzY3MiAxMi40MTcwMTk3LDguNjk5NjY0MyAxMi45ODA3MTExLDguOTA3Njc5NjYgTDMsMTUgTDMsMTMgTDEyLjAwMDI4ODksNy41Mjk3Mzg5MyBaIE0xNC4yMTcyNzIyLDYuMTgyMjg0NzIgTDE5LjQ1MzEyNSwzIEwyMi42NTg5MzU1LDMgTDE0Ljk4OTEwMiw3LjY4MTczODg1IEMxNC45OTYyOTcxLDcuNjIyMTY0NTkgMTUsNy41NjE1MTQ3MiAxNSw3LjUgQzE1LDYuOTMxMzgzODEgMTQuNjgzNjA5OCw2LjQzNjY2NDUgMTQuMjE3MjcyMiw2LjE4MjI4NDcyIFogTTIzLjQ0MzQwNDIsMTkuMjg1MTczNiBMMjAuMTI4Mjc5OSwxOS4yODUxNzM2IEwyMS44NzI5OTgzLDIzLjUzNDk1MjUgQzIxLjk5NDUyOTYsMjMuODI5NTc3MyAyMS44NTU2NTQ2LDI0LjE1OTkyMDkgMjEuNTc3ODczNCwyNC4yODQ5MjA4IEwyMC4wNDE0Njc1LDI0Ljk1NDUxNDIgQzE5Ljc1NTA2MTMsMjUuMDc5NTE0MSAxOS40MzM4NzM4LDI0LjkzNjY3MDQgMTkuMzEyMzQyNiwyNC42NTA5NTE4IEwxNy42NTQ0MzY3LDIwLjYxNTQ1NDEgTDE0Ljk0NjE4NzMsMjMuNDAxMDE1MSBDMTQuNTg1MjgxMSwyMy43NzIxNzExIDE0LDIzLjQ4NjA0NjMgMTQsMjIuOTk5MjY1MyBMMTQsOS41NzE4MzUzMyBDMTQsOS4wNTkzMzU2MSAxNC42MjI1MzExLDguODA5NDkyIDE0Ljk0NjE1Niw5LjE3MDA4NTU1IEwyMy44MzQwMjkyLDE4LjMxMjAxNzkgQzI0LjE5MjUyOTEsMTguNjYxMzYxNSAyMy45Mjc5OTc5LDE5LjI4NTE3MzYgMjMuNDQzNDA0MiwxOS4yODUxNzM2IFoiLz4KICA8L2RlZnM+CiAgPGcgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMyAtMykiPgogICAgPG1hc2sgaWQ9ImVkaXRfYW5jaG9yLWIiIGZpbGw9IiNmZmYiPgogICAgICA8dXNlIHhsaW5rOmhyZWY9IiNlZGl0X2FuY2hvci1hIi8+CiAgICA8L21hc2s+CiAgICA8dXNlIGZpbGw9IiM1QjVCNUIiIGZpbGwtcnVsZT0ibm9uemVybyIgeGxpbms6aHJlZj0iI2VkaXRfYW5jaG9yLWEiLz4KICAgIDxnIGZpbGw9IiM1QjVCNUIiIG1hc2s9InVybCgjZWRpdF9hbmNob3ItYikiPgogICAgICA8cmVjdCB3aWR0aD0iMzAiIGhlaWdodD0iMzAiLz4KICAgIDwvZz4KICA8L2c+Cjwvc3ZnPgo=);
|
||||
}
|
||||
.leaflet-pm-toolbar .leaflet-pm-icon-drag {
|
||||
background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCI+CiAgPGRlZnM+CiAgICA8cGF0aCBpZD0ibW92ZS1hIiBkPSJNMjEsMTQgTDIxLDEwIEwyNywxNSBMMjEsMjAgTDIxLDE2IEwxNiwxNiBMMTYsMjEgTDIwLDIxIEwxNSwyNyBMMTAsMjEgTDE0LDIxIEwxNCwxNiBMOSwxNiBMOSwyMCBMMywxNSBMOSwxMCBMOSwxNCBMMTQsMTQgTDE0LDkgTDEwLDkgTDE1LDMgTDIwLDkgTDE2LDkgTDE2LDE0IEwyMSwxNCBaIi8+CiAgPC9kZWZzPgogIDxnIGZpbGw9Im5vbmUiIGZpbGwtcnVsZT0iZXZlbm9kZCIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTMgLTMpIj4KICAgIDxtYXNrIGlkPSJtb3ZlLWIiIGZpbGw9IiNmZmYiPgogICAgICA8dXNlIHhsaW5rOmhyZWY9IiNtb3ZlLWEiLz4KICAgIDwvbWFzaz4KICAgIDx1c2UgZmlsbD0iI0Q4RDhEOCIgeGxpbms6aHJlZj0iI21vdmUtYSIvPgogICAgPGcgZmlsbD0iIzVCNUI1QiIgbWFzaz0idXJsKCNtb3ZlLWIpIj4KICAgICAgPHJlY3Qgd2lkdGg9IjMwIiBoZWlnaHQ9IjMwIi8+CiAgICA8L2c+CiAgPC9nPgo8L3N2Zz4K);
|
||||
}
|
||||
.leaflet-pm-toolbar .leaflet-pm-icon-cut {
|
||||
background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB3aWR0aD0iMjRweCIgaGVpZ2h0PSIyNHB4IiB2aWV3Qm94PSIwIDAgMjQgMjQiIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+CiAgICA8IS0tIEdlbmVyYXRvcjogU2tldGNoIDUyLjUgKDY3NDY5KSAtIGh0dHA6Ly93d3cuYm9oZW1pYW5jb2RpbmcuY29tL3NrZXRjaCAtLT4KICAgIDx0aXRsZT5BdG9tcy9JY29ucy9Ub29scy9TY2lzc29yczwvdGl0bGU+CiAgICA8ZGVzYz5DcmVhdGVkIHdpdGggU2tldGNoLjwvZGVzYz4KICAgIDxkZWZzPgogICAgICAgIDxwYXRoIGQ9Ik0xMi45NjkxNTc0LDEzLjQ5Mzk0MzUgTDIxLjAzMTcwMzIsNS41NDE2NzAxMyBMMjMuNDY0OTQ5OSw1LjY3NzIyOTU3IEwxNy4wNDcwNzEzLDE0LjUxMDY4MTYgTDI3LjU2NjAzMzYsMTcuMTMzMzUzNSBMMjUuNzg5MTk0NCwxOC44MDEyNTg4IEwxNC41ODU0OTUxLDE3Ljg5ODc1MDYgTDEzLjY0ODc5NTUsMTkuMTg4MDA3IEMxMy43OTQ2MzksMTkuMjY1MDk1OCAxMy45MzY3OTg1LDE5LjM1MzQ0MTcgMTQuMDc0MTM3NywxOS40NTMyMjQ1IEMxNS42Mzc5NjQ4LDIwLjU4OTQxMTQgMTUuOTg0NjM1NywyMi43NzgyMDUyIDE0Ljg0ODQ0ODgsMjQuMzQyMDMyNCBDMTMuNzEyMjYxOSwyNS45MDU4NTk1IDExLjUyMzQ2ODEsMjYuMjUyNTMwNCA5Ljk1OTY0MDk2LDI1LjExNjM0MzUgQzguMzk1ODEzODQsMjMuOTgwMTU2NSA4LjA0OTE0Mjk2LDIxLjc5MTM2MjcgOS4xODUzMjk4NiwyMC4yMjc1MzU2IEM5Ljc0NTg3Mjc2LDE5LjQ1NjAxNDUgMTAuNTYyNjE4OCwxOC45ODA3NDc1IDExLjQzNDEyMTgsMTguODMzNjQwNyBMMTIuNjgwNTY1NiwxNy4xMTgwNTc5IEwxMi41MjM5NzI0LDE2LjM3NDcyMTYgTDExLjk1MDY5MzIsMTUuMzAxMjM5MSBMOS44OTMxMDY0NiwxNC43ODgyMjUxIEM5LjEzMDkzNzk2LDE1LjIzNTcyNjEgOC4xOTk3Nzg1NCwxNS4zOTY2NDQ3IDcuMjc0NDUzNTUsMTUuMTY1OTM1MiBDNS4zOTg4NzUxOSwxNC42OTgzMDEgNC4yNTc1MTA5NCwxMi43OTg3NTE5IDQuNzI1MTQ1MTUsMTAuOTIzMTczNiBDNS4xOTI3NzkzNSw5LjA0NzU5NTE5IDcuMDkyMzI4NDYsNy45MDYyMzA5NCA4Ljk2NzkwNjgyLDguMzczODY1MTUgQzEwLjg0MzQ4NTIsOC44NDE0OTkzNSAxMS45ODQ4NDk0LDEwLjc0MTA0ODUgMTEuNTE3MjE1MiwxMi42MTY2MjY4IEMxMS40NzYxNDY0LDEyLjc4MTM0NDkgMTEuNDI0MDMzNSwxMi45NDA0MDAxIDExLjM2MTg2MjcsMTMuMDkzMTk5OSBMMTIuOTY5MTU3NCwxMy40OTM5NDM1IFogTTcuNzU4Mjk3MzUsMTMuMjI1MzQzOCBDOC41NjIxMTY2NCwxMy40MjU3NTg0IDkuMzc2MjA5MTIsMTIuOTM2NjAyMyA5LjU3NjYyMzc4LDEyLjEzMjc4MyBDOS43NzcwMzg0NCwxMS4zMjg5NjM3IDkuMjg3ODgyMzMsMTAuNTE0ODcxMyA4LjQ4NDA2MzAzLDEwLjMxNDQ1NjYgQzcuNjgwMjQzNzMsMTAuMTE0MDQxOSA2Ljg2NjE1MTI2LDEwLjYwMzE5OCA2LjY2NTczNjYsMTEuNDA3MDE3MyBDNi40NjUzMjE5NCwxMi4yMTA4MzY2IDYuOTU0NDc4MDUsMTMuMDI0OTI5MSA3Ljc1ODI5NzM1LDEzLjIyNTM0MzggWiBNMTAuODAzMzYzOSwyMS40MDMxMDYxIEMxMC4zMTY0MjY2LDIyLjA3MzMxNzcgMTAuNDY0OTk5OCwyMy4wMTEzNzIyIDExLjEzNTIxMTUsMjMuNDk4MzA5NSBDMTEuODA1NDIzMSwyMy45ODUyNDY3IDEyLjc0MzQ3NzYsMjMuODM2NjczNSAxMy4yMzA0MTQ4LDIzLjE2NjQ2MTkgQzEzLjcxNzM1MjEsMjIuNDk2MjUwMiAxMy41Njg3Nzg4LDIxLjU1ODE5NTcgMTIuODk4NTY3MiwyMS4wNzEyNTg1IEMxMi4yMjgzNTU2LDIwLjU4NDMyMTIgMTEuMjkwMzAxMSwyMC43MzI4OTQ1IDEwLjgwMzM2MzksMjEuNDAzMTA2MSBaIiBpZD0icGF0aC0xIj48L3BhdGg+CiAgICA8L2RlZnM+CiAgICA8ZyBpZD0iU3ltYm9scyIgc3Ryb2tlPSJub25lIiBzdHJva2Utd2lkdGg9IjEiIGZpbGw9Im5vbmUiIGZpbGwtcnVsZT0iZXZlbm9kZCI+CiAgICAgICAgPGcgaWQ9IkF0b21zL0ljb25zL1Rvb2xzL1NjaXNzb3JzIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMy4wMDAwMDAsIC0zLjAwMDAwMCkiPgogICAgICAgICAgICA8bWFzayBpZD0ibWFzay0yIiBmaWxsPSJ3aGl0ZSI+CiAgICAgICAgICAgICAgICA8dXNlIHhsaW5rOmhyZWY9IiNwYXRoLTEiPjwvdXNlPgogICAgICAgICAgICA8L21hc2s+CiAgICAgICAgICAgIDx1c2UgaWQ9Ik1hc2siIGZpbGw9IiM1QjVCNUIiIGZpbGwtcnVsZT0ibm9uemVybyIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMTYuMDkzMTk0LCAxNS42NjMzNTEpIHJvdGF0ZSgtMzIuMDAwMDAwKSB0cmFuc2xhdGUoLTE2LjA5MzE5NCwgLTE1LjY2MzM1MSkgIiB4bGluazpocmVmPSIjcGF0aC0xIj48L3VzZT4KICAgICAgICA8L2c+CiAgICA8L2c+Cjwvc3ZnPg==);
|
||||
}
|
||||
.leaflet-pm-toolbar .leaflet-pm-icon-snapping {
|
||||
background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB3aWR0aD0iMjRweCIgaGVpZ2h0PSIyNHB4IiB2aWV3Qm94PSIwIDAgMjQgMjQiIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+CiAgICA8IS0tIEdlbmVyYXRvcjogU2tldGNoIDU3LjEgKDgzMDg4KSAtIGh0dHBzOi8vc2tldGNoLmNvbSAtLT4KICAgIDx0aXRsZT5BdG9tcy9JY29ucy9Ub29scy9NYWduZXQ8L3RpdGxlPgogICAgPGRlc2M+Q3JlYXRlZCB3aXRoIFNrZXRjaC48L2Rlc2M+CiAgICA8ZGVmcz4KICAgICAgICA8cGF0aCBkPSJNMjEuOTk5NDc1OSwxMC45NDI4MTgzIEwyMS45OTk5OTg1LDE2LjM3MTA0MTcgQzIyLDE2LjY4NzIwMDcgMjIsMTcuMDA1ODI3OCAyMiwxNy4zMjY5NDExIEMyMiwyMS41NjQ2NTQ1IDE4LjY0MjEzNTYsMjUgMTQuNSwyNSBDMTAuMzU3ODY0NCwyNSA3LDIxLjU2NDY1NDUgNywxNy4zMjY5NDExIEw3LjAwMDg3NTA4LDEwLjk5MDc1MDcgTDExLjAwMjI4MDgsMTAuOTk4NDEyNSBDMTEuMDAxNzAzMywxMS42OTgwMTE0IDExLjAwMTI0NywxMi40MTY4MjQ4IDExLjAwMDg5OTIsMTMuMTU1NDg4NyBMMTEsMTcuMzI2OTQxMSBDMTEsMTkuMzc1NjgwOSAxMi41ODc2ODQxLDIxIDE0LjUsMjEgQzE2LjQxMjMxNTksMjEgMTgsMTkuMzc1NjgwOSAxOCwxNy4zMjY5NDExIEMxOCwxNS4wNzAyMDMyIDE3Ljk5OTU2OTYsMTIuOTYxOTY2OCAxNy45OTg1MzksMTAuOTkxMDAzMiBMMjEuOTk5NDc1OSwxMC45NDI4MTgzIFogTTEwLDcgQzEwLjU1MjI4NDcsNyAxMSw3LjQ0NzcxNTI1IDExLDggTDExLDEwIEw3LDEwIEw3LDggQzcsNy40NDc3MTUyNSA3LjQ0NzcxNTI1LDcgOCw3IEwxMCw3IFogTTIxLDcgQzIxLjU1MjI4NDcsNyAyMiw3LjQ0NzcxNTI1IDIyLDggTDIyLDEwIEwxOCwxMCBMMTgsOCBDMTgsNy40NDc3MTUyNSAxOC40NDc3MTUzLDcgMTksNyBMMjEsNyBaIiBpZD0icGF0aC0xIj48L3BhdGg+CiAgICA8L2RlZnM+CiAgICA8ZyBpZD0iU3ltYm9scyIgc3Ryb2tlPSJub25lIiBzdHJva2Utd2lkdGg9IjEiIGZpbGw9Im5vbmUiIGZpbGwtcnVsZT0iZXZlbm9kZCI+CiAgICAgICAgPGcgaWQ9IkF0b21zL0ljb25zL1Rvb2xzL01hZ25ldCIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTMuMDAwMDAwLCAtMy4wMDAwMDApIj4KICAgICAgICAgICAgPG1hc2sgaWQ9Im1hc2stMiIgZmlsbD0id2hpdGUiPgogICAgICAgICAgICAgICAgPHVzZSB4bGluazpocmVmPSIjcGF0aC0xIj48L3VzZT4KICAgICAgICAgICAgPC9tYXNrPgogICAgICAgICAgICA8dXNlIGlkPSJNYXNrIiBmaWxsPSIjNUI1QjVCIiBmaWxsLXJ1bGU9Im5vbnplcm8iIHRyYW5zZm9ybT0idHJhbnNsYXRlKDE0LjUwMDAwMCwgMTYuMDAwMDAwKSByb3RhdGUoNDUuMDAwMDAwKSB0cmFuc2xhdGUoLTE0LjUwMDAwMCwgLTE2LjAwMDAwMCkgIiB4bGluazpocmVmPSIjcGF0aC0xIj48L3VzZT4KICAgICAgICA8L2c+CiAgICA8L2c+Cjwvc3ZnPg==);
|
||||
}
|
||||
.leaflet-pm-toolbar .leaflet-pm-icon-rotate {
|
||||
background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCI+CiAgICA8ZGVmcz4KICAgICAgICA8cGF0aCBpZD0icm90YXRlIiBkPSJNMjEuMiw1LjhjLTAuMS0wLjItMC4yLTAuMy0wLjMtMC41bC0wLjEtMC4yYy0wLjEtMC4yLTAuMi0wLjMtMC4zLTAuNWwtMC4xLTAuMmMtMC4xLTAuMi0wLjItMC4zLTAuNC0wLjVsLTAuMi0wLjNsMi44LTMuMUwxOCwwLjZsLTQuNiwwLjFsMC41LDQuNWwwLjUsNC41bDMuMi0zLjZ2MC4xbDAuMSwwLjJjMC4xLDAuMSwwLjEsMC4yLDAuMiwwLjJsMC4xLDAuMkMxOCw3LDE4LDcuMSwxOC4xLDcuMmMwLjMsMC43LDAuNiwxLjQsMC43LDIuMWMwLjIsMS40LDAsMi45LTAuNiw0LjJMMTgsMTMuOUwxNy45LDE0bC0wLjMsMC41bC0wLjEsMC4yYy0wLjIsMC4yLTAuNCwwLjUtMC42LDAuN2MtMC41LDAuNS0xLjEsMS0xLjcsMS4zYy0wLjYsMC40LTEuMywwLjYtMi4xLDAuOGMtMC43LDAuMS0xLjUsMC4yLTIuMiwwLjFjLTAuOC0wLjEtMS41LTAuMy0yLjItMC41Yy0wLjctMC4zLTEuMy0wLjctMS45LTEuMmwtMC40LTAuNGwtMC4yLTAuM0w2LDE1Yy0wLjEtMC4xLTAuMi0wLjItMC4yLTAuM2wtMC4zLTAuNGwtMC4xLTAuMWwtMC4yLTAuNGMwLTAuMS0wLjEtMC4xLTAuMS0wLjJsLTAuMy0wLjVsLTAuMS0wLjJjLTAuMS0wLjMtMC4yLTAuNi0wLjMtMC45Yy0wLjItMC44LTAuMy0xLjYtMC4zLTIuNGMwLTAuMiwwLTAuMywwLTAuNVY4LjljMC0wLjIsMC0wLjMsMC4xLTAuNGwwLjEtMC42bDAuMi0wLjZjMC4zLTAuOCwwLjctMS41LDEuMi0yLjJjMC41LTAuNywxLjEtMS4zLDEuOC0xLjhjMC4yLTAuMSwwLjMtMC40LDAuMS0wLjZDNy41LDIuNiw3LjQsMi41LDcuMywyLjVINy4xTDcsMi42QzYuMSwzLDUuNCwzLjYsNC43LDQuMkM0LDQuOSwzLjUsNS43LDMsNi42Yy0wLjksMS44LTEuMiwzLjgtMC44LDUuOGMwLjEsMC41LDAuMiwwLjksMC4zLDEuNGwwLjMsMC44QzIuOSwxNC43LDMsMTQuOCwzLDE1bDAuMiwwLjRjMCwwLjEsMC4xLDAuMiwwLjEsMC4ybDAuMywwLjVjMC4xLDAuMiwwLjIsMC4zLDAuMywwLjVsMC4xLDAuMmMwLjEsMC4xLDAuMiwwLjMsMC4zLDAuNEw1LDE3LjhjMC43LDAuNywxLjYsMS4zLDIuNSwxLjhjMC45LDAuNSwxLjksMC44LDMsMC45YzAuNSwwLjEsMSwwLjEsMS41LDAuMWMwLjYsMCwxLjEsMCwxLjYtMC4xYzEtMC4yLDIuMS0wLjUsMy0xbDAuMi0wLjFjMC4yLTAuMSwwLjMtMC4yLDAuNS0wLjNsMC43LTAuNGMwLjItMC4xLDAuMy0wLjIsMC40LTAuM2wwLjItMC4yYzAuMi0wLjEsMC40LTAuMywwLjUtMC41bDAuMS0wLjFjMC4zLTAuMywwLjctMC43LDAuOS0xbDAuNi0wLjlsMC40LTAuNmMxLTEuOSwxLjQtNC4xLDEuMS02LjJDMjIsNy44LDIxLjcsNi43LDIxLjIsNS44eiIvPgogICAgPC9kZWZzPgogICAgPGcgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwIDIpIj4KICAgICAgICA8bWFzayBpZD0icm90YXRlLWIiIGZpbGw9IiNmZmYiPgogICAgICAgICAgICA8dXNlIHhsaW5rOmhyZWY9IiNyb3RhdGUiLz4KICAgICAgICA8L21hc2s+CiAgICAgICAgPHVzZSBmaWxsPSIjNUI1QjVCIiBmaWxsLXJ1bGU9Im5vbnplcm8iIHhsaW5rOmhyZWY9IiNyb3RhdGUiLz4KICAgICAgICA8ZyBmaWxsPSIjNUI1QjVCIiBtYXNrPSJ1cmwoI3JvdGF0ZS1iKSI+CiAgICAgICAgICAgIDxyZWN0IHdpZHRoPSIzMCIgaGVpZ2h0PSIzMCIvPgogICAgICAgIDwvZz4KICAgIDwvZz4KPC9zdmc+Cg==);
|
||||
}
|
||||
.leaflet-pm-toolbar .leaflet-pm-icon-text {
|
||||
background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCI+PGRlZnM+PHN0eWxlPi5jbHMtMXtmaWxsOm5vbmU7c3Ryb2tlOiM1YjViNWI7c3Ryb2tlLWxpbmVjYXA6cm91bmQ7c3Ryb2tlLWxpbmVqb2luOnJvdW5kO3N0cm9rZS13aWR0aDoyLjVweDt9PC9zdHlsZT48L2RlZnM+PHRpdGxlPlRleHQ8L3RpdGxlPjxnIGlkPSJFYmVuZV8yIiBkYXRhLW5hbWU9IkViZW5lIDIiPjxwb2x5bGluZSBjbGFzcz0iY2xzLTEiIHBvaW50cz0iMTkuNjQgNy4yNyAxOS42NCA0IDEyIDQgMTIgMjAgMTUuOTEgMjAgOC4wOSAyMCAxMiAyMCAxMiA0IDQuMzYgNCA0LjM2IDcuMjciLz48L2c+PC9zdmc+);
|
||||
}
|
||||
|
||||
.leaflet-buttons-control-button:hover,
|
||||
.leaflet-buttons-control-button:focus {
|
||||
cursor: pointer;
|
||||
background-color: #f4f4f4;
|
||||
}
|
||||
.active > .leaflet-buttons-control-button {
|
||||
box-shadow: inset 0 -1px 5px 2px rgba(81, 77, 77, 0.31);
|
||||
}
|
||||
|
||||
.leaflet-buttons-control-text-hide {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.button-container {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.button-container .leaflet-pm-actions-container {
|
||||
z-index: 2;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 100%;
|
||||
display: none;
|
||||
white-space: nowrap;
|
||||
direction: ltr;
|
||||
}
|
||||
|
||||
.leaflet-right
|
||||
.leaflet-pm-toolbar
|
||||
.button-container
|
||||
.leaflet-pm-actions-container {
|
||||
right: 100%;
|
||||
left: auto;
|
||||
}
|
||||
|
||||
.button-container.active .leaflet-pm-actions-container {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.button-container
|
||||
.leaflet-pm-actions-container:not(.pos-right)
|
||||
a.leaflet-pm-action:last-child {
|
||||
border-radius: 0 3px 3px 0;
|
||||
border-right: 0;
|
||||
}
|
||||
.button-container
|
||||
.leaflet-pm-actions-container.pos-right
|
||||
a.leaflet-pm-action:first-child {
|
||||
border-radius: 3px 0 0 3px;
|
||||
}
|
||||
.button-container
|
||||
.leaflet-pm-actions-container.pos-right
|
||||
a.leaflet-pm-action:last-child {
|
||||
border-right: 0;
|
||||
}
|
||||
.button-container .leaflet-pm-actions-container .leaflet-pm-action {
|
||||
padding: 0 10px;
|
||||
background-color: #666;
|
||||
color: #fff;
|
||||
display: inline-block;
|
||||
width: auto;
|
||||
border-right: 1px solid #eee;
|
||||
user-select: none;
|
||||
border-bottom: none;
|
||||
height: 29px;
|
||||
line-height: 29px;
|
||||
}
|
||||
.leaflet-pm-toolbar
|
||||
.button-container:first-child.pos-right.active
|
||||
a.leaflet-buttons-control-button {
|
||||
border-top-left-radius: 0;
|
||||
}
|
||||
.leaflet-pm-toolbar
|
||||
.button-container:first-child.active:not(.pos-right)
|
||||
a.leaflet-buttons-control-button {
|
||||
border-top-right-radius: 0;
|
||||
}
|
||||
|
||||
.button-container .leaflet-pm-actions-container .leaflet-pm-action:hover,
|
||||
.button-container .leaflet-pm-actions-container .leaflet-pm-action:focus {
|
||||
cursor: pointer;
|
||||
background-color: #777;
|
||||
}
|
||||
|
||||
/* That the active control is always over the other controls */
|
||||
.leaflet-pm-toolbar.activeChild {
|
||||
z-index: 801;
|
||||
}
|
||||
|
||||
.leaflet-buttons-control-button.pm-disabled {
|
||||
background-color: #f4f4f4;
|
||||
}
|
||||
|
||||
.leaflet-buttons-control-button.pm-disabled > .control-icon {
|
||||
filter: opacity(0.6);
|
||||
}
|
||||
1
web/lib/components/geoman/leaflet-geoman.min.js
vendored
Normal file
BIN
web/lib/components/leaflet/images/layers-2x.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
web/lib/components/leaflet/images/layers.png
Normal file
|
After Width: | Height: | Size: 696 B |
BIN
web/lib/components/leaflet/images/marker-icon-2x.png
Normal file
|
After Width: | Height: | Size: 2.4 KiB |
BIN
web/lib/components/leaflet/images/marker-icon.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
web/lib/components/leaflet/images/marker-shadow.png
Normal file
|
After Width: | Height: | Size: 618 B |
14419
web/lib/components/leaflet/leaflet-src.esm.js
Normal file
1
web/lib/components/leaflet/leaflet-src.esm.js.map
Normal file
14512
web/lib/components/leaflet/leaflet-src.js
Normal file
1
web/lib/components/leaflet/leaflet-src.js.map
Normal file
666
web/lib/components/leaflet/leaflet.css
Normal file
@@ -0,0 +1,666 @@
|
||||
/* required styles */
|
||||
|
||||
.leaflet-pane,
|
||||
.leaflet-tile,
|
||||
.leaflet-marker-icon,
|
||||
.leaflet-marker-shadow,
|
||||
.leaflet-tile-container,
|
||||
.leaflet-pane > svg,
|
||||
.leaflet-pane > canvas,
|
||||
.leaflet-zoom-box,
|
||||
.leaflet-image-layer,
|
||||
.leaflet-layer {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
}
|
||||
.leaflet-container {
|
||||
overflow: hidden;
|
||||
}
|
||||
.leaflet-tile,
|
||||
.leaflet-marker-icon,
|
||||
.leaflet-marker-shadow {
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
user-select: none;
|
||||
-webkit-user-drag: none;
|
||||
}
|
||||
/* Prevents IE11 from highlighting tiles in blue */
|
||||
.leaflet-tile::selection {
|
||||
background: transparent;
|
||||
}
|
||||
/* Safari renders non-retina tile on retina better with this, but Chrome is worse */
|
||||
.leaflet-safari .leaflet-tile {
|
||||
image-rendering: -webkit-optimize-contrast;
|
||||
}
|
||||
/* hack that prevents hw layers "stretching" when loading new tiles */
|
||||
.leaflet-safari .leaflet-tile-container {
|
||||
width: 1600px;
|
||||
height: 1600px;
|
||||
-webkit-transform-origin: 0 0;
|
||||
}
|
||||
.leaflet-marker-icon,
|
||||
.leaflet-marker-shadow {
|
||||
display: block;
|
||||
}
|
||||
/* .leaflet-container svg: reset svg max-width decleration shipped in Joomla! (joomla.org) 3.x */
|
||||
/* .leaflet-container img: map is broken in FF if you have max-width: 100% on tiles */
|
||||
.leaflet-container .leaflet-overlay-pane svg {
|
||||
max-width: none !important;
|
||||
max-height: none !important;
|
||||
}
|
||||
.leaflet-container .leaflet-marker-pane img,
|
||||
.leaflet-container .leaflet-shadow-pane img,
|
||||
.leaflet-container .leaflet-tile-pane img,
|
||||
.leaflet-container img.leaflet-image-layer,
|
||||
.leaflet-container .leaflet-tile {
|
||||
max-width: none !important;
|
||||
max-height: none !important;
|
||||
width: auto;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.leaflet-container img.leaflet-tile {
|
||||
/* See: https://bugs.chromium.org/p/chromium/issues/detail?id=600120 */
|
||||
mix-blend-mode: plus-lighter;
|
||||
}
|
||||
|
||||
.leaflet-container.leaflet-touch-zoom {
|
||||
-ms-touch-action: pan-x pan-y;
|
||||
touch-action: pan-x pan-y;
|
||||
}
|
||||
.leaflet-container.leaflet-touch-drag {
|
||||
-ms-touch-action: pinch-zoom;
|
||||
/* Fallback for FF which doesn't support pinch-zoom */
|
||||
touch-action: none;
|
||||
touch-action: pinch-zoom;
|
||||
}
|
||||
.leaflet-container.leaflet-touch-drag.leaflet-touch-zoom {
|
||||
-ms-touch-action: none;
|
||||
touch-action: none;
|
||||
}
|
||||
.leaflet-container {
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
}
|
||||
.leaflet-container a {
|
||||
-webkit-tap-highlight-color: rgba(51, 181, 229, 0.4);
|
||||
}
|
||||
.leaflet-tile {
|
||||
filter: inherit;
|
||||
visibility: hidden;
|
||||
}
|
||||
.leaflet-tile-loaded {
|
||||
visibility: inherit;
|
||||
}
|
||||
.leaflet-zoom-box {
|
||||
width: 0;
|
||||
height: 0;
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
z-index: 800;
|
||||
}
|
||||
/* workaround for https://bugzilla.mozilla.org/show_bug.cgi?id=888319 */
|
||||
.leaflet-overlay-pane svg {
|
||||
-moz-user-select: none;
|
||||
}
|
||||
|
||||
.leaflet-pane { z-index: 400; }
|
||||
|
||||
.leaflet-tile-pane { z-index: 200; }
|
||||
.leaflet-overlay-pane { z-index: 400; }
|
||||
.leaflet-shadow-pane { z-index: 500; }
|
||||
.leaflet-marker-pane { z-index: 600; }
|
||||
.leaflet-tooltip-pane { z-index: 650; }
|
||||
.leaflet-popup-pane { z-index: 700; }
|
||||
|
||||
.leaflet-map-pane canvas { z-index: 100; }
|
||||
.leaflet-map-pane svg { z-index: 200; }
|
||||
|
||||
.leaflet-vml-shape {
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
}
|
||||
.lvml {
|
||||
behavior: url(#default#VML);
|
||||
display: inline-block;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
|
||||
/* control positioning */
|
||||
|
||||
.leaflet-control {
|
||||
position: relative;
|
||||
z-index: 800;
|
||||
pointer-events: visiblePainted; /* IE 9-10 doesn't have auto */
|
||||
pointer-events: auto;
|
||||
}
|
||||
.leaflet-top,
|
||||
.leaflet-bottom {
|
||||
position: absolute;
|
||||
z-index: 1000;
|
||||
pointer-events: none;
|
||||
}
|
||||
.leaflet-top {
|
||||
top: 0;
|
||||
}
|
||||
.leaflet-right {
|
||||
right: 0;
|
||||
}
|
||||
.leaflet-bottom {
|
||||
bottom: 0;
|
||||
}
|
||||
.leaflet-left {
|
||||
left: 0;
|
||||
}
|
||||
.leaflet-control {
|
||||
float: left;
|
||||
clear: both;
|
||||
}
|
||||
.leaflet-right .leaflet-control {
|
||||
float: right;
|
||||
}
|
||||
.leaflet-top .leaflet-control {
|
||||
margin-top: 10px;
|
||||
}
|
||||
.leaflet-bottom .leaflet-control {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.leaflet-left .leaflet-control {
|
||||
margin-left: 10px;
|
||||
}
|
||||
.leaflet-right .leaflet-control {
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
|
||||
/* zoom and fade animations */
|
||||
|
||||
.leaflet-fade-anim .leaflet-popup {
|
||||
opacity: 0;
|
||||
-webkit-transition: opacity 0.2s linear;
|
||||
-moz-transition: opacity 0.2s linear;
|
||||
transition: opacity 0.2s linear;
|
||||
}
|
||||
.leaflet-fade-anim .leaflet-map-pane .leaflet-popup {
|
||||
opacity: 1;
|
||||
}
|
||||
.leaflet-zoom-animated {
|
||||
-webkit-transform-origin: 0 0;
|
||||
-ms-transform-origin: 0 0;
|
||||
transform-origin: 0 0;
|
||||
}
|
||||
svg.leaflet-zoom-animated {
|
||||
will-change: transform;
|
||||
}
|
||||
|
||||
.leaflet-zoom-anim .leaflet-zoom-animated {
|
||||
-webkit-transition: -webkit-transform 0.25s cubic-bezier(0,0,0.25,1);
|
||||
-moz-transition: -moz-transform 0.25s cubic-bezier(0,0,0.25,1);
|
||||
transition: transform 0.25s cubic-bezier(0,0,0.25,1);
|
||||
}
|
||||
.leaflet-zoom-anim .leaflet-tile,
|
||||
.leaflet-pan-anim .leaflet-tile {
|
||||
-webkit-transition: none;
|
||||
-moz-transition: none;
|
||||
transition: none;
|
||||
}
|
||||
|
||||
.leaflet-zoom-anim .leaflet-zoom-hide {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
|
||||
/* cursors */
|
||||
|
||||
.leaflet-interactive {
|
||||
cursor: pointer;
|
||||
}
|
||||
.leaflet-grab {
|
||||
cursor: -webkit-grab;
|
||||
cursor: -moz-grab;
|
||||
cursor: grab;
|
||||
}
|
||||
.leaflet-crosshair,
|
||||
.leaflet-crosshair .leaflet-interactive {
|
||||
cursor: crosshair;
|
||||
}
|
||||
.leaflet-popup-pane,
|
||||
.leaflet-control {
|
||||
cursor: auto;
|
||||
}
|
||||
.leaflet-dragging .leaflet-grab,
|
||||
.leaflet-dragging .leaflet-grab .leaflet-interactive,
|
||||
.leaflet-dragging .leaflet-marker-draggable {
|
||||
cursor: move;
|
||||
cursor: -webkit-grabbing;
|
||||
cursor: -moz-grabbing;
|
||||
cursor: grabbing;
|
||||
}
|
||||
|
||||
/* marker & overlays interactivity */
|
||||
.leaflet-marker-icon,
|
||||
.leaflet-marker-shadow,
|
||||
.leaflet-image-layer,
|
||||
.leaflet-pane > svg path,
|
||||
.leaflet-tile-container {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.leaflet-marker-icon.leaflet-interactive,
|
||||
.leaflet-image-layer.leaflet-interactive,
|
||||
.leaflet-pane > svg path.leaflet-interactive,
|
||||
svg.leaflet-image-layer.leaflet-interactive path {
|
||||
pointer-events: visiblePainted; /* IE 9-10 doesn't have auto */
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
/* visual tweaks */
|
||||
|
||||
.leaflet-container {
|
||||
background: #ddd;
|
||||
outline-offset: 1px;
|
||||
}
|
||||
.leaflet-container a {
|
||||
color: #0078A8;
|
||||
}
|
||||
.leaflet-zoom-box {
|
||||
border: 2px dotted #38f;
|
||||
background: rgba(255,255,255,0.5);
|
||||
}
|
||||
|
||||
|
||||
/* general typography */
|
||||
.leaflet-container {
|
||||
font-family: "Helvetica Neue", Arial, Helvetica, sans-serif;
|
||||
font-size: 12px;
|
||||
font-size: 0.75rem;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
|
||||
/* general toolbar styles */
|
||||
|
||||
.leaflet-bar {
|
||||
box-shadow: 0 1px 5px rgba(0,0,0,0.65);
|
||||
border-radius: 4px;
|
||||
}
|
||||
.leaflet-bar a {
|
||||
background-color: #fff;
|
||||
border-bottom: 1px solid #ccc;
|
||||
width: 26px;
|
||||
height: 26px;
|
||||
line-height: 26px;
|
||||
display: block;
|
||||
text-align: center;
|
||||
text-decoration: none;
|
||||
color: black;
|
||||
}
|
||||
.leaflet-bar a,
|
||||
.leaflet-control-layers-toggle {
|
||||
background-position: 50% 50%;
|
||||
background-repeat: no-repeat;
|
||||
display: block;
|
||||
}
|
||||
.leaflet-bar a:hover,
|
||||
.leaflet-bar a:focus {
|
||||
background-color: #f4f4f4;
|
||||
}
|
||||
.leaflet-bar a:first-child {
|
||||
border-top-left-radius: 4px;
|
||||
border-top-right-radius: 4px;
|
||||
}
|
||||
.leaflet-bar a:last-child {
|
||||
border-bottom-left-radius: 4px;
|
||||
border-bottom-right-radius: 4px;
|
||||
border-bottom: none;
|
||||
}
|
||||
.leaflet-bar a.leaflet-disabled {
|
||||
cursor: default;
|
||||
background-color: #f4f4f4;
|
||||
color: #bbb;
|
||||
}
|
||||
|
||||
.leaflet-touch .leaflet-bar a {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
line-height: 30px;
|
||||
}
|
||||
.leaflet-touch .leaflet-bar a:first-child {
|
||||
border-top-left-radius: 2px;
|
||||
border-top-right-radius: 2px;
|
||||
}
|
||||
.leaflet-touch .leaflet-bar a:last-child {
|
||||
border-bottom-left-radius: 2px;
|
||||
border-bottom-right-radius: 2px;
|
||||
}
|
||||
|
||||
/* zoom control */
|
||||
|
||||
.leaflet-control-zoom-in,
|
||||
.leaflet-control-zoom-out {
|
||||
font: bold 18px 'Lucida Console', Monaco, monospace;
|
||||
text-indent: 1px;
|
||||
}
|
||||
|
||||
.leaflet-touch .leaflet-control-zoom-in, .leaflet-touch .leaflet-control-zoom-out {
|
||||
font-size: 22px;
|
||||
}
|
||||
|
||||
|
||||
/* layers control */
|
||||
|
||||
.leaflet-control-layers {
|
||||
box-shadow: 0 1px 5px rgba(0,0,0,0.4);
|
||||
background: #fff;
|
||||
border-radius: 5px;
|
||||
}
|
||||
.leaflet-control-layers-toggle {
|
||||
background-image: url(images/layers.png);
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
}
|
||||
.leaflet-retina .leaflet-control-layers-toggle {
|
||||
background-image: url(images/layers-2x.png);
|
||||
background-size: 26px 26px;
|
||||
}
|
||||
.leaflet-touch .leaflet-control-layers-toggle {
|
||||
width: 44px;
|
||||
height: 44px;
|
||||
}
|
||||
.leaflet-control-layers .leaflet-control-layers-list,
|
||||
.leaflet-control-layers-expanded .leaflet-control-layers-toggle {
|
||||
display: none;
|
||||
}
|
||||
.leaflet-control-layers-expanded .leaflet-control-layers-list {
|
||||
display: block;
|
||||
position: relative;
|
||||
}
|
||||
.leaflet-control-layers-expanded {
|
||||
padding: 6px 10px 6px 6px;
|
||||
color: #333;
|
||||
background: #fff;
|
||||
}
|
||||
.leaflet-control-layers-scrollbar {
|
||||
overflow-y: scroll;
|
||||
overflow-x: hidden;
|
||||
padding-right: 5px;
|
||||
}
|
||||
.leaflet-control-layers-selector {
|
||||
margin-top: 2px;
|
||||
position: relative;
|
||||
top: 1px;
|
||||
}
|
||||
.leaflet-control-layers label {
|
||||
display: block;
|
||||
font-size: 13px;
|
||||
font-size: 1.08333em;
|
||||
}
|
||||
.leaflet-control-layers-separator {
|
||||
height: 0;
|
||||
border-top: 1px solid #ddd;
|
||||
margin: 5px -10px 5px -6px;
|
||||
}
|
||||
|
||||
/* Default icon URLs */
|
||||
.leaflet-default-icon-path { /* used only in path-guessing heuristic, see L.Icon.Default */
|
||||
background-image: url(images/marker-icon.png);
|
||||
}
|
||||
|
||||
|
||||
/* attribution and scale controls */
|
||||
|
||||
.leaflet-container .leaflet-control-attribution {
|
||||
background: #fff;
|
||||
background: rgba(255, 255, 255, 0.8);
|
||||
margin: 0;
|
||||
}
|
||||
.leaflet-control-attribution,
|
||||
.leaflet-control-scale-line {
|
||||
padding: 0 5px;
|
||||
color: #333;
|
||||
line-height: 1.4;
|
||||
}
|
||||
.leaflet-control-attribution a {
|
||||
text-decoration: none;
|
||||
}
|
||||
.leaflet-control-attribution a:hover,
|
||||
.leaflet-control-attribution a:focus {
|
||||
text-decoration: underline;
|
||||
}
|
||||
.leaflet-attribution-flag {
|
||||
display: inline !important;
|
||||
vertical-align: baseline !important;
|
||||
width: 1em;
|
||||
height: 0.6669em;
|
||||
}
|
||||
.leaflet-left .leaflet-control-scale {
|
||||
margin-left: 5px;
|
||||
}
|
||||
.leaflet-bottom .leaflet-control-scale {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
.leaflet-control-scale-line {
|
||||
border: 2px solid #777;
|
||||
border-top: none;
|
||||
line-height: 1.1;
|
||||
padding: 2px 5px 1px;
|
||||
white-space: nowrap;
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
background: rgba(255, 255, 255, 0.8);
|
||||
text-shadow: 1px 1px #fff;
|
||||
}
|
||||
.leaflet-control-scale-line:not(:first-child) {
|
||||
border-top: 2px solid #777;
|
||||
border-bottom: none;
|
||||
margin-top: -2px;
|
||||
}
|
||||
.leaflet-control-scale-line:not(:first-child):not(:last-child) {
|
||||
border-bottom: 2px solid #777;
|
||||
}
|
||||
|
||||
.leaflet-touch .leaflet-control-attribution,
|
||||
.leaflet-touch .leaflet-control-layers,
|
||||
.leaflet-touch .leaflet-bar {
|
||||
box-shadow: none;
|
||||
}
|
||||
.leaflet-touch .leaflet-control-layers,
|
||||
.leaflet-touch .leaflet-bar {
|
||||
border: 2px solid rgba(0,0,0,0.2);
|
||||
background-clip: padding-box;
|
||||
}
|
||||
|
||||
|
||||
/* popup */
|
||||
|
||||
.leaflet-popup {
|
||||
position: absolute;
|
||||
text-align: center;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.leaflet-popup-content-wrapper {
|
||||
padding: 1px;
|
||||
text-align: left;
|
||||
border-radius: 12px;
|
||||
}
|
||||
.leaflet-popup-content {
|
||||
margin: 13px 24px 13px 20px;
|
||||
line-height: 1.3;
|
||||
font-size: 13px;
|
||||
font-size: 1.08333em;
|
||||
min-height: 1px;
|
||||
}
|
||||
.leaflet-popup-content p {
|
||||
margin: 17px 0;
|
||||
margin: 1.3em 0;
|
||||
}
|
||||
.leaflet-popup-tip-container {
|
||||
width: 40px;
|
||||
height: 20px;
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
margin-top: -1px;
|
||||
margin-left: -20px;
|
||||
overflow: hidden;
|
||||
pointer-events: none;
|
||||
}
|
||||
.leaflet-popup-tip {
|
||||
width: 17px;
|
||||
height: 17px;
|
||||
padding: 1px;
|
||||
|
||||
margin: -10px auto 0;
|
||||
pointer-events: auto;
|
||||
|
||||
-webkit-transform: rotate(45deg);
|
||||
-moz-transform: rotate(45deg);
|
||||
-ms-transform: rotate(45deg);
|
||||
transform: rotate(45deg);
|
||||
}
|
||||
.leaflet-popup-content-wrapper,
|
||||
.leaflet-popup-tip {
|
||||
background: white;
|
||||
color: #333;
|
||||
box-shadow: 0 3px 14px rgba(0,0,0,0.4);
|
||||
}
|
||||
.leaflet-container a.leaflet-popup-close-button {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
border: none;
|
||||
text-align: center;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
font: 16px/24px Tahoma, Verdana, sans-serif;
|
||||
color: #757575;
|
||||
text-decoration: none;
|
||||
background: transparent;
|
||||
}
|
||||
.leaflet-container a.leaflet-popup-close-button:hover,
|
||||
.leaflet-container a.leaflet-popup-close-button:focus {
|
||||
color: #585858;
|
||||
}
|
||||
.leaflet-popup-scrolled {
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.leaflet-oldie .leaflet-popup-content-wrapper {
|
||||
-ms-zoom: 1;
|
||||
}
|
||||
.leaflet-oldie .leaflet-popup-tip {
|
||||
width: 24px;
|
||||
margin: 0 auto;
|
||||
|
||||
-ms-filter: "progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678)";
|
||||
filter: progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678);
|
||||
}
|
||||
|
||||
.leaflet-oldie .leaflet-control-zoom,
|
||||
.leaflet-oldie .leaflet-control-layers,
|
||||
.leaflet-oldie .leaflet-popup-content-wrapper,
|
||||
.leaflet-oldie .leaflet-popup-tip {
|
||||
border: 1px solid #999;
|
||||
}
|
||||
|
||||
|
||||
/* div icon */
|
||||
|
||||
.leaflet-div-icon {
|
||||
background: #4CAF50;
|
||||
border: 1px solid #666;
|
||||
width: 7px !important;
|
||||
height: 7px !important;
|
||||
margin-left: -5.5px !important;
|
||||
margin-top: -5.5px !important;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
|
||||
/* Tooltip */
|
||||
/* Base styles for the element that has a tooltip */
|
||||
.leaflet-tooltip {
|
||||
position: absolute;
|
||||
padding: 6px;
|
||||
background-color: #fff;
|
||||
border: 1px solid #fff;
|
||||
border-radius: 3px;
|
||||
color: #222;
|
||||
white-space: nowrap;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
pointer-events: none;
|
||||
box-shadow: 0 1px 3px rgba(0,0,0,0.4);
|
||||
}
|
||||
.leaflet-tooltip.leaflet-interactive {
|
||||
cursor: pointer;
|
||||
pointer-events: auto;
|
||||
}
|
||||
.leaflet-tooltip-top:before,
|
||||
.leaflet-tooltip-bottom:before,
|
||||
.leaflet-tooltip-left:before,
|
||||
.leaflet-tooltip-right:before {
|
||||
position: absolute;
|
||||
pointer-events: none;
|
||||
border: 6px solid transparent;
|
||||
background: transparent;
|
||||
content: "";
|
||||
}
|
||||
|
||||
/* Directions */
|
||||
|
||||
.leaflet-tooltip-bottom {
|
||||
margin-top: 6px;
|
||||
}
|
||||
.leaflet-tooltip-top {
|
||||
margin-top: -6px;
|
||||
}
|
||||
.leaflet-tooltip-bottom:before,
|
||||
.leaflet-tooltip-top:before {
|
||||
left: 50%;
|
||||
margin-left: -6px;
|
||||
}
|
||||
.leaflet-tooltip-top:before {
|
||||
bottom: 0;
|
||||
margin-bottom: -12px;
|
||||
border-top-color: #fff;
|
||||
}
|
||||
.leaflet-tooltip-bottom:before {
|
||||
top: 0;
|
||||
margin-top: -12px;
|
||||
margin-left: -6px;
|
||||
border-bottom-color: #fff;
|
||||
}
|
||||
.leaflet-tooltip-left {
|
||||
margin-left: -6px;
|
||||
}
|
||||
.leaflet-tooltip-right {
|
||||
margin-left: 6px;
|
||||
}
|
||||
.leaflet-tooltip-left:before,
|
||||
.leaflet-tooltip-right:before {
|
||||
top: 50%;
|
||||
margin-top: -6px;
|
||||
}
|
||||
.leaflet-tooltip-left:before {
|
||||
right: 0;
|
||||
margin-right: -12px;
|
||||
border-left-color: #fff;
|
||||
}
|
||||
.leaflet-tooltip-right:before {
|
||||
left: 0;
|
||||
margin-left: -12px;
|
||||
border-right-color: #fff;
|
||||
}
|
||||
|
||||
/* Printing */
|
||||
|
||||
@media print {
|
||||
/* Prevent printers from removing background-images of controls. */
|
||||
.leaflet-control {
|
||||
-webkit-print-color-adjust: exact;
|
||||
print-color-adjust: exact;
|
||||
}
|
||||
}
|
||||
6
web/lib/components/leaflet/leaflet.js
Normal file
1
web/lib/components/leaflet/leaflet.js.map
Normal file
11
web/lib/components/makeid.js
Normal file
@@ -0,0 +1,11 @@
|
||||
function makeid(length) {
|
||||
let result = '';
|
||||
const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
||||
const charactersLength = characters.length;
|
||||
let counter = 0;
|
||||
while (counter < length) {
|
||||
result += characters.charAt(Math.floor(Math.random() * charactersLength));
|
||||
counter += 1;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
1
web/lib/components/qrcode.min.js
vendored
Normal file
40
web/lib/components/swipeUpdater.js
Normal file
@@ -0,0 +1,40 @@
|
||||
// Скрипт перезагрузки страници свайпом.
|
||||
let app_scroll = false;
|
||||
let animID = document.getElementById('swipe_updater');
|
||||
let animIconID = document.getElementById('swipe_icon');
|
||||
|
||||
|
||||
window.addEventListener('scroll', function(e) {
|
||||
if (window.matchMedia('(display-mode: standalone)').matches) {
|
||||
let a = window.scrollY;
|
||||
let b = 50;
|
||||
let c = 125;
|
||||
a = -a;
|
||||
a = a;
|
||||
|
||||
animIconID.style.top = a/1.5;
|
||||
|
||||
console.log(window.scrollY);
|
||||
|
||||
if(window.scrollY <= -10){
|
||||
animID.style.zIndex = 115;
|
||||
} else {
|
||||
animID.style.zIndex = 0;
|
||||
}
|
||||
|
||||
if(window.scrollY <= -120){
|
||||
if(app_scroll == false){
|
||||
app_scroll = true;
|
||||
animIconID.style.transform = 'rotate(180deg)';
|
||||
animIconID.setAttribute('data-state', '')
|
||||
}
|
||||
} else if(window.scrollY >= 0){
|
||||
if(app_scroll == true){
|
||||
appReload();
|
||||
app_scroll = false;
|
||||
animIconID.style.transform = 'rotate(0deg)';
|
||||
animIconID.setAttribute('data-state', 'active')
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
88
web/lib/components/turf.min.js
vendored
Normal file
175
web/lib/pages/card/index.html
Normal file
@@ -0,0 +1,175 @@
|
||||
<style>
|
||||
*[disabled] {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
select {
|
||||
-moz-appearance: none;
|
||||
-webkit-appearance: none;
|
||||
appearance: none;
|
||||
/* Arrow */
|
||||
appearance: none;
|
||||
background-image: url("data:image/svg+xml;charset=US-ASCII,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22292.4%22%20height%3D%22292.4%22%3E%3Cpath%20fill%3D%22%237a899d%22%20d%3D%22M287%2069.4a17.6%2017.6%200%200%200-13-5.4H18.4c-5%200-9.3%201.8-12.9%205.4A17.6%2017.6%200%200%200%200%2082.2c0%205%201.8%209.3%205.4%2012.9l128%20127.9c3.6%203.6%207.8%205.4%2012.8%205.4s9.2-1.8%2012.8-5.4L287%2095c3.5-3.5%205.4-7.8%205.4-12.8%200-5-1.9-9.2-5.5-12.8z%22%2F%3E%3C%2Fsvg%3E");
|
||||
background-repeat: no-repeat;
|
||||
background-position: right 0.3rem top 50%;
|
||||
background-size: 0.55rem auto;
|
||||
}
|
||||
|
||||
#header {
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
}
|
||||
#header p {
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
#list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
details {
|
||||
color: var(--ColorThemes3);
|
||||
width: 100%;
|
||||
min-width: 320px;
|
||||
background: var(--ColorThemes1);
|
||||
margin: 20px 0px;
|
||||
border-radius: 10px;
|
||||
overflow: hidden;
|
||||
box-shadow: 0px 2px 4px rgba(0, 0, 0, 0.04), 0px 0px 2px rgba(0, 0, 0, 0.04),
|
||||
0px 0px 1px rgba(0, 0, 0, 0.04);
|
||||
}
|
||||
@media (min-width: 900px) {
|
||||
#list {
|
||||
align-items: flex-start;
|
||||
justify-content: space-between;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
details {
|
||||
width: calc(50% - 10px);
|
||||
}
|
||||
}
|
||||
details[disabled] summary,
|
||||
details.disabled summary {
|
||||
pointer-events: none;
|
||||
user-select: none;
|
||||
}
|
||||
details summary::-webkit-details-marker,
|
||||
details summary::marker {
|
||||
display: none;
|
||||
content: "";
|
||||
}
|
||||
|
||||
summary {
|
||||
cursor: pointer;
|
||||
background: #7a8a9d;
|
||||
background: var(--PrimaryColor);
|
||||
color: var(--PrimaryColorText);
|
||||
height: 45px;
|
||||
font-weight: 500;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
summary p {
|
||||
padding: 0 10px;
|
||||
color: var(--PrimaryColorText);
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
}
|
||||
summary svg {
|
||||
width: 25px;
|
||||
height: 25px;
|
||||
padding: 0 10px;
|
||||
fill: var(--PrimaryColorText);
|
||||
}
|
||||
|
||||
.apartments_list {
|
||||
padding: 10px;
|
||||
border-bottom: 2px solid var(--PrimaryColor);
|
||||
border-left: 2px solid var(--PrimaryColor);
|
||||
border-right: 2px solid var(--PrimaryColor);
|
||||
border-radius: 0 0 10px 10px;
|
||||
}
|
||||
@media (max-width: 500px) {
|
||||
.apartments_list {
|
||||
padding: 1px;
|
||||
}
|
||||
}
|
||||
.apartments_list > div {
|
||||
display: flex;
|
||||
font-size: 14px;
|
||||
border-radius: 8px;
|
||||
margin: 10px 10px 15px 10px;
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
border: 1px solid var(--ColorThemes3);
|
||||
background: var(--ColorThemes2);
|
||||
}
|
||||
.apartments_list > div > .info {
|
||||
display: flex;
|
||||
font-size: 14px;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
border-radius: 8px;
|
||||
}
|
||||
.apartments_list > div > .info > span {
|
||||
min-width: 40px;
|
||||
font-size: 12px;
|
||||
position: relative;
|
||||
margin: 5px;
|
||||
}
|
||||
.apartments_list > div > .info > select {
|
||||
color: #3d3d3d;
|
||||
border-radius: 6px;
|
||||
border: 1px solid #eaebef;
|
||||
margin: 5px;
|
||||
background-color: var(--ColorThemes3);
|
||||
min-width: 110px;
|
||||
width: 100%;
|
||||
padding: 4px 20px 4px 4px;
|
||||
height: 30px;
|
||||
}
|
||||
.apartments_list > div > .info > input {
|
||||
color: #3d3d3d;
|
||||
border-radius: 6px;
|
||||
border: 1px solid #eaebef;
|
||||
margin: 5px;
|
||||
background-color: var(--ColorThemes3);
|
||||
background-color: var(--ColorThemes0);
|
||||
border: 1px solid var(--ColorThemes1);
|
||||
color: var(--ColorThemes3);
|
||||
width: 100%;
|
||||
min-width: 70px;
|
||||
padding: 0 4px;
|
||||
height: calc(30px - 2px);
|
||||
appearance: none;
|
||||
-webkit-appearance: none;
|
||||
}
|
||||
.apartments_list > div > textarea {
|
||||
border-radius: 6px;
|
||||
font-size: 14px;
|
||||
margin: 5px;
|
||||
background-color: var(--ColorThemes0);
|
||||
border: 1px solid var(--ColorThemes1);
|
||||
color: var(--ColorThemes3);
|
||||
width: calc(100% - 22px);
|
||||
min-width: 70px;
|
||||
padding: 5px;
|
||||
min-height: 40px;
|
||||
appearance: none;
|
||||
resize: vertical;
|
||||
-webkit-appearance: none;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="page-card">
|
||||
<div id="header">
|
||||
<p id="status"></p>
|
||||
<p id="hash"></p>
|
||||
</div>
|
||||
|
||||
<div id="list"></div>
|
||||
</div>
|
||||
358
web/lib/pages/card/script.js
Normal file
@@ -0,0 +1,358 @@
|
||||
let socket, username;
|
||||
|
||||
let listEntrances = []
|
||||
let listApartment = []
|
||||
|
||||
let holdTimer;
|
||||
let startTime;
|
||||
|
||||
const Card = {
|
||||
init: async (type, id) => {
|
||||
let html = await fetch('/lib/pages/card/index.html').then((response) => response.text());
|
||||
app.innerHTML = html;
|
||||
|
||||
house = id;
|
||||
|
||||
if (socket) socket.close(1000, "Перезапуск соединения");
|
||||
|
||||
if (type == "house") {
|
||||
getEntrances();
|
||||
start(makeid(6));
|
||||
}
|
||||
|
||||
document.addEventListener("mousedown", handleStart);
|
||||
document.addEventListener("touchstart", handleStart);
|
||||
document.addEventListener("mouseup", handleCancel);
|
||||
document.addEventListener("mouseleave", handleCancel);
|
||||
document.addEventListener("touchend", handleCancel);
|
||||
document.addEventListener("touchcancel", handleCancel);
|
||||
|
||||
function handleStart(event) {
|
||||
const button = event.target.closest(".hold-button");
|
||||
if (!button) return;
|
||||
|
||||
// event.preventDefault();
|
||||
startTime = Date.now();
|
||||
|
||||
holdTimer = setTimeout(() => {
|
||||
console.log("Долгое нажатие на", button.name);
|
||||
let number_id = button.name.split("-");
|
||||
mess(Number(number_id[0]), Number(number_id[1]));
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
function handleCancel() {
|
||||
const holdDuration = Date.now() - startTime; // Считаем, сколько длилось нажатие
|
||||
|
||||
if (holdDuration < 1000) {
|
||||
clearTimeout(holdTimer); // Если нажали менее 1 секунды, сбрасываем таймер
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// let color_status = [
|
||||
// "#000000",
|
||||
// "#C16917",
|
||||
// "#b10202",
|
||||
// "#3d3d3d",
|
||||
// "#11734b",
|
||||
// "#6cc5fc",
|
||||
// "#5a3286"
|
||||
// ];
|
||||
|
||||
// let color_status = [
|
||||
// ["#ffffff", "#000000"],
|
||||
// ["#e7af32", "#ffffff"],
|
||||
// ["#fc2a2a", "#ffffff"],
|
||||
// ["#3d3d3d", "#ffffff"],
|
||||
// ["#11a568", "#ffffff"],
|
||||
// ["#6cc5fc", "#ffffff"],
|
||||
// ["#b381eb", "#ffffff"]
|
||||
// ];
|
||||
|
||||
let color_status = [
|
||||
["var(--ColorThemes2)", "var(--ColorThemes3)"],
|
||||
["#fbf1e0", "#ff8300"],
|
||||
["#fce3e2", "#ff0000"],
|
||||
["#d7ddec", "#2919bd"],
|
||||
["#d5e9dd", "#11a568"],
|
||||
["#d7ebfa", "#3fb4fc"],
|
||||
["#e8dbf5", "#b381eb"]
|
||||
];
|
||||
|
||||
function start(name) {
|
||||
if (!name) return;
|
||||
|
||||
|
||||
document.getElementById("hash").innerText = `HASH: ${name}`
|
||||
username = name;
|
||||
|
||||
let uuid = localStorage.getItem("uuid");
|
||||
socket = new WebSocket(`${CONFIG.wss}?uuid=${uuid}`);
|
||||
|
||||
socket.onopen = function (e) {
|
||||
console.log("[WebSocket | open] Соединение установлено");
|
||||
document.getElementById("status").innerText = "WebSocket | open";
|
||||
|
||||
const message = {
|
||||
event: 'connection',
|
||||
id: getTimeInSeconds(),
|
||||
date: getTimeInSeconds(),
|
||||
uuid: uuid,
|
||||
username: name,
|
||||
data: {
|
||||
id: 1,
|
||||
entrance_id: 1,
|
||||
apartment_number: 1,
|
||||
title: "1",
|
||||
group_number: 1,
|
||||
status: 1,
|
||||
description: "",
|
||||
created_at: 1727541827,
|
||||
updated_at: 1727541827
|
||||
}
|
||||
}
|
||||
|
||||
socket.send(JSON.stringify(message))
|
||||
};
|
||||
|
||||
socket.onmessage = function (event) {
|
||||
let data = JSON.parse(event.data)
|
||||
|
||||
if (data.event == 'connection') {
|
||||
if (data.username == username) return
|
||||
|
||||
console.log(`Добавлен новый пользователь по имени ${data.username}`);
|
||||
} else if (data.event == 'message') {
|
||||
update(data);
|
||||
|
||||
if (data.username == username) return
|
||||
|
||||
console.log(`${data.username} пишет: `, data.data);
|
||||
}
|
||||
};
|
||||
|
||||
socket.onclose = function (event) {
|
||||
if (event.wasClean) {
|
||||
document.getElementById("status").innerText = "WebSocket | close"
|
||||
console.log(`[WebSocket | close] Соединение закрыто чисто, код=${event.code} причина=${event.reason}`);
|
||||
} else {
|
||||
document.getElementById("status").innerText = "WebSocket | close"
|
||||
console.log('[WebSocket | close] Соединение прервано');
|
||||
|
||||
// setTimeout(function() {
|
||||
// start(username);
|
||||
// }, 1000);
|
||||
|
||||
const result = confirm(`З'єднання розірвано! Перепідключитись?`);
|
||||
if (result) {
|
||||
getEntrances();
|
||||
start(username);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
socket.onerror = function (error) {
|
||||
console.log(`[WebSocket | error]`);
|
||||
document.getElementById("status").innerText = "WebSocket | error"
|
||||
};
|
||||
}
|
||||
|
||||
function mess(entrance_number, id, date_type) {
|
||||
let sort_mode = localStorage.getItem('sort_mode') ?? true;
|
||||
console.log(id, listApartment[entrance_number]);
|
||||
|
||||
const pos = listApartment[entrance_number].map(e => e.id).indexOf(id);
|
||||
let apartment = listApartment[entrance_number][pos];
|
||||
|
||||
console.log(pos, apartment);
|
||||
|
||||
|
||||
let status = document.getElementById(`status_${id}`);
|
||||
let description = document.getElementById(`description_${id}`);
|
||||
let date = new Date(document.getElementById(`date_${id}`).value);
|
||||
const timestamp = date.getTime();
|
||||
|
||||
apartment.description = description.value;
|
||||
apartment.status = Number(status.value);
|
||||
apartment.updated_at = date_type ? getTimeInSeconds(timestamp) : getTimeInSeconds(),
|
||||
|
||||
|
||||
status.style.backgroundColor = color_status[status.value][0];
|
||||
status.style.color = color_status[status.value][1];
|
||||
status.style.border = `1px solid ${color_status[status.value][1]}`;
|
||||
|
||||
let user_hash = localStorage.getItem('hash');
|
||||
|
||||
let message = {
|
||||
event: 'message',
|
||||
id: getTimeInSeconds(),
|
||||
date: getTimeInSeconds(),
|
||||
hash: user_hash,
|
||||
username: username,
|
||||
data: {
|
||||
id: apartment.id,
|
||||
entrance_id: apartment.entrance_id,
|
||||
apartment_number: apartment.apartment_number,
|
||||
title: apartment.title,
|
||||
group_number: apartment.group_number,
|
||||
status: apartment.status,
|
||||
description: apartment.description,
|
||||
updated_at: apartment.updated_at,
|
||||
}
|
||||
}
|
||||
|
||||
socket.send(JSON.stringify(message));
|
||||
|
||||
if (!date_type && sort_mode != 'false') sort(apartment.id, apartment.entrance_id);
|
||||
}
|
||||
|
||||
function update(message) {
|
||||
if (!document.getElementById(`status_${message.data.id}`)) return;
|
||||
|
||||
let now = new Date(message.data.updated_at);
|
||||
now.setMinutes(now.getMinutes() - now.getTimezoneOffset());
|
||||
|
||||
document.getElementById(`card_${message.data.id}`).style.backgroundColor = color_status[message.data.status][0];
|
||||
document.getElementById(`card_${message.data.id}`).style.color = color_status[message.data.status][1];
|
||||
document.getElementById(`card_${message.data.id}`).style.border = `1px solid ${color_status[message.data.status][1]}`;
|
||||
|
||||
document.getElementById(`status_${message.data.id}`).style.backgroundColor = color_status[message.data.status][0];
|
||||
document.getElementById(`status_${message.data.id}`).style.color = color_status[message.data.status][1];
|
||||
document.getElementById(`status_${message.data.id}`).style.border = `1px solid ${color_status[message.data.status][1]}`;
|
||||
|
||||
|
||||
|
||||
document.getElementById(`status_${message.data.id}`).value = message.data.status;
|
||||
document.getElementById(`description_${message.data.id}`).value = message.data.description;
|
||||
document.getElementById(`date_${message.data.id}`).value = now.toISOString().slice(0, 16);
|
||||
}
|
||||
|
||||
function getEntrances(house_id = house) {
|
||||
const uuid = localStorage.getItem('uuid');
|
||||
const URL = `${CONFIG.api}/house/${house_id}/entrances`;
|
||||
fetch(URL, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"Authorization": uuid
|
||||
}
|
||||
})
|
||||
.then(function (response) {
|
||||
return response.json();
|
||||
})
|
||||
.then(function (data) {
|
||||
listEntrances = data;
|
||||
|
||||
document.getElementById('list').innerHTML = "";
|
||||
|
||||
for (let i = 0; i < listEntrances.length; i++) {
|
||||
const element = listEntrances[i];
|
||||
|
||||
let status = () => {
|
||||
if ((element.history.name == "Групова" || element.history.name == USER.name) && element.working) return "open";
|
||||
else if (USER.administrator.uuid || (USER.moderator.uuid && USER.moderator.can_manager_territory)) return "close";
|
||||
|
||||
return "style='display: none;'"
|
||||
}
|
||||
|
||||
let statusIcon = () => {
|
||||
if ((element.history.name == "Групова" || element.history.name == USER.name) && element.working) return '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M 12 1 C 9.1277778 1 6.7189086 3.0461453 6.1230469 5.7871094 L 8.078125 6.2128906 C 8.4822632 4.3538547 10.072222 3 12 3 C 14.27619 3 16 4.7238095 16 7 L 16 8 L 6 8 C 4.9069372 8 4 8.9069372 4 10 L 4 20 C 4 21.093063 4.9069372 22 6 22 L 18 22 C 19.093063 22 20 21.093063 20 20 L 20 10 C 20 8.9069372 19.093063 8 18 8 L 18 7 C 18 3.6761905 15.32381 1 12 1 z M 6 10 L 18 10 L 18 20 L 6 20 L 6 10 z M 12 13 C 10.9 13 10 13.9 10 15 C 10 16.1 10.9 17 12 17 C 13.1 17 14 16.1 14 15 C 14 13.9 13.1 13 12 13 z"/></svg>'
|
||||
else return '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"> <path d="M 12 1 C 8.6761905 1 6 3.6761905 6 7 L 6 8 C 4.9069372 8 4 8.9069372 4 10 L 4 20 C 4 21.093063 4.9069372 22 6 22 L 18 22 C 19.093063 22 20 21.093063 20 20 L 20 10 C 20 8.9069372 19.093063 8 18 8 L 18 7 C 18 3.6761905 15.32381 1 12 1 z M 12 3 C 14.27619 3 16 4.7238095 16 7 L 16 8 L 8 8 L 8 7 C 8 4.7238095 9.7238095 3 12 3 z M 6 10 L 18 10 L 18 20 L 6 20 L 6 10 z M 12 13 C 10.9 13 10 13.9 10 15 C 10 16.1 10.9 17 12 17 C 13.1 17 14 16.1 14 15 C 14 13.9 13.1 13 12 13 z"/></svg>'
|
||||
}
|
||||
|
||||
document.getElementById('list').innerHTML += `
|
||||
<details ${status()}>
|
||||
<summary>
|
||||
<p>${element.title}</p>
|
||||
${statusIcon()}
|
||||
</summary>
|
||||
<div id="apartments_${element.id}" class="apartments_list">
|
||||
|
||||
</div>
|
||||
</details>
|
||||
`;
|
||||
getApartment(element.id, element.entrance_number);
|
||||
|
||||
console.log(element);
|
||||
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
function getApartment(entrance_id, entrance_number) {
|
||||
const uuid = localStorage.getItem('uuid');
|
||||
const URL = `${CONFIG.api}/apartment/${entrance_id}`;
|
||||
fetch(URL, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"Authorization": uuid
|
||||
}
|
||||
})
|
||||
.then(function (response) {
|
||||
return response.json();
|
||||
})
|
||||
.then(function (data) {
|
||||
listApartment[entrance_number] = data;
|
||||
|
||||
data.sort((a, b) => a.apartment_number - b.apartment_number);
|
||||
|
||||
data.sort((a, b) => a.updated_at - b.updated_at);
|
||||
|
||||
for (let i = 0; i < data.length; i++) {
|
||||
const element = data[i];
|
||||
|
||||
let now = new Date(element.updated_at);
|
||||
now.setMinutes(now.getMinutes() - now.getTimezoneOffset());
|
||||
now = now.toISOString().slice(0, 16)
|
||||
|
||||
let disabled = () => {
|
||||
if (USER.administrator.uuid || (USER.moderator.uuid && USER.moderator.can_manager_territory)) return '';
|
||||
else if (element.status == 2) return "disabled";
|
||||
}
|
||||
|
||||
document.getElementById(`apartments_${entrance_id}`).innerHTML += `
|
||||
<div id="card_${element.id}" style="border: 1px solid ${color_status[element.status][1]};background: ${color_status[element.status][0]};color: ${color_status[element.status][1]};">
|
||||
<div class="info">
|
||||
<span>кв.${element.title}</span>
|
||||
<select id="status_${element.id}" onchange="mess(${entrance_number}, ${element.id})" style="background-color: ${color_status[element.status][0]}; color: ${color_status[element.status][1]}; border: 1px solid ${color_status[element.status][1]};" ${disabled()}>
|
||||
<option value="0" ${element.status == 0 ? "selected" : ""}></option>
|
||||
<option value="1" ${element.status == 1 ? "selected" : ""}>Відмова</option>
|
||||
<option value="2" ${element.status == 2 ? "selected" : ""}>Не заходити (Груба відмова)</option>
|
||||
<option value="3" ${element.status == 3 ? "selected" : ""}>Нема домофона</option>
|
||||
<option value="4" ${element.status == 4 ? "selected" : ""}>Повторна відвідина</option>
|
||||
<option value="5" ${element.status == 5 ? "selected" : ""}>Немає вдома</option>
|
||||
<option value="6" ${element.status == 6 ? "selected" : ""}>Свідки Єгови</option>
|
||||
</select>
|
||||
<input onchange="mess(${entrance_number}, ${element.id}, true)" name="${entrance_number}-${element.id}" class="hold-button" type="datetime-local" id="date_${element.id}" placeholder="Дата" value="${element.updated_at ? now : ""}" ${disabled()} style="max-width: 170px;">
|
||||
</div>
|
||||
<textarea onchange="mess(${entrance_number}, ${element.id}, true)" id="description_${element.id}" placeholder="Нотатки..." ${disabled()}}>${element.description ?? ""}</textarea>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
function sort(id, entrance_id) {
|
||||
let child = document.getElementById(`card_${id}`);
|
||||
|
||||
document.getElementById(`apartments_${entrance_id}`).removeChild(child);
|
||||
|
||||
document.getElementById(`apartments_${entrance_id}`).append(child);
|
||||
|
||||
child.style.border = "1px solid var(--PrimaryColor)";
|
||||
}
|
||||
|
||||
function getTimeInSeconds(time = Date.now()) {
|
||||
// Если время больше 10 знаков (это значит, что время в миллисекундах)
|
||||
if (time.toString().length < 10) {
|
||||
// Округляем до секунд, убирая последние 3 цифры (миллисекунды)
|
||||
time = Math.floor(time * 1000);
|
||||
}
|
||||
|
||||
return time;
|
||||
}
|
||||
6
web/lib/pages/card/style.css
Normal file
@@ -0,0 +1,6 @@
|
||||
.page-card {
|
||||
width: calc(100% - 40px);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin: 20px 20px 0 20px;
|
||||
}
|
||||
192
web/lib/pages/constructor/index.html
Normal file
@@ -0,0 +1,192 @@
|
||||
<div class="page-constructor">
|
||||
<details id="details-info" open>
|
||||
<summary>
|
||||
<span>Крок 1.</span> Інформація про будинок, територію, точки на карті
|
||||
</summary>
|
||||
<form id="info-form">
|
||||
<div id="details-info-type">
|
||||
<div class="tabs">
|
||||
<input
|
||||
type="radio"
|
||||
id="info-type-house"
|
||||
value="house"
|
||||
name="info-type"
|
||||
checked
|
||||
/>
|
||||
<label class="tab" for="info-type-house">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48">
|
||||
<path
|
||||
d="M 14.5 6 A 1.50015 1.50015 0 0 0 13 7.5 L 13 25 L 7.5 25 A 1.50015 1.50015 0 0 0 6 26.5 L 6 42.5 A 1.50015 1.50015 0 1 0 9 42.5 L 9 28 L 14.253906 28 A 1.50015 1.50015 0 0 0 14.740234 28 L 19 28 L 19 42.5 A 1.50015 1.50015 0 1 0 22 42.5 L 22 26.746094 A 1.50015 1.50015 0 0 0 22 26.259766 L 22 22 L 33.253906 22 A 1.50015 1.50015 0 0 0 33.740234 22 L 39 22 L 39 42.5 A 1.50015 1.50015 0 1 0 42 42.5 L 42 20.5 A 1.50015 1.50015 0 0 0 40.5 19 L 35 19 L 35 7.5 A 1.50015 1.50015 0 0 0 33.5 6 L 14.5 6 z M 16 9 L 32 9 L 32 19 L 20.5 19 A 1.50015 1.50015 0 0 0 19 20.5 L 19 25 L 16 25 L 16 9 z M 20 12 C 19.448 12 19 12.448 19 13 L 19 15 C 19 15.552 19.448 16 20 16 L 22 16 C 22.552 16 23 15.552 23 15 L 23 13 C 23 12.448 22.552 12 22 12 L 20 12 z M 26 12 C 25.448 12 25 12.448 25 13 L 25 15 C 25 15.552 25.448 16 26 16 L 28 16 C 28.552 16 29 15.552 29 15 L 29 13 C 29 12.448 28.552 12 28 12 L 26 12 z M 26 25 C 25.448 25 25 25.448 25 26 L 25 28 C 25 28.552 25.448 29 26 29 L 28 29 C 28.552 29 29 28.552 29 28 L 29 26 C 29 25.448 28.552 25 28 25 L 26 25 z M 33 25 C 32.448 25 32 25.448 32 26 L 32 28 C 32 28.552 32.448 29 33 29 L 35 29 C 35.552 29 36 28.552 36 28 L 36 26 C 36 25.448 35.552 25 35 25 L 33 25 z M 13 31 C 12.448 31 12 31.448 12 32 L 12 34 C 12 34.552 12.448 35 13 35 L 15 35 C 15.552 35 16 34.552 16 34 L 16 32 C 16 31.448 15.552 31 15 31 L 13 31 z M 26 31 C 25.448 31 25 31.448 25 32 L 25 34 C 25 34.552 25.448 35 26 35 L 28 35 C 28.552 35 29 34.552 29 34 L 29 32 C 29 31.448 28.552 31 28 31 L 26 31 z M 33 31 C 32.448 31 32 31.448 32 32 L 32 34 C 32 34.552 32.448 35 33 35 L 35 35 C 35.552 35 36 34.552 36 34 L 36 32 C 36 31.448 35.552 31 35 31 L 33 31 z M 13 37 C 12.448 37 12 37.448 12 38 L 12 40 C 12 40.552 12.448 41 13 41 L 15 41 C 15.552 41 16 40.552 16 40 L 16 38 C 16 37.448 15.552 37 15 37 L 13 37 z M 26 37 C 25.448 37 25 37.448 25 38 L 25 40 C 25 40.552 25.448 41 26 41 L 28 41 C 28.552 41 29 40.552 29 40 L 29 38 C 29 37.448 28.552 37 28 37 L 26 37 z M 33 37 C 32.448 37 32 37.448 32 38 L 32 40 C 32 40.552 32.448 41 33 41 L 35 41 C 35.552 41 36 40.552 36 40 L 36 38 C 36 37.448 35.552 37 35 37 L 33 37 z"
|
||||
/>
|
||||
</svg>
|
||||
<span>Багатоквартирний будинок</span>
|
||||
</label>
|
||||
<input
|
||||
type="radio"
|
||||
id="info-type-homestead"
|
||||
value="homestead"
|
||||
name="info-type"
|
||||
/>
|
||||
<label class="tab" for="info-type-homestead">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48">
|
||||
<path
|
||||
d="M 24 5.015625 C 22.851301 5.015625 21.70304 5.3892757 20.753906 6.1367188 A 1.50015 1.50015 0 0 0 20.751953 6.1367188 L 8.859375 15.509766 C 7.0558128 16.931133 6 19.102989 6 21.400391 L 6 39.488281 C 6 41.403236 7.5850452 42.988281 9.5 42.988281 L 38.5 42.988281 C 40.414955 42.988281 42 41.403236 42 39.488281 L 42 21.400391 C 42 19.102989 40.944187 16.931133 39.140625 15.509766 L 39 15.396484 L 39 7.5 A 1.50015 1.50015 0 0 0 37.5 6 L 32.5 6 A 1.50015 1.50015 0 0 0 31 7.5 L 31 9.09375 L 27.246094 6.1367188 C 26.29696 5.3892758 25.148699 5.015625 24 5.015625 z M 24 8.0078125 C 24.489801 8.0078125 24.979759 8.1705836 25.390625 8.4941406 L 31.572266 13.363281 A 1.50015 1.50015 0 0 0 34 12.185547 L 34 9 L 36 9 L 36 16.125 A 1.50015 1.50015 0 0 0 36.572266 17.302734 L 37.285156 17.865234 C 38.369594 18.719867 39 20.019792 39 21.400391 L 39 39.488281 C 39 39.783326 38.795045 39.988281 38.5 39.988281 L 9.5 39.988281 C 9.2049548 39.988281 9 39.783326 9 39.488281 L 9 21.400391 C 9 20.019792 9.6304058 18.719867 10.714844 17.865234 L 22.609375 8.4941406 C 23.020241 8.1705836 23.510199 8.0078125 24 8.0078125 z M 14.5 23.988281 A 1.50015 1.50015 0 0 0 13 25.488281 L 13 33.488281 A 1.50015 1.50015 0 0 0 14.5 34.988281 L 20.5 34.988281 A 1.50015 1.50015 0 0 0 22 33.488281 L 22 25.488281 A 1.50015 1.50015 0 0 0 20.5 23.988281 L 14.5 23.988281 z M 27.5 23.988281 A 1.50015 1.50015 0 0 0 26 25.488281 L 26 33.488281 A 1.50015 1.50015 0 0 0 27.5 34.988281 L 33.5 34.988281 A 1.50015 1.50015 0 0 0 35 33.488281 L 35 25.488281 A 1.50015 1.50015 0 0 0 33.5 23.988281 L 27.5 23.988281 z M 16 26.988281 L 19 26.988281 L 19 31.988281 L 16 31.988281 L 16 26.988281 z M 29 26.988281 L 32 26.988281 L 32 31.988281 L 29 31.988281 L 29 26.988281 z"
|
||||
/>
|
||||
</svg>
|
||||
<span>Житловий район</span>
|
||||
</label>
|
||||
<input
|
||||
type="radio"
|
||||
id="info-type-points"
|
||||
value="points"
|
||||
name="info-type"
|
||||
/>
|
||||
<label class="tab" for="info-type-points">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48">
|
||||
<path
|
||||
d="M 24 4 C 16.285455 4 10 10.285455 10 18 C 10 21.46372 11.272608 24.643548 13.359375 27.085938 L 13.359375 27.087891 L 13.361328 27.087891 C 13.361328 27.087891 19.149094 33.866566 21.298828 35.917969 C 22.798087 37.348278 25.199464 37.347492 26.699219 35.917969 C 29.129083 33.600994 34.636721 27.090553 34.640625 27.085938 L 34.642578 27.082031 C 36.728766 24.639939 38 21.462159 38 18 C 38 10.285455 31.714545 4 24 4 z M 24 7 C 30.093455 7 35 11.906545 35 18 C 35 20.73228 34.005417 23.211194 32.359375 25.136719 L 32.359375 25.138672 L 32.357422 25.138672 C 32.357422 25.138672 26.632181 31.83589 24.628906 33.746094 C 24.258577 34.099392 23.73947 34.099392 23.369141 33.746094 C 21.715477 32.16807 15.643092 25.141834 15.638672 25.136719 L 15.636719 25.132812 C 13.99327 23.20762 13 20.730712 13 18 C 13 11.906545 17.906545 7 24 7 z M 24 12 C 22.125 12 20.528815 12.757133 19.503906 13.910156 C 18.478997 15.063179 18 16.541667 18 18 C 18 19.458333 18.478997 20.936821 19.503906 22.089844 C 20.528815 23.242867 22.125 24 24 24 C 25.875 24 27.471185 23.242867 28.496094 22.089844 C 29.521003 20.936821 30 19.458333 30 18 C 30 16.541667 29.521003 15.063179 28.496094 13.910156 C 27.471185 12.757133 25.875 12 24 12 z M 24 15 C 25.124999 15 25.778816 15.367867 26.253906 15.902344 C 26.728997 16.436821 27 17.208333 27 18 C 27 18.791667 26.728997 19.563179 26.253906 20.097656 C 25.778816 20.632133 25.124999 21 24 21 C 22.875001 21 22.221184 20.632133 21.746094 20.097656 C 21.271003 19.563179 21 18.791667 21 18 C 21 17.208333 21.271003 16.436821 21.746094 15.902344 C 22.221184 15.367867 22.875001 15 24 15 z M 12.771484 29.441406 C 8.2264844 30.754406 5 32.953 5 36 C 5 41.252 14.558 44 24 44 C 33.442 44 43 41.252 43 36 C 43 32.954 39.775422 30.757359 35.232422 29.443359 C 34.654422 30.099359 33.863187 30.993844 32.992188 31.964844 C 37.418188 33.005844 40 34.691 40 36 C 40 38.039 33.767 41 24 41 C 14.233 41 8 38.039 8 36 C 8 34.69 10.586531 33.001938 15.019531 31.960938 C 14.152531 30.995938 13.355484 30.100406 12.771484 29.441406 z"
|
||||
/>
|
||||
</svg>
|
||||
<span>Точки на карті</span>
|
||||
</label>
|
||||
<span class="glider"></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="details-info-address" class="details-info-input">
|
||||
<label for="info-address-title">Назва вулиці</label>
|
||||
<input
|
||||
type="text"
|
||||
id="info-address-title"
|
||||
name="address"
|
||||
required
|
||||
value=""
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div id="details-info-number" class="details-info-input">
|
||||
<label for="info-number-title">Номер будинку</label>
|
||||
<input
|
||||
type="text"
|
||||
id="info-number-title"
|
||||
name="number"
|
||||
required
|
||||
value=""
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div id="details-info-settlement" class="details-info-input">
|
||||
<label for="info-settlement-title">Місто</label>
|
||||
<input
|
||||
type="text"
|
||||
id="info-settlement-title"
|
||||
name="settlement"
|
||||
required
|
||||
value="Тернопіль"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div id="details-info-group" class="details-info-input">
|
||||
<label for="info-group-title">Теократична група</label>
|
||||
<input
|
||||
type="number"
|
||||
id="info-group-title"
|
||||
name="group"
|
||||
required
|
||||
value=""
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div id="details-info-osm" class="details-info-input">
|
||||
<label for="info-settlement-title">OSM iD</label>
|
||||
<div>
|
||||
<input
|
||||
type="text"
|
||||
id="info-osm-title"
|
||||
name="osm"
|
||||
placeholder="123, 345, 678"
|
||||
required
|
||||
value=""
|
||||
/>
|
||||
<a href="https://www.openstreetmap.org/#map=19/49.561725/25.604458" target="_blank" title="Де знайти OSM iD ?"
|
||||
><svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 48 48"
|
||||
width="100px"
|
||||
height="100px"
|
||||
>
|
||||
<path
|
||||
d="M 24 4 C 12.972066 4 4 12.972074 4 24 C 4 35.027926 12.972066 44 24 44 C 35.027934 44 44 35.027926 44 24 C 44 12.972074 35.027934 4 24 4 z M 24 7 C 33.406615 7 41 14.593391 41 24 C 41 33.406609 33.406615 41 24 41 C 14.593385 41 7 33.406609 7 24 C 7 14.593391 14.593385 7 24 7 z M 24 14 A 2 2 0 0 0 24 18 A 2 2 0 0 0 24 14 z M 23.976562 20.978516 A 1.50015 1.50015 0 0 0 22.5 22.5 L 22.5 33.5 A 1.50015 1.50015 0 1 0 25.5 33.5 L 25.5 22.5 A 1.50015 1.50015 0 0 0 23.976562 20.978516 z"
|
||||
/></svg
|
||||
></a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button id="info-form-button" type="submit">Далі</button>
|
||||
</form>
|
||||
</details>
|
||||
|
||||
<details id="details-map" disabled>
|
||||
<summary id="details-map-title">
|
||||
<span>Крок 2.</span> Створення підїздів
|
||||
</summary>
|
||||
<form id="map-form">
|
||||
<div class="editor-buttons" id="details-map-buttons-entranse">
|
||||
<button type="button" onclick="Constructor.editor.drawEntranse()">
|
||||
Створити новий під'їзд
|
||||
</button>
|
||||
<div>
|
||||
<button type="button" id="ruler" onclick="Constructor.editor.drawRectangle()">
|
||||
Лінійка
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
id="ruler_divide"
|
||||
onclick="Constructor.editor.ruler()"
|
||||
style="display: none"
|
||||
>
|
||||
Поділити
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="editor-buttons"
|
||||
id="details-map-buttons-homestead"
|
||||
style="display: none"
|
||||
>
|
||||
<div>
|
||||
<button type="button" id="ruler" onclick="Constructor.editor.drawRectangle()">
|
||||
Лінійка
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
id="ruler_divide"
|
||||
onclick="Constructor.editor.ruler()"
|
||||
style="display: none"
|
||||
>
|
||||
Поділити
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="list-entranse" style="display: none"></div>
|
||||
<div id="list-homestead" style="display: none"></div>
|
||||
|
||||
<div class="block-map">
|
||||
<div id="map"></div>
|
||||
</div>
|
||||
<button id="map-form-button" type="submit">Далі</button>
|
||||
</form>
|
||||
</details>
|
||||
|
||||
<details id="details-area" disabled>
|
||||
<summary><span>Крок 3.</span> Конструктор квартир <input type="number" value="1" id="next-apartment-title" onchange="Constructor.apartments.editNum(this)" title="Авто-номер наступної квартири"></summary>
|
||||
|
||||
<form id="area-form">
|
||||
<div id="list-area"></div>
|
||||
|
||||
<button id="area-form-button" type="submit">Зберегти</button>
|
||||
</form>
|
||||
</details>
|
||||
</div>
|
||||
731
web/lib/pages/constructor/script.js
Normal file
@@ -0,0 +1,731 @@
|
||||
let map, houseGroup, entransePolygonsGroup, entranseNumPolygonsGroup, splitPolygonsGroup, RectangleGroup;
|
||||
let numApartments = 1;
|
||||
let mode = '';
|
||||
|
||||
|
||||
const Constructor = {
|
||||
info: {
|
||||
type: null,
|
||||
group_id: null,
|
||||
title: null,
|
||||
number: null,
|
||||
points: [],
|
||||
points_number: [],
|
||||
point_icons: [],
|
||||
geo: [],
|
||||
osm_id: [],
|
||||
settlement: [],
|
||||
description: null,
|
||||
entrance: [],
|
||||
apartments: {},
|
||||
zoom: null
|
||||
},
|
||||
init: async () => {
|
||||
let html = await fetch('/lib/pages/constructor/index.html').then((response) => response.text());
|
||||
app.innerHTML = html;
|
||||
|
||||
map = "";
|
||||
map = "";
|
||||
houseGroup = "";
|
||||
entransePolygonsGroup = "";
|
||||
entranseNumPolygonsGroup = "";
|
||||
splitPolygonsGroup = "";
|
||||
RectangleGroup = "";
|
||||
numApartments = 1;
|
||||
|
||||
Constructor.apartments.init();
|
||||
|
||||
document.querySelectorAll('input[name="info-type"]').forEach(radio => {
|
||||
radio.addEventListener('change', event => {
|
||||
console.log(`Выбран: ${event.target.value}`);
|
||||
Constructor.info.type = event.target.value;
|
||||
|
||||
let detailsInfo_number = document.getElementById('details-info-number');
|
||||
let detailsInfo_osm = document.getElementById('details-info-osm');
|
||||
let detailsInfo_number_title = document.getElementById('info-number-title');
|
||||
let detailsInfo_osm_title = document.getElementById('info-osm-title');
|
||||
|
||||
let detailsMap_title = document.getElementById('details-map-title');
|
||||
let detailsMap_buttons_entranse = document.getElementById('details-map-buttons-entranse');
|
||||
let detailsMap_buttons_homestead = document.getElementById('details-map-buttons-homestead');
|
||||
let detailsMap_button = document.getElementById('map-form-button');
|
||||
|
||||
|
||||
let detailsArea = document.getElementById('details-area');
|
||||
|
||||
switch (event.target.value) {
|
||||
case 'points':
|
||||
detailsInfo_number.style.display = "none";
|
||||
detailsInfo_osm.style.display = "none";
|
||||
detailsInfo_number_title.removeAttribute("required");
|
||||
detailsInfo_osm_title.removeAttribute("required");
|
||||
|
||||
detailsMap_title.innerHTML = "<span>Крок 2.</span> Створення точок на карті"
|
||||
detailsMap_buttons_entranse.style.display = "none";
|
||||
detailsMap_buttons_homestead.style.display = "none";
|
||||
detailsMap_button.innerText = "Зберегти";
|
||||
|
||||
detailsArea.style.display = "none";
|
||||
break;
|
||||
|
||||
case 'homestead':
|
||||
detailsInfo_number.style.display = "";
|
||||
detailsInfo_osm.style.display = "";
|
||||
detailsInfo_number_title.setAttribute("required", "");
|
||||
detailsInfo_osm_title.setAttribute("required", "");
|
||||
|
||||
detailsMap_title.innerHTML = "<span>Крок 2.</span> Створення житлових територій"
|
||||
detailsMap_buttons_entranse.style.display = "none";
|
||||
detailsMap_buttons_homestead.style.display = "";
|
||||
detailsMap_button.innerText = "Зберегти";
|
||||
|
||||
detailsArea.style.display = "none";
|
||||
break;
|
||||
|
||||
default:
|
||||
detailsInfo_number.style.display = "";
|
||||
detailsInfo_osm.style.display = "";
|
||||
detailsInfo_number_title.setAttribute("required", "");
|
||||
detailsInfo_osm_title.setAttribute("required", "");
|
||||
|
||||
detailsMap_title.innerHTML = "<span>Крок 2.</span> Створення підʼїздів"
|
||||
detailsMap_buttons_entranse.style.display = "";
|
||||
detailsMap_buttons_homestead.style.display = "none";
|
||||
detailsMap_button.innerText = "Далі";
|
||||
|
||||
detailsArea.style.display = "";
|
||||
break;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
document.getElementById("info-form").addEventListener("submit", function (event) {
|
||||
event.preventDefault();
|
||||
|
||||
let details_map = document.getElementById("details-map");
|
||||
details_map.removeAttribute("disabled");
|
||||
details_map.open = true;
|
||||
|
||||
const infoForm = document.getElementById("info-form");
|
||||
let osm = () => {
|
||||
const a = document.getElementById("info-osm-title").value;
|
||||
const b = a.replace(/\s+/g, "").split(',')
|
||||
|
||||
return b;
|
||||
}
|
||||
|
||||
Constructor.info.type = infoForm.querySelector('input[name="info-type"]:checked').value;
|
||||
Constructor.info.title = document.getElementById("info-address-title").value;
|
||||
Constructor.info.number = document.getElementById("info-number-title").value;
|
||||
Constructor.info.settlement = document.getElementById("info-settlement-title").value;
|
||||
Constructor.info.group_id = Number(document.getElementById("info-group-title").value);
|
||||
Constructor.info.osm_id = osm();
|
||||
|
||||
Constructor.osm.init();
|
||||
|
||||
Constructor.osm.setMap();
|
||||
})
|
||||
|
||||
document.getElementById("map-form").addEventListener("submit", async function (event) {
|
||||
event.preventDefault();
|
||||
|
||||
let details_area = document.getElementById("details-area");
|
||||
details_area.removeAttribute("disabled");
|
||||
details_area.open = true;
|
||||
|
||||
switch (Constructor.info.type) {
|
||||
case 'points':
|
||||
|
||||
break;
|
||||
|
||||
case 'homestead':
|
||||
await Constructor.api.setPack();
|
||||
break;
|
||||
|
||||
default:
|
||||
let details_area = document.getElementById("details-area");
|
||||
details_area.removeAttribute("disabled");
|
||||
details_area.open = true;
|
||||
break;
|
||||
}
|
||||
})
|
||||
|
||||
document.getElementById("area-form").addEventListener("submit", async function (event) {
|
||||
event.preventDefault();
|
||||
|
||||
await Constructor.api.setPack();
|
||||
})
|
||||
},
|
||||
apartments: {
|
||||
init: () => {
|
||||
let listArea = document.getElementById('list-area');
|
||||
listArea.innerHTML = ``;
|
||||
|
||||
for (const key in Constructor.info.apartments) {
|
||||
const element = Constructor.info.apartments[key];
|
||||
const pos = Constructor.info.entrance.map(e => e.editor_id).indexOf(key);
|
||||
console.log(element);
|
||||
|
||||
let listArea = document.getElementById('list-area');
|
||||
listArea.innerHTML += `
|
||||
<div class="block-area" id="block-area-${key}">
|
||||
<h3>${Constructor.info.entrance[pos].title}</h3>
|
||||
<button class="addFloors" title="Додати поверх" type="button" onclick="Constructor.apartments.addFloors('${key}')"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 26 26"><path d="M 6.65625 4 C 6.367188 4 6.105469 4.113281 5.90625 4.3125 L 4.3125 5.90625 C 3.914063 6.304688 3.914063 7 4.3125 7.5 L 9.8125 13 L 4.3125 18.5 C 3.914063 19 3.914063 19.695313 4.3125 20.09375 L 5.90625 21.6875 C 6.40625 22.085938 7.101563 22.085938 7.5 21.6875 L 13 16.1875 L 18.5 21.6875 C 19 22.085938 19.695313 22.085938 20.09375 21.6875 L 21.6875 20.09375 C 22.085938 19.59375 22.085938 18.898438 21.6875 18.5 L 16.1875 13 L 21.6875 7.5 C 22.085938 7 22.085938 6.304688 21.6875 5.90625 L 20.09375 4.3125 C 19.59375 3.914063 18.898438 3.914063 18.5 4.3125 L 13 9.8125 L 7.5 4.3125 C 7.25 4.113281 6.945313 4 6.65625 4 Z"></path></svg></button>
|
||||
|
||||
<div id="area-${key}"></div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
element.sort((a, b) => a.floors_number - b.floors_number);
|
||||
|
||||
let uniqueFloors = [...new Set(element.map(obj => obj.floors_number))];
|
||||
|
||||
for (let i = 0; i < uniqueFloors.length; i++) {
|
||||
let num = uniqueFloors[i];
|
||||
|
||||
let areaBlock = document.getElementById(`area-${key}`);
|
||||
|
||||
let div = document.createElement('div');
|
||||
div.className = "block-apartments-floors";
|
||||
div.id = `floors-${key}-${num}`
|
||||
div.innerHTML = `
|
||||
<button class="addApartment" id="buttonApartment-${key}-${num}" title="Додати квартиру" type="button" onclick="Constructor.apartments.addApartment('${key}', '${num}')"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 26 26"><path d="M 6.65625 4 C 6.367188 4 6.105469 4.113281 5.90625 4.3125 L 4.3125 5.90625 C 3.914063 6.304688 3.914063 7 4.3125 7.5 L 9.8125 13 L 4.3125 18.5 C 3.914063 19 3.914063 19.695313 4.3125 20.09375 L 5.90625 21.6875 C 6.40625 22.085938 7.101563 22.085938 7.5 21.6875 L 13 16.1875 L 18.5 21.6875 C 19 22.085938 19.695313 22.085938 20.09375 21.6875 L 21.6875 20.09375 C 22.085938 19.59375 22.085938 18.898438 21.6875 18.5 L 16.1875 13 L 21.6875 7.5 C 22.085938 7 22.085938 6.304688 21.6875 5.90625 L 20.09375 4.3125 C 19.59375 3.914063 18.898438 3.914063 18.5 4.3125 L 13 9.8125 L 7.5 4.3125 C 7.25 4.113281 6.945313 4 6.65625 4 Z"></path></svg></button>
|
||||
`;
|
||||
|
||||
areaBlock.prepend(div);
|
||||
}
|
||||
|
||||
element.sort((a, b) => b.title - a.title);
|
||||
|
||||
for (let i = 0; i < element.length; i++) {
|
||||
const apartment = element[i];
|
||||
let num = apartment.floors_number;
|
||||
|
||||
let floorsBlock = document.getElementById(`floors-${key}-${apartment.floors_number}`);
|
||||
|
||||
let div = document.createElement('div');
|
||||
div.className = "block-apartments-number";
|
||||
div.id = `block-apartments-${key}-${apartment.editor_id}`
|
||||
div.innerHTML = `
|
||||
<input type="text" value="${apartment.title}" id="apartament-${key}-${apartment.editor_id}" onchange="Constructor.apartments.editApartment('${key}','${apartment.editor_id}')">
|
||||
<button type="button" onclick="Constructor.apartments.deleteApartment('${key}','${apartment.editor_id}')">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 26 26"><path d="M 6.65625 4 C 6.367188 4 6.105469 4.113281 5.90625 4.3125 L 4.3125 5.90625 C 3.914063 6.304688 3.914063 7 4.3125 7.5 L 9.8125 13 L 4.3125 18.5 C 3.914063 19 3.914063 19.695313 4.3125 20.09375 L 5.90625 21.6875 C 6.40625 22.085938 7.101563 22.085938 7.5 21.6875 L 13 16.1875 L 18.5 21.6875 C 19 22.085938 19.695313 22.085938 20.09375 21.6875 L 21.6875 20.09375 C 22.085938 19.59375 22.085938 18.898438 21.6875 18.5 L 16.1875 13 L 21.6875 7.5 C 22.085938 7 22.085938 6.304688 21.6875 5.90625 L 20.09375 4.3125 C 19.59375 3.914063 18.898438 3.914063 18.5 4.3125 L 13 9.8125 L 7.5 4.3125 C 7.25 4.113281 6.945313 4 6.65625 4 Z"></path></svg>
|
||||
</button>
|
||||
`;
|
||||
|
||||
floorsBlock.prepend(div);
|
||||
}
|
||||
|
||||
element.sort((a, b) => b.floors_number - a.floors_number);
|
||||
}
|
||||
},
|
||||
editNum: (element) => {
|
||||
numApartments = Number(element.value);
|
||||
},
|
||||
addFloors: (area) => {
|
||||
let areaBlock = document.getElementById(`area-${area}`);
|
||||
|
||||
let uniqueFloors = [...new Set(Constructor.info.apartments[area].map(obj => obj.floors_number))];
|
||||
let new_floors = uniqueFloors.length + 1;
|
||||
let new_id = makeid(5);
|
||||
|
||||
let div = document.createElement('div');
|
||||
div.className = "block-apartments-floors";
|
||||
div.id = `floors-${area}-${new_floors}`
|
||||
div.innerHTML = `
|
||||
<h2>Поверх ${new_floors}</h2>
|
||||
<div class="block-apartments-number" id="block-apartments-${area}-${new_id}">
|
||||
<input type="text" value="${numApartments}" id="apartament-${area}-${new_id}" onchange="Constructor.apartments.editApartment('${area}', '${new_id}')">
|
||||
<button type="button" onclick="Constructor.apartments.deleteApartment('${area}', '${new_id}')">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 26 26"><path d="M 6.65625 4 C 6.367188 4 6.105469 4.113281 5.90625 4.3125 L 4.3125 5.90625 C 3.914063 6.304688 3.914063 7 4.3125 7.5 L 9.8125 13 L 4.3125 18.5 C 3.914063 19 3.914063 19.695313 4.3125 20.09375 L 5.90625 21.6875 C 6.40625 22.085938 7.101563 22.085938 7.5 21.6875 L 13 16.1875 L 18.5 21.6875 C 19 22.085938 19.695313 22.085938 20.09375 21.6875 L 21.6875 20.09375 C 22.085938 19.59375 22.085938 18.898438 21.6875 18.5 L 16.1875 13 L 21.6875 7.5 C 22.085938 7 22.085938 6.304688 21.6875 5.90625 L 20.09375 4.3125 C 19.59375 3.914063 18.898438 3.914063 18.5 4.3125 L 13 9.8125 L 7.5 4.3125 C 7.25 4.113281 6.945313 4 6.65625 4 Z"></path></svg>
|
||||
</button>
|
||||
</div>
|
||||
<button class="addApartment" id="buttonApartment-${area}-${new_floors}" title="Додати квартиру" type="button" onclick="Constructor.apartments.addApartment('${area}', '${new_floors}')"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 26 26"><path d="M 6.65625 4 C 6.367188 4 6.105469 4.113281 5.90625 4.3125 L 4.3125 5.90625 C 3.914063 6.304688 3.914063 7 4.3125 7.5 L 9.8125 13 L 4.3125 18.5 C 3.914063 19 3.914063 19.695313 4.3125 20.09375 L 5.90625 21.6875 C 6.40625 22.085938 7.101563 22.085938 7.5 21.6875 L 13 16.1875 L 18.5 21.6875 C 19 22.085938 19.695313 22.085938 20.09375 21.6875 L 21.6875 20.09375 C 22.085938 19.59375 22.085938 18.898438 21.6875 18.5 L 16.1875 13 L 21.6875 7.5 C 22.085938 7 22.085938 6.304688 21.6875 5.90625 L 20.09375 4.3125 C 19.59375 3.914063 18.898438 3.914063 18.5 4.3125 L 13 9.8125 L 7.5 4.3125 C 7.25 4.113281 6.945313 4 6.65625 4 Z"></path></svg></button>
|
||||
`
|
||||
|
||||
areaBlock.prepend(div);
|
||||
|
||||
Constructor.info.apartments[area].push({
|
||||
editor_id: new_id,
|
||||
entrance_id: null,
|
||||
apartment_number: Constructor.info.apartments[area].length,
|
||||
title: numApartments,
|
||||
floors_number: new_floors
|
||||
});
|
||||
|
||||
numApartments++;
|
||||
|
||||
let next_apartment_title = document.getElementById('next-apartment-title');
|
||||
next_apartment_title.value = numApartments;
|
||||
|
||||
},
|
||||
addApartment: (area, floors) => {
|
||||
let new_id = makeid(5);
|
||||
|
||||
Constructor.info.apartments[area].push({
|
||||
editor_id: new_id,
|
||||
entrance_id: null,
|
||||
apartment_number: Constructor.info.apartments[area].length,
|
||||
title: numApartments,
|
||||
floors_number: Number(floors)
|
||||
})
|
||||
|
||||
let floorsBlock = document.getElementById(`floors-${area}-${floors}`);
|
||||
document.getElementById(`buttonApartment-${area}-${floors}`).remove();
|
||||
|
||||
floorsBlock.innerHTML += `
|
||||
<div class="block-apartments-number" id="block-apartments-${area}-${new_id}">
|
||||
<input type="text" value="${numApartments}" id="apartament-${area}-${new_id}" onchange="Constructor.apartments.editApartment('${area}', '${new_id}')">
|
||||
<button type="button" onclick="Constructor.apartments.deleteApartment('${area}', '${new_id}')">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 26 26"><path d="M 6.65625 4 C 6.367188 4 6.105469 4.113281 5.90625 4.3125 L 4.3125 5.90625 C 3.914063 6.304688 3.914063 7 4.3125 7.5 L 9.8125 13 L 4.3125 18.5 C 3.914063 19 3.914063 19.695313 4.3125 20.09375 L 5.90625 21.6875 C 6.40625 22.085938 7.101563 22.085938 7.5 21.6875 L 13 16.1875 L 18.5 21.6875 C 19 22.085938 19.695313 22.085938 20.09375 21.6875 L 21.6875 20.09375 C 22.085938 19.59375 22.085938 18.898438 21.6875 18.5 L 16.1875 13 L 21.6875 7.5 C 22.085938 7 22.085938 6.304688 21.6875 5.90625 L 20.09375 4.3125 C 19.59375 3.914063 18.898438 3.914063 18.5 4.3125 L 13 9.8125 L 7.5 4.3125 C 7.25 4.113281 6.945313 4 6.65625 4 Z"></path></svg>
|
||||
</button>
|
||||
</div>
|
||||
`;
|
||||
floorsBlock.innerHTML += `<button class="addApartment" id="buttonApartment-${area}-${floors}" title="Додати квартиру" type="button" onclick="Constructor.apartments.addApartment('${area}', '${floors}')"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 26 26"><path d="M 6.65625 4 C 6.367188 4 6.105469 4.113281 5.90625 4.3125 L 4.3125 5.90625 C 3.914063 6.304688 3.914063 7 4.3125 7.5 L 9.8125 13 L 4.3125 18.5 C 3.914063 19 3.914063 19.695313 4.3125 20.09375 L 5.90625 21.6875 C 6.40625 22.085938 7.101563 22.085938 7.5 21.6875 L 13 16.1875 L 18.5 21.6875 C 19 22.085938 19.695313 22.085938 20.09375 21.6875 L 21.6875 20.09375 C 22.085938 19.59375 22.085938 18.898438 21.6875 18.5 L 16.1875 13 L 21.6875 7.5 C 22.085938 7 22.085938 6.304688 21.6875 5.90625 L 20.09375 4.3125 C 19.59375 3.914063 18.898438 3.914063 18.5 4.3125 L 13 9.8125 L 7.5 4.3125 C 7.25 4.113281 6.945313 4 6.65625 4 Z"></path></svg></button>`
|
||||
|
||||
numApartments++;
|
||||
|
||||
let next_apartment_title = document.getElementById('next-apartment-title');
|
||||
next_apartment_title.value = numApartments;
|
||||
},
|
||||
editApartment: (area, apartament) => {
|
||||
let input = document.getElementById(`apartament-${area}-${apartament}`);
|
||||
input.setAttribute("value", input.value);
|
||||
|
||||
const pos = Constructor.info.apartments[area].map(e => e.editor_id).indexOf(apartament);
|
||||
|
||||
info.apartments[area][pos].title = input.value;
|
||||
},
|
||||
deleteApartment: (area, apartament) => {
|
||||
document.getElementById(`block-apartments-${area}-${apartament}`).remove();
|
||||
const pos = Constructor.info.apartments[area].map(e => e.editor_id).indexOf(apartament);
|
||||
Constructor.info.apartments[area].splice(pos, 1);
|
||||
|
||||
numApartments--;
|
||||
let next_apartment_title = document.getElementById('next-apartment-title');
|
||||
next_apartment_title.value = numApartments;
|
||||
}
|
||||
},
|
||||
osm: {
|
||||
init: () => {
|
||||
let center = { lat: 49.5629016, lng: 25.6145625 };
|
||||
let zoom = 19;
|
||||
|
||||
let googleHybrid = L.tileLayer('http://{s}.google.com/vt/lyrs=s,h&x={x}&y={y}&z={z}', {
|
||||
maxZoom: 20,
|
||||
minZoom: 15,
|
||||
subdomains: ['mt0', 'mt1', 'mt2', 'mt3']
|
||||
});
|
||||
|
||||
let osm = L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
|
||||
maxZoom: 19,
|
||||
minZoom: 15
|
||||
});
|
||||
|
||||
let mytile = L.tileLayer('https://tm.rozenrod.com/webp/{z}/{x}/{y}.webp', {
|
||||
maxZoom: 20,
|
||||
minZoom: 15,
|
||||
tms: true
|
||||
});
|
||||
|
||||
if (!map) {
|
||||
|
||||
houseGroup = new L.FeatureGroup();
|
||||
splitPolygonsGroup = new L.FeatureGroup();
|
||||
RectangleGroup = new L.FeatureGroup();
|
||||
entransePolygonsGroup = new L.FeatureGroup();
|
||||
entranseNumPolygonsGroup = new L.FeatureGroup();
|
||||
|
||||
map = L.map('map', {
|
||||
renderer: L.canvas(),
|
||||
center,
|
||||
zoom,
|
||||
layers: [
|
||||
googleHybrid,
|
||||
osm,
|
||||
mytile,
|
||||
houseGroup,
|
||||
entransePolygonsGroup,
|
||||
entranseNumPolygonsGroup,
|
||||
splitPolygonsGroup,
|
||||
RectangleGroup,
|
||||
],
|
||||
zoomControl: false
|
||||
});
|
||||
|
||||
|
||||
let baseMaps = {
|
||||
"Google Hybrid": googleHybrid,
|
||||
"OpenStreetMap": osm,
|
||||
"Territory Map": mytile
|
||||
};
|
||||
let overlayMaps = {
|
||||
"Будинки": houseGroup,
|
||||
"Під'їзди": entransePolygonsGroup,
|
||||
"Номера під'їздів": entranseNumPolygonsGroup,
|
||||
"Слой редактирования": splitPolygonsGroup,
|
||||
"Слой линейки": RectangleGroup,
|
||||
};
|
||||
|
||||
L.control.layers(baseMaps, overlayMaps, { position: 'bottomright' }).addTo(map);
|
||||
|
||||
map.pm.setLang("ua");
|
||||
|
||||
map.pm.addControls({
|
||||
position: 'bottomright',
|
||||
drawCircleMarker: false,
|
||||
drawPolyline: false,
|
||||
drawPolygon: false,
|
||||
drawRectangle: false,
|
||||
drawCircle: false,
|
||||
drawText: false,
|
||||
drawMarker: false,
|
||||
cutPolygon: false,
|
||||
tooltips: false
|
||||
});
|
||||
map.pm.toggleControls()
|
||||
|
||||
map.pm.setGlobalOptions({
|
||||
layerGroup: splitPolygonsGroup
|
||||
})
|
||||
}
|
||||
|
||||
Constructor.editor.init();
|
||||
},
|
||||
getOSM: async (wayId) => {
|
||||
const overpassUrl = `https://overpass-api.de/api/interpreter?data=[out:json];way(${wayId});(._;>;);out;`;
|
||||
|
||||
return await fetch(overpassUrl)
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
const nodes = new Map();
|
||||
|
||||
data.elements.forEach(el => {
|
||||
if (el.type === "node") {
|
||||
nodes.set(el.id, { lat: el.lat, lng: el.lon });
|
||||
}
|
||||
});
|
||||
|
||||
const way = data.elements.find(el => el.type === "way");
|
||||
if (way) {
|
||||
const coordinates = way.nodes.map(nodeId => nodes.get(nodeId));
|
||||
console.log("Координаты точек:", coordinates);
|
||||
|
||||
return [coordinates];
|
||||
} else {
|
||||
console.log("Way не найден!");
|
||||
}
|
||||
})
|
||||
.catch(error => console.error("Ошибка запроса:", error));
|
||||
},
|
||||
setMap: async () => {
|
||||
houseGroup.clearLayers();
|
||||
|
||||
if (!Constructor.info.osm_id) {
|
||||
let osm = () => {
|
||||
const a = document.getElementById("info-osm-title").value;
|
||||
const b = a.replace(/\s+/g, "").split(',')
|
||||
|
||||
return b;
|
||||
}
|
||||
Constructor.info.osm_id = osm();
|
||||
}
|
||||
|
||||
for (let i = 0; i < Constructor.info.osm_id.length; i++) {
|
||||
const element = await Constructor.osm.getOSM(Constructor.info.osm_id[i]);
|
||||
let coords = [];
|
||||
element[0].forEach((feature) => coords.push([feature.lat, feature.lng]));
|
||||
|
||||
let centerPoint = turf.centerOfMass(turf.polygon([coords]));
|
||||
|
||||
|
||||
if (Constructor.info.type == "homestead") {
|
||||
map.setView([centerPoint.geometry.coordinates[0], centerPoint.geometry.coordinates[1]], 17);
|
||||
|
||||
L.polygon(element, {
|
||||
color: colorGroup(Constructor.info.group_id),
|
||||
radius: 500,
|
||||
fillOpacity: 0.3,
|
||||
dashArray: '20, 15',
|
||||
dashOffset: '20',
|
||||
}).addTo(houseGroup);
|
||||
} else if (Constructor.info.type == "house") {
|
||||
map.setView([centerPoint.geometry.coordinates[0], centerPoint.geometry.coordinates[1]], 18);
|
||||
|
||||
Constructor.info.points.push(element);
|
||||
Constructor.info.points_number.push(element[0][0]);
|
||||
|
||||
L.polygon(element, {
|
||||
color: "#585858",
|
||||
fillColor: colorGroup(Constructor.info.group_id),
|
||||
fillOpacity: 0.8,
|
||||
tm_id: `house_${i}`
|
||||
}).addTo(houseGroup);
|
||||
}
|
||||
}
|
||||
|
||||
console.log(Constructor.info);
|
||||
|
||||
}
|
||||
},
|
||||
api: {
|
||||
setPack: async () => {
|
||||
let area_form_button = document.getElementById('area-form-button');
|
||||
area_form_button.innerText = "Зачекайте...";
|
||||
|
||||
Constructor.info.geo = await map.getCenter();
|
||||
Constructor.info.zoom = await map.getZoom();
|
||||
|
||||
console.log(Constructor.info);
|
||||
|
||||
const uuid = localStorage.getItem('uuid');
|
||||
const URL = `${CONFIG.api}constructor`;
|
||||
await fetch(URL, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"Authorization": uuid
|
||||
},
|
||||
body: JSON.stringify(Constructor.info)
|
||||
})
|
||||
.then(response => {
|
||||
if (response.status == 200) {
|
||||
console.log({ 'setPack': 'ok' });
|
||||
area_form_button.innerText = "Запис додано";
|
||||
|
||||
return response.json()
|
||||
} else {
|
||||
console.log('err');
|
||||
area_form_button.innerText = "Помилка запису";
|
||||
|
||||
return
|
||||
}
|
||||
})
|
||||
.then(data => {
|
||||
console.log(data);
|
||||
|
||||
Router.navigate((`/territory/manager/${Constructor.info.type}/${data.id}`).replace(window.location.origin, ''));
|
||||
|
||||
setTimeout(() => {
|
||||
area_form_button.innerText = "Зберегти";
|
||||
}, 3000);
|
||||
})
|
||||
.catch(err => {
|
||||
console.log(err);
|
||||
area_form_button.innerText = "Помилка запису";
|
||||
})
|
||||
}
|
||||
},
|
||||
editor: {
|
||||
init: () => {
|
||||
map.on('pm:create', function (event) {
|
||||
let layer = event.layer;
|
||||
|
||||
let newCoords = layer.getLatLngs()[0].map(function (coords) {
|
||||
return [coords.lng, coords.lat];
|
||||
});
|
||||
newCoords.push(newCoords[0]);
|
||||
let turfNew = turf.polygon([newCoords]);
|
||||
|
||||
if (mode == 'entranse') {
|
||||
console.log(L.PM.Utils.findLayers(houseGroup));
|
||||
for (let i = 0; i < L.PM.Utils.findLayers(houseGroup).length; i++) {
|
||||
const polygon = L.PM.Utils.findLayers(houseGroup)[i]._latlngs;
|
||||
|
||||
let polygonCoords = polygon[0].map(function (coords) {
|
||||
return [coords.lng, coords.lat];
|
||||
});
|
||||
polygonCoords.push(polygonCoords[0]); // Замикаємо полігон
|
||||
let turfPolygon = turf.polygon([polygonCoords]);
|
||||
|
||||
// Пошук точки перехрестя
|
||||
let intersections = turf.intersect(turfNew, turfPolygon);
|
||||
|
||||
if (intersections) {
|
||||
let points = [];
|
||||
let coords = [];
|
||||
|
||||
intersections.geometry.coordinates[0].forEach(function (feature) {
|
||||
coords.push([feature[1], feature[0]])
|
||||
points.push({ lat: feature[1], lng: feature[0] })
|
||||
});
|
||||
|
||||
let centerPoint = turf.centerOfMass(turf.polygon([coords]));
|
||||
|
||||
let points_number = { lat: centerPoint.geometry.coordinates[0], lng: centerPoint.geometry.coordinates[1] }
|
||||
|
||||
let newID = makeid(6);
|
||||
|
||||
Constructor.info.entrance.push({
|
||||
editor_id: newID,
|
||||
house_id: null,
|
||||
entrance_number: Constructor.info.entrance.length,
|
||||
title: `Під'їзд ${Constructor.info.entrance.length + 1}`,
|
||||
points: points,
|
||||
points_number: points_number,
|
||||
floors_quantity: null,
|
||||
apartments_quantity: null,
|
||||
created_at: null
|
||||
})
|
||||
|
||||
Constructor.info.apartments[newID] = [];
|
||||
Constructor.apartments.init();
|
||||
|
||||
let listEntranse = document.getElementById('list-entranse');
|
||||
listEntranse.style.display = "";
|
||||
listEntranse.innerHTML += `
|
||||
<div class="house" style="align-items: center;" id="Entranse_${newID}">
|
||||
<input type="number" value="${Constructor.info.entrance.length}" id="Entranse_input_${newID}" onchange="Constructor.editor.editEntranse('${newID}')">
|
||||
<button type="button" onclick="Constructor.editor.dellEntranse('${newID}')">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 26 26"><path d="M 6.65625 4 C 6.367188 4 6.105469 4.113281 5.90625 4.3125 L 4.3125 5.90625 C 3.914063 6.304688 3.914063 7 4.3125 7.5 L 9.8125 13 L 4.3125 18.5 C 3.914063 19 3.914063 19.695313 4.3125 20.09375 L 5.90625 21.6875 C 6.40625 22.085938 7.101563 22.085938 7.5 21.6875 L 13 16.1875 L 18.5 21.6875 C 19 22.085938 19.695313 22.085938 20.09375 21.6875 L 21.6875 20.09375 C 22.085938 19.59375 22.085938 18.898438 21.6875 18.5 L 16.1875 13 L 21.6875 7.5 C 22.085938 7 22.085938 6.304688 21.6875 5.90625 L 20.09375 4.3125 C 19.59375 3.914063 18.898438 3.914063 18.5 4.3125 L 13 9.8125 L 7.5 4.3125 C 7.25 4.113281 6.945313 4 6.65625 4 Z"></path></svg>
|
||||
</button>
|
||||
</div>
|
||||
`;
|
||||
|
||||
L.polygon(coords, { color: 'red' }).addTo(entransePolygonsGroup);
|
||||
|
||||
let myIcon = L.divIcon({ className: 'entranse_number', html: `<div class="markerEntranse">${Constructor.info.entrance.length}</div>` });
|
||||
L.marker(centerPoint.geometry.coordinates, { icon: myIcon }).addTo(entranseNumPolygonsGroup);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
drawEntranse: () => {
|
||||
mode = 'entranse';
|
||||
|
||||
map.pm.setGlobalOptions({
|
||||
layerGroup: splitPolygonsGroup
|
||||
})
|
||||
map.pm.setPathOptions({
|
||||
color: '#f2bd53',
|
||||
fillColor: '#f2bd53',
|
||||
fillOpacity: 0.5,
|
||||
radius: 500
|
||||
});
|
||||
|
||||
if (map.pm.globalDragModeEnabled()) {
|
||||
map.pm.disableDraw();
|
||||
} else {
|
||||
map.pm.enableDraw("Polygon", {
|
||||
snappable: true,
|
||||
snapDistance: 20,
|
||||
tooltips: false,
|
||||
templineStyle: { color: '#f2bd53' },
|
||||
hintlineStyle: { color: '#f2bd53', dashArray: [5, 5] }
|
||||
});
|
||||
}
|
||||
},
|
||||
drawRectangle: () => {
|
||||
mode = 'rectangle';
|
||||
|
||||
document.getElementById('ruler_divide').style.display = 'block'
|
||||
document.getElementById('ruler').style.width = "calc(50% - 5px)"
|
||||
document.getElementById('ruler_divide').style.width = "calc(50% - 5px)"
|
||||
document.getElementById('ruler').innerHTML = 'Лінійка'
|
||||
|
||||
map.pm.toggleControls()
|
||||
RectangleGroup.clearLayers();
|
||||
RectangleGroup.addTo(map);
|
||||
|
||||
map.pm.setGlobalOptions({
|
||||
layerGroup: RectangleGroup
|
||||
})
|
||||
map.pm.setPathOptions({
|
||||
color: '#b645ef',
|
||||
fillColor: '#b645ef',
|
||||
fillOpacity: 0.5,
|
||||
radius: 500
|
||||
});
|
||||
|
||||
if (map.pm.globalDragModeEnabled()) {
|
||||
map.pm.disableDraw();
|
||||
} else {
|
||||
map.pm.enableDraw("Rectangle", {
|
||||
snappable: true,
|
||||
snapDistance: 20,
|
||||
tooltips: false,
|
||||
templineStyle: { color: '#b645ef' },
|
||||
hintlineStyle: { color: '#b645ef', dashArray: [5, 5] }
|
||||
});
|
||||
}
|
||||
},
|
||||
ruler: (n) => {
|
||||
n = prompt('На сколько поделить линейку ?', 2);
|
||||
const polygon = L.PM.Utils.findLayers(RectangleGroup)[0]._latlngs;
|
||||
let newCoords = polygon[0].map(function (coords) {
|
||||
return [coords.lng, coords.lat];
|
||||
});
|
||||
newCoords.push(newCoords[0]);
|
||||
let turfNew = turf.polygon([newCoords]);
|
||||
|
||||
console.log(turfNew);
|
||||
|
||||
|
||||
var line = turf.polygonToLine(turfNew);
|
||||
console.log(line.geometry.coordinates);
|
||||
|
||||
coords = line.geometry.coordinates;
|
||||
|
||||
for (let i = 1; i < n; i++) {
|
||||
let a1 = (((coords[2][1] - coords[1][1]) / n) * i + coords[1][1])
|
||||
let b1 = (((coords[2][0] - coords[1][0]) / n) * i + coords[1][0])
|
||||
let a2 = (((coords[3][1] - coords[0][1]) / n) * i + coords[0][1])
|
||||
let b2 = (((coords[3][0] - coords[0][0]) / n) * i + coords[0][0])
|
||||
|
||||
let c1 = (((coords[1][1] - coords[0][1]) / n) * i + coords[0][1])
|
||||
let d1 = (((coords[1][0] - coords[0][0]) / n) * i + coords[0][0])
|
||||
let c2 = (((coords[2][1] - coords[3][1]) / n) * i + coords[3][1])
|
||||
let d2 = (((coords[2][0] - coords[3][0]) / n) * i + coords[3][0])
|
||||
|
||||
L.circleMarker([a1, b1], { radius: 2, color: 'red' }).addTo(RectangleGroup);
|
||||
L.circleMarker([a2, b2], { radius: 2, color: 'red' }).addTo(RectangleGroup);
|
||||
L.circleMarker([c1, d1], { radius: 2, color: 'red' }).addTo(RectangleGroup);
|
||||
L.circleMarker([c2, d2], { radius: 2, color: 'red' }).addTo(RectangleGroup);
|
||||
}
|
||||
|
||||
coords.forEach(function (feature) {
|
||||
L.circleMarker([feature[1], feature[0]], { radius: 2, color: 'red' }).addTo(RectangleGroup);
|
||||
});
|
||||
},
|
||||
dellEntranse: (id) => {
|
||||
delete Constructor.info.apartments[id];
|
||||
|
||||
const pos = Constructor.info.entrance.map(e => e.editor_id).indexOf(id);
|
||||
console.log(pos);
|
||||
|
||||
|
||||
Constructor.info.entrance.splice(pos, 1);
|
||||
console.log(id);
|
||||
|
||||
document.getElementById(`Entranse_${id}`).remove();
|
||||
|
||||
let Entranse = Object.keys(entransePolygonsGroup._layers);
|
||||
let numsEntranse = Object.keys(entranseNumPolygonsGroup._layers);
|
||||
console.log(Entranse, Entranse[pos]);
|
||||
console.log(numsEntranse, numsEntranse[pos]);
|
||||
|
||||
entransePolygonsGroup.removeLayer(entransePolygonsGroup._layers[Entranse[pos]]);
|
||||
entranseNumPolygonsGroup.removeLayer(entranseNumPolygonsGroup._layers[numsEntranse[pos]]);
|
||||
|
||||
Constructor.apartments.init();
|
||||
},
|
||||
editEntranse: (id) => {
|
||||
const input = document.getElementById(`Entranse_input_${id}`);
|
||||
|
||||
const pos = Constructor.info.entrance.map(e => e.editor_id).indexOf(id);
|
||||
|
||||
Constructor.info.entrance[pos].entrance_number = Number(input.value) - 1;
|
||||
Constructor.info.entrance[pos].title = `Під'їзд ${input.value}`;
|
||||
|
||||
let numsEntranse = Object.keys(entranseNumPolygonsGroup._layers);
|
||||
let newIcon = L.divIcon({ className: 'entranse_number', html: `<div class="markerEntranse">${input.value}</div>` });
|
||||
entranseNumPolygonsGroup._layers[numsEntranse[pos]].setIcon(newIcon);
|
||||
|
||||
input.setAttribute("value", input.value);
|
||||
|
||||
Constructor.apartments.init();
|
||||
}
|
||||
}
|
||||
}
|
||||
494
web/lib/pages/constructor/style.css
Normal file
@@ -0,0 +1,494 @@
|
||||
.page-constructor {
|
||||
width: calc(100% - 40px);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
margin: 20px 20px 0 20px;
|
||||
}
|
||||
|
||||
.page-constructor form>button {
|
||||
border-radius: 6px;
|
||||
background: var(--PrimaryColor);
|
||||
color: var(--PrimaryColorText);
|
||||
width: 100%;
|
||||
height: 40px;
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
margin: 20px 0;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.page-constructor details {
|
||||
border-radius: 10px;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
margin-bottom: 20px;
|
||||
background: var(--ColorThemes1);
|
||||
color: var(--ColorThemes3);
|
||||
border: 1px solid var(--ColorThemes2);
|
||||
box-shadow: var(--shadow-l1);
|
||||
}
|
||||
|
||||
.page-constructor>details[disabled] summary,
|
||||
.page-constructor>details.disabled summary {
|
||||
pointer-events: none;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.page-constructor>details summary::-webkit-details-marker,
|
||||
.page-constructor>details summary::marker {
|
||||
display: none;
|
||||
content: "";
|
||||
}
|
||||
|
||||
.page-constructor summary {
|
||||
width: calc(100% - 40px);
|
||||
cursor: pointer;
|
||||
color: var(--ColorThemes3);
|
||||
border-radius: var(--border-radius);
|
||||
font-size: 16px;
|
||||
font-weight: 300;
|
||||
padding: 20px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.page-constructor summary span {
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.page-constructor summary input {
|
||||
font-weight: 500;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
padding: 10px;
|
||||
margin: 13px;
|
||||
font-size: 12px;
|
||||
background: var(--ColorThemes3);
|
||||
color: var(--ColorThemes0);
|
||||
border-radius: 6px;
|
||||
width: 40px;
|
||||
}
|
||||
|
||||
.page-constructor #info-form,
|
||||
.page-constructor #map-form,
|
||||
.page-constructor #area-form {
|
||||
padding: 0 20px;
|
||||
}
|
||||
|
||||
#details-info-type {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
#details-info-type>.tabs {
|
||||
display: flex;
|
||||
position: relative;
|
||||
background-color: var(--ColorThemes0);
|
||||
padding: 4px;
|
||||
border-radius: 6px;
|
||||
width: calc(100% - 8px);
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
#details-info-type>.tabs>input[type="radio"] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#details-info-type>.tabs>.tab {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 40px;
|
||||
width: calc(100% / 3);
|
||||
cursor: pointer;
|
||||
padding: 0 15px;
|
||||
transition: 0.15s ease-in;
|
||||
color: var(--ColorThemes3);
|
||||
fill: var(--ColorThemes3);
|
||||
flex-direction: row;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
#details-info-type>.tabs>.tab>svg {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
}
|
||||
|
||||
#details-info-type>.tabs>.tab>span {
|
||||
margin-left: 6px;
|
||||
font-size: 12px;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
#details-info-type>.tabs>input[type="radio"]:checked+label {
|
||||
color: var(--PrimaryColorText);
|
||||
fill: var(--PrimaryColorText);
|
||||
}
|
||||
|
||||
#details-info-type>.tabs>.glider {
|
||||
position: absolute;
|
||||
display: flex;
|
||||
height: 40px;
|
||||
width: calc((100% - 8px) / 3);
|
||||
background-color: var(--PrimaryColor);
|
||||
z-index: 1;
|
||||
border-radius: 4px;
|
||||
transition: 0.25s ease-out;
|
||||
}
|
||||
|
||||
@media (min-width: 601px) {
|
||||
#details-info-type>.tabs>input[id="info-type-house"]:checked~.glider {
|
||||
transform: translateX(0);
|
||||
}
|
||||
|
||||
#details-info-type>.tabs>input[id="info-type-homestead"]:checked~.glider {
|
||||
transform: translateX(100%);
|
||||
}
|
||||
|
||||
#details-info-type>.tabs>input[id="info-type-points"]:checked~.glider {
|
||||
transform: translateX(200%);
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 600px) {
|
||||
#details-info-type>.tabs {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
#details-info-type>.tabs>.tab {
|
||||
width: calc(100% - 8px);
|
||||
padding: 0 4px;
|
||||
}
|
||||
|
||||
#details-info-type>.tabs>.glider {
|
||||
width: calc(100% - 8px);
|
||||
}
|
||||
|
||||
#details-info-type>.tabs>input[id="info-type-house"]:checked~.glider {
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
#details-info-type>.tabs>input[id="info-type-homestead"]:checked~.glider {
|
||||
transform: translateY(100%);
|
||||
}
|
||||
|
||||
#details-info-type>.tabs>input[id="info-type-points"]:checked~.glider {
|
||||
transform: translateY(200%);
|
||||
}
|
||||
}
|
||||
|
||||
.page-constructor .details-info-input {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
margin: 20px 0;
|
||||
align-items: flex-start;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.page-constructor .details-info-input label {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
margin-bottom: 5px;
|
||||
|
||||
}
|
||||
|
||||
.page-constructor .details-info-input input {
|
||||
width: calc(100% - 10px);
|
||||
min-width: 140px;
|
||||
padding: 0 5px;
|
||||
border-radius: 6px;
|
||||
height: 30px;
|
||||
background: var(--ColorThemes0);
|
||||
color: var(--ColorThemes3);
|
||||
}
|
||||
|
||||
.page-constructor #details-info-osm div {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.page-constructor #details-info-osm input {
|
||||
width: calc(100% - 10px);
|
||||
min-width: 140px;
|
||||
padding: 0 5px;
|
||||
border-radius: 6px;
|
||||
height: 30px;
|
||||
}
|
||||
|
||||
.page-constructor .details-info-input a {
|
||||
height: 26px;
|
||||
width: 26px;
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
.page-constructor .details-info-input a>svg {
|
||||
height: 26px;
|
||||
width: 26px;
|
||||
fill: var(--ColorThemes3)
|
||||
}
|
||||
|
||||
.page-constructor #list-area {
|
||||
margin-top: 15px;
|
||||
display: flex;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.page-constructor #list-area h3 {
|
||||
text-align: center;
|
||||
font-size: 16px;
|
||||
font-weight: 400;
|
||||
margin: 10px;
|
||||
padding: 7px;
|
||||
color: var(--ColorThemes0);
|
||||
background: var(--ColorThemes3);
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.block-area {
|
||||
min-height: 200px;
|
||||
border: 1px solid var(--ColorThemes3);
|
||||
border-style: dashed;
|
||||
border-radius: 6px;
|
||||
margin: 0 10px 10px 0;
|
||||
}
|
||||
|
||||
.addFloors,
|
||||
.addApartment {
|
||||
display: flex;
|
||||
position: relative;
|
||||
width: 34px;
|
||||
height: 34px;
|
||||
background: var(--PrimaryColor);
|
||||
color: var(--PrimaryColorText);
|
||||
margin: 25px;
|
||||
border-radius: 50%;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 30px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.addFloors>svg,
|
||||
.addApartment>svg {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
fill: var(--PrimaryColorText);
|
||||
transform: rotate(45deg);
|
||||
}
|
||||
|
||||
.block-apartments-floors {
|
||||
position: relative;
|
||||
display: flex;
|
||||
width: calc(100% - 22px);
|
||||
border: 1px solid var(--ColorThemes3);
|
||||
margin: 10px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.block-apartments-floors h2 {
|
||||
position: absolute;
|
||||
width: 65px;
|
||||
right: -1px;
|
||||
top: -1px;
|
||||
margin: 0;
|
||||
background: var(--ColorThemes3);
|
||||
color: var(--ColorThemes2);
|
||||
border-radius: 0 4px 0 4px;
|
||||
font-size: 12px;
|
||||
padding: 2px 4px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.block-apartments-number {
|
||||
display: flex;
|
||||
position: relative;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
background: var(--ColorThemes1);
|
||||
border: 2px solid var(--PrimaryColor);
|
||||
margin: 10px;
|
||||
border-radius: 4px;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.block-apartments-number input {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
font-size: 16px;
|
||||
font-weight: 400;
|
||||
text-align: center;
|
||||
color: var(--ColorThemes3);
|
||||
background: 0;
|
||||
}
|
||||
|
||||
.block-apartments-number button {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
border-radius: 0 4px 0 4px;
|
||||
background: var(--PrimaryColor);
|
||||
font-size: 16px;
|
||||
margin: -2px;
|
||||
border: 0;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.block-apartments-number button>svg {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
fill: var(--PrimaryColorText);
|
||||
}
|
||||
|
||||
|
||||
.block-map {
|
||||
width: 100%;
|
||||
height: 500px;
|
||||
border-radius: 6px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
#map {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.entranse_number {
|
||||
left: -10px !important;
|
||||
top: -10px !important;
|
||||
}
|
||||
|
||||
.markerEntranse {
|
||||
background: hsl(0deg 0% 52.12% / 90%);
|
||||
font-size: 24px;
|
||||
border: 2px solid #676767;
|
||||
border-radius: 2px;
|
||||
display: flex !important;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
color: #fff;
|
||||
min-width: 30px;
|
||||
min-height: 30px;
|
||||
height: 30px;
|
||||
width: 30px;
|
||||
}
|
||||
|
||||
.editor-buttons {
|
||||
margin-top: 15px;
|
||||
}
|
||||
|
||||
.editor-buttons>button {
|
||||
width: 100%;
|
||||
min-height: 30px;
|
||||
margin: 5px 0;
|
||||
border: 0;
|
||||
color: var(--PrimaryColorText);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: var(--PrimaryColor);
|
||||
text-transform: uppercase;
|
||||
cursor: pointer;
|
||||
border-radius: 6px;
|
||||
font-weight: 400;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.editor-buttons>div {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
margin: 10px 0;
|
||||
height: 30px;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.editor-buttons>div>button {
|
||||
background: var(--ColorThemes3);
|
||||
color: var(--ColorThemes1);
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
border-radius: 6px;
|
||||
text-transform: uppercase;
|
||||
font-weight: 400;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.page-constructor #list-entranse,
|
||||
.page-constructor #list-homestead {
|
||||
width: 100%;
|
||||
min-height: 86px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: nowrap;
|
||||
overflow-x: initial;
|
||||
overflow-y: auto;
|
||||
border: 1px solid var(--ColorThemes3);
|
||||
background: 0;
|
||||
border-radius: 6px;
|
||||
border-style: dashed;
|
||||
margin: 10px 0;
|
||||
}
|
||||
|
||||
.page-constructor #list-entranse>.house,
|
||||
.page-constructor #list-homestead>.house {
|
||||
display: flex;
|
||||
position: relative;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
background: var(--ColorThemes1);
|
||||
border: 2px solid var(--PrimaryColor);
|
||||
margin: 10px;
|
||||
border-radius: 4px;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
|
||||
.page-constructor #list-entranse>.house>input,
|
||||
.page-constructor #list-homestead>.house>input {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
font-size: 16px;
|
||||
font-weight: 400;
|
||||
text-align: center;
|
||||
color: var(--ColorThemes3);
|
||||
background: 0;
|
||||
}
|
||||
|
||||
.page-constructor #list-entranse>.house>button,
|
||||
.page-constructor #list-homestead>.house>button {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
border-radius: 0 4px 0 4px;
|
||||
background: var(--PrimaryColor);
|
||||
font-size: 16px;
|
||||
margin: -2px;
|
||||
border: 0;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.page-constructor #list-entranse>.house>button>svg,
|
||||
.page-constructor #list-homestead>.house>button>svg {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
fill: var(--PrimaryColorText);
|
||||
}
|
||||
139
web/lib/pages/editor/index.html
Normal file
@@ -0,0 +1,139 @@
|
||||
<div class="page-editor">
|
||||
<details id="details-info" open>
|
||||
<summary>
|
||||
<span>Крок 1.</span> Інформація про будинок, територію, точки на карті
|
||||
</summary>
|
||||
<form id="info-form">
|
||||
<div id="details-info-address" class="details-info-input">
|
||||
<label for="info-address-title">Назва вулиці</label>
|
||||
<input
|
||||
type="text"
|
||||
id="info-address-title"
|
||||
name="address"
|
||||
required
|
||||
value=""
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div id="details-info-number" class="details-info-input">
|
||||
<label for="info-number-title">Номер будинку</label>
|
||||
<input
|
||||
type="text"
|
||||
id="info-number-title"
|
||||
name="number"
|
||||
required
|
||||
value=""
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div id="details-info-settlement" class="details-info-input">
|
||||
<label for="info-settlement-title">Місто</label>
|
||||
<input
|
||||
type="text"
|
||||
id="info-settlement-title"
|
||||
name="settlement"
|
||||
required
|
||||
value=""
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div id="details-info-group" class="details-info-input">
|
||||
<label for="info-group-title">Теократична група</label>
|
||||
<input
|
||||
type="number"
|
||||
id="info-group-title"
|
||||
name="group"
|
||||
required
|
||||
value=""
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div id="details-info-osm" class="details-info-input">
|
||||
<label for="info-settlement-title">OSM iD</label>
|
||||
<div>
|
||||
<input
|
||||
type="text"
|
||||
id="info-osm-title"
|
||||
name="osm"
|
||||
placeholder="123, 345, 678"
|
||||
required
|
||||
value=""
|
||||
/>
|
||||
<a href="https://www.openstreetmap.org/#map=19/49.561725/25.604458" target="_blank" title="Де знайти OSM iD ?"
|
||||
><svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 48 48"
|
||||
width="100px"
|
||||
height="100px"
|
||||
>
|
||||
<path
|
||||
d="M 24 4 C 12.972066 4 4 12.972074 4 24 C 4 35.027926 12.972066 44 24 44 C 35.027934 44 44 35.027926 44 24 C 44 12.972074 35.027934 4 24 4 z M 24 7 C 33.406615 7 41 14.593391 41 24 C 41 33.406609 33.406615 41 24 41 C 14.593385 41 7 33.406609 7 24 C 7 14.593391 14.593385 7 24 7 z M 24 14 A 2 2 0 0 0 24 18 A 2 2 0 0 0 24 14 z M 23.976562 20.978516 A 1.50015 1.50015 0 0 0 22.5 22.5 L 22.5 33.5 A 1.50015 1.50015 0 1 0 25.5 33.5 L 25.5 22.5 A 1.50015 1.50015 0 0 0 23.976562 20.978516 z"
|
||||
/></svg
|
||||
></a>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</details>
|
||||
|
||||
<details id="details-map" open>
|
||||
<summary id="details-map-title">
|
||||
<span>Крок 2.</span> Перегляд
|
||||
</summary>
|
||||
<form id="map-form">
|
||||
<!-- <div class="editor-buttons" id="details-map-buttons-entranse">
|
||||
<button type="button" onclick="Editor.editor.drawEntranse()">
|
||||
Створити новий під'їзд
|
||||
</button>
|
||||
<div>
|
||||
<button type="button" id="ruler" onclick="Editor.editor.drawRectangle()">
|
||||
Лінійка
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
id="ruler_divide"
|
||||
onclick="Editor.editor.ruler()"
|
||||
style="display: none"
|
||||
>
|
||||
Поділити
|
||||
</button>
|
||||
</div>
|
||||
</div> -->
|
||||
|
||||
<div
|
||||
class="editor-buttons"
|
||||
id="details-map-buttons-homestead"
|
||||
style="display: none"
|
||||
>
|
||||
<!-- <div>
|
||||
<button type="button" id="ruler" onclick="Editor.editor.drawRectangle()">
|
||||
Лінійка
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
id="ruler_divide"
|
||||
onclick="Editor.editor.ruler()"
|
||||
style="display: none"
|
||||
>
|
||||
Поділити
|
||||
</button>
|
||||
</div> -->
|
||||
</div>
|
||||
|
||||
<div id="list-entranse" style="display: none"></div>
|
||||
<div id="list-homestead" style="display: none"></div>
|
||||
|
||||
<div class="block-map">
|
||||
<div id="map"></div>
|
||||
</div>
|
||||
<button id="map-form-button" type="submit" style="display: none;">Далі</button>
|
||||
</form>
|
||||
</details>
|
||||
|
||||
<details id="details-area" open style="display: none;">
|
||||
<summary><span>Крок 3.</span> Конструктор квартир <input type="number" value="1" id="next-apartment-title" onchange="Editor.apartments.editNum(this)" title="Авто-номер наступної квартири"></summary>
|
||||
|
||||
<form id="area-form">
|
||||
<div id="list-area"></div>
|
||||
</form>
|
||||
</details>
|
||||
</div>
|
||||
449
web/lib/pages/editor/script.js
Normal file
@@ -0,0 +1,449 @@
|
||||
const Editor = {
|
||||
init: async (type, id) => {
|
||||
let html = await fetch('/lib/pages/editor/index.html').then((response) => response.text());
|
||||
app.innerHTML = html;
|
||||
|
||||
map = "";
|
||||
houseGroup = "";
|
||||
entransePolygonsGroup = "";
|
||||
entranseNumPolygonsGroup = "";
|
||||
splitPolygonsGroup = "";
|
||||
RectangleGroup = "";
|
||||
numApartments = 1;
|
||||
|
||||
Editor.info.setHTML(type, id);
|
||||
|
||||
// document.getElementById("area-form").addEventListener("submit", async function (event) {
|
||||
// event.preventDefault();
|
||||
|
||||
// await Editor.api.setPack();
|
||||
// })
|
||||
},
|
||||
loadAPI: async function (URL) {
|
||||
let uuid = localStorage.getItem("uuid");
|
||||
return await fetch(URL, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"Authorization": uuid
|
||||
}
|
||||
}).then((response) => response.json());
|
||||
},
|
||||
info: {
|
||||
list: {
|
||||
type: null,
|
||||
group_id: null,
|
||||
title: null,
|
||||
number: null,
|
||||
points: [],
|
||||
points_number: [],
|
||||
point_icons: [],
|
||||
geo: [],
|
||||
osm_id: [],
|
||||
settlement: [],
|
||||
description: null,
|
||||
entrance: [],
|
||||
apartments: {}
|
||||
},
|
||||
setHTML: async (type, id) => {
|
||||
let detailsInfo_address_title = document.getElementById('info-address-title');
|
||||
let detailsInfo_number_title = document.getElementById('info-number-title');
|
||||
let detailsInfo_settlement_title = document.getElementById('info-settlement-title');
|
||||
let detailsInfo_group_title = document.getElementById('info-group-title');
|
||||
let detailsInfo_osm_title = document.getElementById('info-osm-title');
|
||||
|
||||
Editor.info.list = await Editor.loadAPI(`${CONFIG.api}${type}/${id}`);
|
||||
Editor.info.list.type = type;
|
||||
Editor.info.list.entrance = [];
|
||||
Editor.info.list.apartments = {};
|
||||
|
||||
console.log(Editor.info.list);
|
||||
detailsInfo_address_title.value = Editor.info.list.title;
|
||||
detailsInfo_number_title.value = Editor.info.list.number;
|
||||
detailsInfo_settlement_title.value = Editor.info.list.settlement;
|
||||
detailsInfo_group_title.value = Editor.info.list.group_id;
|
||||
detailsInfo_osm_title.value = Editor.info.list.osm_id.join(", ");
|
||||
|
||||
Editor.osm.init();
|
||||
Editor.info.setMap();
|
||||
|
||||
if (type == "house") {
|
||||
Editor.entrances.setHTML(id);
|
||||
document.getElementById('details-area').style.display = "";
|
||||
}
|
||||
},
|
||||
setMap: async () => {
|
||||
houseGroup.clearLayers();
|
||||
|
||||
for (let i = 0; i < Editor.info.list.points.length; i++) {
|
||||
const element = Editor.info.list.points[i];
|
||||
|
||||
if (Editor.info.list.type == "homestead") {
|
||||
map.setView([Editor.info.list.geo.lat, Editor.info.list.geo.lng], 17);
|
||||
|
||||
L.polygon(element, {
|
||||
color: colorGroup(Editor.info.list.group_id),
|
||||
radius: 500,
|
||||
fillOpacity: 0.3,
|
||||
dashArray: '20, 15',
|
||||
dashOffset: '20',
|
||||
}).addTo(houseGroup);
|
||||
} else if (Editor.info.list.type == "house") {
|
||||
map.setView([Editor.info.list.geo.lat, Editor.info.list.geo.lng], 18);
|
||||
|
||||
L.polygon(element, {
|
||||
color: "#585858",
|
||||
fillColor: colorGroup(Editor.info.list.group_id),
|
||||
fillOpacity: 0.8,
|
||||
tm_id: `house_${i}`
|
||||
}).addTo(houseGroup);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
entrances: {
|
||||
list: [],
|
||||
setHTML: async (id) => {
|
||||
Editor.entrances.list = await Editor.loadAPI(`${CONFIG.api}house/${id}/entrances`);
|
||||
|
||||
console.log(Editor.entrances.list);
|
||||
Editor.entrances.setMap()
|
||||
},
|
||||
setMap: async () => {
|
||||
entransePolygonsGroup.clearLayers();
|
||||
entranseNumPolygonsGroup.clearLayers();
|
||||
|
||||
for (let i = 0; i < Editor.entrances.list.length; i++) {
|
||||
const element = Editor.entrances.list[i];
|
||||
console.log(element);
|
||||
|
||||
let listEntranse = document.getElementById('list-entranse');
|
||||
listEntranse.style.display = "";
|
||||
listEntranse.innerHTML += `
|
||||
<div class="house" style="align-items: center;" id="Entranse_${element.id}">
|
||||
<p>${element.entrance_number + 1}</p>
|
||||
</div>
|
||||
`;
|
||||
|
||||
let listArea = document.getElementById('list-area');
|
||||
listArea.innerHTML += `
|
||||
<div class="block-area" id="block-area-${element.id}">
|
||||
<h3>${element.title}</h3>
|
||||
<button class="addFloors" title="Додати поверх" type="button" onclick="Editor.apartments.addFloors('${element.id}')"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 26 26"><path d="M 6.65625 4 C 6.367188 4 6.105469 4.113281 5.90625 4.3125 L 4.3125 5.90625 C 3.914063 6.304688 3.914063 7 4.3125 7.5 L 9.8125 13 L 4.3125 18.5 C 3.914063 19 3.914063 19.695313 4.3125 20.09375 L 5.90625 21.6875 C 6.40625 22.085938 7.101563 22.085938 7.5 21.6875 L 13 16.1875 L 18.5 21.6875 C 19 22.085938 19.695313 22.085938 20.09375 21.6875 L 21.6875 20.09375 C 22.085938 19.59375 22.085938 18.898438 21.6875 18.5 L 16.1875 13 L 21.6875 7.5 C 22.085938 7 22.085938 6.304688 21.6875 5.90625 L 20.09375 4.3125 C 19.59375 3.914063 18.898438 3.914063 18.5 4.3125 L 13 9.8125 L 7.5 4.3125 C 7.25 4.113281 6.945313 4 6.65625 4 Z"></path></svg></button>
|
||||
|
||||
<div id="area-${element.id}"></div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
Editor.apartments.setHTML(element.id);
|
||||
|
||||
L.polygon(element.points, { color: 'red' }).addTo(entransePolygonsGroup);
|
||||
|
||||
let myIcon = L.divIcon({ className: 'entranse_number', html: `<div class="markerEntranse">${element.entrance_number + 1}</div>` });
|
||||
L.marker(element.points_number, { icon: myIcon }).addTo(entranseNumPolygonsGroup);
|
||||
}
|
||||
}
|
||||
},
|
||||
apartments: {
|
||||
list: [],
|
||||
setHTML: async (id) => {
|
||||
Editor.apartments.list[`${id}`] = await Editor.loadAPI(`${CONFIG.api}apartments/${id}`);
|
||||
|
||||
const uniqueFloors = [...new Set(Editor.apartments.list[`${id}`].map(item => item.floors_number))];
|
||||
for (let i = 0; i < uniqueFloors.length; i++) {
|
||||
let num = uniqueFloors[i];
|
||||
|
||||
let area = document.getElementById(`area-${id}`);
|
||||
|
||||
let div = document.createElement('div');
|
||||
div.className = "block-apartments-floors";
|
||||
div.id = `floors-${id}-${num}`
|
||||
div.innerHTML = `
|
||||
<h2>Поверх ${num}</h2>
|
||||
<button class="addApartment" id="buttonApartment-${id}-${num}" title="Додати квартиру" type="button" onclick="Editor.apartments.addApartment('${id}', '${num}')"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 26 26"><path d="M 6.65625 4 C 6.367188 4 6.105469 4.113281 5.90625 4.3125 L 4.3125 5.90625 C 3.914063 6.304688 3.914063 7 4.3125 7.5 L 9.8125 13 L 4.3125 18.5 C 3.914063 19 3.914063 19.695313 4.3125 20.09375 L 5.90625 21.6875 C 6.40625 22.085938 7.101563 22.085938 7.5 21.6875 L 13 16.1875 L 18.5 21.6875 C 19 22.085938 19.695313 22.085938 20.09375 21.6875 L 21.6875 20.09375 C 22.085938 19.59375 22.085938 18.898438 21.6875 18.5 L 16.1875 13 L 21.6875 7.5 C 22.085938 7 22.085938 6.304688 21.6875 5.90625 L 20.09375 4.3125 C 19.59375 3.914063 18.898438 3.914063 18.5 4.3125 L 13 9.8125 L 7.5 4.3125 C 7.25 4.113281 6.945313 4 6.65625 4 Z"></path></svg></button>
|
||||
`;
|
||||
|
||||
area.prepend(div);
|
||||
}
|
||||
|
||||
Editor.apartments.list[`${id}`].sort((a, b) => b.title - a.title);
|
||||
|
||||
for (let i = 0; i < Editor.apartments.list[`${id}`].length; i++) {
|
||||
const apartment = Editor.apartments.list[`${id}`][i];
|
||||
let num = apartment.floors_number;
|
||||
|
||||
let floorsBlock = document.getElementById(`floors-${id}-${num}`);
|
||||
|
||||
let div = document.createElement('div');
|
||||
div.className = "block-apartments-number";
|
||||
div.id = `block-apartments-${id}-${apartment.id}`
|
||||
div.innerHTML = `
|
||||
<input type="text" value="${apartment.title}" id="apartament-${id}-${apartment.id}" onchange="Editor.apartments.editApartment('${id}','${apartment.id}')">
|
||||
<button type="button" onclick="Editor.apartments.deleteApartment('${id}','${apartment.id}')">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 26 26"><path d="M 6.65625 4 C 6.367188 4 6.105469 4.113281 5.90625 4.3125 L 4.3125 5.90625 C 3.914063 6.304688 3.914063 7 4.3125 7.5 L 9.8125 13 L 4.3125 18.5 C 3.914063 19 3.914063 19.695313 4.3125 20.09375 L 5.90625 21.6875 C 6.40625 22.085938 7.101563 22.085938 7.5 21.6875 L 13 16.1875 L 18.5 21.6875 C 19 22.085938 19.695313 22.085938 20.09375 21.6875 L 21.6875 20.09375 C 22.085938 19.59375 22.085938 18.898438 21.6875 18.5 L 16.1875 13 L 21.6875 7.5 C 22.085938 7 22.085938 6.304688 21.6875 5.90625 L 20.09375 4.3125 C 19.59375 3.914063 18.898438 3.914063 18.5 4.3125 L 13 9.8125 L 7.5 4.3125 C 7.25 4.113281 6.945313 4 6.65625 4 Z"></path></svg>
|
||||
</button>
|
||||
`;
|
||||
floorsBlock.prepend(div);
|
||||
|
||||
numApartments++;
|
||||
let next_apartment_title = document.getElementById('next-apartment-title');
|
||||
next_apartment_title.value = numApartments;
|
||||
}
|
||||
},
|
||||
editNum: (element) => {
|
||||
numApartments = Number(element.value);
|
||||
},
|
||||
addFloors: async (area) => {
|
||||
let areaBlock = document.getElementById(`area-${area}`);
|
||||
let uniqueFloors = [...new Set(Editor.apartments.list[area].map(obj => obj.floors_number))];
|
||||
let new_floors = uniqueFloors.length + 1;
|
||||
|
||||
const uuid = localStorage.getItem('uuid');
|
||||
const URL = `${CONFIG.api}/apartments/${area}`;
|
||||
await fetch(URL, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"Authorization": uuid
|
||||
},
|
||||
body: JSON.stringify({
|
||||
apartment_number: Editor.apartments.list[area].length,
|
||||
title: numApartments.toString(),
|
||||
floors_number: Number(new_floors)
|
||||
})
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
console.log(data);
|
||||
|
||||
let div = document.createElement('div');
|
||||
div.className = "block-apartments-floors";
|
||||
div.id = `floors-${area}-${new_floors}`
|
||||
div.innerHTML = `
|
||||
<h2>Поверх ${new_floors}</h2>
|
||||
<div class="block-apartments-number" id="block-apartments-${area}-${data.id}">
|
||||
<input type="text" value="${numApartments}" id="apartament-${area}-${data.id}" onchange="Editor.apartments.editApartment('${area}', '${data.id}')">
|
||||
<button type="button" onclick="Editor.apartments.deleteApartment('${area}', '${data.id}')">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 26 26"><path d="M 6.65625 4 C 6.367188 4 6.105469 4.113281 5.90625 4.3125 L 4.3125 5.90625 C 3.914063 6.304688 3.914063 7 4.3125 7.5 L 9.8125 13 L 4.3125 18.5 C 3.914063 19 3.914063 19.695313 4.3125 20.09375 L 5.90625 21.6875 C 6.40625 22.085938 7.101563 22.085938 7.5 21.6875 L 13 16.1875 L 18.5 21.6875 C 19 22.085938 19.695313 22.085938 20.09375 21.6875 L 21.6875 20.09375 C 22.085938 19.59375 22.085938 18.898438 21.6875 18.5 L 16.1875 13 L 21.6875 7.5 C 22.085938 7 22.085938 6.304688 21.6875 5.90625 L 20.09375 4.3125 C 19.59375 3.914063 18.898438 3.914063 18.5 4.3125 L 13 9.8125 L 7.5 4.3125 C 7.25 4.113281 6.945313 4 6.65625 4 Z"></path></svg>
|
||||
</button>
|
||||
</div>
|
||||
<button class="addApartment" id="buttonApartment-${area}-${new_floors}" title="Додати квартиру" type="button" onclick="Editor.apartments.addApartment('${area}', '${new_floors}')"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 26 26"><path d="M 6.65625 4 C 6.367188 4 6.105469 4.113281 5.90625 4.3125 L 4.3125 5.90625 C 3.914063 6.304688 3.914063 7 4.3125 7.5 L 9.8125 13 L 4.3125 18.5 C 3.914063 19 3.914063 19.695313 4.3125 20.09375 L 5.90625 21.6875 C 6.40625 22.085938 7.101563 22.085938 7.5 21.6875 L 13 16.1875 L 18.5 21.6875 C 19 22.085938 19.695313 22.085938 20.09375 21.6875 L 21.6875 20.09375 C 22.085938 19.59375 22.085938 18.898438 21.6875 18.5 L 16.1875 13 L 21.6875 7.5 C 22.085938 7 22.085938 6.304688 21.6875 5.90625 L 20.09375 4.3125 C 19.59375 3.914063 18.898438 3.914063 18.5 4.3125 L 13 9.8125 L 7.5 4.3125 C 7.25 4.113281 6.945313 4 6.65625 4 Z"></path></svg></button>
|
||||
`
|
||||
|
||||
areaBlock.prepend(div);
|
||||
|
||||
console.log(Editor.apartments.list[area]);
|
||||
|
||||
|
||||
Editor.apartments.list[area].push({
|
||||
id: data.id,
|
||||
entrance_id: Number(area),
|
||||
apartment_number: Editor.apartments.list[area].length,
|
||||
title: numApartments.toString(),
|
||||
floors_number: Number(new_floors)
|
||||
});
|
||||
|
||||
numApartments++;
|
||||
|
||||
let next_apartment_title = document.getElementById('next-apartment-title');
|
||||
next_apartment_title.value = numApartments;
|
||||
})
|
||||
.catch(err => {
|
||||
console.log(err);
|
||||
})
|
||||
},
|
||||
addApartment: async (area, floors) => {
|
||||
const uuid = localStorage.getItem('uuid');
|
||||
const URL = `${CONFIG.api}/apartments/${area}`;
|
||||
await fetch(URL, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"Authorization": uuid
|
||||
},
|
||||
body: JSON.stringify({
|
||||
apartment_number: Editor.apartments.list[area].length,
|
||||
title: numApartments.toString(),
|
||||
floors_number: Number(floors)
|
||||
})
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
console.log(data);
|
||||
|
||||
Editor.apartments.list[area].push({
|
||||
id: data.id,
|
||||
entrance_id: Number(area),
|
||||
apartment_number: Editor.apartments.list[area].length,
|
||||
title: numApartments.toString(),
|
||||
floors_number: Number(floors)
|
||||
});
|
||||
|
||||
let floorsBlock = document.getElementById(`floors-${area}-${floors}`);
|
||||
document.getElementById(`buttonApartment-${area}-${floors}`).remove();
|
||||
|
||||
floorsBlock.innerHTML += `
|
||||
<div class="block-apartments-number" id="block-apartments-${area}-${data.id}">
|
||||
<input type="text" value="${numApartments}" id="apartament-${area}-${data.id}" onchange="Editor.apartments.editApartment('${area}', '${data.id}')">
|
||||
<button type="button" onclick="Editor.apartments.deleteApartment('${area}', '${data.id}')">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 26 26"><path d="M 6.65625 4 C 6.367188 4 6.105469 4.113281 5.90625 4.3125 L 4.3125 5.90625 C 3.914063 6.304688 3.914063 7 4.3125 7.5 L 9.8125 13 L 4.3125 18.5 C 3.914063 19 3.914063 19.695313 4.3125 20.09375 L 5.90625 21.6875 C 6.40625 22.085938 7.101563 22.085938 7.5 21.6875 L 13 16.1875 L 18.5 21.6875 C 19 22.085938 19.695313 22.085938 20.09375 21.6875 L 21.6875 20.09375 C 22.085938 19.59375 22.085938 18.898438 21.6875 18.5 L 16.1875 13 L 21.6875 7.5 C 22.085938 7 22.085938 6.304688 21.6875 5.90625 L 20.09375 4.3125 C 19.59375 3.914063 18.898438 3.914063 18.5 4.3125 L 13 9.8125 L 7.5 4.3125 C 7.25 4.113281 6.945313 4 6.65625 4 Z"></path></svg>
|
||||
</button>
|
||||
</div>
|
||||
`;
|
||||
floorsBlock.innerHTML += `<button class="addApartment" id="buttonApartment-${area}-${floors}" title="Додати квартиру" type="button" onclick="Editor.apartments.addApartment('${area}', '${floors}')"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 26 26"><path d="M 6.65625 4 C 6.367188 4 6.105469 4.113281 5.90625 4.3125 L 4.3125 5.90625 C 3.914063 6.304688 3.914063 7 4.3125 7.5 L 9.8125 13 L 4.3125 18.5 C 3.914063 19 3.914063 19.695313 4.3125 20.09375 L 5.90625 21.6875 C 6.40625 22.085938 7.101563 22.085938 7.5 21.6875 L 13 16.1875 L 18.5 21.6875 C 19 22.085938 19.695313 22.085938 20.09375 21.6875 L 21.6875 20.09375 C 22.085938 19.59375 22.085938 18.898438 21.6875 18.5 L 16.1875 13 L 21.6875 7.5 C 22.085938 7 22.085938 6.304688 21.6875 5.90625 L 20.09375 4.3125 C 19.59375 3.914063 18.898438 3.914063 18.5 4.3125 L 13 9.8125 L 7.5 4.3125 C 7.25 4.113281 6.945313 4 6.65625 4 Z"></path></svg></button>`
|
||||
|
||||
numApartments++;
|
||||
|
||||
let next_apartment_title = document.getElementById('next-apartment-title');
|
||||
next_apartment_title.value = numApartments;
|
||||
})
|
||||
.catch(err => {
|
||||
console.log(err);
|
||||
})
|
||||
},
|
||||
editApartment: async (area, apartament) => {
|
||||
let input = document.getElementById(`apartament-${area}-${apartament}`);
|
||||
input.setAttribute("value", input.value);
|
||||
|
||||
const pos = Editor.apartments.list[area].map(e => e.id).indexOf(Number(apartament));
|
||||
Editor.apartments.list[area][pos].title = input.value;
|
||||
|
||||
const uuid = localStorage.getItem('uuid');
|
||||
const URL = `${CONFIG.api}/apartments/${area}`;
|
||||
await fetch(URL, {
|
||||
method: 'PUT',
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"Authorization": uuid
|
||||
},
|
||||
body: JSON.stringify({
|
||||
title: Editor.apartments.list[area][pos].title,
|
||||
status: Editor.apartments.list[area][pos].status,
|
||||
description: Editor.apartments.list[area][pos].description,
|
||||
id: Editor.apartments.list[area][pos].id
|
||||
})
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
console.log(data);
|
||||
})
|
||||
.catch(err => {
|
||||
console.log(err);
|
||||
})
|
||||
},
|
||||
deleteApartment: async (area, apartament) => {
|
||||
const pos = Editor.apartments.list[area].map(e => e.id).indexOf(Number(apartament));
|
||||
|
||||
const uuid = localStorage.getItem('uuid');
|
||||
const URL = `${CONFIG.api}/apartments/${area}`;
|
||||
await fetch(URL, {
|
||||
method: 'DELETE',
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"Authorization": uuid
|
||||
},
|
||||
body: JSON.stringify({
|
||||
id: Editor.apartments.list[area][pos].id
|
||||
})
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
console.log(data);
|
||||
document.getElementById(`block-apartments-${area}-${apartament}`).remove();
|
||||
Editor.apartments.list[area].splice(pos, 1);
|
||||
|
||||
numApartments--;
|
||||
let next_apartment_title = document.getElementById('next-apartment-title');
|
||||
next_apartment_title.value = numApartments;
|
||||
})
|
||||
.catch(err => {
|
||||
console.log(err);
|
||||
})
|
||||
}
|
||||
},
|
||||
osm: {
|
||||
init: () => {
|
||||
let center = { lat: 49.5629016, lng: 25.6145625 };
|
||||
let zoom = 19;
|
||||
|
||||
let googleHybrid = L.tileLayer('http://{s}.google.com/vt/lyrs=s,h&x={x}&y={y}&z={z}', {
|
||||
maxZoom: 20,
|
||||
minZoom: 15,
|
||||
subdomains: ['mt0', 'mt1', 'mt2', 'mt3']
|
||||
});
|
||||
|
||||
let osm = L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
|
||||
maxZoom: 19,
|
||||
minZoom: 15
|
||||
});
|
||||
|
||||
let mytile = L.tileLayer('https://tm.rozenrod.com/webp/{z}/{x}/{y}.webp', {
|
||||
maxZoom: 20,
|
||||
minZoom: 15,
|
||||
tms: true
|
||||
});
|
||||
|
||||
if (!map) {
|
||||
|
||||
houseGroup = new L.FeatureGroup();
|
||||
splitPolygonsGroup = new L.FeatureGroup();
|
||||
RectangleGroup = new L.FeatureGroup();
|
||||
entransePolygonsGroup = new L.FeatureGroup();
|
||||
entranseNumPolygonsGroup = new L.FeatureGroup();
|
||||
|
||||
map = L.map('map', {
|
||||
renderer: L.canvas(),
|
||||
center,
|
||||
zoom,
|
||||
layers: [
|
||||
googleHybrid,
|
||||
osm,
|
||||
mytile,
|
||||
houseGroup,
|
||||
entransePolygonsGroup,
|
||||
entranseNumPolygonsGroup,
|
||||
splitPolygonsGroup,
|
||||
RectangleGroup,
|
||||
],
|
||||
zoomControl: false
|
||||
});
|
||||
|
||||
|
||||
let baseMaps = {
|
||||
"Google Hybrid": googleHybrid,
|
||||
"OpenStreetMap": osm,
|
||||
"Territory Map": mytile
|
||||
};
|
||||
let overlayMaps = {
|
||||
"Будинки": houseGroup,
|
||||
"Під'їзди": entransePolygonsGroup,
|
||||
"Номера під'їздів": entranseNumPolygonsGroup,
|
||||
"Слой редактирования": splitPolygonsGroup,
|
||||
"Слой линейки": RectangleGroup,
|
||||
};
|
||||
|
||||
L.control.layers(baseMaps, overlayMaps, { position: 'bottomright' }).addTo(map);
|
||||
|
||||
map.pm.setLang("ua");
|
||||
|
||||
map.pm.addControls({
|
||||
position: 'bottomright',
|
||||
drawCircleMarker: false,
|
||||
drawPolyline: false,
|
||||
drawPolygon: false,
|
||||
drawRectangle: false,
|
||||
drawCircle: false,
|
||||
drawText: false,
|
||||
drawMarker: false,
|
||||
cutPolygon: false,
|
||||
tooltips: false
|
||||
});
|
||||
map.pm.toggleControls()
|
||||
|
||||
map.pm.setGlobalOptions({
|
||||
layerGroup: splitPolygonsGroup
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
500
web/lib/pages/editor/style.css
Normal file
@@ -0,0 +1,500 @@
|
||||
.page-editor {
|
||||
width: calc(100% - 40px);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
margin: 20px 20px 0 20px;
|
||||
}
|
||||
|
||||
.page-editor form>button {
|
||||
border-radius: 6px;
|
||||
background: var(--PrimaryColor);
|
||||
color: var(--PrimaryColorText);
|
||||
width: 100%;
|
||||
height: 40px;
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
margin: 20px 0;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.page-editor details {
|
||||
border-radius: 10px;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
margin-bottom: 20px;
|
||||
background: var(--ColorThemes1);
|
||||
color: var(--ColorThemes3);
|
||||
border: 1px solid var(--ColorThemes2);
|
||||
box-shadow: var(--shadow-l1);
|
||||
}
|
||||
|
||||
.page-editor>details[disabled] summary,
|
||||
.page-editor>details.disabled summary {
|
||||
pointer-events: none;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.page-editor>details summary::-webkit-details-marker,
|
||||
.page-editor>details summary::marker {
|
||||
display: none;
|
||||
content: "";
|
||||
}
|
||||
|
||||
.page-editor summary {
|
||||
width: calc(100% - 40px);
|
||||
cursor: pointer;
|
||||
color: var(--ColorThemes3);
|
||||
border-radius: var(--border-radius);
|
||||
font-size: 16px;
|
||||
font-weight: 300;
|
||||
padding: 20px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.page-editor summary span {
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.page-editor summary input {
|
||||
font-weight: 500;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
padding: 10px;
|
||||
margin: 13px;
|
||||
font-size: 12px;
|
||||
background: var(--ColorThemes3);
|
||||
color: var(--ColorThemes0);
|
||||
border-radius: 6px;
|
||||
width: 40px;
|
||||
}
|
||||
|
||||
.page-editor #info-form,
|
||||
.page-editor #map-form,
|
||||
.page-editor #area-form {
|
||||
padding: 0 20px;
|
||||
}
|
||||
|
||||
#details-info-type {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
#details-info-type>.tabs {
|
||||
display: flex;
|
||||
position: relative;
|
||||
background-color: var(--ColorThemes0);
|
||||
padding: 4px;
|
||||
border-radius: 6px;
|
||||
width: calc(100% - 8px);
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
#details-info-type>.tabs>input[type="radio"] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#details-info-type>.tabs>.tab {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 40px;
|
||||
width: calc(100% / 3);
|
||||
cursor: pointer;
|
||||
padding: 0 15px;
|
||||
transition: 0.15s ease-in;
|
||||
color: var(--ColorThemes3);
|
||||
fill: var(--ColorThemes3);
|
||||
flex-direction: row;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
#details-info-type>.tabs>.tab>svg {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
}
|
||||
|
||||
#details-info-type>.tabs>.tab>span {
|
||||
margin-left: 6px;
|
||||
font-size: 12px;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
#details-info-type>.tabs>input[type="radio"]:checked+label {
|
||||
color: var(--PrimaryColorText);
|
||||
fill: var(--PrimaryColorText);
|
||||
}
|
||||
|
||||
#details-info-type>.tabs>.glider {
|
||||
position: absolute;
|
||||
display: flex;
|
||||
height: 40px;
|
||||
width: calc((100% - 8px) / 3);
|
||||
background-color: var(--PrimaryColor);
|
||||
z-index: 1;
|
||||
border-radius: 4px;
|
||||
transition: 0.25s ease-out;
|
||||
}
|
||||
|
||||
@media (min-width: 601px) {
|
||||
#details-info-type>.tabs>input[id="info-type-house"]:checked~.glider {
|
||||
transform: translateX(0);
|
||||
}
|
||||
|
||||
#details-info-type>.tabs>input[id="info-type-homestead"]:checked~.glider {
|
||||
transform: translateX(100%);
|
||||
}
|
||||
|
||||
#details-info-type>.tabs>input[id="info-type-points"]:checked~.glider {
|
||||
transform: translateX(200%);
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 600px) {
|
||||
#details-info-type>.tabs {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
#details-info-type>.tabs>.tab {
|
||||
width: calc(100% - 8px);
|
||||
padding: 0 4px;
|
||||
}
|
||||
|
||||
#details-info-type>.tabs>.glider {
|
||||
width: calc(100% - 8px);
|
||||
}
|
||||
|
||||
#details-info-type>.tabs>input[id="info-type-house"]:checked~.glider {
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
#details-info-type>.tabs>input[id="info-type-homestead"]:checked~.glider {
|
||||
transform: translateY(100%);
|
||||
}
|
||||
|
||||
#details-info-type>.tabs>input[id="info-type-points"]:checked~.glider {
|
||||
transform: translateY(200%);
|
||||
}
|
||||
}
|
||||
|
||||
.page-editor .details-info-input {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
margin: 20px 0;
|
||||
align-items: flex-start;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.page-editor .details-info-input label {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
margin-bottom: 5px;
|
||||
|
||||
}
|
||||
|
||||
.page-editor .details-info-input input {
|
||||
width: calc(100% - 10px);
|
||||
min-width: 140px;
|
||||
padding: 0 5px;
|
||||
border-radius: 6px;
|
||||
height: 30px;
|
||||
background: var(--ColorThemes0);
|
||||
color: var(--ColorThemes3);
|
||||
}
|
||||
|
||||
.page-editor #details-info-osm div {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.page-editor #details-info-osm input {
|
||||
width: calc(100% - 10px);
|
||||
min-width: 140px;
|
||||
padding: 0 5px;
|
||||
border-radius: 6px;
|
||||
height: 30px;
|
||||
}
|
||||
|
||||
.page-editor .details-info-input a {
|
||||
height: 26px;
|
||||
width: 26px;
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
.page-editor .details-info-input a>svg {
|
||||
height: 26px;
|
||||
width: 26px;
|
||||
fill: var(--ColorThemes3)
|
||||
}
|
||||
|
||||
.page-editor #list-area {
|
||||
display: flex;
|
||||
overflow: auto;
|
||||
margin: 15px 0 20px 0;
|
||||
}
|
||||
|
||||
.page-editor #list-area h3 {
|
||||
text-align: center;
|
||||
font-size: 16px;
|
||||
font-weight: 400;
|
||||
margin: 10px;
|
||||
padding: 7px;
|
||||
color: var(--ColorThemes0);
|
||||
background: var(--ColorThemes3);
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.block-area {
|
||||
min-height: 200px;
|
||||
border: 1px solid var(--ColorThemes3);
|
||||
border-style: dashed;
|
||||
border-radius: 6px;
|
||||
margin: 0 10px 10px 0;
|
||||
}
|
||||
|
||||
.addFloors,
|
||||
.addApartment {
|
||||
display: flex;
|
||||
position: relative;
|
||||
width: 34px;
|
||||
height: 34px;
|
||||
background: var(--PrimaryColor);
|
||||
color: var(--PrimaryColorText);
|
||||
margin: 25px;
|
||||
border-radius: 50%;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 30px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.addFloors>svg,
|
||||
.addApartment>svg {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
fill: var(--PrimaryColorText);
|
||||
transform: rotate(45deg);
|
||||
}
|
||||
|
||||
.block-apartments-floors {
|
||||
position: relative;
|
||||
display: flex;
|
||||
width: calc(100% - 22px);
|
||||
border: 1px solid var(--ColorThemes3);
|
||||
margin: 10px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.block-apartments-floors h2 {
|
||||
position: absolute;
|
||||
width: 65px;
|
||||
right: -1px;
|
||||
top: -1px;
|
||||
margin: 0;
|
||||
background: var(--ColorThemes3);
|
||||
color: var(--ColorThemes2);
|
||||
border-radius: 0 4px 0 4px;
|
||||
font-size: 12px;
|
||||
padding: 2px 4px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.block-apartments-number {
|
||||
display: flex;
|
||||
position: relative;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
background: var(--ColorThemes1);
|
||||
border: 2px solid var(--PrimaryColor);
|
||||
margin: 10px;
|
||||
border-radius: 4px;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.block-apartments-number input {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
font-size: 16px;
|
||||
font-weight: 400;
|
||||
text-align: center;
|
||||
color: var(--ColorThemes3);
|
||||
background: 0;
|
||||
}
|
||||
|
||||
.block-apartments-number button {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
border-radius: 0 4px 0 4px;
|
||||
background: var(--PrimaryColor);
|
||||
font-size: 16px;
|
||||
margin: -2px;
|
||||
border: 0;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.block-apartments-number button>svg {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
fill: var(--PrimaryColorText);
|
||||
}
|
||||
|
||||
|
||||
.block-map {
|
||||
width: 100%;
|
||||
height: 500px;
|
||||
border-radius: 6px;
|
||||
overflow: hidden;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
#map {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.entranse_number {
|
||||
left: -10px !important;
|
||||
top: -10px !important;
|
||||
}
|
||||
|
||||
.markerEntranse {
|
||||
background: hsl(0deg 0% 52.12% / 90%);
|
||||
font-size: 24px;
|
||||
border: 2px solid #676767;
|
||||
border-radius: 2px;
|
||||
display: flex !important;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
color: #fff;
|
||||
min-width: 30px;
|
||||
min-height: 30px;
|
||||
height: 30px;
|
||||
width: 30px;
|
||||
}
|
||||
|
||||
.editor-buttons {
|
||||
margin-top: 15px;
|
||||
}
|
||||
|
||||
.editor-buttons>button {
|
||||
width: 100%;
|
||||
min-height: 30px;
|
||||
margin: 5px 0;
|
||||
border: 0;
|
||||
color: var(--PrimaryColorText);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: var(--PrimaryColor);
|
||||
text-transform: uppercase;
|
||||
cursor: pointer;
|
||||
border-radius: 6px;
|
||||
font-weight: 400;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.editor-buttons>div {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
margin: 10px 0;
|
||||
height: 30px;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.editor-buttons>div>button {
|
||||
background: var(--ColorThemes3);
|
||||
color: var(--ColorThemes1);
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
border-radius: 6px;
|
||||
text-transform: uppercase;
|
||||
font-weight: 400;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.page-editor #list-entranse,
|
||||
.page-editor #list-homestead {
|
||||
width: 100%;
|
||||
min-height: 86px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: nowrap;
|
||||
overflow-x: initial;
|
||||
overflow-y: auto;
|
||||
border: 1px solid var(--ColorThemes3);
|
||||
background: 0;
|
||||
border-radius: 6px;
|
||||
border-style: dashed;
|
||||
margin: 10px 0;
|
||||
}
|
||||
|
||||
.page-editor #list-entranse>.house,
|
||||
.page-editor #list-homestead>.house {
|
||||
display: flex;
|
||||
position: relative;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
background: var(--ColorThemes1);
|
||||
border: 2px solid var(--PrimaryColor);
|
||||
margin: 10px;
|
||||
border-radius: 4px;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
|
||||
.page-editor #list-entranse>.house>input,
|
||||
.page-editor #list-homestead>.house>input,
|
||||
.page-editor #list-entranse>.house>p,
|
||||
.page-editor #list-homestead>.house>p {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
font-size: 16px;
|
||||
font-weight: 400;
|
||||
text-align: center;
|
||||
color: var(--ColorThemes3);
|
||||
background: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.page-editor #list-entranse>.house>button,
|
||||
.page-editor #list-homestead>.house>button {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
border-radius: 0 4px 0 4px;
|
||||
background: var(--PrimaryColor);
|
||||
font-size: 16px;
|
||||
margin: -2px;
|
||||
border: 0;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.page-editor #list-entranse>.house>button>svg,
|
||||
.page-editor #list-homestead>.house>button>svg {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
fill: var(--PrimaryColorText);
|
||||
}
|
||||
9
web/lib/pages/home/index.html
Normal file
@@ -0,0 +1,9 @@
|
||||
<div class="page-home">
|
||||
<details id="details-personal-territory" open>
|
||||
<summary>
|
||||
<span>Території для опрацювання</span>
|
||||
</summary>
|
||||
|
||||
<div id="home-personal-territory-list"></div>
|
||||
</details>
|
||||
</div>
|
||||
95
web/lib/pages/home/script.js
Normal file
@@ -0,0 +1,95 @@
|
||||
const Home = {
|
||||
init: async () => {
|
||||
let html = await fetch('/lib/pages/home/index.html').then((response) => response.text());
|
||||
app.innerHTML = html;
|
||||
|
||||
Home.house.setHTML();
|
||||
Home.homestead.setHTML();
|
||||
},
|
||||
house: {
|
||||
loadAPI: async function () {
|
||||
let uuid = localStorage.getItem("uuid");
|
||||
|
||||
const URL = `${CONFIG.api}houses/list?mode=sheep`;
|
||||
return await fetch(URL, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"Authorization": uuid
|
||||
}
|
||||
}).then((response) => response.json());
|
||||
},
|
||||
setHTML: async function () {
|
||||
let list = await Home.house.loadAPI();
|
||||
|
||||
list.sort((a, b) => b.id - a.id);
|
||||
|
||||
console.log(list);
|
||||
let block_house = document.getElementById('home-personal-territory-list')
|
||||
|
||||
for (let i = 0; i < list.length; i++) {
|
||||
const element = list[i];
|
||||
|
||||
block_house.innerHTML += `
|
||||
<div class="card">
|
||||
<i style="background-image: url(https://sheep-service.com/cards/house/T${element.id}.webp);"></i>
|
||||
<div class="contents">
|
||||
<div class="group" style="background: ${colorGroup(element.group_id)}">
|
||||
<span>Група №${element.group_id}</span>
|
||||
</div>
|
||||
<div class="info">
|
||||
<div>
|
||||
<p>${element.title} ${element.number}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<a href="/territory/card/house/${element.id}" data-route></a>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
}
|
||||
},
|
||||
homestead: {
|
||||
loadAPI: async function () {
|
||||
let uuid = localStorage.getItem("uuid");
|
||||
|
||||
const URL = `${CONFIG.api}homestead/list?mode=sheep`;
|
||||
return await fetch(URL, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"Authorization": uuid
|
||||
}
|
||||
}).then((response) => response.json());
|
||||
},
|
||||
setHTML: async function () {
|
||||
let list = await Home.homestead.loadAPI();
|
||||
|
||||
list.sort((a, b) => b.id - a.id);
|
||||
|
||||
console.log(list);
|
||||
let block_homestead = document.getElementById('home-personal-territory-list')
|
||||
|
||||
for (let i = 0; i < list.length; i++) {
|
||||
const element = list[i];
|
||||
|
||||
block_homestead.innerHTML += `
|
||||
<div class="card">
|
||||
<i style="background-image: url(https://sheep-service.com/cards/homestead/H${element.id}.webp);"></i>
|
||||
<div class="contents">
|
||||
<div class="group" style="background: ${colorGroup(element.group_id)}">
|
||||
<span>Група №${element.group_id}</span>
|
||||
</div>
|
||||
<div class="info">
|
||||
<div>
|
||||
<p>${element.title} ${element.number}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<a href="/territory/card/homestead/${element.id}" data-route></a>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
191
web/lib/pages/home/style.css
Normal file
@@ -0,0 +1,191 @@
|
||||
.page-home {
|
||||
width: calc(100% - 40px);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin: 20px 20px 0 20px;
|
||||
}
|
||||
|
||||
.page-home details {
|
||||
border-radius: 15px;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
margin-bottom: 20px;
|
||||
background: var(--ColorThemes1);
|
||||
color: var(--ColorThemes3);
|
||||
border: 1px solid var(--ColorThemes2);
|
||||
box-shadow: var(--shadow-l1);
|
||||
}
|
||||
|
||||
.page-home>details[disabled] summary,
|
||||
.page-home>details.disabled summary {
|
||||
pointer-events: none;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.page-home>details summary::-webkit-details-marker,
|
||||
.page-home>details summary::marker {
|
||||
display: none;
|
||||
content: "";
|
||||
}
|
||||
|
||||
|
||||
.page-home summary {
|
||||
width: calc(100% - 40px);
|
||||
cursor: pointer;
|
||||
color: var(--ColorThemes3);
|
||||
border-radius: var(--border-radius);
|
||||
font-size: 16px;
|
||||
font-weight: 300;
|
||||
padding: 20px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.page-home summary span {
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
|
||||
.page-home #home-personal-territory-list {
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
flex-direction: row;
|
||||
align-content: flex-start;
|
||||
justify-content: center;
|
||||
overflow-y: auto;
|
||||
align-items: flex-start;
|
||||
transition: .3s ease;
|
||||
}
|
||||
|
||||
.page-home .card {
|
||||
position: relative;
|
||||
width: 300px;
|
||||
height: 200px;
|
||||
background-color: var(--ColorThemes2);
|
||||
margin: 0px 10px 20px 10px;
|
||||
overflow: hidden;
|
||||
cursor: pointer;
|
||||
border-radius: 10px;
|
||||
}
|
||||
@media (max-width: 2300px) {
|
||||
.page-home .card {
|
||||
width: calc((100% / 5) - 30px);
|
||||
}
|
||||
}
|
||||
@media (max-width: 1960px) {
|
||||
.page-home .card {
|
||||
width: calc((100% / 4) - 30px);
|
||||
}
|
||||
}
|
||||
@media (max-width: 1640px) {
|
||||
.page-home .card {
|
||||
width: calc((100% / 3) - 30px);
|
||||
}
|
||||
}
|
||||
@media (max-width: 1280px) {
|
||||
.page-home .card {
|
||||
width: calc((100% / 2) - 30px);
|
||||
}
|
||||
}
|
||||
@media (max-width: 650px) {
|
||||
.page-home .card {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
@media(hover: hover) {
|
||||
.page-home .card:hover {
|
||||
opacity: 0.8;
|
||||
}
|
||||
}
|
||||
|
||||
.page-home .card>i {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
z-index: 1;
|
||||
filter: blur(2px);
|
||||
/* background-repeat: round; */
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
background-image: url(https://tm.rozenrod.com/web/img/bg.webp);
|
||||
}
|
||||
.page-home .card>a {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.page-home .contents {
|
||||
position: absolute;
|
||||
z-index: 2;
|
||||
background: rgb(64 64 64 / 0.7);
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
font-size: 40px;
|
||||
font-weight: 500;
|
||||
color: #fff;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.page-home .group {
|
||||
width: calc(100% - 20px);
|
||||
max-height: 50px;
|
||||
border-radius: 7px;
|
||||
padding: 10px 0;
|
||||
margin-top: 10px;
|
||||
display: flex;
|
||||
background: var(--PrimaryColor);
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
justify-content: space-around;
|
||||
}
|
||||
|
||||
.page-home .group>span {
|
||||
color: #fff;
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
.page-home .info {
|
||||
width: calc(100% - 20px);
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.page-home .info>div {
|
||||
width: 100%;
|
||||
height: 35px;
|
||||
margin-top: 5px;
|
||||
display: flex;
|
||||
background: var(--ColorThemes0);
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 12px;
|
||||
color: var(--ColorThemes3);
|
||||
border-radius: 7px;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.page-home .info>div>span {
|
||||
color: var(--ColorThemes3);
|
||||
font-size: 14px;
|
||||
font-weight: 300;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.page-home .info>div>p {
|
||||
color: var(--ColorThemes3);
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
padding: 10px;
|
||||
z-index: 2;
|
||||
}
|
||||
0
web/lib/pages/options/index.html
Normal file
6
web/lib/pages/options/script.js
Normal file
@@ -0,0 +1,6 @@
|
||||
const Options = {
|
||||
init: async () => {
|
||||
let html = await fetch('/lib/pages/options/index.html').then((response) => response.text());
|
||||
app.innerHTML = html;
|
||||
}
|
||||
}
|
||||
0
web/lib/pages/options/style.css
Normal file
250
web/lib/pages/sheeps/index.html
Normal file
@@ -0,0 +1,250 @@
|
||||
<div class="page-sheeps">
|
||||
<div id="block-sheeps-list">
|
||||
<div class="header">
|
||||
<h1>Всі вісники</h1>
|
||||
</div>
|
||||
|
||||
<div class="card-profile"></div>
|
||||
<div class="card-profile"></div>
|
||||
<div class="card-profile"></div>
|
||||
<div class="card-profile"></div>
|
||||
<div class="card-profile"></div>
|
||||
<div class="card-profile"></div>
|
||||
<div class="card-profile"></div>
|
||||
<div class="card-profile"></div>
|
||||
<div class="card-profile"></div>
|
||||
<div class="card-profile"></div>
|
||||
<div class="card-profile"></div>
|
||||
<div class="card-profile"></div>
|
||||
</div>
|
||||
|
||||
<div id="block-sheep-info">
|
||||
<div id="sheep-mess">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
|
||||
<path
|
||||
d="M 25.042969 12 C 20.698969 12 18 15.029297 18 19.904297 C 18 24.104297 20.766812 28.599609 24.882812 28.599609 C 27.167812 28.599609 31 27.369813 31 19.132812 C 31 14.999813 28.494969 12 25.042969 12 z M 39.974609 12 C 35.672609 12 33 14.931437 33 19.648438 C 33 24.104438 34.862391 28.599609 39.025391 28.599609 C 43.603391 28.599609 46 23.922734 46 19.302734 C 46 14.285734 42.876609 12 39.974609 12 z M 25.042969 16 C 26.388969 16 27 17.623812 27 19.132812 C 27 20.776813 26.794812 24.599609 24.882812 24.599609 C 23.428813 24.599609 22 22.274297 22 19.904297 C 22 16.000297 24.132969 16 25.042969 16 z M 39.974609 16 C 41.224609 16 42 17.265734 42 19.302734 C 42 21.906734 40.886391 24.599609 39.025391 24.599609 C 37.594391 24.599609 37 21.375438 37 19.648438 C 37 16.000438 39.084609 16 39.974609 16 z M 13.689453 24 C 9.8134531 24 7 27.465234 7 32.240234 C 7 35.462234 9.0299688 40 13.542969 40 C 17.224969 40 20 36.250297 20 31.279297 C 20 27.061297 17.346453 24 13.689453 24 z M 50.75 24 C 46.94 24 43 27.440219 43 33.199219 C 43 36.541219 45.15 40 48.75 40 C 52.612 40 56 35.477312 56 30.320312 C 56 26.480313 53.939 24 50.75 24 z M 13.689453 28 C 15.514453 28 16 30.061297 16 31.279297 C 16 33.793297 14.852969 36 13.542969 36 C 11.603969 36 11 33.244234 11 32.240234 C 11 29.783234 12.131453 28 13.689453 28 z M 50.75 28 C 51.783 28 52 29.262313 52 30.320312 C 52 33.788312 49.866 36 48.75 36 C 47.514 36 47 34.175219 47 33.199219 C 47 29.652219 49.237 28 50.75 28 z M 31.806641 30.001953 C 29.371641 29.947953 27.296656 31.058937 25.597656 33.335938 C 22.515656 37.450938 21.695953 38.210313 19.376953 39.695312 C 17.528953 40.875312 14.998047 42.492141 14.998047 45.994141 C 14.998047 49.769141 18.164641 52.839844 22.056641 52.839844 C 23.872641 52.839844 25.588266 52.174453 27.697266 51.439453 C 29.071266 52.348453 30.722125 52.839844 32.453125 52.839844 C 34.215125 52.839844 35.869422 52.353125 37.232422 51.453125 C 41.805422 53.496125 44.150719 53.039344 45.636719 52.277344 C 47.314719 51.416344 48.403953 49.800703 48.876953 47.470703 C 49.107953 46.334703 48.997375 45.198781 48.609375 44.175781 C 48.012375 42.602781 46.757453 41.293531 45.064453 40.644531 C 43.137453 39.916531 42.576406 39.753172 41.316406 38.826172 C 39.672406 37.616172 39.015453 35.742422 37.814453 33.607422 C 36.601453 31.449422 34.298641 30.067953 31.806641 30.001953 z M 31.701172 34.001953 C 32.777172 34.029953 33.808125 34.644359 34.328125 35.568359 C 35.480125 37.621359 36.442312 40.205828 38.945312 42.048828 C 40.748312 43.375828 41.894813 43.725812 43.632812 44.382812 C 44.073813 44.550813 44.501812 44.883844 44.757812 45.339844 C 44.966813 45.711844 45.061031 46.164781 44.957031 46.675781 C 44.738031 47.753781 44.3535 48.44175 43.8125 48.71875 C 42.4475 49.41975 39.736125 48.192875 38.578125 47.671875 C 38.187125 47.495875 36.729781 46.582125 35.550781 47.703125 C 34.778781 48.436125 33.679125 48.839844 32.453125 48.839844 C 31.288125 48.839844 30.211922 48.444562 29.419922 47.726562 C 28.893922 47.247562 28.151609 47.085828 27.474609 47.298828 C 25.411609 47.948828 23.441594 48.839844 22.058594 48.839844 C 20.372594 48.839844 19.001953 47.562141 19.001953 45.994141 C 19.001953 44.795141 19.69525 44.240406 21.53125 43.066406 C 24.29525 41.302406 25.514688 40.146469 28.804688 35.730469 C 29.975687 34.161469 30.981172 33.980953 31.701172 34.001953 z"
|
||||
/>
|
||||
</svg>
|
||||
<h1>Виберіть вісника для редагування</h1>
|
||||
</div>
|
||||
|
||||
<form id="sheep-editor" style="display: none; opacity: 0">
|
||||
<div class="header">
|
||||
<h1>Інформація про вісника</h1>
|
||||
|
||||
<button onclick="Sheeps.editor.close()">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 26 26">
|
||||
<path
|
||||
d="M 6.65625 4 C 6.367188 4 6.105469 4.113281 5.90625 4.3125 L 4.3125 5.90625 C 3.914063 6.304688 3.914063 7 4.3125 7.5 L 9.8125 13 L 4.3125 18.5 C 3.914063 19 3.914063 19.695313 4.3125 20.09375 L 5.90625 21.6875 C 6.40625 22.085938 7.101563 22.085938 7.5 21.6875 L 13 16.1875 L 18.5 21.6875 C 19 22.085938 19.695313 22.085938 20.09375 21.6875 L 21.6875 20.09375 C 22.085938 19.59375 22.085938 18.898438 21.6875 18.5 L 16.1875 13 L 21.6875 7.5 C 22.085938 7 22.085938 6.304688 21.6875 5.90625 L 20.09375 4.3125 C 19.59375 3.914063 18.898438 3.914063 18.5 4.3125 L 13 9.8125 L 7.5 4.3125 C 7.25 4.113281 6.945313 4 6.65625 4 Z"
|
||||
></path>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
<i id="sheep-editor-icon"></i>
|
||||
<div class="editor-blocks-inputs" id="editor-blocks-inputs-uuid">
|
||||
<label>UUID</label>
|
||||
<input
|
||||
id="sheep-editor-uuid"
|
||||
type="text"
|
||||
name="uuid"
|
||||
value=""
|
||||
disabled
|
||||
style="display: none"
|
||||
/>
|
||||
<p id="sheep-editor-uuid-copy" style="cursor: copy !important"></p>
|
||||
</div>
|
||||
<div class="editor-blocks-inputs">
|
||||
<label for="sheep-editor-name">Імʼя</label>
|
||||
<input id="sheep-editor-name" type="text" name="name" required="" />
|
||||
</div>
|
||||
<div class="editor-blocks-inputs">
|
||||
<label for="sheep-editor-group_id">Група</label>
|
||||
<select id="sheep-editor-group_id" name="group_id">
|
||||
<option value="1">Група 1</option>
|
||||
<option value="2" selected>Група 2</option>
|
||||
<option value="3">Група 3</option>
|
||||
<option value="4">Група 4</option>
|
||||
<option value="5">Група 5</option>
|
||||
<option value="6">Група 6</option>
|
||||
<option value="7">Група 7</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="editor-blocks-inputs">
|
||||
<label for="sheep-editor-appointment">Призначення</label>
|
||||
<select id="sheep-editor-appointment" name="appointment">
|
||||
<option value="lamb" selected>Вісник</option>
|
||||
<option value="pioneer">Піонер</option>
|
||||
<option value="attender">Служитель збору</option>
|
||||
<option value="elder">Старійшина збору</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="editor-blocks-inputs">
|
||||
<label for="sheep-editor-mode">Права</label>
|
||||
<select id="sheep-editor-mode" name="mode">
|
||||
<option value="sheep" selected>Користувач</option>
|
||||
<option value="moderator">Модератор</option>
|
||||
<option value="administrator">Адміністратор</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="editor-blocks-inputs"
|
||||
id="editor-blocks-inputs-uuid-moder"
|
||||
style="display: none"
|
||||
>
|
||||
<label>UUID адміністратора/модератора</label>
|
||||
<p id="sheep-editor-uuid-moder" style="cursor: copy !important"></p>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="editor-blocks-checkbox"
|
||||
id="sheep-editor-access-moder"
|
||||
style="display: none"
|
||||
>
|
||||
<p for="editor-access">Дозволи модератора</p>
|
||||
<div>
|
||||
<div class="checkbox">
|
||||
<input
|
||||
name="can_add_sheeps"
|
||||
class="custom-checkbox"
|
||||
id="sheep-editor-can_add_sheeps"
|
||||
type="checkbox"
|
||||
/>
|
||||
<label for="sheep-editor-can_add_sheeps"> Create Sheeps </label>
|
||||
</div>
|
||||
<div class="checkbox">
|
||||
<input
|
||||
name="can_add_territory"
|
||||
class="custom-checkbox"
|
||||
id="sheep-editor-can_add_territory"
|
||||
type="checkbox"
|
||||
/>
|
||||
<label for="sheep-editor-can_add_territory">
|
||||
Create Territory
|
||||
</label>
|
||||
</div>
|
||||
<div class="checkbox">
|
||||
<input
|
||||
name="can_manager_territory"
|
||||
class="custom-checkbox"
|
||||
id="sheep-editor-can_manager_territory"
|
||||
type="checkbox"
|
||||
/>
|
||||
<label for="sheep-editor-can_manager_territory">
|
||||
Manager Territory
|
||||
</label>
|
||||
</div>
|
||||
<div class="checkbox">
|
||||
<input
|
||||
name="can_add_stand"
|
||||
class="custom-checkbox"
|
||||
id="sheep-editor-can_add_stand"
|
||||
type="checkbox"
|
||||
/>
|
||||
<label for="sheep-editor-can_add_stand"> Create Stand </label>
|
||||
</div>
|
||||
<div class="checkbox">
|
||||
<input
|
||||
name="can_manager_stand"
|
||||
class="custom-checkbox"
|
||||
id="sheep-editor-can_manager_stand"
|
||||
type="checkbox"
|
||||
/>
|
||||
<label for="sheep-editor-can_manager_stand"> Manager Stand </label>
|
||||
</div>
|
||||
<div class="checkbox">
|
||||
<input
|
||||
name="can_add_schedule"
|
||||
class="custom-checkbox"
|
||||
id="sheep-editor-can_add_schedule"
|
||||
type="checkbox"
|
||||
/>
|
||||
<label for="sheep-editor-can_add_schedule"> Create Schedule </label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="editor-blocks-checkbox">
|
||||
<p for="editor-access">Дозволи вісника</p>
|
||||
<div>
|
||||
<div class="checkbox">
|
||||
<input
|
||||
name="can_view_schedule"
|
||||
class="custom-checkbox"
|
||||
id="sheep-editor-can_view_schedule"
|
||||
type="checkbox"
|
||||
/>
|
||||
<label for="sheep-editor-can_view_schedule"> View Schedule </label>
|
||||
</div>
|
||||
<div class="checkbox">
|
||||
<input
|
||||
name="can_view_stand"
|
||||
class="custom-checkbox"
|
||||
id="sheep-editor-can_view_stand"
|
||||
type="checkbox"
|
||||
/>
|
||||
<label for="sheep-editor-can_view_stand"> View Stand </label>
|
||||
</div>
|
||||
<div class="checkbox">
|
||||
<input
|
||||
name="can_view_territory"
|
||||
class="custom-checkbox"
|
||||
id="sheep-editor-can_view_territory"
|
||||
type="checkbox"
|
||||
/>
|
||||
<label for="sheep-editor-can_view_territory">
|
||||
View Territory
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button id="sheep-editor-button" style="display: none">Зберегти</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div id="block-sheep-addeds" style="display: none; opacity: 0">
|
||||
<form id="sheep-addeds">
|
||||
<div class="header">
|
||||
<h1>Додавання нового вісника</h1>
|
||||
<button onclick="Sheeps.addeds.close()" class="close" type="button">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 26 26">
|
||||
<path
|
||||
d="M 6.65625 4 C 6.367188 4 6.105469 4.113281 5.90625 4.3125 L 4.3125 5.90625 C 3.914063 6.304688 3.914063 7 4.3125 7.5 L 9.8125 13 L 4.3125 18.5 C 3.914063 19 3.914063 19.695313 4.3125 20.09375 L 5.90625 21.6875 C 6.40625 22.085938 7.101563 22.085938 7.5 21.6875 L 13 16.1875 L 18.5 21.6875 C 19 22.085938 19.695313 22.085938 20.09375 21.6875 L 21.6875 20.09375 C 22.085938 19.59375 22.085938 18.898438 21.6875 18.5 L 16.1875 13 L 21.6875 7.5 C 22.085938 7 22.085938 6.304688 21.6875 5.90625 L 20.09375 4.3125 C 19.59375 3.914063 18.898438 3.914063 18.5 4.3125 L 13 9.8125 L 7.5 4.3125 C 7.25 4.113281 6.945313 4 6.65625 4 Z"
|
||||
></path>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<i id="sheep-addeds-icon"></i>
|
||||
<div class="addeds-blocks-inputs">
|
||||
<label for="sheep-addeds-name">Імʼя</label>
|
||||
<input id="sheep-addeds-name" type="text" name="name" required="" />
|
||||
</div>
|
||||
<div class="addeds-blocks-inputs">
|
||||
<label for="sheep-addeds-group_id">Група</label>
|
||||
<select id="sheep-addeds-group_id" name="group_id" required>
|
||||
<option value="" selected disabled>Оберіть...</option>
|
||||
<option value="1">Група 1</option>
|
||||
<option value="2">Група 2</option>
|
||||
<option value="3">Група 3</option>
|
||||
<option value="4">Група 4</option>
|
||||
<option value="5">Група 5</option>
|
||||
<option value="6">Група 6</option>
|
||||
<option value="7">Група 7</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="addeds-blocks-inputs">
|
||||
<label for="sheep-addeds-appointment">Призначення</label>
|
||||
<select id="sheep-addeds-appointment" name="appointment" required>
|
||||
<option value="lamb" selected>Вісник</option>
|
||||
<option value="pioneer">Піонер</option>
|
||||
<option value="attender">Служитель збору</option>
|
||||
<option value="elder">Старійшина збору</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<button id="sheep-addeds-button">Додати</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
428
web/lib/pages/sheeps/script.js
Normal file
482
web/lib/pages/sheeps/style.css
Normal file
@@ -0,0 +1,482 @@
|
||||
.page-sheeps {
|
||||
width: calc(100% - 18px);
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
margin: 20px 9px 0 9px;
|
||||
justify-content: space-between;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
#block-sheeps-list,
|
||||
#block-sheep-info {
|
||||
width: 100%;
|
||||
margin: 0 10px 15px;
|
||||
border-radius: 15px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
background: var(--ColorThemes1);
|
||||
color: var(--ColorThemes3);
|
||||
border: 1px solid var(--ColorThemes2);
|
||||
box-shadow: var(--shadow-l1);
|
||||
transition: all .2s ease 0s;
|
||||
}
|
||||
|
||||
#block-sheep-info {
|
||||
min-height: calc(100vh - 40px);
|
||||
max-height: calc(100vh - 40px);
|
||||
position: sticky;
|
||||
overflow: auto;
|
||||
top: 20px;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
#block-sheeps-list>.header {
|
||||
min-height: 40px;
|
||||
width: calc(100% - 20px);
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
background: var(--PrimaryColor);
|
||||
margin: 10px;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
#block-sheeps-list>.header>h1 {
|
||||
font-size: 16px;
|
||||
font-weight: 400;
|
||||
color: var(--PrimaryColorText);
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
#block-sheeps-list>.header>button {
|
||||
display: flex;
|
||||
position: relative;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
background: var(--ColorThemes0);
|
||||
margin-right: 5px;
|
||||
border-radius: 8px;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 30px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#block-sheeps-list>.header>button>svg {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
fill: var(--ColorThemes3);
|
||||
transform: rotate(45deg);
|
||||
}
|
||||
|
||||
#block-sheeps-list>.card-profile {
|
||||
width: calc(100% - 30px);
|
||||
min-height: 100px;
|
||||
background-color: var(--ColorThemes2);
|
||||
border: 1px solid var(--ColorThemes0);
|
||||
box-shadow: var(--shadow-l1);
|
||||
border-radius: 10px;
|
||||
margin: 10px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
padding: 5px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#block-sheeps-list>.card-profile>img,
|
||||
#block-sheeps-list>.card-profile>svg {
|
||||
width: 65px;
|
||||
min-width: 65px;
|
||||
height: 65px;
|
||||
margin: 10px 15px 10px 10px;
|
||||
fill: var(--PrimaryColor);
|
||||
}
|
||||
|
||||
#block-sheeps-list>.card-profile>.info {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 90px;
|
||||
justify-content: space-between;
|
||||
position: relative;
|
||||
width: calc(100% - 95px);
|
||||
}
|
||||
|
||||
#block-sheeps-list>.card-profile>.info>.text>h1 {
|
||||
font-size: 16px;
|
||||
color: var(--ColorThemes3);
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
#block-sheeps-list>.card-profile>.info>.text>h2 {
|
||||
font-size: 12px;
|
||||
color: var(--ColorThemes3);
|
||||
font-weight: 400;
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
#block-sheeps-list>.card-profile>.info>.access {
|
||||
display: flex;
|
||||
overflow-x: auto;
|
||||
overflow-y: hidden;
|
||||
max-width: 100%;
|
||||
padding-bottom: 4px;
|
||||
height: 30px;
|
||||
}
|
||||
|
||||
#block-sheeps-list>.card-profile>.info>.access>b {
|
||||
padding: 2px 5px;
|
||||
border-radius: 5px;
|
||||
background: var(--PrimaryColor);
|
||||
color: var(--PrimaryColorText);
|
||||
margin-right: 5px;
|
||||
white-space: nowrap;
|
||||
font-size: 13px;
|
||||
height: 20px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#block-sheep-info>#sheep-mess {
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
margin-top: -100px;
|
||||
margin-left: -100px;
|
||||
justify-content: center;
|
||||
opacity: 0.6;
|
||||
transition: all .2s ease 0s;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
#block-sheep-info>#sheep-mess>svg {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
fill: var(--ColorThemes3);
|
||||
}
|
||||
|
||||
#block-sheep-info>#sheep-mess>h1 {
|
||||
font-size: 20px;
|
||||
color: var(--ColorThemes3);
|
||||
font-weight: 400;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#block-sheep-info>#sheep-editor {
|
||||
display: flex;
|
||||
padding: 10px;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
transition: all .3s ease 0s;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
#block-sheep-info>#sheep-editor>.header {
|
||||
display: none;
|
||||
min-height: 40px;
|
||||
width: 100%;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
background: var(--ColorThemes3);
|
||||
margin: 0 0 10px 0;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
#block-sheep-info>#sheep-editor>.header>h1 {
|
||||
font-size: 16px;
|
||||
font-weight: 400;
|
||||
color: var(--ColorThemes0);
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
#block-sheep-info>#sheep-editor>.header>button {
|
||||
display: flex;
|
||||
position: relative;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
background: var(--ColorThemes0);
|
||||
margin-right: 5px;
|
||||
border-radius: 8px;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 30px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#block-sheep-info>#sheep-editor>.header>button>svg {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
fill: var(--ColorThemes3);
|
||||
}
|
||||
|
||||
#block-sheep-info>#sheep-editor>i>svg {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
fill: var(--PrimaryColor);
|
||||
}
|
||||
|
||||
#block-sheep-info>#sheep-editor>.editor-blocks-inputs {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
margin: 10px 0;
|
||||
align-items: flex-start;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
#block-sheep-info>#sheep-editor>.editor-blocks-inputs label {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
#block-sheep-info>#sheep-editor>.editor-blocks-inputs input {
|
||||
width: calc(100% - 10px);
|
||||
min-width: 140px;
|
||||
padding: 0 5px;
|
||||
border-radius: 6px;
|
||||
height: 30px;
|
||||
background: var(--ColorThemes0);
|
||||
color: var(--ColorThemes3);
|
||||
}
|
||||
|
||||
#block-sheep-info>#sheep-editor>.editor-blocks-inputs select {
|
||||
width: 100%;
|
||||
min-width: 140px;
|
||||
padding: 0 5px;
|
||||
border-radius: 6px;
|
||||
height: 30px;
|
||||
background-color: var(--ColorThemes0);
|
||||
color: var(--ColorThemes3);
|
||||
}
|
||||
|
||||
#block-sheep-info>#sheep-editor>.editor-blocks-inputs p {
|
||||
display: flex;
|
||||
width: calc(100% - 10px);
|
||||
min-width: 140px;
|
||||
font-size: 14px;
|
||||
padding: 0 5px;
|
||||
border-radius: 6px;
|
||||
height: 30px;
|
||||
background: var(--ColorThemes0);
|
||||
color: var(--ColorThemes3);
|
||||
align-items: center;
|
||||
cursor: copy;
|
||||
}
|
||||
|
||||
#block-sheep-info>#sheep-editor>.editor-blocks-checkbox {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
margin: 10px 0;
|
||||
align-items: flex-start;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
#block-sheep-info>#sheep-editor>.editor-blocks-checkbox>p {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
#block-sheep-info>#sheep-editor>.editor-blocks-checkbox>div {
|
||||
background: var(--ColorThemes0);
|
||||
border-radius: 6px;
|
||||
width: calc(100% - 15px);
|
||||
padding: 0 5px 0 10px;
|
||||
}
|
||||
|
||||
#block-sheep-info>#sheep-editor>.editor-blocks-checkbox>div>.checkbox {
|
||||
margin: 10px 0;
|
||||
width: 100%;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
#block-sheep-info>#sheep-editor>.editor-blocks-checkbox>div>.checkbox>.custom-checkbox+label {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
user-select: none;
|
||||
flex-direction: row-reverse;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
#block-sheep-info>#sheep-editor>button {
|
||||
border-radius: 6px;
|
||||
background: var(--PrimaryColor);
|
||||
color: var(--PrimaryColorText);
|
||||
width: 100%;
|
||||
height: 40px;
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
margin: 20px 0 0 0;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
#block-sheep-addeds {
|
||||
width: 100%;
|
||||
height: fit-content;
|
||||
margin: 0 10px 15px;
|
||||
border-radius: 15px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
background: var(--ColorThemes1);
|
||||
color: var(--ColorThemes3);
|
||||
border: 1px solid var(--ColorThemes2);
|
||||
box-shadow: var(--shadow-l1);
|
||||
transition: all .2s ease 0s;
|
||||
}
|
||||
|
||||
#block-sheep-addeds>#sheep-addeds {
|
||||
display: flex;
|
||||
padding: 10px;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
transition: all .3s ease 0s;
|
||||
}
|
||||
|
||||
#block-sheep-addeds>#sheep-addeds>div {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
#block-sheep-addeds>#sheep-addeds>.header {
|
||||
min-height: 40px;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
background: var(--ColorThemes3);
|
||||
margin: 0 0 10px 0;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
#block-sheep-addeds>#sheep-addeds>.header>h1 {
|
||||
font-size: 16px;
|
||||
font-weight: 400;
|
||||
color: var(--ColorThemes0);
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
#block-sheep-addeds>#sheep-addeds>.header>button {
|
||||
display: flex;
|
||||
position: relative;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
background: var(--ColorThemes0);
|
||||
margin-right: 5px;
|
||||
border-radius: 8px;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 30px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#block-sheep-addeds>#sheep-addeds>.header>button>svg {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
fill: var(--ColorThemes3);
|
||||
}
|
||||
|
||||
#block-sheep-addeds>#sheep-addeds>i>svg {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
fill: var(--PrimaryColor);
|
||||
}
|
||||
|
||||
#block-sheep-addeds>#sheep-addeds>.addeds-blocks-inputs {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
margin: 10px 0;
|
||||
align-items: flex-start;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
#block-sheep-addeds>#sheep-addeds>.addeds-blocks-inputs label {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
#block-sheep-addeds>#sheep-addeds>.addeds-blocks-inputs input {
|
||||
width: calc(100% - 10px);
|
||||
min-width: 140px;
|
||||
padding: 0 5px;
|
||||
border-radius: 6px;
|
||||
height: 30px;
|
||||
background: var(--ColorThemes0);
|
||||
color: var(--ColorThemes3);
|
||||
}
|
||||
|
||||
#block-sheep-addeds>#sheep-addeds>.addeds-blocks-inputs select {
|
||||
width: 100%;
|
||||
min-width: 140px;
|
||||
padding: 0 5px;
|
||||
border-radius: 6px;
|
||||
height: 30px;
|
||||
background-color: var(--ColorThemes0);
|
||||
color: var(--ColorThemes3);
|
||||
}
|
||||
|
||||
#block-sheep-addeds>#sheep-addeds>button {
|
||||
border-radius: 6px;
|
||||
background: var(--PrimaryColor);
|
||||
color: var(--PrimaryColorText);
|
||||
width: 100%;
|
||||
height: 40px;
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
margin: 20px 0 0 0;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
@media (min-width: 1001px),
|
||||
(min-height: 541px) {
|
||||
|
||||
#block-sheeps-list,
|
||||
#block-sheep-info {
|
||||
opacity: 1 !important;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 1000px),
|
||||
(max-height: 540px) {
|
||||
#block-sheeps-list {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#block-sheep-info {
|
||||
display: none;
|
||||
min-height: fit-content;
|
||||
}
|
||||
#block-sheep-info>#sheep-editor>.header {
|
||||
display: flex;
|
||||
}
|
||||
}
|
||||
|
||||
/* @media (min-height: 600px) and (max-height: 700px) {
|
||||
#block-sheep-info>#sheep-editor>i>svg {
|
||||
display: none;
|
||||
}
|
||||
} */
|
||||
4
web/lib/pages/stand/index.html
Normal file
@@ -0,0 +1,4 @@
|
||||
<div class="page-stand">
|
||||
<label for="dateSelect">Виберіть дату:</label>
|
||||
<select id="dateSelect"></select>
|
||||
</div>
|
||||
38
web/lib/pages/stand/script.js
Normal file
@@ -0,0 +1,38 @@
|
||||
const Stand = {
|
||||
init: async () => {
|
||||
let html = await fetch('/lib/pages/stand/index.html').then((response) => response.text());
|
||||
app.innerHTML = html;
|
||||
|
||||
let listDate = [1, 4];
|
||||
|
||||
function generateAvailableDates() {
|
||||
let select = document.getElementById("dateSelect");
|
||||
select.innerHTML = "";
|
||||
|
||||
let today = new Date();
|
||||
today.setHours(0, 0, 0, 0);
|
||||
let months = [today.getMonth(), today.getMonth() + 1];
|
||||
let year = today.getFullYear();
|
||||
|
||||
months.forEach(month => {
|
||||
let date = new Date(year, month, 1);
|
||||
while (date.getMonth() === month) {
|
||||
if (date >= today) {
|
||||
let day = date.getDay();
|
||||
if (listDate.includes(day)) {
|
||||
let option = document.createElement("option");
|
||||
option.value = date.toISOString().split("T")[0];
|
||||
option.textContent = date.toLocaleDateString("uk-UA", {
|
||||
weekday: "long", year: "numeric", month: "long", day: "numeric"
|
||||
});
|
||||
select.appendChild(option);
|
||||
}
|
||||
}
|
||||
date.setDate(date.getDate() + 1);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
generateAvailableDates();
|
||||
}
|
||||
}
|
||||
20
web/lib/pages/stand/style.css
Normal file
@@ -0,0 +1,20 @@
|
||||
.page-stand {
|
||||
width: calc(100% - 40px);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin: 20px 20px 0 20px;
|
||||
}
|
||||
|
||||
.page-stand select {
|
||||
width: 100%;
|
||||
min-width: 140px;
|
||||
padding: 0 5px;
|
||||
border-radius: 6px;
|
||||
height: 30px;
|
||||
background-color: var(--ColorThemes1);
|
||||
color: var(--ColorThemes3);
|
||||
border: 1px solid var(--ColorThemes2);
|
||||
margin: 10px 0;
|
||||
box-shadow: var(--shadow-l1);
|
||||
font-size: 14px;
|
||||
}
|
||||
39
web/lib/pages/territory/index.html
Normal file
@@ -0,0 +1,39 @@
|
||||
<div class="page-territory">
|
||||
<div class="buttons-list">
|
||||
<button onclick="Rotation()" id="rotationButton" style="display: none;">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48">
|
||||
<path
|
||||
d="M16.5 25.5c-.52.893-1.476 1.5-2.584 1.5-1.657 0-3-1.343-3-3s1.343-3 3-3c1.108 0 2.064.607 2.584 1.5H23v-11C23 8.468 20.533 6 17.5 6h-6C8.467 6 6 8.468 6 11.5v25c0 3.032 2.467 5.5 5.5 5.5h6c3.033 0 5.5-2.468 5.5-5.5v-11H16.5zM36.5 6h-6C27.467 6 25 8.468 25 11.5v11h7.879l-1.439-1.439c-.586-.586-.586-1.535 0-2.121s1.535-.586 2.121 0l4 4c.586.586.586 1.535 0 2.121l-4 4C33.268 29.354 32.884 29.5 32.5 29.5s-.768-.146-1.061-.439c-.586-.586-.586-1.535 0-2.121l1.439-1.439H25v11c0 3.032 2.467 5.5 5.5 5.5h6c3.033 0 5.5-2.468 5.5-5.5v-25C42 8.468 39.533 6 36.5 6z"
|
||||
/>
|
||||
</svg>
|
||||
<span id="rotationButton-title">Провести ротацію</span>
|
||||
</button>
|
||||
|
||||
<a href="/constructor" data-route id="constructorButton" style="display: none;">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48">
|
||||
<path
|
||||
d="M 14.5 4 C 12.015 4 10 6.015 10 8.5 L 10 39.5 C 10 41.985 12.015 44 14.5 44 L 22.042969 44 C 22.079969 43.749 22.138516 43.502672 22.228516 43.263672 L 22.283203 43.285156 C 22.353203 42.961156 23.236422 40.161109 23.982422 37.787109 C 24.272422 36.865109 24.779891 36.029703 25.462891 35.345703 L 33.904297 27 L 27.5 27 C 26.672 27 26 26.328 26 25.5 L 26 16 L 38 16 L 38 23.054688 C 38.72 22.587688 39.4975 22.254422 40.3125 22.107422 C 40.5365 22.067422 40.769 22.062922 41 22.044922 L 41 14.5 C 41 13.672 40.328 13 39.5 13 L 34 13 L 34 8.5 C 34 6.015 31.985 4 29.5 4 L 14.5 4 z M 30.5 18 A 1.50015 1.50015 0 1 0 30.5 21 L 33.5 21 A 1.50015 1.50015 0 1 0 33.5 18 L 30.5 18 z M 41.498047 24 C 41.224047 24.001 40.946969 24.025172 40.667969 24.076172 C 39.783969 24.235172 38.939563 24.696156 38.226562 25.410156 L 26.427734 37.208984 C 26.070734 37.565984 25.807969 38.011141 25.667969 38.494141 L 24.097656 43.974609 C 24.025656 44.164609 23.993 44.365406 24 44.566406 C 24.013 44.929406 24.155594 45.288406 24.433594 45.566406 C 24.710594 45.843406 25.067688 45.986 25.429688 46 C 25.630688 46.007 25.834391 45.975344 26.025391 45.902344 L 31.505859 44.332031 C 31.988859 44.192031 32.431062 43.930266 32.789062 43.572266 L 44.589844 31.773438 C 45.303844 31.060437 45.764828 30.216031 45.923828 29.332031 C 45.973828 29.053031 45.997047 28.775953 45.998047 28.501953 C 46.001047 27.307953 45.540687 26.179312 44.679688 25.320312 C 43.820687 24.460313 42.692047 23.998 41.498047 24 z M 22 35 C 22.828 35 23.5 35.672 23.5 36.5 C 23.5 37.328 22.828 38 22 38 C 21.172 38 20.5 37.328 20.5 36.5 C 20.5 35.672 21.172 35 22 35 z"
|
||||
/>
|
||||
</svg>
|
||||
<span>Конструктор</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="list-controls"></div>
|
||||
|
||||
<details open>
|
||||
<summary>
|
||||
<span>Багатоквартирні будинки</span>
|
||||
</summary>
|
||||
|
||||
<div id="list-house"></div>
|
||||
</details>
|
||||
|
||||
<details open>
|
||||
<summary>
|
||||
<span>Житлові райони</span>
|
||||
</summary>
|
||||
|
||||
<div id="list-homestead"></div>
|
||||
</details>
|
||||
</div>
|
||||
130
web/lib/pages/territory/script.js
Normal file
@@ -0,0 +1,130 @@
|
||||
const Territory = {
|
||||
init: async () => {
|
||||
let html = await fetch('/lib/pages/territory/index.html').then((response) => response.text());
|
||||
app.innerHTML = html;
|
||||
|
||||
if (USER.administrator.uuid) document.getElementById('rotationButton').style.display = "";
|
||||
if (USER.administrator.uuid || (USER.moderator.uuid && USER.moderator.can_add_territory)) document.getElementById("constructorButton").style.display = "";
|
||||
|
||||
Territory.house.setHTML();
|
||||
Territory.homestead.setHTML();
|
||||
},
|
||||
house: {
|
||||
loadAPI: async function () {
|
||||
let uuid = localStorage.getItem("uuid");
|
||||
|
||||
const URL = `${CONFIG.api}houses/list`;
|
||||
return await fetch(URL, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"Authorization": uuid
|
||||
}
|
||||
}).then((response) => response.json());
|
||||
},
|
||||
setHTML: async function () {
|
||||
let list = await Territory.house.loadAPI();
|
||||
|
||||
list.sort((a, b) => b.id - a.id);
|
||||
|
||||
console.log(list);
|
||||
let block_house = document.getElementById('list-house')
|
||||
block_house.innerHTML = "";
|
||||
|
||||
for (let i = 0; i < list.length; i++) {
|
||||
const element = list[i];
|
||||
|
||||
let progress = ((element.entrance.working / element.entrance.quantity) * 100);
|
||||
|
||||
let pageURL = () => {
|
||||
if (USER.administrator.uuid || (USER.moderator.uuid && USER.moderator.can_manager_territory)) return `/territory/manager/house/${element.id}`;
|
||||
else return `/territory/card/house/${element.id}`
|
||||
}
|
||||
|
||||
block_house.innerHTML += `
|
||||
<div class="card">
|
||||
<i style="background-image: url(https://sheep-service.com/cards/house/T${element.id}.webp);"></i>
|
||||
<div class="contents">
|
||||
<div class="group" style="background: ${colorGroup(element.group_id)}">
|
||||
<span>Група №${element.group_id}</span>
|
||||
</div>
|
||||
<div class="info">
|
||||
<div>
|
||||
<div class="progress" style="width: ${progress}%"></div>
|
||||
<span>Вільні під'їзди:</span>
|
||||
<p>${element.entrance.quantity - element.entrance.working} / ${element.entrance.quantity}</p>
|
||||
</div>
|
||||
<div>
|
||||
<p>${element.title} ${element.number}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<a href="${pageURL()}" data-route></a>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
}
|
||||
},
|
||||
homestead: {
|
||||
loadAPI: async function () {
|
||||
let uuid = localStorage.getItem("uuid");
|
||||
|
||||
const URL = `${CONFIG.api}homestead/list`;
|
||||
return await fetch(URL, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"Authorization": uuid
|
||||
}
|
||||
}).then((response) => response.json());
|
||||
},
|
||||
setHTML: async function () {
|
||||
let list = await Territory.homestead.loadAPI();
|
||||
|
||||
list.sort((a, b) => b.id - a.id);
|
||||
|
||||
console.log(list);
|
||||
let block_homestead = document.getElementById('list-homestead')
|
||||
block_homestead.innerHTML = "";
|
||||
|
||||
for (let i = 0; i < list.length; i++) {
|
||||
const element = list[i];
|
||||
|
||||
let block_history = () => {
|
||||
if (element.working) {
|
||||
return `
|
||||
<div>
|
||||
<div class="progress" style="width: 100%"></div>
|
||||
<p>${element.history.name}</p>
|
||||
</div>
|
||||
`
|
||||
}
|
||||
return ''
|
||||
}
|
||||
|
||||
let pageURL = () => {
|
||||
if (USER.administrator.uuid || (USER.moderator.uuid && USER.moderator.can_manager_territory)) return `/territory/manager/homestead/${element.id}`;
|
||||
else return `/territory/card/homestead/${element.id}`
|
||||
}
|
||||
|
||||
block_homestead.innerHTML += `
|
||||
<div class="card">
|
||||
<i style="background-image: url(https://sheep-service.com/cards/homestead/H${element.id}.webp);"></i>
|
||||
<div class="contents">
|
||||
<div class="group" style="background: ${colorGroup(element.group_id)}">
|
||||
<span>Група №${element.group_id}</span>
|
||||
</div>
|
||||
<div class="info">
|
||||
${block_history()}
|
||||
<div>
|
||||
<p>${element.title} ${element.number}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<a href="${pageURL()}" data-route></a>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
247
web/lib/pages/territory/style.css
Normal file
@@ -0,0 +1,247 @@
|
||||
.page-territory {
|
||||
width: calc(100% - 40px);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin: 20px 20px 0 20px;
|
||||
}
|
||||
|
||||
|
||||
.page-territory>.buttons-list {
|
||||
padding: 10px;
|
||||
margin-bottom: 20px;
|
||||
background: var(--ColorThemes1);
|
||||
color: var(--ColorThemes3);
|
||||
border: 1px solid var(--ColorThemes2);
|
||||
box-shadow: var(--shadow-l1);
|
||||
border-radius: 15px;
|
||||
overflow: auto;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.page-territory>.buttons-list>button,
|
||||
.page-territory>.buttons-list>a {
|
||||
cursor: pointer;
|
||||
border-radius: 10px;
|
||||
padding: 0 10px;
|
||||
margin-right: 20px;
|
||||
min-width: fit-content;
|
||||
min-height: 40px;
|
||||
background: var(--PrimaryColor);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.page-territory>.buttons-list>button>span,
|
||||
.page-territory>.buttons-list>a>span {
|
||||
color: var(--PrimaryColorText);
|
||||
font-size: 14px;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.page-territory>.buttons-list>button>svg,
|
||||
.page-territory>.buttons-list>a>svg {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
fill: var(--PrimaryColorText);
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.page-territory details {
|
||||
border-radius: 15px;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
margin-bottom: 20px;
|
||||
background: var(--ColorThemes1);
|
||||
color: var(--ColorThemes3);
|
||||
border: 1px solid var(--ColorThemes2);
|
||||
box-shadow: var(--shadow-l1);
|
||||
}
|
||||
|
||||
.page-territory>details[disabled] summary,
|
||||
.page-territory>details.disabled summary {
|
||||
pointer-events: none;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.page-territory>details summary::-webkit-details-marker,
|
||||
.page-territory>details summary::marker {
|
||||
display: none;
|
||||
content: "";
|
||||
}
|
||||
|
||||
|
||||
.page-territory summary {
|
||||
width: calc(100% - 40px);
|
||||
cursor: pointer;
|
||||
color: var(--ColorThemes3);
|
||||
border-radius: var(--border-radius);
|
||||
font-size: 16px;
|
||||
font-weight: 300;
|
||||
padding: 20px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.page-territory summary span {
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.page-territory #list-house,
|
||||
.page-territory #list-homestead {
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
flex-direction: row;
|
||||
align-content: flex-start;
|
||||
justify-content: center;
|
||||
overflow-y: auto;
|
||||
align-items: flex-start;
|
||||
transition: .3s ease;
|
||||
}
|
||||
|
||||
.page-territory .card {
|
||||
position: relative;
|
||||
width: 300px;
|
||||
height: 200px;
|
||||
background-color: var(--ColorThemes2);
|
||||
margin: 0px 10px 20px 10px;
|
||||
overflow: hidden;
|
||||
cursor: pointer;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
@media (max-width: 2300px) {
|
||||
.page-territory .card {
|
||||
width: calc((100% / 5) - 40px);
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 1960px) {
|
||||
.page-territory .card {
|
||||
width: calc((100% / 4) - 40px);
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 1640px) {
|
||||
.page-territory .card {
|
||||
width: calc((100% / 3) - 40px);
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 1280px) {
|
||||
.page-territory .card {
|
||||
width: calc((100% / 2) - 40px);
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 650px) {
|
||||
.page-territory .card {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
@media(hover: hover) {
|
||||
.page-territory .card:hover {
|
||||
opacity: 0.8;
|
||||
}
|
||||
}
|
||||
|
||||
.page-territory .card>i {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
z-index: 1;
|
||||
filter: blur(2px);
|
||||
/* background-repeat: round; */
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
background-image: url(https://tm.rozenrod.com/web/img/bg.webp);
|
||||
}
|
||||
|
||||
.page-territory .card>a {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.page-territory .contents {
|
||||
position: absolute;
|
||||
z-index: 2;
|
||||
background: rgb(64 64 64 / 0.7);
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
font-size: 40px;
|
||||
font-weight: 500;
|
||||
color: #fff;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.page-territory .group {
|
||||
width: calc(100% - 20px);
|
||||
max-height: 50px;
|
||||
border-radius: 7px;
|
||||
padding: 10px 0;
|
||||
margin-top: 10px;
|
||||
display: flex;
|
||||
background: var(--PrimaryColor);
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
justify-content: space-around;
|
||||
}
|
||||
|
||||
.page-territory .group>span {
|
||||
color: #fff;
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
.page-territory .info {
|
||||
width: calc(100% - 20px);
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.page-territory .info>div {
|
||||
width: 100%;
|
||||
height: 35px;
|
||||
margin-top: 5px;
|
||||
display: flex;
|
||||
background: var(--ColorThemes0);
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 12px;
|
||||
color: var(--ColorThemes3);
|
||||
border-radius: 7px;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.page-territory .progress {
|
||||
background: var(--PrimaryColor);
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.page-territory .info>div>span {
|
||||
color: var(--ColorThemes3);
|
||||
font-size: 14px;
|
||||
font-weight: 300;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.page-territory .info>div>p {
|
||||
color: var(--ColorThemes3);
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
padding: 10px;
|
||||
z-index: 2;
|
||||
}
|
||||
75
web/lib/pages/territory_manager/index.html
Normal file
@@ -0,0 +1,75 @@
|
||||
<div class="page-territory_manager">
|
||||
<div id="territory-info">
|
||||
<div class="territory-info-image" id="CardPicture">
|
||||
<img id="info-picture" src="" alt="" style="display: none" />
|
||||
|
||||
<div id="map_territory_manager"></div>
|
||||
|
||||
<div class="menu-picture">
|
||||
<a id="menu-picture-error" title="Зображення не знайдено!">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 30 30" style="fill: #c14d4d;">
|
||||
<path
|
||||
d="M 3.7070312 2.2929688 L 2.2929688 3.7070312 L 26.292969 27.707031 L 27.707031 26.292969 L 26.375 24.960938 C 27.299776 24.784872 28 23.976233 28 23 L 28 7 C 28 5.895 27.105 5 26 5 L 6.4140625 5 L 3.7070312 2.2929688 z M 2.1367188 6.2851562 C 2.0517188 6.5071563 2 6.747 2 7 L 2 23 C 2 24.105 2.895 25 4 25 L 20.851562 25 L 17.851562 22 L 5 22 L 5 15 L 7.2890625 12.710938 C 7.5140625 12.485938 7.7747812 12.317219 8.0507812 12.199219 L 2.1367188 6.2851562 z M 23 8 C 24.105 8 25 8.895 25 10 C 25 11.105 24.105 12 23 12 C 21.895 12 21 11.105 21 10 C 21 8.895 21.895 8 23 8 z M 19 14.001953 C 19.61925 14.001953 20.238437 14.238437 20.710938 14.710938 L 25 19 L 25 22 L 23.414062 22 L 16.707031 15.292969 L 17.289062 14.710938 C 17.761563 14.238437 18.38075 14.001953 19 14.001953 z"
|
||||
/>
|
||||
</svg>
|
||||
</a>
|
||||
<a id="menu-picture-ok" style="display: none;" title="Зображення знайдено" target="_blank">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 30 30" style="fill: #8BC34A;">
|
||||
<path
|
||||
d="M 4 5 C 2.895 5 2 5.895 2 7 L 2 23 C 2 24.105 2.895 25 4 25 L 26 25 C 27.105 25 28 24.105 28 23 L 28 7 C 28 5.895 27.105 5 26 5 L 4 5 z M 23 8 C 24.105 8 25 8.895 25 10 C 25 11.105 24.105 12 23 12 C 21.895 12 21 11.105 21 10 C 21 8.895 21.895 8 23 8 z M 9 13.001953 C 9.61925 13.001953 10.238437 13.238437 10.710938 13.710938 L 13.972656 16.972656 L 15 18 L 16.15625 19.15625 C 16.57825 19.57825 17.259641 19.574344 17.681641 19.152344 C 18.104641 18.730344 18.104641 18.044094 17.681641 17.621094 L 16.529297 16.470703 L 17.289062 15.710938 C 18.234063 14.765937 19.765937 14.765937 20.710938 15.710938 L 25 20 L 25 22 L 5 22 L 5 16 L 7.2890625 13.710938 C 7.7615625 13.238437 8.38075 13.001953 9 13.001953 z"
|
||||
/>
|
||||
</svg>
|
||||
</a>
|
||||
|
||||
<button title="Створити нове зображення" onclick="Territory_Manager.getScreen()">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 30 30"> <path d="M 22.828125 3 C 22.316375 3 21.804562 3.1954375 21.414062 3.5859375 L 19 6 L 24 11 L 26.414062 8.5859375 C 27.195062 7.8049375 27.195062 6.5388125 26.414062 5.7578125 L 24.242188 3.5859375 C 23.851688 3.1954375 23.339875 3 22.828125 3 z M 17 8 L 5.2597656 19.740234 C 5.2597656 19.740234 6.1775313 19.658 6.5195312 20 C 6.8615312 20.342 6.58 22.58 7 23 C 7.42 23.42 9.6438906 23.124359 9.9628906 23.443359 C 10.281891 23.762359 10.259766 24.740234 10.259766 24.740234 L 22 13 L 17 8 z M 4 23 L 3.0566406 25.671875 A 1 1 0 0 0 3 26 A 1 1 0 0 0 4 27 A 1 1 0 0 0 4.328125 26.943359 A 1 1 0 0 0 4.3378906 26.939453 L 4.3632812 26.931641 A 1 1 0 0 0 4.3691406 26.927734 L 7 26 L 5.5 24.5 L 4 23 z"/></svg>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="territory-info-text">
|
||||
<h1>Вулиця:</h1>
|
||||
<h2 id="info-title">--</h2>
|
||||
</div>
|
||||
|
||||
<div class="territory-info-text">
|
||||
<h1>Номер:</h1>
|
||||
<h2 id="info-number">--</h2>
|
||||
</div>
|
||||
|
||||
<div class="territory-info-text">
|
||||
<h1>Населений пункт:</h1>
|
||||
<h2 id="info-settlement">--</h2>
|
||||
</div>
|
||||
|
||||
<div class="territory-info-text">
|
||||
<textarea
|
||||
name="info-description"
|
||||
id="info-description"
|
||||
placeholder="Примітка"
|
||||
></textarea>
|
||||
</div>
|
||||
<a id="editor_button" style="display: none" data-route>Змінити територію</a>
|
||||
</div>
|
||||
|
||||
<div id="territory-entrance"></div>
|
||||
</div>
|
||||
|
||||
<div id="territory-new" style="display: none; opacity: 0">
|
||||
<div class="mess">
|
||||
<span>Налаштування</span>
|
||||
<select id="new-worker-name" name="new-worker-name" required="">
|
||||
<option value="" selected="" disabled="">Оберіть...</option>
|
||||
</select>
|
||||
<div>
|
||||
<button onclick="Territory_Manager.mess.close()">Закрити</button>
|
||||
<button
|
||||
id="new-worker-button"
|
||||
onclick="Territory_Manager.newWorker()"
|
||||
style="background: var(--PrimaryColor); color: var(--PrimaryColorText)"
|
||||
>
|
||||
Призначити
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
506
web/lib/pages/territory_manager/script.js
Normal file
@@ -0,0 +1,506 @@
|
||||
let map_territory, type_territory;
|
||||
|
||||
const Territory_Manager = {
|
||||
init: async (type, id) => {
|
||||
let html = await fetch('/lib/pages/territory_manager/index.html').then((response) => response.text());
|
||||
app.innerHTML = html;
|
||||
|
||||
type_territory = type;
|
||||
|
||||
let sheeps_list = [];
|
||||
if (Sheeps.sheeps_list.list.length == 0) {
|
||||
sheeps_list = await Sheeps.sheeps_list.loadAPI();
|
||||
} else {
|
||||
sheeps_list = Sheeps.sheeps_list.list;
|
||||
}
|
||||
|
||||
let editor_button = document.getElementById('editor_button');
|
||||
if (USER.administrator.uuid || (USER.moderator.uuid && USER.moderator.can_add_territory)){
|
||||
editor_button.style.display = "";
|
||||
editor_button.setAttribute("href", `/territory/editor/${type}/${id}`)
|
||||
}
|
||||
|
||||
await Territory_Manager.info.setHTML(type, id);
|
||||
Territory_Manager.entrances.setHTML(type, id);
|
||||
|
||||
for (let i = 0; i < sheeps_list.length; i++) {
|
||||
const element = sheeps_list[i];
|
||||
|
||||
if (Territory_Manager.info.list.group_id == element.group_id) {
|
||||
document.getElementById('new-worker-name').innerHTML += `
|
||||
<option value="${element.name}">${element.name}</option>
|
||||
`;
|
||||
}
|
||||
}
|
||||
},
|
||||
info: {
|
||||
list: {},
|
||||
loadAPI: async (url) => {
|
||||
let uuid = localStorage.getItem("uuid");
|
||||
Territory_Manager.info.list = await fetch(url, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"Authorization": uuid
|
||||
}
|
||||
}).then((response) => response.json());
|
||||
return Territory_Manager.info.list;
|
||||
},
|
||||
setHTML: async (type, id) => {
|
||||
if (type == "house") {
|
||||
let url = `${CONFIG.api}house/${id}`;
|
||||
let data = await Territory_Manager.info.loadAPI(url);
|
||||
|
||||
Territory_Manager.map(type, data);
|
||||
|
||||
let info_picture = document.getElementById('info-picture');
|
||||
let info_title = document.getElementById('info-title');
|
||||
let info_number = document.getElementById('info-number');
|
||||
let info_settlement = document.getElementById('info-settlement');
|
||||
let info_description = document.getElementById('info-description');
|
||||
|
||||
info_picture.addEventListener("click", (event) => {
|
||||
let state = info_picture.getAttribute('data-state')
|
||||
if (state == 'active') info_picture.setAttribute('data-state', '')
|
||||
else info_picture.setAttribute('data-state', 'active')
|
||||
});
|
||||
|
||||
info_picture.setAttribute("src", ``);
|
||||
info_title.innerText = data.title;
|
||||
info_number.innerText = data.number;
|
||||
info_settlement.innerText = data.settlement;
|
||||
info_description.value = data.description;
|
||||
} else if (type == "homestead") {
|
||||
let url = `${CONFIG.api}homestead/${id}`;
|
||||
let data = await Territory_Manager.info.loadAPI(url);
|
||||
|
||||
Territory_Manager.map(type, data);
|
||||
|
||||
let info_picture = document.getElementById('info-picture');
|
||||
let info_title = document.getElementById('info-title');
|
||||
let info_number = document.getElementById('info-number');
|
||||
let info_settlement = document.getElementById('info-settlement');
|
||||
let info_description = document.getElementById('info-description');
|
||||
|
||||
info_picture.addEventListener("click", (event) => {
|
||||
let state = info_picture.getAttribute('data-state')
|
||||
if (state == 'active') info_picture.setAttribute('data-state', '')
|
||||
else info_picture.setAttribute('data-state', 'active')
|
||||
});
|
||||
|
||||
info_picture.setAttribute("src", ``);
|
||||
info_title.innerText = data.title;
|
||||
info_number.innerText = data.number;
|
||||
info_settlement.innerText = data.settlement;
|
||||
info_description.value = data.description;
|
||||
}
|
||||
|
||||
urlImage = `https://sheep-service.com/cards/${type}/${type == "house" ? "T" : "H"}${id}.webp`;
|
||||
const checkImage = await fetch(urlImage);
|
||||
|
||||
if(checkImage.ok) {
|
||||
document.getElementById('menu-picture-error').style.display = 'none';
|
||||
document.getElementById('menu-picture-ok').style.display = '';
|
||||
document.getElementById('menu-picture-ok').setAttribute("href", urlImage);
|
||||
} else {
|
||||
document.getElementById('menu-picture-error').style.display = '';
|
||||
document.getElementById('menu-picture-ok').style.display = 'none';
|
||||
}
|
||||
}
|
||||
},
|
||||
entrances: {
|
||||
list: [],
|
||||
loadAPI: async (url) => {
|
||||
let uuid = localStorage.getItem("uuid");
|
||||
Territory_Manager.entrances.list = await fetch(url, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"Authorization": uuid
|
||||
}
|
||||
}).then((response) => response.json());
|
||||
return Territory_Manager.entrances.list;
|
||||
},
|
||||
setHTML: async (type, id) => {
|
||||
if (type == "house") {
|
||||
let url = `${CONFIG.api}house/${id}/entrances`;
|
||||
let listEntrances = await Territory_Manager.entrances.loadAPI(url);
|
||||
|
||||
document.getElementById('territory-entrance').innerHTML = "";
|
||||
|
||||
for (let i = 0; i < listEntrances.length; i++) {
|
||||
const element = listEntrances[i];
|
||||
|
||||
let name = () => {
|
||||
if (element.history.name == "Групова")
|
||||
return `<p>${element.history.name + " " + element.history.group_id}</p>`;
|
||||
else {
|
||||
let sheeps_list = Sheeps.sheeps_list.list;
|
||||
let filtered = sheeps_list.filter(item => item.group_id === Territory_Manager.info.list.group_id);
|
||||
let sheep = filtered.find(item => item.name === element.history.name);
|
||||
|
||||
return `<a href="/sheeps/${sheep.uuid}" data-route="">${element.history.name}</a>`;
|
||||
}
|
||||
}
|
||||
|
||||
if (element.working) {
|
||||
document.getElementById('territory-entrance').innerHTML += `
|
||||
<div class="entrance" data-state="working">
|
||||
<div id="title">
|
||||
<h1>${element.title}</h1>
|
||||
<a href="/territory/card/${type}/${id}" title="Редактор квартир" data-route>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48"><path d="M 12.5 6 C 8.9280619 6 6 8.9280619 6 12.5 L 6 35.5 C 6 39.071938 8.9280619 42 12.5 42 L 35.5 42 C 39.071938 42 42 39.071938 42 35.5 L 42 12.5 C 42 8.9280619 39.071938 6 35.5 6 L 12.5 6 z M 12.5 9 L 14 9 L 14 15 L 9 15 L 9 12.5 C 9 10.549938 10.549938 9 12.5 9 z M 17 9 L 35.5 9 C 37.450062 9 39 10.549938 39 12.5 L 39 15 L 17 15 L 17 9 z M 9 18 L 14 18 L 14 23 L 9 23 L 9 18 z M 17 18 L 39 18 L 39 23 L 17 23 L 17 18 z M 9 26 L 14 26 L 14 31 L 9 31 L 9 26 z M 17 26 L 39 26 L 39 31 L 17 31 L 17 26 z M 9 34 L 14 34 L 14 39 L 12.5 39 C 10.549938 39 9 37.450062 9 35.5 L 9 34 z M 17 34 L 39 34 L 39 35.5 C 39 37.450062 37.450062 39 35.5 39 L 17 39 L 17 34 z"/></svg>
|
||||
</a>
|
||||
</div>
|
||||
<div>
|
||||
<h1>Територію опрацьовує: </h1>
|
||||
${name()}
|
||||
</div>
|
||||
<div>
|
||||
<h1>Територія видана: </h1>
|
||||
<h2>${formattedDate(element.history.date.start)}</h2>
|
||||
</div>
|
||||
<div>
|
||||
<h1>Варто забрати: </h1>
|
||||
<h2>${formattedDate(element.history.date.end) ?? formattedDate(element.history.date.start + (1000 * 2629743 * 4))}</h2>
|
||||
</div>
|
||||
<div class="edit_working">
|
||||
<button onclick="Territory_Manager.endWorker('${type}', ${id}, ${element.history.id})" id="end-working-button" style="color: #121214;background: #c14d4d;">Забрати</button>
|
||||
<button onclick="Territory_Manager.share('${type}', ${i})">Відправити посилання</button>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
} else {
|
||||
document.getElementById('territory-entrance').innerHTML += `
|
||||
<div class="entrance">
|
||||
<div id="title">
|
||||
<h1>${element.title}</h1>
|
||||
</div>
|
||||
<div>
|
||||
<h1>Територія не опрацьовується</h1>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h1>Останнє опрацювання: </h1>
|
||||
<h2>${formattedDate(element.history.date.end) ?? "..."}</h2>
|
||||
</div>
|
||||
|
||||
<div class="edit">
|
||||
<button onclick="Territory_Manager.newWorker('${type}',${id}, ${i}, 'Групова')" id="group-working-button" style="color: var(--ColorThemes0);background: var(--ColorThemes3);">Призначити груповою</button>
|
||||
<button onclick="Territory_Manager.mess.open('${type}', ${id}, ${i})">Призначити вісника</button>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
console.log(element);
|
||||
|
||||
}
|
||||
} else if (type == "homestead") {
|
||||
let url = `${CONFIG.api}homestead/${id}`;
|
||||
let element = await Territory_Manager.entrances.loadAPI(url);
|
||||
|
||||
document.getElementById('territory-entrance').innerHTML = "";
|
||||
|
||||
let name = () => {
|
||||
if (element.history.name == "Групова")
|
||||
return `<p>${element.history.name + " " + element.history.group_id}</p>`;
|
||||
else
|
||||
return `<a href="/sheeps/${element.history.name}" data-route="">${element.history.name}</a>`;
|
||||
}
|
||||
|
||||
if (element.working) {
|
||||
document.getElementById('territory-entrance').innerHTML += `
|
||||
<div class="entrance" data-state="working">
|
||||
<div>
|
||||
<h1>Територію опрацьовує: </h1>
|
||||
${name()}
|
||||
</div>
|
||||
<div>
|
||||
<h1>Територія видана: </h1>
|
||||
<h2>${formattedDate(element.history.date.start)}</h2>
|
||||
</div>
|
||||
<div>
|
||||
<h1>Варто забрати: </h1>
|
||||
<h2>${formattedDate(element.history.date.end) ?? formattedDate(element.history.date.start + (1000 * 2629743 * 4))}</h2>
|
||||
</div>
|
||||
<div class="edit_working">
|
||||
<button onclick="Territory_Manager.endWorker('${type}', ${id}, ${element.history.id})" id="end-working-button" style="color: #121214;background: #c14d4d;">Забрати</button>
|
||||
<button onclick="Territory_Manager.share('${type}', ${i})">Відправити посилання</button>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
} else {
|
||||
document.getElementById('territory-entrance').innerHTML += `
|
||||
<div class="entrance">
|
||||
<div>
|
||||
<h1>Територія не опрацьовується</h1>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h1>Останнє опрацювання: </h1>
|
||||
<h2>${formattedDate(element.history.date.end) ?? "..."}</h2>
|
||||
</div>
|
||||
|
||||
<div class="edit">
|
||||
<button onclick="Territory_Manager.newWorker('${type}',${id}, ${i}, 'Групова')" id="group-working-button" style="color: var(--ColorThemes0);background: var(--ColorThemes3);">Призначити груповою</button>
|
||||
<button onclick="Territory_Manager.mess.open('${type}',${id}, ${i})">Призначити вісника</button>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
console.log(element);
|
||||
}
|
||||
}
|
||||
},
|
||||
map: (type, data) => {
|
||||
map_territory = {};
|
||||
let center = { lat: 49.5629016, lng: 25.6145625 };
|
||||
let zoom = 19;
|
||||
|
||||
let mytile = L.tileLayer('https://tm.rozenrod.com/webp/{z}/{x}/{y}.webp', {
|
||||
maxZoom: 20,
|
||||
minZoom: 15,
|
||||
tms: true
|
||||
});
|
||||
|
||||
map_territory = L.map('map_territory_manager', {
|
||||
renderer: L.canvas(),
|
||||
center,
|
||||
zoom,
|
||||
zoomControl: false,
|
||||
layers: [
|
||||
mytile
|
||||
],
|
||||
});
|
||||
|
||||
map_territory.pm.setLang("ua");
|
||||
|
||||
if (type == "homestead") {
|
||||
if (data.geo.lat) map_territory.setView([data.geo.lat, data.geo.lng], 15);
|
||||
else map_territory.setView([data.points[0][0][0].lat, data.points[0][0][0].lng], 15);
|
||||
|
||||
L.polygon(data.points, {
|
||||
color: colorGroup(data.group_id),
|
||||
radius: 500,
|
||||
fillOpacity: 0.3,
|
||||
dashArray: '20, 15',
|
||||
dashOffset: '20',
|
||||
}).on('click', function (e) {
|
||||
|
||||
}).addTo(map_territory);
|
||||
} else if (type == "house") {
|
||||
map_territory.setView([data.geo.lat, data.geo.lng], 17);
|
||||
|
||||
L.polygon(data.points, {
|
||||
color: "#585858",
|
||||
fillColor: colorGroup(data.group_id),
|
||||
fillOpacity: 0.8,
|
||||
tm_id: `house_${i}`
|
||||
}).on('click', function (e) {
|
||||
|
||||
}).addTo(map_territory);
|
||||
}
|
||||
},
|
||||
mess: {
|
||||
open: (type, id, number) => {
|
||||
const block = document.getElementById('territory-new');
|
||||
const new_worker_button = document.getElementById('new-worker-button');
|
||||
|
||||
block.style.display = "";
|
||||
setTimeout(() => {
|
||||
block.style.opacity = "1";
|
||||
}, 100)
|
||||
|
||||
new_worker_button.setAttribute("onclick", `Territory_Manager.newWorker('${type}', ${id}, ${number})`);
|
||||
},
|
||||
close: () => {
|
||||
const block = document.getElementById('territory-new');
|
||||
|
||||
block.style.opacity = "0";
|
||||
setTimeout(() => {
|
||||
block.style.display = "none";
|
||||
}, 200)
|
||||
}
|
||||
},
|
||||
newWorker: async (type, id, number, name) => {
|
||||
const uuid = localStorage.getItem('uuid');
|
||||
|
||||
const new_worker_button = document.getElementById('new-worker-button');
|
||||
const group_worker_button = document.getElementById('group-working-button');
|
||||
|
||||
let URL, territory_id, data;
|
||||
|
||||
|
||||
const pos = Sheeps.sheeps_list.list.map(e => e.name).indexOf(name ?? document.getElementById("new-worker-name").value);
|
||||
let sheep = Sheeps.sheeps_list.list[pos];
|
||||
|
||||
if (type == "house") {
|
||||
territory_id = Territory_Manager.entrances.list[number].id;
|
||||
data = {
|
||||
name: name ?? document.getElementById("new-worker-name").value,
|
||||
group_id: Territory_Manager.info.list.group_id,
|
||||
sheep_id: sheep ? sheep.id : null
|
||||
}
|
||||
URL = `${CONFIG.api}history/entrance/${territory_id}`;
|
||||
}
|
||||
else if (type == "homestead") {
|
||||
territory_id = Territory_Manager.info.list.id;
|
||||
data = {
|
||||
name: name ?? document.getElementById("new-worker-name").value,
|
||||
group_id: Territory_Manager.info.list.group_id,
|
||||
sheep_id: sheep ? sheep.id : null
|
||||
}
|
||||
URL = `${CONFIG.api}history/homestead/${territory_id}`;
|
||||
}
|
||||
|
||||
console.log(territory_id, data);
|
||||
|
||||
await fetch(URL, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"Authorization": uuid
|
||||
},
|
||||
body: JSON.stringify(data)
|
||||
})
|
||||
.then(response => {
|
||||
if (response.status == 200) {
|
||||
Territory_Manager.mess.close();
|
||||
Territory_Manager.entrances.list = [];
|
||||
Territory_Manager.entrances.setHTML(type, id);
|
||||
|
||||
return response.json()
|
||||
} else {
|
||||
console.log('err');
|
||||
new_worker_button.innerText = "Помилка";
|
||||
group_worker_button.innerText = "Помилка";
|
||||
|
||||
return
|
||||
}
|
||||
})
|
||||
},
|
||||
endWorker: async (type, id, territory_id) => {
|
||||
const end_working_button = document.getElementById('end-working-button');
|
||||
let uuid = localStorage.getItem('uuid');
|
||||
let URL = "";
|
||||
|
||||
if (type == "house") {
|
||||
URL = `${CONFIG.api}history/entrance/${territory_id}`;
|
||||
}
|
||||
else if (type == "homestead") {
|
||||
URL = `${CONFIG.api}history/homestead/${territory_id}`;
|
||||
}
|
||||
|
||||
await fetch(URL, {
|
||||
method: 'PUT',
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"Authorization": uuid
|
||||
},
|
||||
data: JSON.stringify({})
|
||||
})
|
||||
.then(response => {
|
||||
if (response.status == 200) {
|
||||
Territory_Manager.entrances.list = [];
|
||||
Territory_Manager.entrances.setHTML(type, id);
|
||||
|
||||
return response.json()
|
||||
} else {
|
||||
console.log('err');
|
||||
end_working_button.innerText = "Помилка";
|
||||
|
||||
return
|
||||
}
|
||||
})
|
||||
},
|
||||
share: async (type, number) => {
|
||||
let territory, id;
|
||||
|
||||
if (type == "house") {
|
||||
territory = Territory_Manager.entrances.list[number];
|
||||
id = Territory_Manager.entrances.list[number].id;
|
||||
}
|
||||
else if (type == "homestead") {
|
||||
territory = Territory_Manager.info.list;
|
||||
id = Territory_Manager.info.list.id;
|
||||
}
|
||||
|
||||
|
||||
let description = () => {
|
||||
if (Territory_Manager.info.list.description && Territory_Manager.info.list.description.length > 0) {
|
||||
return `\n\nДодатково:\n• ${Territory_Manager.info.list.description}`;
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
let sheepUuid = () => {
|
||||
const pos = Sheeps.sheeps_list.list.map(e => e.name).indexOf(territory.history.name);
|
||||
let sheep = Sheeps.sheeps_list.list[pos];
|
||||
|
||||
if (sheep) {
|
||||
return `\n\nПосилання на Sheep-Service:\n• https://sheep-service.com/?uuid=${sheep.uuid}`;
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
if (navigator.share) {
|
||||
console.log("Congrats! Your browser supports Web Share API")
|
||||
try {
|
||||
let url;
|
||||
if(type == 'house') url = `https://sheep-service.com/cards/house/T${Territory_Manager.info.list.id}.webp`;
|
||||
if(type == 'homestead') url = `https://sheep-service.com/cards/homestead/H${Territory_Manager.info.list.id}.webp`;
|
||||
|
||||
const response = await fetch(url);
|
||||
const blob = await response.blob();
|
||||
const file = new File([blob], `${type == "house" ? "E" + id : "H" + id}.webp`, { type: blob.type });
|
||||
|
||||
await navigator.share({
|
||||
text: `Територія:\n• ${type == "house" ? "E" + id : "H" + id}\n\nНаселений пункт:\n• ${Territory_Manager.info.list.settlement}\n\nВулиця:\n• ${Territory_Manager.info.list.title + " " + Territory_Manager.info.list.number}${description()}\n\nПризначення:\n • З ${formattedDate(territory.history.date.start)}\n • До ${formattedDate(territory.history.date.end) ?? formattedDate(territory.history.date.start + (1000 * 2629743 * 4))}${sheepUuid()}`,
|
||||
files: [file]
|
||||
});
|
||||
|
||||
console.log('Успешно отправлено!');
|
||||
} catch (error) {
|
||||
console.error('Ошибка при отправке:', error);
|
||||
}
|
||||
|
||||
|
||||
} else {
|
||||
console.log("Sorry! Your browser does not support Web Share API")
|
||||
}
|
||||
},
|
||||
getScreen: async () => {
|
||||
const center = map_territory.getCenter();
|
||||
console.log(center.lat, center.lng);
|
||||
|
||||
let lat = center.lat;
|
||||
let lng = center.lng;
|
||||
let wayId = Territory_Manager.info.list.osm_id;
|
||||
let zoom = map_territory.getZoom() + 2 ?? 17;
|
||||
let address = Territory_Manager.info.list.title;
|
||||
let number = Territory_Manager.info.list.number;
|
||||
let id = Territory_Manager.info.list.id;
|
||||
|
||||
let url = `https://sheep-service.com/api/generator/cards?lat=${lat}&lng=${lng}&type=${type_territory}&wayId=${wayId}&zoom=${zoom}&address=${address}&number=${number}&id=${id}`;
|
||||
let uuid = localStorage.getItem("uuid");
|
||||
let result = await fetch(url, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"Authorization": uuid
|
||||
}
|
||||
}).then((response) => response.json());
|
||||
|
||||
|
||||
urlImage = `https://sheep-service.com/cards/${type}/${type == "house" ? "T" : "H"}${id}.webp`;
|
||||
if(result) {
|
||||
document.getElementById('menu-picture-error').style.display = 'none';
|
||||
document.getElementById('menu-picture-ok').style.display = '';
|
||||
document.getElementById('menu-picture-ok').setAttribute("href", urlImage);
|
||||
} else {
|
||||
document.getElementById('menu-picture-error').style.display = '';
|
||||
document.getElementById('menu-picture-ok').style.display = 'none';
|
||||
}
|
||||
}
|
||||
}
|
||||
418
web/lib/pages/territory_manager/style.css
Normal file
@@ -0,0 +1,418 @@
|
||||
.page-territory_manager {
|
||||
width: calc(100% - 18px);
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
margin: 20px 9px 0 9px;
|
||||
justify-content: space-between;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
#territory-info,
|
||||
#territory-entrance {
|
||||
width: 100%;
|
||||
min-height: calc(100vh - 40px - 50px);
|
||||
height: fit-content;
|
||||
margin: 0 10px 15px;
|
||||
border-radius: 15px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
background: var(--ColorThemes1);
|
||||
color: var(--ColorThemes3);
|
||||
border: 1px solid var(--ColorThemes2);
|
||||
box-shadow: var(--shadow-l1);
|
||||
transition: all .2sease 0s;
|
||||
}
|
||||
|
||||
#territory-info {
|
||||
position: sticky;
|
||||
overflow: auto;
|
||||
top: 20px;
|
||||
}
|
||||
|
||||
#territory-info>.territory-info-image {
|
||||
width: calc(100% - 20px);
|
||||
min-height: 200px;
|
||||
margin: 10px;
|
||||
border-radius: 10px;
|
||||
background: var(--ColorThemes0);
|
||||
position: relative;
|
||||
display: flex;
|
||||
overflow: hidden;
|
||||
background-position: 50%;
|
||||
background-size: cover;
|
||||
justify-content: center;
|
||||
aspect-ratio: 1147 / 751;
|
||||
max-height: 300px;
|
||||
}
|
||||
|
||||
#territory-info>.territory-info-image>img {
|
||||
width: 100%;
|
||||
object-fit: cover;
|
||||
z-index: 3;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#territory-info>.territory-info-image>#map_territory_manager {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
#territory-info>.territory-info-image>img[data-state="active"] {
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
#territory-info>.territory-info-image>.menu-picture {
|
||||
position: absolute;
|
||||
right: 10px;
|
||||
top: 10px;
|
||||
z-index: 999;
|
||||
background: var(--ColorThemes0);
|
||||
border: 1px solid var(--ColorThemes2);
|
||||
padding: 5px;
|
||||
border-radius: 6px;
|
||||
min-width: 70px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
#territory-info>.territory-info-image>.menu-picture>a {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
}
|
||||
|
||||
#territory-info>.territory-info-image>.menu-picture>a>svg {
|
||||
width: 22px;
|
||||
height: 22px;
|
||||
}
|
||||
|
||||
#territory-info>.territory-info-image>.menu-picture>button {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
border-radius: 2px;
|
||||
background: var(--PrimaryColor);
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
#territory-info>.territory-info-image>.menu-picture>button>svg {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
fill: var(--PrimaryColorText);
|
||||
}
|
||||
|
||||
#territory-info>.territory-info-text {
|
||||
width: calc(100% - 40px);
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
margin: 10px;
|
||||
border-radius: 10px;
|
||||
position: relative;
|
||||
align-items: center;
|
||||
background: var(--ColorThemes0);
|
||||
padding: 10px;
|
||||
|
||||
}
|
||||
|
||||
#territory-info>.territory-info-text>h1 {
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
color: var(--ColorThemes3);
|
||||
}
|
||||
|
||||
#territory-info>.territory-info-text>h2 {
|
||||
font-size: 14px;
|
||||
font-weight: 300;
|
||||
color: var(--ColorThemes3);
|
||||
opacity: 0.8;
|
||||
margin: 0 7px;
|
||||
}
|
||||
|
||||
#territory-info>.territory-info-text>textarea {
|
||||
width: 100%;
|
||||
min-height: 100px;
|
||||
background: var(--ColorThemes0);
|
||||
color: var(--ColorThemes3);
|
||||
font-size: 14px;
|
||||
resize: vertical;
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
#territory-info>#editor_button {
|
||||
width: calc(100% - 20px);
|
||||
font-size: 13px;
|
||||
font-weight: 400;
|
||||
min-height: 40px;
|
||||
display: flex;
|
||||
background: var(--PrimaryColor);
|
||||
color: var(--PrimaryColorText);
|
||||
cursor: pointer;
|
||||
border: 0;
|
||||
position: relative;
|
||||
border-radius: 8px;
|
||||
margin: 20px 10px 10px 10px;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
#territory-entrance>.entrance {
|
||||
width: calc(100% - 40px);
|
||||
color: var(--ColorThemes3);
|
||||
background-color: var(--ColorThemes2);
|
||||
border: 1px solid var(--ColorThemes0);
|
||||
box-shadow: var(--shadow-l1);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
margin: 10px;
|
||||
padding: 10px;
|
||||
min-height: 100px;
|
||||
justify-content: center;
|
||||
position: relative;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
#territory-entrance>.entrance[data-state="working"] {
|
||||
border: 1px solid var(--PrimaryColor);
|
||||
}
|
||||
|
||||
#territory-entrance>.entrance>#title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 30px;
|
||||
margin-bottom: 10px;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
#territory-entrance>.entrance>#title>h1 {
|
||||
width: 100%;
|
||||
height: 30px;
|
||||
background: var(--ColorThemes0);
|
||||
color: var(--ColorThemes3);
|
||||
border-radius: 6px;
|
||||
font-size: 16px;
|
||||
font-weight: 400;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
#territory-entrance>.entrance>#title>a {
|
||||
min-height: 30px;
|
||||
min-width: 30px;
|
||||
padding: 0;
|
||||
margin: 0 0 0 10px;
|
||||
background: var(--PrimaryColor);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
#territory-entrance>.entrance>#title>a>svg {
|
||||
width: 25px;
|
||||
height: 25px;
|
||||
fill: var(--PrimaryColorText);
|
||||
}
|
||||
|
||||
#territory-entrance>.entrance>div {
|
||||
display: flex;
|
||||
margin-bottom: 10px;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#territory-entrance>.entrance>div>h1 {
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
color: var(--ColorThemes3);
|
||||
}
|
||||
|
||||
#territory-entrance>.entrance>div>h2,
|
||||
#territory-entrance>.entrance>div>a,
|
||||
#territory-entrance>.entrance>div>p {
|
||||
font-size: 14px;
|
||||
font-weight: 300;
|
||||
color: var(--ColorThemes3);
|
||||
opacity: 0.8;
|
||||
margin: 0 7px;
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
#territory-entrance>.entrance>div>a,
|
||||
#territory-entrance>.entrance>div>p {
|
||||
color: var(--ColorThemes0);
|
||||
background: var(--ColorThemes3);
|
||||
border-radius: 6px;
|
||||
padding: 2px 5px;
|
||||
font-weight: 400;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.date_old {
|
||||
background: var(--ColorThemes1) !important;
|
||||
color: var(--ColorThemes3) !important;
|
||||
font-size: 18px !important;
|
||||
padding: 5px 10px !important;
|
||||
}
|
||||
|
||||
#territory-entrance>.entrance>.edit_working,
|
||||
#territory-entrance>.entrance>.edit {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
#territory-entrance>.entrance>.edit_working>button,
|
||||
#territory-entrance>.entrance>.edit>button {
|
||||
width: 100%;
|
||||
font-size: 13px;
|
||||
font-weight: 400;
|
||||
min-height: 40px;
|
||||
display: flex;
|
||||
padding: 2px 10px;
|
||||
background: var(--PrimaryColor);
|
||||
color: var(--PrimaryColorText);
|
||||
cursor: pointer;
|
||||
border: 0;
|
||||
position: relative;
|
||||
border-radius: 8px;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
#territory-entrance>.entrance>.edit_working>button:nth-child(2n),
|
||||
#territory-entrance>.entrance>.edit>button:nth-child(2n) {
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
#territory-entrance>.entrance>.edit_working>button:nth-child(2n-1),
|
||||
#territory-entrance>.entrance>.edit>button:nth-child(2n-1) {
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
#territory-entrance>.entrance>button>span {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#territory-entrance>.entrance>button>svg {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
fill: var(--PrimaryColorText);
|
||||
}
|
||||
|
||||
#territory-entrance>.entrance>.apartment_button {
|
||||
width: 100%;
|
||||
font-size: 13px;
|
||||
font-weight: 400;
|
||||
min-height: 40px;
|
||||
display: flex;
|
||||
background: var(--PrimaryColor);
|
||||
color: var(--PrimaryColorText);
|
||||
cursor: pointer;
|
||||
border: 0;
|
||||
position: relative;
|
||||
border-radius: 8px;
|
||||
margin: 20px 0 2px 0;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
#territory-new {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
left: 0;
|
||||
top: 0;
|
||||
position: fixed;
|
||||
z-index: 999;
|
||||
backdrop-filter: blur(10px);
|
||||
-webkit-backdrop-filter: blur(10px);
|
||||
background: rgb(31 31 33 / 41%);
|
||||
transition: all .2s ease 0s;
|
||||
}
|
||||
|
||||
#territory-new>.mess {
|
||||
display: flex;
|
||||
width: 300px;
|
||||
height: 200px;
|
||||
border: 1px solid var(--ColorThemes2);
|
||||
background: var(--ColorThemes0);
|
||||
box-shadow: 0px 2px 3px rgb(0 0 0 / 5%), 0px 5px 15px rgb(0 0 0 / 5%), 0px 4px 8px rgb(0 0 0 / 5%), 0px 0px 1px rgb(0 0 0 / 5%);
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
margin-top: -110px;
|
||||
margin-left: -160px;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
z-index: 9999;
|
||||
padding: 10px;
|
||||
border-radius: 15px;
|
||||
justify-content: space-between;
|
||||
|
||||
}
|
||||
|
||||
#territory-new>.mess>span {
|
||||
color: var(--ColorThemes3);
|
||||
font-size: 18px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#territory-new>.mess>select {
|
||||
width: 100%;
|
||||
min-width: 140px;
|
||||
padding: 0 5px;
|
||||
border-radius: 6px;
|
||||
height: 30px;
|
||||
background-color: var(--ColorThemes2);
|
||||
color: var(--ColorThemes3);
|
||||
}
|
||||
|
||||
#territory-new>.mess>div {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
#territory-new>.mess>div>button {
|
||||
text-decoration: none;
|
||||
font-size: 15px;
|
||||
font-weight: 400;
|
||||
height: 35px;
|
||||
color: var(--ColorThemes0);
|
||||
padding: 2px 10px;
|
||||
background: var(--ColorThemes3);
|
||||
cursor: pointer;
|
||||
border: 0;
|
||||
margin-bottom: 5px;
|
||||
margin-left: 0;
|
||||
width: calc(50% - 5px);
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
@media (max-width: 1000px),
|
||||
(max-height: 540px) {
|
||||
.page-territory_manager {
|
||||
flex-direction: column;
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
#territory-info,
|
||||
#territory-entrance {
|
||||
width: calc(100% - 20px);
|
||||
height: fit-content;
|
||||
min-height: 100px;
|
||||
}
|
||||
|
||||
#territory-info {
|
||||
position: relative;
|
||||
top: auto;
|
||||
}
|
||||
}
|
||||
142
web/lib/router/router.js
Normal file
@@ -0,0 +1,142 @@
|
||||
const Router = {
|
||||
routes: [],
|
||||
mode: null,
|
||||
root: '/',
|
||||
config: function(options) {
|
||||
this.mode = options && options.mode && options.mode == 'history' && !!(history.pushState) ? 'history' : 'hash';
|
||||
this.root = options && options.root ? '/' + this.clearSlashes(options.root) + '/' : '/';
|
||||
return this;
|
||||
},
|
||||
getFragment: function() {
|
||||
let fragment = '';
|
||||
if(this.mode === 'history') {
|
||||
// fragment = this.clearSlashes(decodeURI(location.pathname + location.search));
|
||||
fragment = this.clearSlashes(decodeURI(window.location.href.replace('/#', '').replace(window.location.origin, '/')));
|
||||
fragment = fragment.replace(/\?(.*)$/, '');
|
||||
fragment = this.root != '/' ? fragment.replace(this.root, '') : fragment;
|
||||
} else {
|
||||
let match = window.location.href.match(/#(.*)$/);
|
||||
fragment = match ? match[1] : '';
|
||||
}
|
||||
return this.clearSlashes(fragment);
|
||||
},
|
||||
getParams: function () {
|
||||
let query = '';
|
||||
if(this.mode === 'history') {
|
||||
query = decodeURI(window.location.href.replace('/#', '')).split("?")[1];
|
||||
} else {
|
||||
let index = window.location.hash.indexOf("?");
|
||||
query = (index !== -1) ? window.location.hash.substring(index) : "";
|
||||
}
|
||||
let _query = {};
|
||||
if (typeof query !== "string") {
|
||||
return _query;
|
||||
}
|
||||
if (query[0] === "?") {
|
||||
query = query.substring(1);
|
||||
}
|
||||
query.split("&").forEach(function (row) {
|
||||
let parts = row.split("=");
|
||||
if (parts[0] !== "") {
|
||||
if (parts[1] === undefined) {
|
||||
parts[1] = true;
|
||||
}
|
||||
_query[decodeURIComponent(parts[0])] = decodeURIComponent(parts[1]);
|
||||
}
|
||||
});
|
||||
return _query;
|
||||
},
|
||||
clearSlashes: function(path) {
|
||||
return path.toString().replace(/\/$/, '').replace(/^\//, '');
|
||||
},
|
||||
add: function(re, handler, options) {
|
||||
if(typeof re == 'function') {
|
||||
handler = re;
|
||||
re = '';
|
||||
}
|
||||
this.routes.push({ re: re, handler: handler, options: options});
|
||||
return this;
|
||||
},
|
||||
remove: function(param) {
|
||||
for(let i=0, r; i < this.routes.length, r = this.routes[i]; i++) {
|
||||
if(r.handler === param || r.re.toString() === param.toString()) {
|
||||
this.routes.splice(i, 1);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
return this;
|
||||
},
|
||||
flush: function() {
|
||||
this.routes = [];
|
||||
this.mode = null;
|
||||
this.root = '/';
|
||||
return this;
|
||||
},
|
||||
check: function(f) {
|
||||
let fragment = f || this.getFragment();
|
||||
for(let i=0; i < this.routes.length; i++) {
|
||||
let match = fragment.match(this.routes[i].re);
|
||||
if(fragment == '' || fragment == '/') match = 'home'.match(this.routes[i].re);
|
||||
if(match) {
|
||||
match.shift();
|
||||
let query = this.getParams();
|
||||
this.routes[i].handler.apply({query}, match);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
return this;
|
||||
},
|
||||
listen: function() {
|
||||
let self = this;
|
||||
let current = self.getFragment();
|
||||
let current_query = self.getParams();
|
||||
let fn = function() {
|
||||
if(current !== self.getFragment()) {
|
||||
current = self.getFragment();
|
||||
self.check(current);
|
||||
}
|
||||
// if(current !== self.getFragment() || JSON.stringify(current_query) !== JSON.stringify(self.getParams())) {
|
||||
// current = self.getFragment();
|
||||
// current_query = self.getParams();
|
||||
// self.check(current);
|
||||
// }
|
||||
}
|
||||
clearInterval(this.interval);
|
||||
this.interval = setInterval(fn, 50);
|
||||
return this;
|
||||
},
|
||||
navigate: function(path, mode = true) {
|
||||
path = path || '';
|
||||
if(mode){
|
||||
if(this.mode === 'history') {
|
||||
history.replaceState({position: window.pageYOffset}, null);
|
||||
history.pushState({position: 0}, null, this.root + this.clearSlashes(path));
|
||||
} else {
|
||||
window.location.href = window.location.href.replace(/#(.*)$/, '') + '#' + path;
|
||||
}
|
||||
}
|
||||
return this;
|
||||
},
|
||||
update: function(key, value) {
|
||||
let url = window.location;
|
||||
let URLParams = new URLSearchParams(url.search);
|
||||
let RouterParams = Router.getParams();
|
||||
URLParams.set(key, value);
|
||||
|
||||
history.replaceState({position: window.pageYOffset}, null, window.location.origin + window.location.pathname + '?' + URLParams.toString());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
window.addEventListener('click', function (event) {
|
||||
if (!event.target.matches('[data-route]')) return;
|
||||
event.preventDefault();
|
||||
Router.navigate((event.target.href).replace(window.location.origin, ''));
|
||||
}, false);
|
||||
|
||||
if(Router.mode === 'history'){
|
||||
window.addEventListener('popstate', function (event) {
|
||||
if (!history.state.url) return;
|
||||
Router.navigate(history.state.url);
|
||||
}, false);
|
||||
}
|
||||
78
web/lib/router/routes.js
Normal file
@@ -0,0 +1,78 @@
|
||||
Router
|
||||
.add('territory/manager/(.*)/(.*)', function (type, id) {
|
||||
Territory_Manager.init(type, id);
|
||||
pageActive()
|
||||
routerScroll()
|
||||
})
|
||||
.add('territory/editor/(.*)/(.*)', function (type, id) {
|
||||
Editor.init(type, id);
|
||||
pageActive()
|
||||
routerScroll()
|
||||
})
|
||||
.add('territory/card/(.*)/(.*)', function (type, id) {
|
||||
Card.init(type, id);
|
||||
pageActive()
|
||||
routerScroll()
|
||||
})
|
||||
.add('territory', function () {
|
||||
Territory.init();
|
||||
pageActive('territory')
|
||||
routerScroll()
|
||||
})
|
||||
.add('sheeps/(.*)', function (name) {
|
||||
Sheeps.init(name);
|
||||
routerScroll();
|
||||
pageActive('sheeps')
|
||||
})
|
||||
.add('sheeps', function () {
|
||||
Sheeps.init();
|
||||
routerScroll();
|
||||
pageActive('sheeps')
|
||||
})
|
||||
.add('home', function () {
|
||||
Home.init();
|
||||
pageActive('home')
|
||||
routerScroll()
|
||||
})
|
||||
.add('schedule', function () {
|
||||
Options.init();
|
||||
routerScroll();
|
||||
pageActive('schedule')
|
||||
})
|
||||
.add('stand', function () {
|
||||
Stand.init();
|
||||
routerScroll();
|
||||
pageActive('stand')
|
||||
})
|
||||
.add('options', function () {
|
||||
Options.init();
|
||||
routerScroll();
|
||||
pageActive('options')
|
||||
})
|
||||
.add('constructor', function () {
|
||||
Constructor.init();
|
||||
routerScroll();
|
||||
pageActive()
|
||||
})
|
||||
.add(function () {
|
||||
page_404();
|
||||
routerScroll();
|
||||
pageActive();
|
||||
})
|
||||
|
||||
|
||||
function routerScroll() {
|
||||
if (!history.state) return;
|
||||
window.scroll(0, history.state.position);
|
||||
}
|
||||
|
||||
function pageActive(element) {
|
||||
let nav = document.getElementsByTagName("nav")[0];
|
||||
let dots = nav.getElementsByTagName("li");
|
||||
|
||||
for (i = 0; i < dots.length; i++) {
|
||||
dots[i].children[0].setAttribute('data-state', '');
|
||||
}
|
||||
if (element) document.getElementById(`nav-${element}`).setAttribute('data-state', 'active')
|
||||
|
||||
}
|
||||
18
web/manifest.json
Normal file
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"author": "rozenrod.com",
|
||||
"name": "Sheep Service",
|
||||
"short_name": "Sheep Service",
|
||||
"display": "standalone",
|
||||
"start_url": "/",
|
||||
"scope": "/",
|
||||
"background_color": "#232325",
|
||||
"theme_color": "#121214",
|
||||
"version": "0.4.4",
|
||||
"icons": [
|
||||
{ "src": "img/favicon.ico", "type": "image/x-icon", "sizes": "32x32" },
|
||||
{ "src": "img/icon-192.png", "type": "image/png", "sizes": "192x192" },
|
||||
{ "src": "img/icon-512.png", "type": "image/png", "sizes": "512x512" },
|
||||
{ "src": "img/icon-192-maskable.png", "type": "image/png", "sizes": "192x192", "purpose": "maskable" },
|
||||
{ "src": "img/icon-512-maskable.png", "type": "image/png", "sizes": "512x512", "purpose": "maskable" }
|
||||
]
|
||||
}
|
||||
764
web/package-lock.json
generated
Normal file
@@ -0,0 +1,764 @@
|
||||
{
|
||||
"name": "WEB Sheep Service",
|
||||
"version": "1.0.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "WEB Sheep Service",
|
||||
"version": "1.0.0",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"express": "^4.21.0"
|
||||
}
|
||||
},
|
||||
"node_modules/accepts": {
|
||||
"version": "1.3.8",
|
||||
"resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
|
||||
"integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==",
|
||||
"dependencies": {
|
||||
"mime-types": "~2.1.34",
|
||||
"negotiator": "0.6.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/array-flatten": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
|
||||
"integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg=="
|
||||
},
|
||||
"node_modules/body-parser": {
|
||||
"version": "1.20.3",
|
||||
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz",
|
||||
"integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==",
|
||||
"dependencies": {
|
||||
"bytes": "3.1.2",
|
||||
"content-type": "~1.0.5",
|
||||
"debug": "2.6.9",
|
||||
"depd": "2.0.0",
|
||||
"destroy": "1.2.0",
|
||||
"http-errors": "2.0.0",
|
||||
"iconv-lite": "0.4.24",
|
||||
"on-finished": "2.4.1",
|
||||
"qs": "6.13.0",
|
||||
"raw-body": "2.5.2",
|
||||
"type-is": "~1.6.18",
|
||||
"unpipe": "1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.8",
|
||||
"npm": "1.2.8000 || >= 1.4.16"
|
||||
}
|
||||
},
|
||||
"node_modules/bytes": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
|
||||
"integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==",
|
||||
"engines": {
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/call-bind-apply-helpers": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.1.tgz",
|
||||
"integrity": "sha512-BhYE+WDaywFg2TBWYNXAE+8B1ATnThNBqXHP5nQu0jWJdVvY2hvkpyB3qOmtmDePiS5/BDQ8wASEWGMWRG148g==",
|
||||
"dependencies": {
|
||||
"es-errors": "^1.3.0",
|
||||
"function-bind": "^1.1.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/call-bound": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.3.tgz",
|
||||
"integrity": "sha512-YTd+6wGlNlPxSuri7Y6X8tY2dmm12UMH66RpKMhiX6rsk5wXXnYgbUcOt8kiS31/AjfoTOvCsE+w8nZQLQnzHA==",
|
||||
"dependencies": {
|
||||
"call-bind-apply-helpers": "^1.0.1",
|
||||
"get-intrinsic": "^1.2.6"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/content-disposition": {
|
||||
"version": "0.5.4",
|
||||
"resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz",
|
||||
"integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==",
|
||||
"dependencies": {
|
||||
"safe-buffer": "5.2.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/content-type": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz",
|
||||
"integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==",
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/cookie": {
|
||||
"version": "0.7.1",
|
||||
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz",
|
||||
"integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==",
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/cookie-signature": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
|
||||
"integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ=="
|
||||
},
|
||||
"node_modules/debug": {
|
||||
"version": "2.6.9",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
|
||||
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
|
||||
"dependencies": {
|
||||
"ms": "2.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/depd": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
|
||||
"integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
|
||||
"engines": {
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/destroy": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz",
|
||||
"integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==",
|
||||
"engines": {
|
||||
"node": ">= 0.8",
|
||||
"npm": "1.2.8000 || >= 1.4.16"
|
||||
}
|
||||
},
|
||||
"node_modules/dunder-proto": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
|
||||
"integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
|
||||
"dependencies": {
|
||||
"call-bind-apply-helpers": "^1.0.1",
|
||||
"es-errors": "^1.3.0",
|
||||
"gopd": "^1.2.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/ee-first": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
|
||||
"integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="
|
||||
},
|
||||
"node_modules/encodeurl": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz",
|
||||
"integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==",
|
||||
"engines": {
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/es-define-property": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
|
||||
"integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/es-errors": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
|
||||
"integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/es-object-atoms": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
|
||||
"integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
|
||||
"dependencies": {
|
||||
"es-errors": "^1.3.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/escape-html": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
|
||||
"integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow=="
|
||||
},
|
||||
"node_modules/etag": {
|
||||
"version": "1.8.1",
|
||||
"resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
|
||||
"integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==",
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/express": {
|
||||
"version": "4.21.2",
|
||||
"resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz",
|
||||
"integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==",
|
||||
"dependencies": {
|
||||
"accepts": "~1.3.8",
|
||||
"array-flatten": "1.1.1",
|
||||
"body-parser": "1.20.3",
|
||||
"content-disposition": "0.5.4",
|
||||
"content-type": "~1.0.4",
|
||||
"cookie": "0.7.1",
|
||||
"cookie-signature": "1.0.6",
|
||||
"debug": "2.6.9",
|
||||
"depd": "2.0.0",
|
||||
"encodeurl": "~2.0.0",
|
||||
"escape-html": "~1.0.3",
|
||||
"etag": "~1.8.1",
|
||||
"finalhandler": "1.3.1",
|
||||
"fresh": "0.5.2",
|
||||
"http-errors": "2.0.0",
|
||||
"merge-descriptors": "1.0.3",
|
||||
"methods": "~1.1.2",
|
||||
"on-finished": "2.4.1",
|
||||
"parseurl": "~1.3.3",
|
||||
"path-to-regexp": "0.1.12",
|
||||
"proxy-addr": "~2.0.7",
|
||||
"qs": "6.13.0",
|
||||
"range-parser": "~1.2.1",
|
||||
"safe-buffer": "5.2.1",
|
||||
"send": "0.19.0",
|
||||
"serve-static": "1.16.2",
|
||||
"setprototypeof": "1.2.0",
|
||||
"statuses": "2.0.1",
|
||||
"type-is": "~1.6.18",
|
||||
"utils-merge": "1.0.1",
|
||||
"vary": "~1.1.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.10.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/express"
|
||||
}
|
||||
},
|
||||
"node_modules/finalhandler": {
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz",
|
||||
"integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==",
|
||||
"dependencies": {
|
||||
"debug": "2.6.9",
|
||||
"encodeurl": "~2.0.0",
|
||||
"escape-html": "~1.0.3",
|
||||
"on-finished": "2.4.1",
|
||||
"parseurl": "~1.3.3",
|
||||
"statuses": "2.0.1",
|
||||
"unpipe": "~1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/forwarded": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
|
||||
"integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==",
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/fresh": {
|
||||
"version": "0.5.2",
|
||||
"resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
|
||||
"integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==",
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/function-bind": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
|
||||
"integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/get-intrinsic": {
|
||||
"version": "1.2.7",
|
||||
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.7.tgz",
|
||||
"integrity": "sha512-VW6Pxhsrk0KAOqs3WEd0klDiF/+V7gQOpAvY1jVU/LHmaD/kQO4523aiJuikX/QAKYiW6x8Jh+RJej1almdtCA==",
|
||||
"dependencies": {
|
||||
"call-bind-apply-helpers": "^1.0.1",
|
||||
"es-define-property": "^1.0.1",
|
||||
"es-errors": "^1.3.0",
|
||||
"es-object-atoms": "^1.0.0",
|
||||
"function-bind": "^1.1.2",
|
||||
"get-proto": "^1.0.0",
|
||||
"gopd": "^1.2.0",
|
||||
"has-symbols": "^1.1.0",
|
||||
"hasown": "^2.0.2",
|
||||
"math-intrinsics": "^1.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/get-proto": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
|
||||
"integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
|
||||
"dependencies": {
|
||||
"dunder-proto": "^1.0.1",
|
||||
"es-object-atoms": "^1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/gopd": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
|
||||
"integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/has-symbols": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
|
||||
"integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/hasown": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
|
||||
"integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
|
||||
"dependencies": {
|
||||
"function-bind": "^1.1.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/http-errors": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
|
||||
"integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==",
|
||||
"dependencies": {
|
||||
"depd": "2.0.0",
|
||||
"inherits": "2.0.4",
|
||||
"setprototypeof": "1.2.0",
|
||||
"statuses": "2.0.1",
|
||||
"toidentifier": "1.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/iconv-lite": {
|
||||
"version": "0.4.24",
|
||||
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
|
||||
"integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
|
||||
"dependencies": {
|
||||
"safer-buffer": ">= 2.1.2 < 3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/inherits": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
|
||||
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
|
||||
},
|
||||
"node_modules/ipaddr.js": {
|
||||
"version": "1.9.1",
|
||||
"resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
|
||||
"integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==",
|
||||
"engines": {
|
||||
"node": ">= 0.10"
|
||||
}
|
||||
},
|
||||
"node_modules/math-intrinsics": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
|
||||
"integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/media-typer": {
|
||||
"version": "0.3.0",
|
||||
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
|
||||
"integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==",
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/merge-descriptors": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz",
|
||||
"integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==",
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/methods": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
|
||||
"integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==",
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/mime": {
|
||||
"version": "1.6.0",
|
||||
"resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
|
||||
"integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
|
||||
"bin": {
|
||||
"mime": "cli.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/mime-db": {
|
||||
"version": "1.52.0",
|
||||
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
|
||||
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/mime-types": {
|
||||
"version": "2.1.35",
|
||||
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
|
||||
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
|
||||
"dependencies": {
|
||||
"mime-db": "1.52.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/ms": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
||||
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
|
||||
},
|
||||
"node_modules/negotiator": {
|
||||
"version": "0.6.3",
|
||||
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
|
||||
"integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==",
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/object-inspect": {
|
||||
"version": "1.13.3",
|
||||
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.3.tgz",
|
||||
"integrity": "sha512-kDCGIbxkDSXE3euJZZXzc6to7fCrKHNI/hSRQnRuQ+BWjFNzZwiFF8fj/6o2t2G9/jTj8PSIYTfCLelLZEeRpA==",
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/on-finished": {
|
||||
"version": "2.4.1",
|
||||
"resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
|
||||
"integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==",
|
||||
"dependencies": {
|
||||
"ee-first": "1.1.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/parseurl": {
|
||||
"version": "1.3.3",
|
||||
"resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
|
||||
"integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
|
||||
"engines": {
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/path-to-regexp": {
|
||||
"version": "0.1.12",
|
||||
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz",
|
||||
"integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ=="
|
||||
},
|
||||
"node_modules/proxy-addr": {
|
||||
"version": "2.0.7",
|
||||
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
|
||||
"integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==",
|
||||
"dependencies": {
|
||||
"forwarded": "0.2.0",
|
||||
"ipaddr.js": "1.9.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.10"
|
||||
}
|
||||
},
|
||||
"node_modules/qs": {
|
||||
"version": "6.13.0",
|
||||
"resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz",
|
||||
"integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==",
|
||||
"dependencies": {
|
||||
"side-channel": "^1.0.6"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.6"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/range-parser": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
|
||||
"integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==",
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/raw-body": {
|
||||
"version": "2.5.2",
|
||||
"resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz",
|
||||
"integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==",
|
||||
"dependencies": {
|
||||
"bytes": "3.1.2",
|
||||
"http-errors": "2.0.0",
|
||||
"iconv-lite": "0.4.24",
|
||||
"unpipe": "1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/safe-buffer": {
|
||||
"version": "5.2.1",
|
||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
|
||||
"integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/feross"
|
||||
},
|
||||
{
|
||||
"type": "patreon",
|
||||
"url": "https://www.patreon.com/feross"
|
||||
},
|
||||
{
|
||||
"type": "consulting",
|
||||
"url": "https://feross.org/support"
|
||||
}
|
||||
]
|
||||
},
|
||||
"node_modules/safer-buffer": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
|
||||
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
|
||||
},
|
||||
"node_modules/send": {
|
||||
"version": "0.19.0",
|
||||
"resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz",
|
||||
"integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==",
|
||||
"dependencies": {
|
||||
"debug": "2.6.9",
|
||||
"depd": "2.0.0",
|
||||
"destroy": "1.2.0",
|
||||
"encodeurl": "~1.0.2",
|
||||
"escape-html": "~1.0.3",
|
||||
"etag": "~1.8.1",
|
||||
"fresh": "0.5.2",
|
||||
"http-errors": "2.0.0",
|
||||
"mime": "1.6.0",
|
||||
"ms": "2.1.3",
|
||||
"on-finished": "2.4.1",
|
||||
"range-parser": "~1.2.1",
|
||||
"statuses": "2.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/send/node_modules/encodeurl": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
|
||||
"integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==",
|
||||
"engines": {
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/send/node_modules/ms": {
|
||||
"version": "2.1.3",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
||||
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
|
||||
},
|
||||
"node_modules/serve-static": {
|
||||
"version": "1.16.2",
|
||||
"resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz",
|
||||
"integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==",
|
||||
"dependencies": {
|
||||
"encodeurl": "~2.0.0",
|
||||
"escape-html": "~1.0.3",
|
||||
"parseurl": "~1.3.3",
|
||||
"send": "0.19.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/setprototypeof": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
|
||||
"integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="
|
||||
},
|
||||
"node_modules/side-channel": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz",
|
||||
"integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==",
|
||||
"dependencies": {
|
||||
"es-errors": "^1.3.0",
|
||||
"object-inspect": "^1.13.3",
|
||||
"side-channel-list": "^1.0.0",
|
||||
"side-channel-map": "^1.0.1",
|
||||
"side-channel-weakmap": "^1.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/side-channel-list": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz",
|
||||
"integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==",
|
||||
"dependencies": {
|
||||
"es-errors": "^1.3.0",
|
||||
"object-inspect": "^1.13.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/side-channel-map": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz",
|
||||
"integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==",
|
||||
"dependencies": {
|
||||
"call-bound": "^1.0.2",
|
||||
"es-errors": "^1.3.0",
|
||||
"get-intrinsic": "^1.2.5",
|
||||
"object-inspect": "^1.13.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/side-channel-weakmap": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz",
|
||||
"integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==",
|
||||
"dependencies": {
|
||||
"call-bound": "^1.0.2",
|
||||
"es-errors": "^1.3.0",
|
||||
"get-intrinsic": "^1.2.5",
|
||||
"object-inspect": "^1.13.3",
|
||||
"side-channel-map": "^1.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/statuses": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
|
||||
"integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==",
|
||||
"engines": {
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/toidentifier": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
|
||||
"integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==",
|
||||
"engines": {
|
||||
"node": ">=0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/type-is": {
|
||||
"version": "1.6.18",
|
||||
"resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
|
||||
"integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
|
||||
"dependencies": {
|
||||
"media-typer": "0.3.0",
|
||||
"mime-types": "~2.1.24"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/unpipe": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
|
||||
"integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==",
|
||||
"engines": {
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/utils-merge": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
|
||||
"integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==",
|
||||
"engines": {
|
||||
"node": ">= 0.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/vary": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
|
||||
"integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==",
|
||||
"engines": {
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
14
web/package.json
Normal file
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"name": "WEB Sheep Service",
|
||||
"version": "1.0.0",
|
||||
"main": "server.js",
|
||||
"scripts": {
|
||||
"start": "node server.js"
|
||||
},
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"description": "",
|
||||
"dependencies": {
|
||||
"express": "^4.21.0"
|
||||
}
|
||||
}
|
||||
254
web/screenshot.html
Normal file
@@ -0,0 +1,254 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="stylesheet" href="/lib/components/leaflet/leaflet.css" />
|
||||
<script src="/lib/components/leaflet/leaflet.js"></script>
|
||||
|
||||
<link rel="stylesheet" href="/lib/components/geoman/leaflet-geoman.css" />
|
||||
<script src="/lib/components/geoman/leaflet-geoman.min.js"></script>
|
||||
|
||||
<script src="/lib/components/turf.min.js" defer></script>
|
||||
|
||||
<script src="/lib/components/qrcode.min.js"></script>
|
||||
<style>
|
||||
@import url("https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;700&display=swap");
|
||||
|
||||
* {
|
||||
border: 0;
|
||||
padding: 0;
|
||||
font-family: "Roboto", sans-serif;
|
||||
margin: 0;
|
||||
font-weight: 500;
|
||||
outline: none;
|
||||
}
|
||||
#content {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
z-index: 9999;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
#content > #title {
|
||||
width: calc(100% - 30px);
|
||||
min-height: 120px;
|
||||
background: rgb(255 255 255 / 51%);
|
||||
backdrop-filter: blur(10px);
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
padding: 15px;
|
||||
align-items: center;
|
||||
color: #333;
|
||||
}
|
||||
#content > #title > div {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
align-items: center;
|
||||
}
|
||||
#content > #title > h1 {
|
||||
font-size: 65px;
|
||||
font-weight: 700;
|
||||
margin: 0;
|
||||
min-width: 200px;
|
||||
text-align: center;
|
||||
}
|
||||
#content > #title > div > h2 {
|
||||
font-size: 45px;
|
||||
font-weight: 700;
|
||||
margin: 0;
|
||||
}
|
||||
#content > #title > div > h3 {
|
||||
font-size: 38px;
|
||||
font-weight: 500;
|
||||
margin: 0px 0 10px 0;
|
||||
}
|
||||
|
||||
#qrcode {
|
||||
position: absolute;
|
||||
bottom: 160px;
|
||||
left: 20px;
|
||||
width: 130px;
|
||||
height: 130px;
|
||||
background: #fff;
|
||||
padding: 10px;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
.line-left {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 150px;
|
||||
width: 10px;
|
||||
height: calc(100% - 150px);
|
||||
background: rgb(255 255 255 / 51%);
|
||||
backdrop-filter: blur(10px);
|
||||
}
|
||||
.line-right {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 150px;
|
||||
width: 10px;
|
||||
height: calc(100% - 150px);
|
||||
background: rgb(255 255 255 / 51%);
|
||||
backdrop-filter: blur(10px);
|
||||
}
|
||||
.line-bottom {
|
||||
position: absolute;
|
||||
left: 10px;
|
||||
bottom: 0;
|
||||
width: calc(100% - 20px);
|
||||
height: 150px;
|
||||
background: rgb(255 255 255 / 51%);
|
||||
backdrop-filter: blur(10px);
|
||||
}
|
||||
#map {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="content">
|
||||
<div id="title">
|
||||
<div>
|
||||
<h3>Картка плану території</h3>
|
||||
<h2 id="address"></h2>
|
||||
</div>
|
||||
<h1 id="number"></h1>
|
||||
</div>
|
||||
|
||||
<div id="qrcode"></div>
|
||||
|
||||
<div class="line-left"></div>
|
||||
<div class="line-right"></div>
|
||||
<div class="line-bottom"></div>
|
||||
</div>
|
||||
<div id="map"></div>
|
||||
<script>
|
||||
const urlParams = new URLSearchParams(window.location.search);
|
||||
|
||||
let center = {
|
||||
lat: urlParams.get("lat") ?? 49.589443,
|
||||
lng: urlParams.get("lng") ?? 25.5812376,
|
||||
};
|
||||
let zoom = urlParams.get("zoom") ?? 19;
|
||||
let type = urlParams.get("type") ?? "homestead";
|
||||
let wayIds = urlParams.get("wayId") ?? "396982388";
|
||||
let address = urlParams.get("address") ?? "Житловий район";
|
||||
let number = urlParams.get("number") ?? 36;
|
||||
|
||||
let map = L.map("map", {
|
||||
renderer: L.canvas(),
|
||||
center,
|
||||
zoom,
|
||||
zoomControl: false,
|
||||
});
|
||||
let layer = L.tileLayer("https://tm.rozenrod.com/webp/{z}/{x}/{y}.webp", {
|
||||
maxZoom: 20,
|
||||
minZoom: 15,
|
||||
tms: true,
|
||||
}).addTo(map);
|
||||
|
||||
window.onload = async function () {
|
||||
if (type && wayIds) {
|
||||
new QRCode(document.getElementById("qrcode"), {
|
||||
text: `https://www.google.com/maps/search/?api=1&query=${center.lat},${center.lng}`, // Ваша ссылка
|
||||
width: 130,
|
||||
height: 130,
|
||||
correctLevel: QRCode.CorrectLevel.L, // Минимальный уровень коррекции (меньше деталей)
|
||||
version: 5,
|
||||
});
|
||||
|
||||
let wayId = wayIds.split(",");
|
||||
|
||||
console.log(wayId);
|
||||
|
||||
for (let i = 0; i < wayId.length; i++) {
|
||||
const element = wayId[i];
|
||||
let geo = await getOSM(element);
|
||||
|
||||
let coords = [];
|
||||
geo[0].forEach((feature) =>
|
||||
coords.push([feature.lat, feature.lng])
|
||||
);
|
||||
|
||||
let centerPoint = turf.centerOfMass(turf.polygon([coords]));
|
||||
console.log(centerPoint);
|
||||
|
||||
if (!urlParams.get("lat")) {
|
||||
map.setView(
|
||||
[
|
||||
centerPoint.geometry.coordinates[0],
|
||||
centerPoint.geometry.coordinates[1],
|
||||
],
|
||||
urlParams.get("zoom") ?? 17
|
||||
);
|
||||
document.getElementById("qrcode").innerHTML = "";
|
||||
new QRCode(document.getElementById("qrcode"), {
|
||||
text: `https://www.google.com/maps/search/?api=1&query=${centerPoint.geometry.coordinates[0]},${centerPoint.geometry.coordinates[1]}`, // Ваша ссылка
|
||||
width: 130,
|
||||
height: 130,
|
||||
});
|
||||
}
|
||||
|
||||
if (type == "house") {
|
||||
document.getElementById("address").innerText = address;
|
||||
document.getElementById("number").innerText = "T" + number;
|
||||
L.polygon(geo, {
|
||||
color: "#a12121",
|
||||
fillColor: "#c12525",
|
||||
fillOpacity: 0.4,
|
||||
}).addTo(map);
|
||||
} else if (type == "homestead") {
|
||||
document.getElementById("address").innerText = address;
|
||||
document.getElementById("number").innerText = "H" + number;
|
||||
L.polygon(geo, {
|
||||
color: "#a12121",
|
||||
fillColor: "#c12525",
|
||||
radius: 500,
|
||||
fillOpacity: 0.3,
|
||||
dashArray: "20, 15",
|
||||
dashOffset: "20",
|
||||
}).addTo(map);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function getOSM(wayId) {
|
||||
const overpassUrl = `https://overpass-api.de/api/interpreter?data=[out:json];way(${wayId});(._;>;);out;`;
|
||||
|
||||
return await fetch(overpassUrl)
|
||||
.then((response) => response.json())
|
||||
.then((data) => {
|
||||
const nodes = new Map();
|
||||
|
||||
data.elements.forEach((el) => {
|
||||
if (el.type === "node") {
|
||||
nodes.set(el.id, { lat: el.lat, lng: el.lon });
|
||||
}
|
||||
});
|
||||
|
||||
const way = data.elements.find((el) => el.type === "way");
|
||||
if (way) {
|
||||
const coordinates = way.nodes.map((nodeId) =>
|
||||
nodes.get(nodeId)
|
||||
);
|
||||
console.log("Координаты точек:", coordinates);
|
||||
|
||||
return [coordinates];
|
||||
} else {
|
||||
console.log("Way не найден!");
|
||||
}
|
||||
})
|
||||
.catch((error) => console.error("Ошибка запроса:", error));
|
||||
}
|
||||
|
||||
layer.on("load", () => {
|
||||
window.status = "ready";
|
||||
});
|
||||
};
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
21
web/server.js
Normal file
@@ -0,0 +1,21 @@
|
||||
const express = require("express");
|
||||
const path = require("path");
|
||||
|
||||
const app = express();
|
||||
const PORT = 4002;
|
||||
const DIR = process.env.CARDS_PATH || path.join(__dirname, '../cards');
|
||||
|
||||
// Раздача статических файлов из папки, указанной в DIR
|
||||
app.use('/cards', express.static(DIR));
|
||||
|
||||
// Раздача других статических файлов из текущей папки
|
||||
app.use(express.static(__dirname));
|
||||
|
||||
// Обработка 404 ошибки
|
||||
app.use((req, res) => {
|
||||
res.status(404).sendFile(path.join(__dirname, "index.html"));
|
||||
});
|
||||
|
||||
app.listen(PORT, () => {
|
||||
console.log(`Serving app on port ${PORT} ...`);
|
||||
});
|
||||
31
web/server.py
Normal file
@@ -0,0 +1,31 @@
|
||||
import os
|
||||
from http.server import HTTPServer, SimpleHTTPRequestHandler
|
||||
|
||||
# Default error message template
|
||||
DEFAULT_ERROR_MESSAGE = """\
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Single Page Apps for GitHub Pages</title>
|
||||
<script>
|
||||
sessionStorage.redirect = location.href;
|
||||
</script>
|
||||
<meta http-equiv="refresh" content="0;URL='/'">
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
||||
"""
|
||||
|
||||
class MyHandler(SimpleHTTPRequestHandler):
|
||||
def send_error(self, code, message=None):
|
||||
if code == 404:
|
||||
self.error_message_format = DEFAULT_ERROR_MESSAGE
|
||||
SimpleHTTPRequestHandler.send_error(self, code, message)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
httpd = HTTPServer(('', 4002), MyHandler)
|
||||
print("Serving app on port 4002 ...")
|
||||
httpd.serve_forever()
|
||||
238
web/share.html
Normal file
@@ -0,0 +1,238 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<meta
|
||||
name="viewport"
|
||||
content="user-scalable=no, initial-scale=1.0, maximum-scale=1.0"
|
||||
/>
|
||||
<title>Sheep Service</title>
|
||||
|
||||
<link rel="icon" href="/img/favicon.ico" sizes="any" />
|
||||
<link rel="apple-touch-icon" href="/img/apple-touch-icon.png" />
|
||||
|
||||
<script src="js/app.js" defer></script>
|
||||
<style>
|
||||
@import url("https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;700&display=swap");
|
||||
|
||||
@media (prefers-color-scheme: light) {
|
||||
:root {
|
||||
/* PrimaryColor */
|
||||
--PrimaryColor: #28a55a;
|
||||
--PrimaryColor: #f2bd53;
|
||||
--PrimaryColorText: #2e2e2e;
|
||||
/* BGColor */
|
||||
--ColorThemes0: #fbfbfb;
|
||||
--ColorThemes1: #f3f3f3;
|
||||
--ColorThemes2: #e5e5df;
|
||||
/* TextColor */
|
||||
--ColorThemes3: #313131;
|
||||
|
||||
--ColorAnimation: linear-gradient(90deg, #f3f3f3, #efefef, #f3f3f3);
|
||||
|
||||
--shadow-l1: 0px 2px 4px rgba(0, 0, 0, 0.02),
|
||||
0px 0px 2px rgba(0, 0, 0, 0.04), 0px 0px 1px rgba(0, 0, 0, 0.04);
|
||||
--border-radius: 15px;
|
||||
|
||||
--CardAnimation: linear-gradient(
|
||||
to right,
|
||||
#fbfbfb 0%,
|
||||
#fbfbfb 30%,
|
||||
#d8d8d8 45%,
|
||||
#d8d8d8 50%,
|
||||
#fbfbfb 60%,
|
||||
#fbfbfb 100%
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:root {
|
||||
/* PrimaryColor */
|
||||
--PrimaryColor: #28a55a;
|
||||
--PrimaryColor: #cb9e44;
|
||||
--PrimaryColorText: #2e2e2e;
|
||||
/* BGColor */
|
||||
--ColorThemes0: #1c1c19;
|
||||
--ColorThemes1: #21221d;
|
||||
--ColorThemes2: #252523;
|
||||
/* TextColor */
|
||||
--ColorThemes3: #f3f3f3;
|
||||
|
||||
--ColorAnimation: linear-gradient(90deg, #21221d, #242520, #21221d);
|
||||
|
||||
--shadow-l1: 0px 4px 8px rgba(0, 0, 0, 0.04),
|
||||
0px 0px 2px rgba(0, 0, 0, 0.06), 0px 0px 1px rgba(0, 0, 0, 0.04);
|
||||
--border-radius: 15px;
|
||||
|
||||
--CardAnimation: linear-gradient(
|
||||
to right,
|
||||
#1c1c19 0%,
|
||||
#1c1c19 30%,
|
||||
#252525 45%,
|
||||
#252525 50%,
|
||||
#1c1c19 60%,
|
||||
#1c1c19 100%
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
* {
|
||||
border: 0;
|
||||
padding: 0;
|
||||
font-family: "Roboto", sans-serif;
|
||||
margin: 0;
|
||||
font-weight: 300;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
*[disabled] {
|
||||
opacity: 0.6 !important;
|
||||
cursor: no-drop !important;
|
||||
}
|
||||
|
||||
body {
|
||||
background: var(--ColorThemes0);
|
||||
color: var(--ColorThemes3);
|
||||
}
|
||||
|
||||
select {
|
||||
-moz-appearance: none;
|
||||
-webkit-appearance: none;
|
||||
appearance: none;
|
||||
/* Arrow */
|
||||
appearance: none;
|
||||
background-image: url("data:image/svg+xml;charset=US-ASCII,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22292.4%22%20height%3D%22292.4%22%3E%3Cpath%20fill%3D%22%237a899d%22%20d%3D%22M287%2069.4a17.6%2017.6%200%200%200-13-5.4H18.4c-5%200-9.3%201.8-12.9%205.4A17.6%2017.6%200%200%200%200%2082.2c0%205%201.8%209.3%205.4%2012.9l128%20127.9c3.6%203.6%207.8%205.4%2012.8%205.4s9.2-1.8%2012.8-5.4L287%2095c3.5-3.5%205.4-7.8%205.4-12.8%200-5-1.9-9.2-5.5-12.8z%22%2F%3E%3C%2Fsvg%3E");
|
||||
background-repeat: no-repeat;
|
||||
background-position: right 0.3rem top 50%;
|
||||
background-size: 0.55rem auto;
|
||||
}
|
||||
|
||||
#header {
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
margin: 10px;
|
||||
}
|
||||
#header p {
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
#list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
details {
|
||||
color: var(--ColorThemes3);
|
||||
width: 100%;
|
||||
min-width: 320px;
|
||||
background: var(--ColorThemes1);
|
||||
margin: 20px 0px;
|
||||
border-radius: 10px;
|
||||
overflow: hidden;
|
||||
box-shadow: 0px 2px 4px rgba(0, 0, 0, 0.04),
|
||||
0px 0px 2px rgba(0, 0, 0, 0.04), 0px 0px 1px rgba(0, 0, 0, 0.04);
|
||||
}
|
||||
@media (min-width: 500px) {
|
||||
details {
|
||||
/* width: calc(100% - 30px); */
|
||||
}
|
||||
}
|
||||
details[disabled] summary,
|
||||
details.disabled summary {
|
||||
pointer-events: none;
|
||||
user-select: none;
|
||||
}
|
||||
details summary::-webkit-details-marker,
|
||||
details summary::marker {
|
||||
display: none;
|
||||
content: "";
|
||||
}
|
||||
summary {
|
||||
cursor: pointer;
|
||||
background: #7a8a9d;
|
||||
background: var(--PrimaryColor);
|
||||
height: 45px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
summary p {
|
||||
padding: 0 10px;
|
||||
color: var(--PrimaryColorText);
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
}
|
||||
summary svg {
|
||||
width: 25px;
|
||||
height: 25px;
|
||||
padding: 0 10px;
|
||||
fill: var(--PrimaryColorText);
|
||||
}
|
||||
|
||||
.apartments_list {
|
||||
padding: 10px;
|
||||
border-top: 2px solid var(--ColorThemes1);
|
||||
border-bottom: 2px solid var(--PrimaryColor);
|
||||
border-left: 2px solid var(--PrimaryColor);
|
||||
border-right: 2px solid var(--PrimaryColor);
|
||||
border-style: dotted;
|
||||
border-radius: 0 0 10px 10px;
|
||||
}
|
||||
@media (max-width: 500px) {
|
||||
.apartments_list {
|
||||
padding: 0px;
|
||||
}
|
||||
}
|
||||
.apartments_list div {
|
||||
display: flex;
|
||||
font-size: 14px;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
border-radius: 8px;
|
||||
margin: 5px 0;
|
||||
}
|
||||
.apartments_list div span {
|
||||
min-width: 30px;
|
||||
font-size: 12px;
|
||||
position: relative;
|
||||
margin: 5px;
|
||||
}
|
||||
.apartments_list div select {
|
||||
color: #3d3d3d;
|
||||
border-radius: 6px;
|
||||
border: 1px solid #eaebef;
|
||||
margin: 5px;
|
||||
background-color: #fff;
|
||||
min-width: 110px;
|
||||
width: 100%;
|
||||
padding: 4px 20px 4px 4px;
|
||||
height: 30px;
|
||||
}
|
||||
.apartments_list div input {
|
||||
color: #3d3d3d;
|
||||
border-radius: 6px;
|
||||
border: 1px solid #eaebef;
|
||||
margin: 5px;
|
||||
background-color: #fff;
|
||||
width: 100%;
|
||||
min-width: 70px;
|
||||
padding: 0 4px;
|
||||
height: calc(30px - 2px);
|
||||
appearance: none;
|
||||
-webkit-appearance: none;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="header">
|
||||
<p id="status"></p>
|
||||
<p id="hash"></p>
|
||||
</div>
|
||||
|
||||
<div id="list"></div>
|
||||
</body>
|
||||
</html>
|
||||
15
web/sw.js
Normal file
@@ -0,0 +1,15 @@
|
||||
self.addEventListener('install', async event => {
|
||||
|
||||
})
|
||||
|
||||
self.addEventListener('activate', async event => {
|
||||
|
||||
})
|
||||
|
||||
self.addEventListener('fetch', event => {
|
||||
|
||||
})
|
||||
|
||||
self.addEventListener('message', event => {
|
||||
if (event.data === 'skipWaiting') return skipWaiting();
|
||||
});
|
||||