├── .gitignore ├── README.md ├── back ├── __init__.py ├── admin.py ├── apps.py ├── forms.py ├── models.py ├── templates │ └── back │ │ ├── index.html │ │ └── success.html ├── tests.py ├── urls.py └── views.py ├── interview_task ├── __init__.py ├── asgi.py ├── settings.py ├── urls.py └── wsgi.py ├── manage.py ├── requirements.txt └── static ├── css ├── vendor │ ├── app.min.css │ ├── fonts │ │ ├── bootstrap-icons.woff │ │ └── bootstrap-icons.woff2 │ ├── images │ │ ├── cover-2.jpg │ │ ├── cover-3.jpg │ │ ├── cover-4.jpg │ │ ├── cover-5.jpg │ │ ├── cover.jpg │ │ ├── logo.png │ │ └── pattern.png │ └── vendor.min.css └── zoom.css ├── favicon.ico ├── image ├── delete.png └── pc.png ├── js ├── vendor │ ├── app.min.js │ └── vendor.min.js └── zoom.js └── webfonts ├── fa-brands-400.ttf ├── fa-brands-400.woff2 ├── fa-regular-400.ttf ├── fa-regular-400.woff2 ├── fa-solid-900.ttf ├── fa-solid-900.woff2 ├── fa-v4compatibility.ttf └── fa-v4compatibility.woff2 /.gitignore: -------------------------------------------------------------------------------- 1 | venv 2 | *.pyc 3 | db.sqlite3 4 | __pycache__/ 5 | .env -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Please follow the following steps to run the project: 2 | 3 | >python -m venv venv 4 | > 5 | >venv\scripts\activate 6 | > 7 | >pip install -r requirments.txt 8 | > 9 | >python manage.py migrate 10 | > 11 | >python mange.py runserver 0.0.0.0:8000 12 | -------------------------------------------------------------------------------- /back/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maks-Ars1/Django-simple-page/b907442acc963b7145b1c981938e2865fb814caa/back/__init__.py -------------------------------------------------------------------------------- /back/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | from .models import MyUser, Task 3 | 4 | 5 | # Register your models here. 6 | admin.site.register(MyUser) 7 | admin.site.register(Task) 8 | 9 | -------------------------------------------------------------------------------- /back/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class BackConfig(AppConfig): 5 | default_auto_field = 'django.db.models.BigAutoField' 6 | name = 'back' 7 | -------------------------------------------------------------------------------- /back/forms.py: -------------------------------------------------------------------------------- 1 | from django.forms import ModelForm 2 | from .models import MyUser 3 | from django.utils.translation import gettext_lazy as _ 4 | from django import forms 5 | 6 | class MyUserForm(ModelForm): 7 | class Meta: 8 | model = MyUser 9 | fields = ['username', 'password'] 10 | labels = { 11 | 'username': _('Username'), 12 | 'password': _('Password') 13 | } 14 | widgets = { 15 | 'username': forms.TextInput(attrs={'class':'form-control'}), 16 | 'password': forms.PasswordInput(attrs={'class':'form-control'}) 17 | } -------------------------------------------------------------------------------- /back/models.py: -------------------------------------------------------------------------------- 1 | from pickle import FALSE 2 | from django.db import models 3 | from django.contrib.auth.models import User 4 | 5 | 6 | class MyUser(User): 7 | def __str__(self) -> str: 8 | return self.username 9 | 10 | class Task(models.Model): 11 | userId = models.IntegerField() 12 | id = models.IntegerField(primary_key=True) 13 | title = models.CharField(max_length=255) 14 | body = models.CharField(max_length=255) -------------------------------------------------------------------------------- /back/templates/back/index.html: -------------------------------------------------------------------------------- 1 | {% load static %} 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 |
21 | 29 |
30 |
31 | 32 | 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /back/templates/back/success.html: -------------------------------------------------------------------------------- 1 | {% load static %} 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 |
21 | 32 |
33 |
34 | 35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /back/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /back/urls.py: -------------------------------------------------------------------------------- 1 | from django.urls import path 2 | from . import views 3 | 4 | app_name = 'back' 5 | 6 | urlpatterns = [ 7 | path('', views.index, name='index'), 8 | path('success', views.post_data, name='success') 9 | ] -------------------------------------------------------------------------------- /back/views.py: -------------------------------------------------------------------------------- 1 | from django.shortcuts import render 2 | from .forms import MyUserForm 3 | import requests 4 | from back.models import Task 5 | 6 | 7 | # Create your views here. 8 | def index(request): 9 | context = { 10 | } 11 | return render(request, 'back/index.html', context) 12 | 13 | def post_data(request): 14 | if request.method == 'POST': 15 | api_url = 'http://jsonplaceholder.typicode.com/posts' 16 | try: 17 | response = requests.post(api_url) 18 | print(response.json()) 19 | idval = '' 20 | if 'id' in response.json(): 21 | idval = response.json()['id'] 22 | title = '' 23 | if 'title' in response.json(): 24 | title = response.json()['title'] 25 | bd = '' 26 | if 'body' in response.json(): 27 | bd = response.json()['body'] 28 | userId = 0 29 | if 'userId' in response.json(): 30 | userId = response.json()['userId'] 31 | new_db = Task(id=idval, title=title, body=bd, userId=userId) 32 | except Exception as e: 33 | print("error") 34 | user_form = MyUserForm() 35 | context = { 36 | 'success': '1', 37 | 'id': idval, 38 | 'title': title, 39 | 'body': bd, 40 | 'userId': userId 41 | } 42 | return render(request, 'back/success.html', context) 43 | else: 44 | user_form = MyUserForm() 45 | context = { 46 | 'success': '0' 47 | } 48 | return render(request, 'back/index.html', context) -------------------------------------------------------------------------------- /interview_task/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maks-Ars1/Django-simple-page/b907442acc963b7145b1c981938e2865fb814caa/interview_task/__init__.py -------------------------------------------------------------------------------- /interview_task/asgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | ASGI config for interview_task project. 3 | 4 | It exposes the ASGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/4.0/howto/deployment/asgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.asgi import get_asgi_application 13 | 14 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'interview_task.settings') 15 | 16 | application = get_asgi_application() 17 | -------------------------------------------------------------------------------- /interview_task/settings.py: -------------------------------------------------------------------------------- 1 | """ 2 | Django settings for interview_task project. 3 | 4 | Generated by 'django-admin startproject' using Django 4.0.6. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/4.0/topics/settings/ 8 | 9 | For the full list of settings and their values, see 10 | https://docs.djangoproject.com/en/4.0/ref/settings/ 11 | """ 12 | 13 | from pathlib import Path 14 | import os 15 | from dotenv import load_dotenv 16 | 17 | 18 | load_dotenv() 19 | 20 | # Build paths inside the project like this: BASE_DIR / 'subdir'. 21 | BASE_DIR = Path(__file__).resolve().parent.parent 22 | 23 | 24 | # Quick-start development settings - unsuitable for production 25 | # See https://docs.djangoproject.com/en/4.0/howto/deployment/checklist/ 26 | 27 | # SECURITY WARNING: keep the secret key used in production secret! 28 | SECRET_KEY = '9cg2x%f4dnbh^uu56k0ig038ir)m6k2e4a&(6$g)%g1#c2w#77'#os.environ['SECRET_KEY'] 29 | 30 | # SECURITY WARNING: don't run with debug turned on in production! 31 | DEBUG = True 32 | 33 | ALLOWED_HOSTS = [] 34 | 35 | 36 | # Application definition 37 | 38 | INSTALLED_APPS = [ 39 | 'django.contrib.admin', 40 | 'django.contrib.auth', 41 | 'django.contrib.contenttypes', 42 | 'django.contrib.sessions', 43 | 'django.contrib.messages', 44 | 'django.contrib.staticfiles', 45 | 'storages', 46 | 'rest_framework', 47 | 'back', 48 | ] 49 | 50 | MIDDLEWARE = [ 51 | 'django.middleware.security.SecurityMiddleware', 52 | 'django.contrib.sessions.middleware.SessionMiddleware', 53 | 'django.middleware.common.CommonMiddleware', 54 | 'django.middleware.csrf.CsrfViewMiddleware', 55 | 'django.contrib.auth.middleware.AuthenticationMiddleware', 56 | 'django.contrib.messages.middleware.MessageMiddleware', 57 | 'django.middleware.clickjacking.XFrameOptionsMiddleware', 58 | ] 59 | 60 | ROOT_URLCONF = 'interview_task.urls' 61 | 62 | TEMPLATES = [ 63 | { 64 | 'BACKEND': 'django.template.backends.django.DjangoTemplates', 65 | 'DIRS': [], 66 | 'APP_DIRS': True, 67 | 'OPTIONS': { 68 | 'context_processors': [ 69 | 'django.template.context_processors.debug', 70 | 'django.template.context_processors.request', 71 | 'django.contrib.auth.context_processors.auth', 72 | 'django.contrib.messages.context_processors.messages', 73 | ], 74 | }, 75 | }, 76 | ] 77 | 78 | WSGI_APPLICATION = 'interview_task.wsgi.application' 79 | 80 | 81 | # Database 82 | # https://docs.djangoproject.com/en/4.0/ref/settings/#databases 83 | 84 | DATABASES = { 85 | 'default': { 86 | 'ENGINE': 'django.db.backends.sqlite3', 87 | 'NAME': BASE_DIR / 'db.sqlite3', 88 | } 89 | } 90 | 91 | 92 | # Password validation 93 | # https://docs.djangoproject.com/en/4.0/ref/settings/#auth-password-validators 94 | 95 | AUTH_PASSWORD_VALIDATORS = [ 96 | { 97 | 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', 98 | }, 99 | { 100 | 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', 101 | }, 102 | { 103 | 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', 104 | }, 105 | { 106 | 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', 107 | }, 108 | ] 109 | 110 | 111 | # Internationalization 112 | # https://docs.djangoproject.com/en/4.0/topics/i18n/ 113 | 114 | LANGUAGE_CODE = 'en-us' 115 | 116 | TIME_ZONE = 'UTC' 117 | 118 | USE_I18N = True 119 | 120 | USE_TZ = True 121 | 122 | 123 | # Static files (CSS, JavaScript, Images) 124 | # https://docs.djangoproject.com/en/4.0/howto/static-files/ 125 | STATIC_URL = '/static/' 126 | STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles') 127 | STATICFILES_DIRS = ( 128 | os.path.join(BASE_DIR, 'static'), 129 | ) 130 | 131 | 132 | # Default primary key field type 133 | # https://docs.djangoproject.com/en/4.0/ref/settings/#default-auto-field 134 | 135 | DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' 136 | 137 | # Configure Django App for Heroku. 138 | import django_on_heroku 139 | django_on_heroku.settings(locals()) 140 | 141 | 142 | AWS_ACCESS_KEY_ID = ''#os.environ['AWS_ACCESS_KEY_ID'] 143 | AWS_SECRET_ACCESS_KEY = ''#os.environ['AWS_SECRET_ACCESS_KEY'] 144 | AWS_STORAGE_BUCKET_NAME = ''#os.environ['AWS_STORAGE_BUCKET_NAME'] 145 | AWS_S3_REGION_NAME = ''#os.environ['AWS_S3_REGION_NAME'] 146 | AWS_S3_SIGNATURE_VERSION = '4.0.6'#os.environ['AWS_S3_SIGNATURE_VERSION'] 147 | 148 | AWS_S3_FILE_OVERWRITE=False 149 | AWS_DEFAULT_ACL=None 150 | DEFAULT_FILE_STORAGE = 'django.core.files.storage.FileSystemStorage' 151 | AWS_QUERYSTRING_AUTH = False 152 | 153 | REST_FRAMEWORK = { 154 | 'DEFAULT_AUTHENTICATION_CLASSES': [ 155 | 'rest_framework.authentication.TokenAuthentication', 156 | ] 157 | } 158 | 159 | SECURE_CROSS_ORIGIN_OPENER_POLICY = None 160 | 161 | -------------------------------------------------------------------------------- /interview_task/urls.py: -------------------------------------------------------------------------------- 1 | """interview_task URL Configuration 2 | 3 | The `urlpatterns` list routes URLs to views. For more information please see: 4 | https://docs.djangoproject.com/en/4.0/topics/http/urls/ 5 | Examples: 6 | Function views 7 | 1. Add an import: from my_app import views 8 | 2. Add a URL to urlpatterns: path('', views.home, name='home') 9 | Class-based views 10 | 1. Add an import: from other_app.views import Home 11 | 2. Add a URL to urlpatterns: path('', Home.as_view(), name='home') 12 | Including another URLconf 13 | 1. Import the include() function: from django.urls import include, path 14 | 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) 15 | """ 16 | from django.contrib import admin 17 | from django.urls import path, include 18 | from django.conf import settings 19 | from django.conf.urls.static import static 20 | urlpatterns = [ 21 | path('admin/', admin.site.urls), 22 | path('', include('back.urls')) 23 | ]+ static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) 24 | -------------------------------------------------------------------------------- /interview_task/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for interview_task project. 3 | 4 | It exposes the WSGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/4.0/howto/deployment/wsgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.wsgi import get_wsgi_application 13 | 14 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'interview_task.settings') 15 | 16 | application = get_wsgi_application() 17 | -------------------------------------------------------------------------------- /manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """Django's command-line utility for administrative tasks.""" 3 | import os 4 | import sys 5 | 6 | 7 | def main(): 8 | """Run administrative tasks.""" 9 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'interview_task.settings') 10 | try: 11 | from django.core.management import execute_from_command_line 12 | except ImportError as exc: 13 | raise ImportError( 14 | "Couldn't import Django. Are you sure it's installed and " 15 | "available on your PYTHONPATH environment variable? Did you " 16 | "forget to activate a virtual environment?" 17 | ) from exc 18 | execute_from_command_line(sys.argv) 19 | 20 | 21 | if __name__ == '__main__': 22 | main() 23 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maks-Ars1/Django-simple-page/b907442acc963b7145b1c981938e2865fb814caa/requirements.txt -------------------------------------------------------------------------------- /static/css/vendor/fonts/bootstrap-icons.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maks-Ars1/Django-simple-page/b907442acc963b7145b1c981938e2865fb814caa/static/css/vendor/fonts/bootstrap-icons.woff -------------------------------------------------------------------------------- /static/css/vendor/fonts/bootstrap-icons.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maks-Ars1/Django-simple-page/b907442acc963b7145b1c981938e2865fb814caa/static/css/vendor/fonts/bootstrap-icons.woff2 -------------------------------------------------------------------------------- /static/css/vendor/images/cover-2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maks-Ars1/Django-simple-page/b907442acc963b7145b1c981938e2865fb814caa/static/css/vendor/images/cover-2.jpg -------------------------------------------------------------------------------- /static/css/vendor/images/cover-3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maks-Ars1/Django-simple-page/b907442acc963b7145b1c981938e2865fb814caa/static/css/vendor/images/cover-3.jpg -------------------------------------------------------------------------------- /static/css/vendor/images/cover-4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maks-Ars1/Django-simple-page/b907442acc963b7145b1c981938e2865fb814caa/static/css/vendor/images/cover-4.jpg -------------------------------------------------------------------------------- /static/css/vendor/images/cover-5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maks-Ars1/Django-simple-page/b907442acc963b7145b1c981938e2865fb814caa/static/css/vendor/images/cover-5.jpg -------------------------------------------------------------------------------- /static/css/vendor/images/cover.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maks-Ars1/Django-simple-page/b907442acc963b7145b1c981938e2865fb814caa/static/css/vendor/images/cover.jpg -------------------------------------------------------------------------------- /static/css/vendor/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maks-Ars1/Django-simple-page/b907442acc963b7145b1c981938e2865fb814caa/static/css/vendor/images/logo.png -------------------------------------------------------------------------------- /static/css/vendor/images/pattern.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maks-Ars1/Django-simple-page/b907442acc963b7145b1c981938e2865fb814caa/static/css/vendor/images/pattern.png -------------------------------------------------------------------------------- /static/css/zoom.css: -------------------------------------------------------------------------------- 1 | img[data-action="zoom"] { 2 | cursor: pointer; 3 | cursor: -webkit-zoom-in; 4 | cursor: -moz-zoom-in; 5 | 6 | } 7 | .zoom-img, 8 | .zoom-img-wrap { 9 | position: relative; 10 | z-index: 666; 11 | -webkit-transition: all 300ms; 12 | -o-transition: all 300ms; 13 | transition: all 300ms; 14 | } 15 | img.zoom-img { 16 | cursor: pointer; 17 | cursor: -webkit-zoom-out; 18 | cursor: -moz-zoom-out; 19 | 20 | } 21 | .zoom-overlay { 22 | z-index: 420; 23 | background: #fff; 24 | position: fixed; 25 | top: 0; 26 | left: 0; 27 | right: 0; 28 | bottom: 0; 29 | pointer-events: none; 30 | filter: "alpha(opacity=0)"; 31 | opacity: 0; 32 | -webkit-transition: opacity 300ms; 33 | -o-transition: opacity 300ms; 34 | transition: opacity 300ms; 35 | } 36 | .zoom-overlay-open .zoom-overlay { 37 | filter: "alpha(opacity=100)"; 38 | opacity: 1; 39 | } 40 | .zoom-overlay-open, 41 | .zoom-overlay-transitioning { 42 | cursor: default; 43 | } 44 | .delete_button { 45 | cursor: pointer; 46 | } 47 | .gallery { 48 | position: relative; 49 | padding: 10px; 50 | } 51 | 52 | .img-thumbnail { 53 | opacity: 1; 54 | display: block; 55 | width: 100%; 56 | height: auto; 57 | transition: .5s ease; 58 | backface-visibility: hidden; 59 | } 60 | 61 | .middle { 62 | transition: .5s ease; 63 | opacity: 0; 64 | position: absolute; 65 | top: 10px; 66 | right: 0px; 67 | transform: translate(-50%, -50%); 68 | -ms-transform: translate(-50%, -50%); 69 | text-align: center; 70 | } 71 | .gallery:hover .img-thumbnail { 72 | opacity : 0.5; 73 | background-color: rgba(0, 0, 0, 0.7) 74 | } 75 | .gallery:hover .zoom-img { 76 | opacity : 1; 77 | background-color: rgba(0, 0, 0, 0.7) 78 | } 79 | 80 | .gallery:hover .middle { 81 | opacity: 1; 82 | } 83 | 84 | 85 | 86 | 87 | -------------------------------------------------------------------------------- /static/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maks-Ars1/Django-simple-page/b907442acc963b7145b1c981938e2865fb814caa/static/favicon.ico -------------------------------------------------------------------------------- /static/image/delete.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maks-Ars1/Django-simple-page/b907442acc963b7145b1c981938e2865fb814caa/static/image/delete.png -------------------------------------------------------------------------------- /static/image/pc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maks-Ars1/Django-simple-page/b907442acc963b7145b1c981938e2865fb814caa/static/image/pc.png -------------------------------------------------------------------------------- /static/js/vendor/app.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | Template Name: HUD - Responsive Bootstrap 5 Admin Template 3 | Version: 1.9.0 4 | Author: Sean Ngu 5 | Website: http://www.seantheme.com/hud/ 6 | ---------------------------- 7 | APPS CONTENT TABLE 8 | ---------------------------- 9 | 10 | 11 | 01. Global Variable 12 | 02. Handle Scrollbar 13 | 03. Handle Sidebar Menu 14 | 04. Handle Sidebar Scroll Memory 15 | 05. Handle Card Action 16 | 06. Handle Tooltip & Popover Activation 17 | 07. Handle Scroll to Top Button 18 | 08. Handle hexToRgba 19 | 09. Handle Scroll To 20 | 10. Handle Toggle Class 21 | 11. Handle Theme Panel 22 | 12. Application Controller 23 | 13. Initialise 24 | 25 | 26 | Application Controller 27 | */ 28 | 29 | 30 | 31 | /* 01. Global Variable 32 | ------------------------------------------------ */ 33 | var app = { 34 | id: '#app', 35 | isMobile: ((/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)) || window.innerWidth < 992), 36 | bootstrap: { 37 | tooltip: { 38 | attr: 'data-bs-toggle="tooltip"' 39 | }, 40 | popover: { 41 | attr: 'data-bs-toggle="popover"' 42 | }, 43 | modal: { 44 | attr: 'data-bs-toggle="modal"', 45 | dismissAttr: 'data-bs-dismiss="modal"', 46 | event: { 47 | hidden: 'hidden.bs.modal' 48 | } 49 | }, 50 | nav: { 51 | class: 'nav', 52 | tabs: { 53 | class: 'nav-tabs', 54 | activeClass: 'active', 55 | itemClass: 'nav-item', 56 | itemLinkClass: 'nav-link' 57 | } 58 | } 59 | }, 60 | header: { 61 | id: '#header', 62 | class: 'app-header', 63 | hasScrollClass: 'has-scroll' 64 | }, 65 | sidebar: { 66 | id: '#sidebar', 67 | class: 'app-sidebar', 68 | scrollBar: { 69 | localStorage: 'appSidebarScrollPosition', 70 | dom: '' 71 | }, 72 | menu: { 73 | class: 'menu', 74 | initAttr: 'data-init', 75 | animationTime: 0, 76 | itemClass: 'menu-item', 77 | itemLinkClass: 'menu-link', 78 | hasSubClass: 'has-sub', 79 | activeClass: 'active', 80 | expandingClass: 'expanding', 81 | expandClass: 'expand', 82 | submenu: { 83 | class: 'menu-submenu', 84 | } 85 | }, 86 | mobile: { 87 | toggleAttr: 'data-toggle="app-sidebar-mobile"', 88 | dismissAttr: 'data-dismiss="app-sidebar-mobile"', 89 | toggledClass: 'app-sidebar-mobile-toggled', 90 | closedClass: 'app-sidebar-mobile-closed', 91 | backdrop: { 92 | class: 'app-sidebar-mobile-backdrop' 93 | } 94 | }, 95 | minify: { 96 | toggleAttr: 'data-toggle="app-sidebar-minify"', 97 | toggledClass: 'app-sidebar-minified', 98 | cookieName: 'app-sidebar-minified' 99 | }, 100 | floatSubmenu: { 101 | id: '#app-sidebar-float-submenu', 102 | dom: '', 103 | timeout: '', 104 | class: 'app-sidebar-float-submenu', 105 | container: { 106 | class: 'app-sidebar-float-submenu-container' 107 | }, 108 | arrow: { 109 | id: '#app-sidebar-float-submenu-arrow', 110 | class: 'app-sidebar-float-submenu-arrow' 111 | }, 112 | line: { 113 | id: '#app-sidebar-float-submenu-line', 114 | class: 'app-sidebar-float-submenu-line' 115 | }, 116 | overflow: { 117 | class: 'overflow-scroll mh-100vh' 118 | } 119 | }, 120 | search: { 121 | class: 'menu-search', 122 | toggleAttr: 'data-sidebar-search="true"', 123 | hideClass: 'd-none', 124 | foundClass: 'has-text' 125 | }, 126 | transparent: { 127 | class: 'app-sidebar-transparent' 128 | } 129 | }, 130 | scrollBar: { 131 | attr: 'data-scrollbar="true"', 132 | skipMobileAttr: 'data-skip-mobile', 133 | heightAttr: 'data-height', 134 | wheelPropagationAttr: 'data-wheel-propagation' 135 | }, 136 | content: { 137 | id: '#content', 138 | class: 'app-content', 139 | fullHeight: { 140 | class: 'app-content-full-height' 141 | }, 142 | fullWidth: { 143 | class: 'app-content-full-width' 144 | } 145 | }, 146 | layout: { 147 | sidebarLight: { 148 | class: 'app-with-light-sidebar' 149 | }, 150 | sidebarEnd: { 151 | class: 'app-with-end-sidebar' 152 | }, 153 | sidebarWide: { 154 | class: 'app-with-wide-sidebar' 155 | }, 156 | sidebarMinified: { 157 | class: 'app-sidebar-minified' 158 | }, 159 | sidebarTwo: { 160 | class: 'app-with-two-sidebar' 161 | }, 162 | withoutHeader: { 163 | class: 'app-without-header' 164 | }, 165 | withoutSidebar: { 166 | class: 'app-without-sidebar' 167 | }, 168 | topMenu: { 169 | class: 'app-with-top-menu' 170 | }, 171 | boxedLayout: { 172 | class: 'boxed-layout' 173 | } 174 | }, 175 | scrollToTopBtn: { 176 | showClass: 'show', 177 | heightShow: 200, 178 | toggleAttr: 'data-toggle="scroll-to-top"', 179 | scrollSpeed: 500 180 | }, 181 | scrollTo: { 182 | attr: 'data-toggle="scroll-to"', 183 | target: 'data-target', 184 | linkTarget: 'href' 185 | }, 186 | themePanel: { 187 | class: 'app-theme-panel', 188 | toggleAttr: 'data-toggle="theme-panel-expand"', 189 | cookieName: 'app-theme-panel-expand', 190 | activeClass: 'active', 191 | themeListCLass: 'app-theme-list', 192 | themeListItemCLass: 'app-theme-list-item', 193 | themeCoverClass: 'app-theme-cover', 194 | themeCoverItemClass: 'app-theme-cover-item', 195 | theme: { 196 | toggleAttr: 'data-toggle="theme-selector"', 197 | classAttr: 'data-theme-class', 198 | cookieName: 'app-theme', 199 | activeClass: 'active' 200 | }, 201 | themeCover: { 202 | toggleAttr: 'data-toggle="theme-cover-selector"', 203 | classAttr: 'data-theme-cover-class', 204 | cookieName: 'app-theme-cover', 205 | activeClass: 'active' 206 | } 207 | }, 208 | dismissClass: { 209 | toggleAttr: 'data-dismiss-class', 210 | targetAttr: 'data-dismiss-target' 211 | }, 212 | toggleClass: { 213 | toggleAttr: 'data-toggle-class', 214 | targetAttr: 'data-toggle-target' 215 | }, 216 | font: { 217 | family: (getComputedStyle(document.body).getPropertyValue('--bs-body-font-family')).trim(), 218 | size: (getComputedStyle(document.body).getPropertyValue('--bs-body-font-size')).trim(), 219 | weight: (getComputedStyle(document.body).getPropertyValue('--bs-body-font-weight')).trim() 220 | }, 221 | color: { 222 | theme: (getComputedStyle(document.body).getPropertyValue('--bs-theme')).trim(), 223 | blue: (getComputedStyle(document.body).getPropertyValue('--bs-blue')).trim(), 224 | green: (getComputedStyle(document.body).getPropertyValue('--bs-green')).trim(), 225 | orange: (getComputedStyle(document.body).getPropertyValue('--bs-orange')).trim(), 226 | red: (getComputedStyle(document.body).getPropertyValue('--bs-red')).trim(), 227 | cyan: (getComputedStyle(document.body).getPropertyValue('--bs-cyan')).trim(), 228 | purple: (getComputedStyle(document.body).getPropertyValue('--bs-purple')).trim(), 229 | yellow: (getComputedStyle(document.body).getPropertyValue('--bs-yellow')).trim(), 230 | indigo: (getComputedStyle(document.body).getPropertyValue('--bs-indigo')).trim(), 231 | pink: (getComputedStyle(document.body).getPropertyValue('--bs-pink')).trim(), 232 | black: (getComputedStyle(document.body).getPropertyValue('--bs-black')).trim(), 233 | white: (getComputedStyle(document.body).getPropertyValue('--bs-white')).trim(), 234 | gray: (getComputedStyle(document.body).getPropertyValue('--bs-gray')).trim(), 235 | dark: (getComputedStyle(document.body).getPropertyValue('--bs-dark')).trim(), 236 | gray100: (getComputedStyle(document.body).getPropertyValue('--bs-gray-100')).trim(), 237 | gray200: (getComputedStyle(document.body).getPropertyValue('--bs-gray-200')).trim(), 238 | gray300: (getComputedStyle(document.body).getPropertyValue('--bs-gray-300')).trim(), 239 | gray400: (getComputedStyle(document.body).getPropertyValue('--bs-gray-400')).trim(), 240 | gray500: (getComputedStyle(document.body).getPropertyValue('--bs-gray-500')).trim(), 241 | gray600: (getComputedStyle(document.body).getPropertyValue('--bs-gray-600')).trim(), 242 | gray700: (getComputedStyle(document.body).getPropertyValue('--bs-gray-700')).trim(), 243 | gray800: (getComputedStyle(document.body).getPropertyValue('--bs-gray-800')).trim(), 244 | gray900: (getComputedStyle(document.body).getPropertyValue('--bs-gray-900')).trim(), 245 | 246 | themeRgb: (getComputedStyle(document.body).getPropertyValue('--bs-theme-rgb')).trim(), 247 | blueRgb: (getComputedStyle(document.body).getPropertyValue('--bs-blue-rgb')).trim(), 248 | greenRgb: (getComputedStyle(document.body).getPropertyValue('--bs-green-rgb')).trim(), 249 | orangeRgb: (getComputedStyle(document.body).getPropertyValue('--bs-orange-rgb')).trim(), 250 | redRgb: (getComputedStyle(document.body).getPropertyValue('--bs-red-rgb')).trim(), 251 | cyanRgb: (getComputedStyle(document.body).getPropertyValue('--bs-cyan-rgb')).trim(), 252 | purpleRgb: (getComputedStyle(document.body).getPropertyValue('--bs-purple-rgb')).trim(), 253 | yellowRgb: (getComputedStyle(document.body).getPropertyValue('--bs-yellow-rgb')).trim(), 254 | indigoRgb: (getComputedStyle(document.body).getPropertyValue('--bs-indigo-rgb')).trim(), 255 | pinkRgb: (getComputedStyle(document.body).getPropertyValue('--bs-pink-rgb')).trim(), 256 | blackRgb: (getComputedStyle(document.body).getPropertyValue('--bs-black-rgb')).trim(), 257 | whiteRgb: (getComputedStyle(document.body).getPropertyValue('--bs-white-rgb')).trim(), 258 | grayRgb: (getComputedStyle(document.body).getPropertyValue('--bs-gray-rgb')).trim(), 259 | darkRgb: (getComputedStyle(document.body).getPropertyValue('--bs-dark-rgb')).trim(), 260 | gray100Rgb: (getComputedStyle(document.body).getPropertyValue('--bs-gray-100-rgb')).trim(), 261 | gray200Rgb: (getComputedStyle(document.body).getPropertyValue('--bs-gray-200-rgb')).trim(), 262 | gray300Rgb: (getComputedStyle(document.body).getPropertyValue('--bs-gray-300-rgb')).trim(), 263 | gray400Rgb: (getComputedStyle(document.body).getPropertyValue('--bs-gray-400-rgb')).trim(), 264 | gray500Rgb: (getComputedStyle(document.body).getPropertyValue('--bs-gray-500-rgb')).trim(), 265 | gray600Rgb: (getComputedStyle(document.body).getPropertyValue('--bs-gray-600-rgb')).trim(), 266 | gray700Rgb: (getComputedStyle(document.body).getPropertyValue('--bs-gray-700-rgb')).trim(), 267 | gray800Rgb: (getComputedStyle(document.body).getPropertyValue('--bs-gray-800-rgb')).trim(), 268 | gray900Rgb: (getComputedStyle(document.body).getPropertyValue('--bs-gray-900-rgb')).trim() 269 | }, 270 | card: { 271 | expand: { 272 | status: false, 273 | toggleAttr: 'data-toggle="card-expand"', 274 | toggleTitle: 'Expand / Compress', 275 | class: 'card-expand' 276 | } 277 | }, 278 | init: { 279 | attr: 'data-init', 280 | class: 'app-init' 281 | } 282 | }; 283 | 284 | 285 | 286 | /* 02. Handle Scrollbar 287 | ------------------------------------------------ */ 288 | var handleScrollbar = function() { 289 | "use strict"; 290 | var elms = document.querySelectorAll('['+ app.scrollBar.attr +']'); 291 | 292 | for (var i = 0; i < elms.length; i++) { 293 | generateScrollbar(elms[i]) 294 | } 295 | }; 296 | var generateScrollbar = function(elm) { 297 | "use strict"; 298 | 299 | if (elm.scrollbarInit || (app.isMobile && elm.getAttribute(app.scrollBar.skipMobileAttr))) { 300 | return; 301 | } 302 | var dataHeight = (!elm.getAttribute(app.scrollBar.heightAttr)) ? elm.offsetHeight : elm.getAttribute(app.scrollBar.heightAttr); 303 | 304 | elm.style.height = dataHeight; 305 | elm.scrollbarInit = true; 306 | 307 | if(app.isMobile) { 308 | elm.style.overflowX = 'scroll'; 309 | } else { 310 | var dataWheelPropagation = (elm.getAttribute(app.scrollBar.wheelPropagationAttr)) ? elm.getAttribute(app.scrollBar.wheelPropagationAttr) : false; 311 | 312 | if (elm.closest('.'+ app.sidebar.class) && elm.closest('.'+ app.sidebar.class).length !== 0) { 313 | app.sidebar.scrollBar.dom = new PerfectScrollbar(elm, { 314 | wheelPropagation: dataWheelPropagation 315 | }); 316 | } else { 317 | new PerfectScrollbar(elm, { 318 | wheelPropagation: dataWheelPropagation 319 | }); 320 | } 321 | } 322 | elm.setAttribute(app.init.attr, true); 323 | elm.classList.remove('invisible'); 324 | }; 325 | 326 | 327 | 328 | /* 03. Handle Sidebar Menu 329 | ------------------------------------------------ */ 330 | var handleSidebarMenuToggle = function(menus) { 331 | menus.map(function(menu) { 332 | menu.onclick = function(e) { 333 | e.preventDefault(); 334 | var target = this.nextElementSibling; 335 | 336 | menus.map(function(m) { 337 | var otherTarget = m.nextElementSibling; 338 | if (otherTarget !== target) { 339 | otherTarget.style.display = 'none'; 340 | otherTarget.closest('.'+ app.sidebar.menu.itemClass).classList.remove(app.sidebar.menu.expandClass); 341 | } 342 | }); 343 | 344 | var targetItemElm = target.closest('.'+ app.sidebar.menu.itemClass); 345 | 346 | if (targetItemElm.classList.contains(app.sidebar.menu.expandClass) || (targetItemElm.classList.contains(app.sidebar.menu.activeClass) && !target.style.display)) { 347 | targetItemElm.classList.remove(app.sidebar.menu.expandClass); 348 | target.style.display = 'none'; 349 | } else { 350 | targetItemElm.classList.add(app.sidebar.menu.expandClass); 351 | target.style.display = 'block'; 352 | } 353 | } 354 | }); 355 | }; 356 | var handleSidebarMenu = function() { 357 | "use strict"; 358 | 359 | var menuBaseSelector = '.'+ app.sidebar.class +' .'+ app.sidebar.menu.class +' > .'+ app.sidebar.menu.itemClass +'.'+ app.sidebar.menu.hasSubClass; 360 | var submenuBaseSelector = ' > .'+ app.sidebar.menu.submenu.class +' > .'+ app.sidebar.menu.itemClass + '.' + app.sidebar.menu.hasSubClass; 361 | 362 | // menu 363 | var menuLinkSelector = menuBaseSelector + ' > .'+ app.sidebar.menu.itemLinkClass; 364 | var menus = [].slice.call(document.querySelectorAll(menuLinkSelector)); 365 | handleSidebarMenuToggle(menus); 366 | 367 | // submenu lvl 1 368 | var submenuLvl1Selector = menuBaseSelector + submenuBaseSelector; 369 | var submenusLvl1 = [].slice.call(document.querySelectorAll(submenuLvl1Selector + ' > .' + app.sidebar.menu.itemLinkClass)); 370 | handleSidebarMenuToggle(submenusLvl1); 371 | 372 | // submenu lvl 2 373 | var submenuLvl2Selector = menuBaseSelector + submenuBaseSelector + submenuBaseSelector; 374 | var submenusLvl2 = [].slice.call(document.querySelectorAll(submenuLvl2Selector + ' > .' + app.sidebar.menu.itemLinkClass)); 375 | handleSidebarMenuToggle(submenusLvl2); 376 | }; 377 | 378 | 379 | 380 | /* 04. Handle Sidebar Scroll Memory 381 | ------------------------------------------------ */ 382 | var handleSidebarScrollMemory = function() { 383 | if (!app.isMobile) { 384 | try { 385 | if (typeof(Storage) !== 'undefined' && typeof(localStorage) !== 'undefined') { 386 | var elm = document.querySelector('.'+ app.sidebar.class +' ['+ app.scrollBar.attr +']'); 387 | 388 | if (elm) { 389 | elm.onscroll = function() { 390 | localStorage.setItem(app.sidebar.scrollBar.localStorage, this.scrollTop); 391 | } 392 | var defaultScroll = localStorage.getItem(app.sidebar.scrollBar.localStorage); 393 | if (defaultScroll) { 394 | document.querySelector('.'+ app.sidebar.class +' ['+ app.scrollBar.attr +']').scrollTop = defaultScroll; 395 | } 396 | } 397 | } 398 | } catch (error) { 399 | console.log(error); 400 | } 401 | } 402 | }; 403 | 404 | 405 | 406 | /* 05. Handle Card Action 407 | ------------------------------------------------ */ 408 | var handleCardAction = function() { 409 | "use strict"; 410 | 411 | if (app.card.expand.status) { 412 | return false; 413 | } 414 | app.card.expand.status = true; 415 | 416 | // expand 417 | var expandTogglerList = [].slice.call(document.querySelectorAll('['+ app.card.expand.toggleAttr +']')); 418 | var expandTogglerTooltipList = expandTogglerList.map(function (expandTogglerEl) { 419 | expandTogglerEl.onclick = function(e) { 420 | e.preventDefault(); 421 | 422 | var target = this.closest('.card'); 423 | var targetClass = app.card.expand.class; 424 | var targetTop = 40; 425 | 426 | if (document.body.classList.contains(targetClass) && target.classList.contains(targetClass)) { 427 | target.removeAttribute('style'); 428 | target.classList.remove(targetClass); 429 | document.body.classList.remove(targetClass); 430 | } else { 431 | document.body.classList.add(targetClass); 432 | target.classList.add(targetClass); 433 | } 434 | 435 | window.dispatchEvent(new Event('resize')); 436 | }; 437 | 438 | return new bootstrap.Tooltip(expandTogglerEl, { 439 | title: app.card.expand.toggleTitle, 440 | placement: 'bottom', 441 | trigger: 'hover', 442 | container: 'body' 443 | }); 444 | }); 445 | }; 446 | 447 | 448 | 449 | /* 06. Handle Tooltip & Popover Activation 450 | ------------------------------------------------ */ 451 | var handelTooltipPopoverActivation = function() { 452 | "use strict"; 453 | 454 | var tooltipTriggerList = [].slice.call(document.querySelectorAll('['+ app.bootstrap.tooltip.attr +']')) 455 | var tooltipList = tooltipTriggerList.map(function (tooltipTriggerEl) { 456 | return new bootstrap.Tooltip(tooltipTriggerEl); 457 | }); 458 | 459 | var popoverTriggerList = [].slice.call(document.querySelectorAll('['+ app.bootstrap.popover.attr +']')) 460 | var popoverList = popoverTriggerList.map(function (popoverTriggerEl) { 461 | return new bootstrap.Popover(popoverTriggerEl); 462 | }); 463 | }; 464 | 465 | 466 | 467 | /* 07. Handle Scroll to Top Button 468 | ------------------------------------------------ */ 469 | var handleScrollToTopButton = function() { 470 | "use strict"; 471 | 472 | var elmTriggerList = [].slice.call(document.querySelectorAll('['+ app.scrollToTopBtn.toggleAttr +']')); 473 | 474 | document.onscroll = function() { 475 | var doc = document.documentElement; 476 | var totalScroll = (window.pageYOffset || doc.scrollTop) - (doc.clientTop || 0); 477 | var elmList = elmTriggerList.map(function(elm) { 478 | if (totalScroll >= app.scrollToTopBtn.heightShow) { 479 | if (!elm.classList.contains(app.scrollToTopBtn.showClass)) { 480 | elm.classList.add(app.scrollToTopBtn.showClass); 481 | } 482 | } else { 483 | elm.classList.remove(app.scrollToTopBtn.showClass); 484 | } 485 | }); 486 | 487 | var elm = document.querySelectorAll(app.id)[0]; 488 | 489 | if (totalScroll > 0) { 490 | elm.classList.add(app.header.hasScrollClass); 491 | } else { 492 | elm.classList.remove(app.header.hasScrollClass); 493 | } 494 | } 495 | 496 | var elmList = elmTriggerList.map(function(elm) { 497 | elm.onclick = function(e) { 498 | e.preventDefault(); 499 | 500 | window.scrollTo({top: 0, behavior: 'smooth'}); 501 | } 502 | }); 503 | }; 504 | 505 | 506 | 507 | /* 08. Handle hexToRgba 508 | ------------------------------------------------ */ 509 | var hexToRgba = function(hex, transparent = 1) { 510 | var c; 511 | if(/^#([A-Fa-f0-9]{3}){1,2}$/.test(hex)){ 512 | c= hex.substring(1).split(''); 513 | if(c.length== 3){ 514 | c= [c[0], c[0], c[1], c[1], c[2], c[2]]; 515 | } 516 | c= '0x'+c.join(''); 517 | return 'rgba('+[(c>>16)&255, (c>>8)&255, c&255].join(',')+','+ transparent +')'; 518 | } 519 | throw new Error('Bad Hex'); 520 | }; 521 | 522 | 523 | 524 | /* 09. Handle Scroll To 525 | ------------------------------------------------ */ 526 | var handleScrollTo = function() { 527 | var elmTriggerList = [].slice.call(document.querySelectorAll('['+ app.scrollTo.attr +']')); 528 | var elmList = elmTriggerList.map(function(elm) { 529 | elm.onclick = function(e) { 530 | e.preventDefault(); 531 | 532 | var targetAttr = (elm.getAttribute(app.scrollTo.target)) ? this.getAttribute(app.scrollTo.target) : this.getAttribute(app.scrollTo.linkTarget); 533 | var targetElm = document.querySelectorAll(targetAttr)[0]; 534 | var targetHeader = document.querySelectorAll(app.header.id)[0]; 535 | var targetHeight = targetHeader.offsetHeight; 536 | if (targetElm) { 537 | var targetTop = targetElm.offsetTop - targetHeight - 24; 538 | window.scrollTo({top: targetTop, behavior: 'smooth'}); 539 | } 540 | } 541 | }); 542 | }; 543 | 544 | 545 | 546 | /* 10. Handle Toggle Class 547 | ------------------------------------------------ */ 548 | var handleToggleClass = function() { 549 | var elmList = [].slice.call(document.querySelectorAll('['+ app.toggleClass.toggleAttr +']')); 550 | 551 | elmList.map(function(elm) { 552 | elm.onclick = function(e) { 553 | e.preventDefault(); 554 | 555 | var targetToggleClass = this.getAttribute(app.toggleClass.toggleAttr); 556 | var targetDismissClass = this.getAttribute(app.dismissClass.toggleAttr); 557 | var targetToggleElm = document.querySelector(this.getAttribute(app.toggleClass.targetAttr)); 558 | 559 | if (!targetDismissClass) { 560 | if (targetToggleElm.classList.contains(targetToggleClass)) { 561 | targetToggleElm.classList.remove(targetToggleClass); 562 | } else { 563 | targetToggleElm.classList.add(targetToggleClass); 564 | } 565 | } else { 566 | if (!targetToggleElm.classList.contains(targetToggleClass) && !targetToggleElm.classList.contains(targetDismissClass)) { 567 | if (targetToggleElm.classList.contains(targetToggleClass)) { 568 | targetToggleElm.classList.remove(targetToggleClass); 569 | } else { 570 | targetToggleElm.classList.add(targetToggleClass); 571 | } 572 | } else { 573 | if (targetToggleElm.classList.contains(targetToggleClass)) { 574 | targetToggleElm.classList.remove(targetToggleClass); 575 | } else { 576 | targetToggleElm.classList.add(targetToggleClass); 577 | } 578 | if (targetToggleElm.classList.contains(targetDismissClass)) { 579 | targetToggleElm.classList.remove(targetDismissClass); 580 | } else { 581 | targetToggleElm.classList.add(targetDismissClass); 582 | } 583 | } 584 | } 585 | } 586 | }); 587 | } 588 | 589 | 590 | 591 | /* 11. Handle Theme Panel 592 | ------------------------------------------------ */ 593 | var handleThemePanel = function() { 594 | "use strict"; 595 | 596 | // 12.1 Theme Panel - Toggle / Dismiss 597 | var elmList = [].slice.call(document.querySelectorAll('['+ app.themePanel.toggleAttr +']')); 598 | 599 | elmList.map(function(elm) { 600 | elm.onclick = function(e) { 601 | e.preventDefault(); 602 | 603 | var targetContainer = document.querySelector('.'+ app.themePanel.class); 604 | var targetExpand = false; 605 | 606 | if (targetContainer.classList.contains(app.themePanel.activeClass)) { 607 | targetContainer.classList.remove(app.themePanel.activeClass); 608 | } else { 609 | targetContainer.classList.add(app.themePanel.activeClass); 610 | targetExpand = true; 611 | } 612 | if (Cookies) { 613 | Cookies.set(app.themePanel.cookieName, targetExpand); 614 | } 615 | } 616 | }); 617 | 618 | // 12.2 Theme Panel - Page Load Cookies 619 | if (Cookies) { 620 | var themePanelExpand = Cookies.get(app.themePanel.cookieName); 621 | 622 | if (themePanelExpand == 'true' || typeof themePanelExpand == 'undefined') { 623 | var elm = document.querySelector('['+ app.themePanel.toggleAttr +']'); 624 | if (elm) { 625 | elm.click(); 626 | } 627 | } 628 | } 629 | 630 | 631 | // 12.3 Theme Panel - Theme Selector 632 | var elmList = [].slice.call(document.querySelectorAll('.'+ app.themePanel.class +' ['+ app.themePanel.theme.toggleAttr +']')); 633 | elmList.map(function(elm) { 634 | elm.onclick = function() { 635 | for (var x = 0; x < document.body.classList.length; x++) { 636 | var targetClass = document.body.classList[x]; 637 | if (targetClass.search('theme-') > -1) { 638 | document.body.classList.remove(targetClass); 639 | } 640 | } 641 | 642 | var targetTheme = this.getAttribute(app.themePanel.theme.classAttr); 643 | var targetThemeList = [].slice.call(document.querySelectorAll('.'+ app.themePanel.class +' ['+ app.themePanel.theme.toggleAttr +']')); 644 | 645 | if (targetTheme) { 646 | document.body.classList.add(targetTheme); 647 | } 648 | targetThemeList.map(function(targetElm) { 649 | if (targetElm.getAttribute(app.themePanel.theme.classAttr) != targetTheme) { 650 | targetElm.closest('.'+ app.themePanel.themeListItemCLass).classList.remove(app.themePanel.theme.activeClass); 651 | } 652 | }); 653 | 654 | this.closest('.'+ app.themePanel.themeListItemCLass).classList.add(app.themePanel.theme.activeClass); 655 | 656 | if (Cookies) { 657 | Cookies.set(app.themePanel.theme.cookieName, targetTheme); 658 | app.color.theme = (getComputedStyle(document.body).getPropertyValue('--bs-theme')).trim(); 659 | app.color.themeRgb = (getComputedStyle(document.body).getPropertyValue('--bs-theme-rgb')).trim(); 660 | 661 | document.dispatchEvent(new Event('theme-reload')); 662 | } 663 | } 664 | }); 665 | 666 | if (Cookies) { 667 | if (Cookies.get(app.themePanel.theme.cookieName)) { 668 | var targetElm = document.querySelector('.'+ app.themePanel.class +' ['+ app.themePanel.theme.toggleAttr +']' + '['+ app.themePanel.theme.classAttr +'="'+ Cookies.get(app.themePanel.theme.cookieName) +'"]'); 669 | 670 | if (targetElm) { 671 | targetElm.click(); 672 | 673 | app.color.theme = (getComputedStyle(document.body).getPropertyValue('--bs-theme')).trim(); 674 | app.color.themeRgb = (getComputedStyle(document.body).getPropertyValue('--bs-theme-rgb')).trim(); 675 | 676 | document.dispatchEvent(new Event('theme-reload')); 677 | } 678 | } 679 | } 680 | 681 | 682 | // 12.4 Theme Panel - Background Selector 683 | var elmList = [].slice.call(document.querySelectorAll('.'+ app.themePanel.class +' ['+ app.themePanel.themeCover.toggleAttr +']')); 684 | elmList.map(function(elm) { 685 | elm.onclick = function(e) { 686 | e.preventDefault(); 687 | 688 | var htmlElm = document.querySelector('html'); 689 | var targetTheme = this.getAttribute(app.themePanel.themeCover.classAttr); 690 | for (var x = 0; x < document.documentElement.classList.length; x++) { 691 | var targetClass = document.documentElement.classList[x]; 692 | if (targetClass.search('bg-cover-') > -1) { 693 | htmlElm.classList.remove(targetClass); 694 | } 695 | } 696 | 697 | if (targetTheme) { 698 | htmlElm.classList.add(targetTheme); 699 | } 700 | 701 | var targetCoverList = [].slice.call(document.querySelectorAll('.'+ app.themePanel.class +' ['+ app.themePanel.themeCover.toggleAttr +']')); 702 | targetCoverList.map(function(targetElm) { 703 | if (targetElm.getAttribute(app.themePanel.themeCover.toggleAttr) != targetTheme) { 704 | targetElm.closest('.'+ app.themePanel.themeCoverItemClass).classList.remove(app.themePanel.themeCover.activeClass); 705 | } 706 | }); 707 | 708 | this.closest('.'+ app.themePanel.themeCoverItemClass).classList.add(app.themePanel.themeCover.activeClass); 709 | if (Cookies) { 710 | Cookies.set(app.themePanel.themeCover.cookieName, targetTheme); 711 | } 712 | }; 713 | }); 714 | 715 | if (Cookies) { 716 | if (Cookies.get(app.themePanel.themeCover.cookieName)) { 717 | var targetElm = document.querySelector('.'+ app.themePanel.class +' ['+ app.themePanel.themeCover.toggleAttr +']' + '['+ app.themePanel.themeCover.classAttr +'="'+ Cookies.get(app.themePanel.themeCover.cookieName) +'"]'); 718 | if (targetElm) { 719 | targetElm.click(); 720 | } 721 | } 722 | } 723 | }; 724 | 725 | 726 | 727 | /* 12. Application Controller 728 | ------------------------------------------------ */ 729 | var App = function () { 730 | "use strict"; 731 | 732 | return { 733 | //main function 734 | init: function () { 735 | this.initComponent(); 736 | this.initSidebar(); 737 | this.initAppLoad(); 738 | }, 739 | initAppLoad: function() { 740 | document.querySelector('body').classList.add(app.init.class); 741 | }, 742 | initSidebar: function() { 743 | handleSidebarMenu(); 744 | handleSidebarScrollMemory(); 745 | }, 746 | initComponent: function() { 747 | handleScrollbar(); 748 | handleScrollToTopButton(); 749 | handleScrollTo(); 750 | handleCardAction(); 751 | handelTooltipPopoverActivation(); 752 | handleToggleClass(); 753 | handleThemePanel(); 754 | }, 755 | scrollTop: function() { 756 | window.scrollTo({top: 0, behavior: 'smooth'}); 757 | } 758 | }; 759 | }(); 760 | 761 | 762 | 763 | /* 13. Initialise 764 | ------------------------------------------------ */ 765 | document.addEventListener('DOMContentLoaded', function() { 766 | App.init(); 767 | }); 768 | //# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImFwcC5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwiZmlsZSI6ImFwcC5taW4uanMiLCJzb3VyY2VzQ29udGVudCI6WyIvKlxuVGVtcGxhdGUgTmFtZTogSFVEIC0gUmVzcG9uc2l2ZSBCb290c3RyYXAgNSBBZG1pbiBUZW1wbGF0ZVxuVmVyc2lvbjogMS45LjBcbkF1dGhvcjogU2VhbiBOZ3VcbldlYnNpdGU6IGh0dHA6Ly93d3cuc2VhbnRoZW1lLmNvbS9odWQvXG5cdC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblx0XHRBUFBTIENPTlRFTlQgVEFCTEVcblx0LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG5cdDwhLS0gPT09PT09PT0gR0xPQkFMIFNDUklQVCBTRVRUSU5HID09PT09PT09IC0tPlxuICAwMS4gR2xvYmFsIFZhcmlhYmxlXG4gIDAyLiBIYW5kbGUgU2Nyb2xsYmFyXG4gIDAzLiBIYW5kbGUgU2lkZWJhciBNZW51XG4gIDA0LiBIYW5kbGUgU2lkZWJhciBTY3JvbGwgTWVtb3J5XG4gIDA1LiBIYW5kbGUgQ2FyZCBBY3Rpb25cbiAgMDYuIEhhbmRsZSBUb29sdGlwICYgUG9wb3ZlciBBY3RpdmF0aW9uXG4gIDA3LiBIYW5kbGUgU2Nyb2xsIHRvIFRvcCBCdXR0b25cbiAgMDguIEhhbmRsZSBoZXhUb1JnYmFcbiAgMDkuIEhhbmRsZSBTY3JvbGwgVG9cbiAgMTAuIEhhbmRsZSBUb2dnbGUgQ2xhc3NcbiAgMTEuIEhhbmRsZSBUaGVtZSBQYW5lbFxuICAxMi4gQXBwbGljYXRpb24gQ29udHJvbGxlclxuICAxMy4gSW5pdGlhbGlzZVxuXHRcblx0PCEtLSA9PT09PT09PSBBUFBMSUNBVElPTiBTRVRUSU5HID09PT09PT09IC0tPlxuXHRBcHBsaWNhdGlvbiBDb250cm9sbGVyXG4qL1xuXG5cblxuLyogMDEuIEdsb2JhbCBWYXJpYWJsZVxuLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovXG52YXIgYXBwID0ge1xuXHRpZDogJyNhcHAnLFxuXHRpc01vYmlsZTogKCgvQW5kcm9pZHx3ZWJPU3xpUGhvbmV8aVBhZHxpUG9kfEJsYWNrQmVycnl8SUVNb2JpbGV8T3BlcmEgTWluaS9pLnRlc3QobmF2aWdhdG9yLnVzZXJBZ2VudCkpIHx8IHdpbmRvdy5pbm5lcldpZHRoIDwgOTkyKSxcblx0Ym9vdHN0cmFwOiB7XG5cdFx0dG9vbHRpcDoge1xuXHRcdFx0YXR0cjogJ2RhdGEtYnMtdG9nZ2xlPVwidG9vbHRpcFwiJ1xuXHRcdH0sXG5cdFx0cG9wb3Zlcjoge1xuXHRcdFx0YXR0cjogJ2RhdGEtYnMtdG9nZ2xlPVwicG9wb3ZlclwiJ1xuXHRcdH0sXG5cdFx0bW9kYWw6IHtcblx0XHRcdGF0dHI6ICdkYXRhLWJzLXRvZ2dsZT1cIm1vZGFsXCInLFxuXHRcdFx0ZGlzbWlzc0F0dHI6ICdkYXRhLWJzLWRpc21pc3M9XCJtb2RhbFwiJyxcblx0XHRcdGV2ZW50OiB7XG5cdFx0XHRcdGhpZGRlbjogJ2hpZGRlbi5icy5tb2RhbCdcblx0XHRcdH1cblx0XHR9LFxuXHRcdG5hdjoge1xuXHRcdFx0Y2xhc3M6ICduYXYnLFxuXHRcdFx0dGFiczoge1xuXHRcdFx0XHRjbGFzczogJ25hdi10YWJzJyxcblx0XHRcdFx0YWN0aXZlQ2xhc3M6ICdhY3RpdmUnLFxuXHRcdFx0XHRpdGVtQ2xhc3M6ICduYXYtaXRlbScsXG5cdFx0XHRcdGl0ZW1MaW5rQ2xhc3M6ICduYXYtbGluaydcblx0XHRcdH1cblx0XHR9XG5cdH0sXG5cdGhlYWRlcjoge1xuXHRcdGlkOiAnI2hlYWRlcicsXG5cdFx0Y2xhc3M6ICdhcHAtaGVhZGVyJyxcblx0XHRoYXNTY3JvbGxDbGFzczogJ2hhcy1zY3JvbGwnXG5cdH0sXG5cdHNpZGViYXI6IHtcblx0XHRpZDogJyNzaWRlYmFyJyxcblx0XHRjbGFzczogJ2FwcC1zaWRlYmFyJyxcblx0XHRzY3JvbGxCYXI6IHtcblx0XHRcdGxvY2FsU3RvcmFnZTogJ2FwcFNpZGViYXJTY3JvbGxQb3NpdGlvbicsXG5cdFx0XHRkb206ICcnXG5cdFx0fSxcblx0XHRtZW51OiB7XG5cdFx0XHRjbGFzczogJ21lbnUnLFxuXHRcdFx0aW5pdEF0dHI6ICdkYXRhLWluaXQnLFxuXHRcdFx0YW5pbWF0aW9uVGltZTogMCxcblx0XHRcdGl0ZW1DbGFzczogJ21lbnUtaXRlbScsXG5cdFx0XHRpdGVtTGlua0NsYXNzOiAnbWVudS1saW5rJyxcblx0XHRcdGhhc1N1YkNsYXNzOiAnaGFzLXN1YicsXG5cdFx0XHRhY3RpdmVDbGFzczogJ2FjdGl2ZScsXG5cdFx0XHRleHBhbmRpbmdDbGFzczogJ2V4cGFuZGluZycsXG5cdFx0XHRleHBhbmRDbGFzczogJ2V4cGFuZCcsXG5cdFx0XHRzdWJtZW51OiB7XG5cdFx0XHRcdGNsYXNzOiAnbWVudS1zdWJtZW51Jyxcblx0XHRcdH1cblx0XHR9LFxuXHRcdG1vYmlsZToge1xuXHRcdFx0dG9nZ2xlQXR0cjogJ2RhdGEtdG9nZ2xlPVwiYXBwLXNpZGViYXItbW9iaWxlXCInLFxuXHRcdFx0ZGlzbWlzc0F0dHI6ICdkYXRhLWRpc21pc3M9XCJhcHAtc2lkZWJhci1tb2JpbGVcIicsXG5cdFx0XHR0b2dnbGVkQ2xhc3M6ICdhcHAtc2lkZWJhci1tb2JpbGUtdG9nZ2xlZCcsXG5cdFx0XHRjbG9zZWRDbGFzczogJ2FwcC1zaWRlYmFyLW1vYmlsZS1jbG9zZWQnLFxuXHRcdFx0YmFja2Ryb3A6IHtcblx0XHRcdFx0Y2xhc3M6ICdhcHAtc2lkZWJhci1tb2JpbGUtYmFja2Ryb3AnXG5cdFx0XHR9XG5cdFx0fSxcblx0XHRtaW5pZnk6IHtcblx0XHRcdHRvZ2dsZUF0dHI6ICdkYXRhLXRvZ2dsZT1cImFwcC1zaWRlYmFyLW1pbmlmeVwiJyxcblx0XHRcdHRvZ2dsZWRDbGFzczogJ2FwcC1zaWRlYmFyLW1pbmlmaWVkJyxcblx0XHRcdGNvb2tpZU5hbWU6ICdhcHAtc2lkZWJhci1taW5pZmllZCdcblx0XHR9LFxuXHRcdGZsb2F0U3VibWVudToge1xuXHRcdFx0aWQ6ICcjYXBwLXNpZGViYXItZmxvYXQtc3VibWVudScsXG5cdFx0XHRkb206ICcnLFxuXHRcdFx0dGltZW91dDogJycsXG5cdFx0XHRjbGFzczogJ2FwcC1zaWRlYmFyLWZsb2F0LXN1Ym1lbnUnLFxuXHRcdFx0Y29udGFpbmVyOiB7XG5cdFx0XHRcdGNsYXNzOiAnYXBwLXNpZGViYXItZmxvYXQtc3VibWVudS1jb250YWluZXInXG5cdFx0XHR9LFxuXHRcdFx0YXJyb3c6IHtcblx0XHRcdFx0aWQ6ICcjYXBwLXNpZGViYXItZmxvYXQtc3VibWVudS1hcnJvdycsXG5cdFx0XHRcdGNsYXNzOiAnYXBwLXNpZGViYXItZmxvYXQtc3VibWVudS1hcnJvdydcblx0XHRcdH0sXG5cdFx0XHRsaW5lOiB7XG5cdFx0XHRcdGlkOiAnI2FwcC1zaWRlYmFyLWZsb2F0LXN1Ym1lbnUtbGluZScsXG5cdFx0XHRcdGNsYXNzOiAnYXBwLXNpZGViYXItZmxvYXQtc3VibWVudS1saW5lJ1xuXHRcdFx0fSxcblx0XHRcdG92ZXJmbG93OiB7XG5cdFx0XHRcdGNsYXNzOiAnb3ZlcmZsb3ctc2Nyb2xsIG1oLTEwMHZoJ1xuXHRcdFx0fVxuXHRcdH0sXG5cdFx0c2VhcmNoOiB7XG5cdFx0XHRjbGFzczogJ21lbnUtc2VhcmNoJyxcblx0XHRcdHRvZ2dsZUF0dHI6ICdkYXRhLXNpZGViYXItc2VhcmNoPVwidHJ1ZVwiJyxcblx0XHRcdGhpZGVDbGFzczogJ2Qtbm9uZScsXG5cdFx0XHRmb3VuZENsYXNzOiAnaGFzLXRleHQnXG5cdFx0fSxcblx0XHR0cmFuc3BhcmVudDoge1xuXHRcdFx0Y2xhc3M6ICdhcHAtc2lkZWJhci10cmFuc3BhcmVudCdcblx0XHR9XG5cdH0sXG5cdHNjcm9sbEJhcjoge1xuXHRcdGF0dHI6ICdkYXRhLXNjcm9sbGJhcj1cInRydWVcIicsXG5cdFx0c2tpcE1vYmlsZUF0dHI6ICdkYXRhLXNraXAtbW9iaWxlJyxcblx0XHRoZWlnaHRBdHRyOiAnZGF0YS1oZWlnaHQnLFxuXHRcdHdoZWVsUHJvcGFnYXRpb25BdHRyOiAnZGF0YS13aGVlbC1wcm9wYWdhdGlvbidcblx0fSxcblx0Y29udGVudDoge1xuXHRcdGlkOiAnI2NvbnRlbnQnLFxuXHRcdGNsYXNzOiAnYXBwLWNvbnRlbnQnLFxuXHRcdGZ1bGxIZWlnaHQ6IHtcblx0XHRcdGNsYXNzOiAnYXBwLWNvbnRlbnQtZnVsbC1oZWlnaHQnXG5cdFx0fSxcblx0XHRmdWxsV2lkdGg6IHtcblx0XHRcdGNsYXNzOiAnYXBwLWNvbnRlbnQtZnVsbC13aWR0aCdcblx0XHR9XG5cdH0sXG5cdGxheW91dDoge1xuXHRcdHNpZGViYXJMaWdodDoge1xuXHRcdFx0Y2xhc3M6ICdhcHAtd2l0aC1saWdodC1zaWRlYmFyJ1xuXHRcdH0sXG5cdFx0c2lkZWJhckVuZDoge1xuXHRcdFx0Y2xhc3M6ICdhcHAtd2l0aC1lbmQtc2lkZWJhcidcblx0XHR9LFxuXHRcdHNpZGViYXJXaWRlOiB7XG5cdFx0XHRjbGFzczogJ2FwcC13aXRoLXdpZGUtc2lkZWJhcidcblx0XHR9LFxuXHRcdHNpZGViYXJNaW5pZmllZDoge1xuXHRcdFx0Y2xhc3M6ICdhcHAtc2lkZWJhci1taW5pZmllZCdcblx0XHR9LFxuXHRcdHNpZGViYXJUd286IHtcblx0XHRcdGNsYXNzOiAnYXBwLXdpdGgtdHdvLXNpZGViYXInXG5cdFx0fSxcblx0XHR3aXRob3V0SGVhZGVyOiB7XG5cdFx0XHRjbGFzczogJ2FwcC13aXRob3V0LWhlYWRlcidcblx0XHR9LFxuXHRcdHdpdGhvdXRTaWRlYmFyOiB7XG5cdFx0XHRjbGFzczogJ2FwcC13aXRob3V0LXNpZGViYXInXG5cdFx0fSxcblx0XHR0b3BNZW51OiB7XG5cdFx0XHRjbGFzczogJ2FwcC13aXRoLXRvcC1tZW51J1xuXHRcdH0sXG5cdFx0Ym94ZWRMYXlvdXQ6IHtcblx0XHRcdGNsYXNzOiAnYm94ZWQtbGF5b3V0J1xuXHRcdH1cblx0fSxcblx0c2Nyb2xsVG9Ub3BCdG46IHtcblx0XHRzaG93Q2xhc3M6ICdzaG93Jyxcblx0XHRoZWlnaHRTaG93OiAyMDAsXG5cdFx0dG9nZ2xlQXR0cjogJ2RhdGEtdG9nZ2xlPVwic2Nyb2xsLXRvLXRvcFwiJyxcblx0XHRzY3JvbGxTcGVlZDogNTAwXG5cdH0sXG5cdHNjcm9sbFRvOiB7XG5cdFx0YXR0cjogJ2RhdGEtdG9nZ2xlPVwic2Nyb2xsLXRvXCInLFxuXHRcdHRhcmdldDogJ2RhdGEtdGFyZ2V0Jyxcblx0XHRsaW5rVGFyZ2V0OiAnaHJlZidcblx0fSxcblx0dGhlbWVQYW5lbDoge1xuXHRcdGNsYXNzOiAnYXBwLXRoZW1lLXBhbmVsJyxcblx0XHR0b2dnbGVBdHRyOiAnZGF0YS10b2dnbGU9XCJ0aGVtZS1wYW5lbC1leHBhbmRcIicsXG5cdFx0Y29va2llTmFtZTogJ2FwcC10aGVtZS1wYW5lbC1leHBhbmQnLFxuXHRcdGFjdGl2ZUNsYXNzOiAnYWN0aXZlJyxcblx0XHR0aGVtZUxpc3RDTGFzczogJ2FwcC10aGVtZS1saXN0Jyxcblx0XHR0aGVtZUxpc3RJdGVtQ0xhc3M6ICdhcHAtdGhlbWUtbGlzdC1pdGVtJyxcblx0XHR0aGVtZUNvdmVyQ2xhc3M6ICdhcHAtdGhlbWUtY292ZXInLFxuXHRcdHRoZW1lQ292ZXJJdGVtQ2xhc3M6ICdhcHAtdGhlbWUtY292ZXItaXRlbScsXG5cdFx0dGhlbWU6IHtcblx0XHRcdHRvZ2dsZUF0dHI6ICdkYXRhLXRvZ2dsZT1cInRoZW1lLXNlbGVjdG9yXCInLFxuXHRcdFx0Y2xhc3NBdHRyOiAnZGF0YS10aGVtZS1jbGFzcycsXG5cdFx0XHRjb29raWVOYW1lOiAnYXBwLXRoZW1lJyxcblx0XHRcdGFjdGl2ZUNsYXNzOiAnYWN0aXZlJ1xuXHRcdH0sXG5cdFx0dGhlbWVDb3Zlcjoge1xuXHRcdFx0dG9nZ2xlQXR0cjogJ2RhdGEtdG9nZ2xlPVwidGhlbWUtY292ZXItc2VsZWN0b3JcIicsXG5cdFx0XHRjbGFzc0F0dHI6ICdkYXRhLXRoZW1lLWNvdmVyLWNsYXNzJyxcblx0XHRcdGNvb2tpZU5hbWU6ICdhcHAtdGhlbWUtY292ZXInLFxuXHRcdFx0YWN0aXZlQ2xhc3M6ICdhY3RpdmUnXG5cdFx0fVxuXHR9LFxuXHRkaXNtaXNzQ2xhc3M6IHtcblx0XHR0b2dnbGVBdHRyOiAnZGF0YS1kaXNtaXNzLWNsYXNzJyxcblx0XHR0YXJnZXRBdHRyOiAnZGF0YS1kaXNtaXNzLXRhcmdldCdcblx0fSxcblx0dG9nZ2xlQ2xhc3M6IHtcblx0XHR0b2dnbGVBdHRyOiAnZGF0YS10b2dnbGUtY2xhc3MnLFxuXHRcdHRhcmdldEF0dHI6ICdkYXRhLXRvZ2dsZS10YXJnZXQnXG5cdH0sXG5cdGZvbnQ6IHtcblx0XHRmYW1pbHk6IChnZXRDb21wdXRlZFN0eWxlKGRvY3VtZW50LmJvZHkpLmdldFByb3BlcnR5VmFsdWUoJy0tYnMtYm9keS1mb250LWZhbWlseScpKS50cmltKCksXG5cdFx0c2l6ZTogKGdldENvbXB1dGVkU3R5bGUoZG9jdW1lbnQuYm9keSkuZ2V0UHJvcGVydHlWYWx1ZSgnLS1icy1ib2R5LWZvbnQtc2l6ZScpKS50cmltKCksXG5cdFx0d2VpZ2h0OiAoZ2V0Q29tcHV0ZWRTdHlsZShkb2N1bWVudC5ib2R5KS5nZXRQcm9wZXJ0eVZhbHVlKCctLWJzLWJvZHktZm9udC13ZWlnaHQnKSkudHJpbSgpXG5cdH0sXG5cdGNvbG9yOiB7XG5cdFx0dGhlbWU6IChnZXRDb21wdXRlZFN0eWxlKGRvY3VtZW50LmJvZHkpLmdldFByb3BlcnR5VmFsdWUoJy0tYnMtdGhlbWUnKSkudHJpbSgpLFxuXHRcdGJsdWU6IChnZXRDb21wdXRlZFN0eWxlKGRvY3VtZW50LmJvZHkpLmdldFByb3BlcnR5VmFsdWUoJy0tYnMtYmx1ZScpKS50cmltKCksXG5cdFx0Z3JlZW46IChnZXRDb21wdXRlZFN0eWxlKGRvY3VtZW50LmJvZHkpLmdldFByb3BlcnR5VmFsdWUoJy0tYnMtZ3JlZW4nKSkudHJpbSgpLFxuXHRcdG9yYW5nZTogKGdldENvbXB1dGVkU3R5bGUoZG9jdW1lbnQuYm9keSkuZ2V0UHJvcGVydHlWYWx1ZSgnLS1icy1vcmFuZ2UnKSkudHJpbSgpLFxuXHRcdHJlZDogKGdldENvbXB1dGVkU3R5bGUoZG9jdW1lbnQuYm9keSkuZ2V0UHJvcGVydHlWYWx1ZSgnLS1icy1yZWQnKSkudHJpbSgpLFxuXHRcdGN5YW46IChnZXRDb21wdXRlZFN0eWxlKGRvY3VtZW50LmJvZHkpLmdldFByb3BlcnR5VmFsdWUoJy0tYnMtY3lhbicpKS50cmltKCksXG5cdFx0cHVycGxlOiAoZ2V0Q29tcHV0ZWRTdHlsZShkb2N1bWVudC5ib2R5KS5nZXRQcm9wZXJ0eVZhbHVlKCctLWJzLXB1cnBsZScpKS50cmltKCksXG5cdFx0eWVsbG93OiAoZ2V0Q29tcHV0ZWRTdHlsZShkb2N1bWVudC5ib2R5KS5nZXRQcm9wZXJ0eVZhbHVlKCctLWJzLXllbGxvdycpKS50cmltKCksXG5cdFx0aW5kaWdvOiAoZ2V0Q29tcHV0ZWRTdHlsZShkb2N1bWVudC5ib2R5KS5nZXRQcm9wZXJ0eVZhbHVlKCctLWJzLWluZGlnbycpKS50cmltKCksXG5cdFx0cGluazogKGdldENvbXB1dGVkU3R5bGUoZG9jdW1lbnQuYm9keSkuZ2V0UHJvcGVydHlWYWx1ZSgnLS1icy1waW5rJykpLnRyaW0oKSxcblx0XHRibGFjazogKGdldENvbXB1dGVkU3R5bGUoZG9jdW1lbnQuYm9keSkuZ2V0UHJvcGVydHlWYWx1ZSgnLS1icy1ibGFjaycpKS50cmltKCksXG5cdFx0d2hpdGU6IChnZXRDb21wdXRlZFN0eWxlKGRvY3VtZW50LmJvZHkpLmdldFByb3BlcnR5VmFsdWUoJy0tYnMtd2hpdGUnKSkudHJpbSgpLFxuXHRcdGdyYXk6IChnZXRDb21wdXRlZFN0eWxlKGRvY3VtZW50LmJvZHkpLmdldFByb3BlcnR5VmFsdWUoJy0tYnMtZ3JheScpKS50cmltKCksXG5cdFx0ZGFyazogKGdldENvbXB1dGVkU3R5bGUoZG9jdW1lbnQuYm9keSkuZ2V0UHJvcGVydHlWYWx1ZSgnLS1icy1kYXJrJykpLnRyaW0oKSxcblx0XHRncmF5MTAwOiAoZ2V0Q29tcHV0ZWRTdHlsZShkb2N1bWVudC5ib2R5KS5nZXRQcm9wZXJ0eVZhbHVlKCctLWJzLWdyYXktMTAwJykpLnRyaW0oKSxcblx0XHRncmF5MjAwOiAoZ2V0Q29tcHV0ZWRTdHlsZShkb2N1bWVudC5ib2R5KS5nZXRQcm9wZXJ0eVZhbHVlKCctLWJzLWdyYXktMjAwJykpLnRyaW0oKSxcblx0XHRncmF5MzAwOiAoZ2V0Q29tcHV0ZWRTdHlsZShkb2N1bWVudC5ib2R5KS5nZXRQcm9wZXJ0eVZhbHVlKCctLWJzLWdyYXktMzAwJykpLnRyaW0oKSxcblx0XHRncmF5NDAwOiAoZ2V0Q29tcHV0ZWRTdHlsZShkb2N1bWVudC5ib2R5KS5nZXRQcm9wZXJ0eVZhbHVlKCctLWJzLWdyYXktNDAwJykpLnRyaW0oKSxcblx0XHRncmF5NTAwOiAoZ2V0Q29tcHV0ZWRTdHlsZShkb2N1bWVudC5ib2R5KS5nZXRQcm9wZXJ0eVZhbHVlKCctLWJzLWdyYXktNTAwJykpLnRyaW0oKSxcblx0XHRncmF5NjAwOiAoZ2V0Q29tcHV0ZWRTdHlsZShkb2N1bWVudC5ib2R5KS5nZXRQcm9wZXJ0eVZhbHVlKCctLWJzLWdyYXktNjAwJykpLnRyaW0oKSxcblx0XHRncmF5NzAwOiAoZ2V0Q29tcHV0ZWRTdHlsZShkb2N1bWVudC5ib2R5KS5nZXRQcm9wZXJ0eVZhbHVlKCctLWJzLWdyYXktNzAwJykpLnRyaW0oKSxcblx0XHRncmF5ODAwOiAoZ2V0Q29tcHV0ZWRTdHlsZShkb2N1bWVudC5ib2R5KS5nZXRQcm9wZXJ0eVZhbHVlKCctLWJzLWdyYXktODAwJykpLnRyaW0oKSxcblx0XHRncmF5OTAwOiAoZ2V0Q29tcHV0ZWRTdHlsZShkb2N1bWVudC5ib2R5KS5nZXRQcm9wZXJ0eVZhbHVlKCctLWJzLWdyYXktOTAwJykpLnRyaW0oKSxcblx0XHRcblx0XHR0aGVtZVJnYjogKGdldENvbXB1dGVkU3R5bGUoZG9jdW1lbnQuYm9keSkuZ2V0UHJvcGVydHlWYWx1ZSgnLS1icy10aGVtZS1yZ2InKSkudHJpbSgpLFxuXHRcdGJsdWVSZ2I6IChnZXRDb21wdXRlZFN0eWxlKGRvY3VtZW50LmJvZHkpLmdldFByb3BlcnR5VmFsdWUoJy0tYnMtYmx1ZS1yZ2InKSkudHJpbSgpLFxuXHRcdGdyZWVuUmdiOiAoZ2V0Q29tcHV0ZWRTdHlsZShkb2N1bWVudC5ib2R5KS5nZXRQcm9wZXJ0eVZhbHVlKCctLWJzLWdyZWVuLXJnYicpKS50cmltKCksXG5cdFx0b3JhbmdlUmdiOiAoZ2V0Q29tcHV0ZWRTdHlsZShkb2N1bWVudC5ib2R5KS5nZXRQcm9wZXJ0eVZhbHVlKCctLWJzLW9yYW5nZS1yZ2InKSkudHJpbSgpLFxuXHRcdHJlZFJnYjogKGdldENvbXB1dGVkU3R5bGUoZG9jdW1lbnQuYm9keSkuZ2V0UHJvcGVydHlWYWx1ZSgnLS1icy1yZWQtcmdiJykpLnRyaW0oKSxcblx0XHRjeWFuUmdiOiAoZ2V0Q29tcHV0ZWRTdHlsZShkb2N1bWVudC5ib2R5KS5nZXRQcm9wZXJ0eVZhbHVlKCctLWJzLWN5YW4tcmdiJykpLnRyaW0oKSxcblx0XHRwdXJwbGVSZ2I6IChnZXRDb21wdXRlZFN0eWxlKGRvY3VtZW50LmJvZHkpLmdldFByb3BlcnR5VmFsdWUoJy0tYnMtcHVycGxlLXJnYicpKS50cmltKCksXG5cdFx0eWVsbG93UmdiOiAoZ2V0Q29tcHV0ZWRTdHlsZShkb2N1bWVudC5ib2R5KS5nZXRQcm9wZXJ0eVZhbHVlKCctLWJzLXllbGxvdy1yZ2InKSkudHJpbSgpLFxuXHRcdGluZGlnb1JnYjogKGdldENvbXB1dGVkU3R5bGUoZG9jdW1lbnQuYm9keSkuZ2V0UHJvcGVydHlWYWx1ZSgnLS1icy1pbmRpZ28tcmdiJykpLnRyaW0oKSxcblx0XHRwaW5rUmdiOiAoZ2V0Q29tcHV0ZWRTdHlsZShkb2N1bWVudC5ib2R5KS5nZXRQcm9wZXJ0eVZhbHVlKCctLWJzLXBpbmstcmdiJykpLnRyaW0oKSxcblx0XHRibGFja1JnYjogKGdldENvbXB1dGVkU3R5bGUoZG9jdW1lbnQuYm9keSkuZ2V0UHJvcGVydHlWYWx1ZSgnLS1icy1ibGFjay1yZ2InKSkudHJpbSgpLFxuXHRcdHdoaXRlUmdiOiAoZ2V0Q29tcHV0ZWRTdHlsZShkb2N1bWVudC5ib2R5KS5nZXRQcm9wZXJ0eVZhbHVlKCctLWJzLXdoaXRlLXJnYicpKS50cmltKCksXG5cdFx0Z3JheVJnYjogKGdldENvbXB1dGVkU3R5bGUoZG9jdW1lbnQuYm9keSkuZ2V0UHJvcGVydHlWYWx1ZSgnLS1icy1ncmF5LXJnYicpKS50cmltKCksXG5cdFx0ZGFya1JnYjogKGdldENvbXB1dGVkU3R5bGUoZG9jdW1lbnQuYm9keSkuZ2V0UHJvcGVydHlWYWx1ZSgnLS1icy1kYXJrLXJnYicpKS50cmltKCksXG5cdFx0Z3JheTEwMFJnYjogKGdldENvbXB1dGVkU3R5bGUoZG9jdW1lbnQuYm9keSkuZ2V0UHJvcGVydHlWYWx1ZSgnLS1icy1ncmF5LTEwMC1yZ2InKSkudHJpbSgpLFxuXHRcdGdyYXkyMDBSZ2I6IChnZXRDb21wdXRlZFN0eWxlKGRvY3VtZW50LmJvZHkpLmdldFByb3BlcnR5VmFsdWUoJy0tYnMtZ3JheS0yMDAtcmdiJykpLnRyaW0oKSxcblx0XHRncmF5MzAwUmdiOiAoZ2V0Q29tcHV0ZWRTdHlsZShkb2N1bWVudC5ib2R5KS5nZXRQcm9wZXJ0eVZhbHVlKCctLWJzLWdyYXktMzAwLXJnYicpKS50cmltKCksXG5cdFx0Z3JheTQwMFJnYjogKGdldENvbXB1dGVkU3R5bGUoZG9jdW1lbnQuYm9keSkuZ2V0UHJvcGVydHlWYWx1ZSgnLS1icy1ncmF5LTQwMC1yZ2InKSkudHJpbSgpLFxuXHRcdGdyYXk1MDBSZ2I6IChnZXRDb21wdXRlZFN0eWxlKGRvY3VtZW50LmJvZHkpLmdldFByb3BlcnR5VmFsdWUoJy0tYnMtZ3JheS01MDAtcmdiJykpLnRyaW0oKSxcblx0XHRncmF5NjAwUmdiOiAoZ2V0Q29tcHV0ZWRTdHlsZShkb2N1bWVudC5ib2R5KS5nZXRQcm9wZXJ0eVZhbHVlKCctLWJzLWdyYXktNjAwLXJnYicpKS50cmltKCksXG5cdFx0Z3JheTcwMFJnYjogKGdldENvbXB1dGVkU3R5bGUoZG9jdW1lbnQuYm9keSkuZ2V0UHJvcGVydHlWYWx1ZSgnLS1icy1ncmF5LTcwMC1yZ2InKSkudHJpbSgpLFxuXHRcdGdyYXk4MDBSZ2I6IChnZXRDb21wdXRlZFN0eWxlKGRvY3VtZW50LmJvZHkpLmdldFByb3BlcnR5VmFsdWUoJy0tYnMtZ3JheS04MDAtcmdiJykpLnRyaW0oKSxcblx0XHRncmF5OTAwUmdiOiAoZ2V0Q29tcHV0ZWRTdHlsZShkb2N1bWVudC5ib2R5KS5nZXRQcm9wZXJ0eVZhbHVlKCctLWJzLWdyYXktOTAwLXJnYicpKS50cmltKClcblx0fSxcblx0Y2FyZDoge1xuXHRcdGV4cGFuZDoge1xuXHRcdFx0c3RhdHVzOiBmYWxzZSxcblx0XHRcdHRvZ2dsZUF0dHI6ICdkYXRhLXRvZ2dsZT1cImNhcmQtZXhwYW5kXCInLFxuXHRcdFx0dG9nZ2xlVGl0bGU6ICdFeHBhbmQgLyBDb21wcmVzcycsXG5cdFx0XHRjbGFzczogJ2NhcmQtZXhwYW5kJ1xuXHRcdH1cblx0fSxcblx0aW5pdDoge1xuXHRcdGF0dHI6ICdkYXRhLWluaXQnLFxuXHRcdGNsYXNzOiAnYXBwLWluaXQnXG5cdH1cbn07XG5cblxuXG4vKiAwMi4gSGFuZGxlIFNjcm9sbGJhclxuLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovXG52YXIgaGFuZGxlU2Nyb2xsYmFyID0gZnVuY3Rpb24oKSB7XG5cdFwidXNlIHN0cmljdFwiO1xuXHR2YXIgZWxtcyA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJ1snKyBhcHAuc2Nyb2xsQmFyLmF0dHIgKyddJyk7XG5cdFx0XG5cdGZvciAodmFyIGkgPSAwOyBpIDwgZWxtcy5sZW5ndGg7IGkrKykge1xuXHRcdGdlbmVyYXRlU2Nyb2xsYmFyKGVsbXNbaV0pXG5cdH1cbn07XG52YXIgZ2VuZXJhdGVTY3JvbGxiYXIgPSBmdW5jdGlvbihlbG0pIHtcbiAgXCJ1c2Ugc3RyaWN0XCI7XG5cdFxuXHRpZiAoZWxtLnNjcm9sbGJhckluaXQgfHwgKGFwcC5pc01vYmlsZSAmJiBlbG0uZ2V0QXR0cmlidXRlKGFwcC5zY3JvbGxCYXIuc2tpcE1vYmlsZUF0dHIpKSkge1xuXHRcdHJldHVybjtcblx0fVxuXHR2YXIgZGF0YUhlaWdodCA9ICghZWxtLmdldEF0dHJpYnV0ZShhcHAuc2Nyb2xsQmFyLmhlaWdodEF0dHIpKSA/IGVsbS5vZmZzZXRIZWlnaHQgOiBlbG0uZ2V0QXR0cmlidXRlKGFwcC5zY3JvbGxCYXIuaGVpZ2h0QXR0cik7XG5cdFxuXHRlbG0uc3R5bGUuaGVpZ2h0ID0gZGF0YUhlaWdodDtcblx0ZWxtLnNjcm9sbGJhckluaXQgPSB0cnVlO1xuXHRcblx0aWYoYXBwLmlzTW9iaWxlKSB7XG5cdFx0ZWxtLnN0eWxlLm92ZXJmbG93WCA9ICdzY3JvbGwnO1xuXHR9IGVsc2Uge1xuXHRcdHZhciBkYXRhV2hlZWxQcm9wYWdhdGlvbiA9IChlbG0uZ2V0QXR0cmlidXRlKGFwcC5zY3JvbGxCYXIud2hlZWxQcm9wYWdhdGlvbkF0dHIpKSA/IGVsbS5nZXRBdHRyaWJ1dGUoYXBwLnNjcm9sbEJhci53aGVlbFByb3BhZ2F0aW9uQXR0cikgOiBmYWxzZTtcblx0XHRcblx0XHRpZiAoZWxtLmNsb3Nlc3QoJy4nKyBhcHAuc2lkZWJhci5jbGFzcykgJiYgZWxtLmNsb3Nlc3QoJy4nKyBhcHAuc2lkZWJhci5jbGFzcykubGVuZ3RoICE9PSAwKSB7XG5cdFx0XHRhcHAuc2lkZWJhci5zY3JvbGxCYXIuZG9tID0gbmV3IFBlcmZlY3RTY3JvbGxiYXIoZWxtLCB7XG5cdFx0XHRcdHdoZWVsUHJvcGFnYXRpb246IGRhdGFXaGVlbFByb3BhZ2F0aW9uXG5cdFx0XHR9KTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0bmV3IFBlcmZlY3RTY3JvbGxiYXIoZWxtLCB7XG5cdFx0XHRcdHdoZWVsUHJvcGFnYXRpb246IGRhdGFXaGVlbFByb3BhZ2F0aW9uXG5cdFx0XHR9KTtcblx0XHR9XG5cdH1cblx0ZWxtLnNldEF0dHJpYnV0ZShhcHAuaW5pdC5hdHRyLCB0cnVlKTtcblx0ZWxtLmNsYXNzTGlzdC5yZW1vdmUoJ2ludmlzaWJsZScpO1xufTtcblxuXG5cbi8qIDAzLiBIYW5kbGUgU2lkZWJhciBNZW51XG4tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi9cbnZhciBoYW5kbGVTaWRlYmFyTWVudVRvZ2dsZSA9IGZ1bmN0aW9uKG1lbnVzKSB7XG5cdG1lbnVzLm1hcChmdW5jdGlvbihtZW51KSB7XG5cdFx0bWVudS5vbmNsaWNrID0gZnVuY3Rpb24oZSkge1xuXHRcdFx0ZS5wcmV2ZW50RGVmYXVsdCgpO1xuXHRcdFx0dmFyIHRhcmdldCA9IHRoaXMubmV4dEVsZW1lbnRTaWJsaW5nO1xuXHRcblx0XHRcdG1lbnVzLm1hcChmdW5jdGlvbihtKSB7XG5cdFx0XHRcdHZhciBvdGhlclRhcmdldCA9IG0ubmV4dEVsZW1lbnRTaWJsaW5nO1xuXHRcdFx0XHRpZiAob3RoZXJUYXJnZXQgIT09IHRhcmdldCkge1xuXHRcdFx0XHRcdG90aGVyVGFyZ2V0LnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG5cdFx0XHRcdFx0b3RoZXJUYXJnZXQuY2xvc2VzdCgnLicrIGFwcC5zaWRlYmFyLm1lbnUuaXRlbUNsYXNzKS5jbGFzc0xpc3QucmVtb3ZlKGFwcC5zaWRlYmFyLm1lbnUuZXhwYW5kQ2xhc3MpO1xuXHRcdFx0XHR9XG5cdFx0XHR9KTtcblx0XG5cdFx0XHR2YXIgdGFyZ2V0SXRlbUVsbSA9IHRhcmdldC5jbG9zZXN0KCcuJysgYXBwLnNpZGViYXIubWVudS5pdGVtQ2xhc3MpO1xuXG5cdFx0XHRpZiAodGFyZ2V0SXRlbUVsbS5jbGFzc0xpc3QuY29udGFpbnMoYXBwLnNpZGViYXIubWVudS5leHBhbmRDbGFzcykgfHwgKHRhcmdldEl0ZW1FbG0uY2xhc3NMaXN0LmNvbnRhaW5zKGFwcC5zaWRlYmFyLm1lbnUuYWN0aXZlQ2xhc3MpICYmICF0YXJnZXQuc3R5bGUuZGlzcGxheSkpIHtcblx0XHRcdFx0dGFyZ2V0SXRlbUVsbS5jbGFzc0xpc3QucmVtb3ZlKGFwcC5zaWRlYmFyLm1lbnUuZXhwYW5kQ2xhc3MpO1xuXHRcdFx0XHR0YXJnZXQuc3R5bGUuZGlzcGxheSA9ICdub25lJztcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdHRhcmdldEl0ZW1FbG0uY2xhc3NMaXN0LmFkZChhcHAuc2lkZWJhci5tZW51LmV4cGFuZENsYXNzKTtcblx0XHRcdFx0dGFyZ2V0LnN0eWxlLmRpc3BsYXkgPSAnYmxvY2snO1xuXHRcdFx0fVxuXHRcdH1cblx0fSk7XG59O1xudmFyIGhhbmRsZVNpZGViYXJNZW51ID0gZnVuY3Rpb24oKSB7XG5cdFwidXNlIHN0cmljdFwiO1xuXHRcblx0dmFyIG1lbnVCYXNlU2VsZWN0b3IgPSAnLicrIGFwcC5zaWRlYmFyLmNsYXNzICsnIC4nKyBhcHAuc2lkZWJhci5tZW51LmNsYXNzICsnID4gLicrIGFwcC5zaWRlYmFyLm1lbnUuaXRlbUNsYXNzICsnLicrIGFwcC5zaWRlYmFyLm1lbnUuaGFzU3ViQ2xhc3M7XG5cdHZhciBzdWJtZW51QmFzZVNlbGVjdG9yID0gJyA+IC4nKyBhcHAuc2lkZWJhci5tZW51LnN1Ym1lbnUuY2xhc3MgKycgPiAuJysgYXBwLnNpZGViYXIubWVudS5pdGVtQ2xhc3MgKyAnLicgKyBhcHAuc2lkZWJhci5tZW51Lmhhc1N1YkNsYXNzO1xuXHRcblx0Ly8gbWVudVxuXHR2YXIgbWVudUxpbmtTZWxlY3RvciA9ICBtZW51QmFzZVNlbGVjdG9yICsgJyA+IC4nKyBhcHAuc2lkZWJhci5tZW51Lml0ZW1MaW5rQ2xhc3M7XG5cdHZhciBtZW51cyA9IFtdLnNsaWNlLmNhbGwoZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbChtZW51TGlua1NlbGVjdG9yKSk7XG5cdGhhbmRsZVNpZGViYXJNZW51VG9nZ2xlKG1lbnVzKTtcblx0XG5cdC8vIHN1Ym1lbnUgbHZsIDFcblx0dmFyIHN1Ym1lbnVMdmwxU2VsZWN0b3IgPSBtZW51QmFzZVNlbGVjdG9yICsgc3VibWVudUJhc2VTZWxlY3Rvcjtcblx0dmFyIHN1Ym1lbnVzTHZsMSA9IFtdLnNsaWNlLmNhbGwoZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbChzdWJtZW51THZsMVNlbGVjdG9yICsgJyA+IC4nICsgYXBwLnNpZGViYXIubWVudS5pdGVtTGlua0NsYXNzKSk7XG5cdGhhbmRsZVNpZGViYXJNZW51VG9nZ2xlKHN1Ym1lbnVzTHZsMSk7XG5cdFxuXHQvLyBzdWJtZW51IGx2bCAyXG5cdHZhciBzdWJtZW51THZsMlNlbGVjdG9yID0gbWVudUJhc2VTZWxlY3RvciArIHN1Ym1lbnVCYXNlU2VsZWN0b3IgKyBzdWJtZW51QmFzZVNlbGVjdG9yO1xuXHR2YXIgc3VibWVudXNMdmwyID0gW10uc2xpY2UuY2FsbChkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKHN1Ym1lbnVMdmwyU2VsZWN0b3IgKyAnID4gLicgKyBhcHAuc2lkZWJhci5tZW51Lml0ZW1MaW5rQ2xhc3MpKTtcblx0aGFuZGxlU2lkZWJhck1lbnVUb2dnbGUoc3VibWVudXNMdmwyKTtcbn07XG5cblxuXG4vKiAwNC4gSGFuZGxlIFNpZGViYXIgU2Nyb2xsIE1lbW9yeVxuLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovXG52YXIgaGFuZGxlU2lkZWJhclNjcm9sbE1lbW9yeSA9IGZ1bmN0aW9uKCkge1xuXHRpZiAoIWFwcC5pc01vYmlsZSkge1xuXHRcdHRyeSB7XG5cdFx0XHRpZiAodHlwZW9mKFN0b3JhZ2UpICE9PSAndW5kZWZpbmVkJyAmJiB0eXBlb2YobG9jYWxTdG9yYWdlKSAhPT0gJ3VuZGVmaW5lZCcpIHtcblx0XHRcdFx0dmFyIGVsbSA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy4nKyBhcHAuc2lkZWJhci5jbGFzcyArJyBbJysgYXBwLnNjcm9sbEJhci5hdHRyICsnXScpO1xuXHRcdFx0XHRcblx0XHRcdFx0aWYgKGVsbSkge1xuXHRcdFx0XHRcdGVsbS5vbnNjcm9sbCA9IGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRcdFx0bG9jYWxTdG9yYWdlLnNldEl0ZW0oYXBwLnNpZGViYXIuc2Nyb2xsQmFyLmxvY2FsU3RvcmFnZSwgdGhpcy5zY3JvbGxUb3ApO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHR2YXIgZGVmYXVsdFNjcm9sbCA9IGxvY2FsU3RvcmFnZS5nZXRJdGVtKGFwcC5zaWRlYmFyLnNjcm9sbEJhci5sb2NhbFN0b3JhZ2UpO1xuXHRcdFx0XHRcdGlmIChkZWZhdWx0U2Nyb2xsKSB7XG5cdFx0XHRcdFx0XHRkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcuJysgYXBwLnNpZGViYXIuY2xhc3MgKycgWycrIGFwcC5zY3JvbGxCYXIuYXR0ciArJ10nKS5zY3JvbGxUb3AgPSBkZWZhdWx0U2Nyb2xsO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH0gY2F0Y2ggKGVycm9yKSB7XG5cdFx0XHRjb25zb2xlLmxvZyhlcnJvcik7XG5cdFx0fVxuXHR9XG59O1xuXG5cblxuLyogMDUuIEhhbmRsZSBDYXJkIEFjdGlvblxuLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovXG52YXIgaGFuZGxlQ2FyZEFjdGlvbiA9IGZ1bmN0aW9uKCkge1xuXHRcInVzZSBzdHJpY3RcIjtcblxuXHRpZiAoYXBwLmNhcmQuZXhwYW5kLnN0YXR1cykge1xuXHRcdHJldHVybiBmYWxzZTtcblx0fVxuXHRhcHAuY2FyZC5leHBhbmQuc3RhdHVzID0gdHJ1ZTtcblxuXHQvLyBleHBhbmRcblx0dmFyIGV4cGFuZFRvZ2dsZXJMaXN0ID0gW10uc2xpY2UuY2FsbChkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCdbJysgYXBwLmNhcmQuZXhwYW5kLnRvZ2dsZUF0dHIgKyddJykpO1xuXHR2YXIgZXhwYW5kVG9nZ2xlclRvb2x0aXBMaXN0ID0gZXhwYW5kVG9nZ2xlckxpc3QubWFwKGZ1bmN0aW9uIChleHBhbmRUb2dnbGVyRWwpIHtcblx0XHRleHBhbmRUb2dnbGVyRWwub25jbGljayA9IGZ1bmN0aW9uKGUpIHtcblx0XHRcdGUucHJldmVudERlZmF1bHQoKTtcblx0XHRcblx0XHRcdHZhciB0YXJnZXQgPSB0aGlzLmNsb3Nlc3QoJy5jYXJkJyk7XG5cdFx0XHR2YXIgdGFyZ2V0Q2xhc3MgPSBhcHAuY2FyZC5leHBhbmQuY2xhc3M7XG5cdFx0XHR2YXIgdGFyZ2V0VG9wID0gNDA7XG5cblx0XHRcdGlmIChkb2N1bWVudC5ib2R5LmNsYXNzTGlzdC5jb250YWlucyh0YXJnZXRDbGFzcykgJiYgdGFyZ2V0LmNsYXNzTGlzdC5jb250YWlucyh0YXJnZXRDbGFzcykpIHtcblx0XHRcdFx0dGFyZ2V0LnJlbW92ZUF0dHJpYnV0ZSgnc3R5bGUnKTtcblx0XHRcdFx0dGFyZ2V0LmNsYXNzTGlzdC5yZW1vdmUodGFyZ2V0Q2xhc3MpO1xuXHRcdFx0XHRkb2N1bWVudC5ib2R5LmNsYXNzTGlzdC5yZW1vdmUodGFyZ2V0Q2xhc3MpO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0ZG9jdW1lbnQuYm9keS5jbGFzc0xpc3QuYWRkKHRhcmdldENsYXNzKTtcblx0XHRcdFx0dGFyZ2V0LmNsYXNzTGlzdC5hZGQodGFyZ2V0Q2xhc3MpO1xuXHRcdFx0fVxuXHRcdFxuXHRcdFx0d2luZG93LmRpc3BhdGNoRXZlbnQobmV3IEV2ZW50KCdyZXNpemUnKSk7XG5cdFx0fTtcblx0XG5cdFx0cmV0dXJuIG5ldyBib290c3RyYXAuVG9vbHRpcChleHBhbmRUb2dnbGVyRWwsIHtcblx0XHRcdHRpdGxlOiBhcHAuY2FyZC5leHBhbmQudG9nZ2xlVGl0bGUsXG5cdFx0XHRwbGFjZW1lbnQ6ICdib3R0b20nLFxuXHRcdFx0dHJpZ2dlcjogJ2hvdmVyJyxcblx0XHRcdGNvbnRhaW5lcjogJ2JvZHknXG5cdFx0fSk7XG5cdH0pO1xufTtcblxuXG5cbi8qIDA2LiBIYW5kbGUgVG9vbHRpcCAmIFBvcG92ZXIgQWN0aXZhdGlvblxuLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovXG52YXIgaGFuZGVsVG9vbHRpcFBvcG92ZXJBY3RpdmF0aW9uID0gZnVuY3Rpb24oKSB7XG5cdFwidXNlIHN0cmljdFwiO1xuXHRcblx0dmFyIHRvb2x0aXBUcmlnZ2VyTGlzdCA9IFtdLnNsaWNlLmNhbGwoZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnWycrIGFwcC5ib290c3RyYXAudG9vbHRpcC5hdHRyICsnXScpKVxuXHR2YXIgdG9vbHRpcExpc3QgPSB0b29sdGlwVHJpZ2dlckxpc3QubWFwKGZ1bmN0aW9uICh0b29sdGlwVHJpZ2dlckVsKSB7XG5cdFx0cmV0dXJuIG5ldyBib290c3RyYXAuVG9vbHRpcCh0b29sdGlwVHJpZ2dlckVsKTtcblx0fSk7XG5cdFxuXHR2YXIgcG9wb3ZlclRyaWdnZXJMaXN0ID0gW10uc2xpY2UuY2FsbChkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCdbJysgYXBwLmJvb3RzdHJhcC5wb3BvdmVyLmF0dHIgKyddJykpXG5cdHZhciBwb3BvdmVyTGlzdCA9IHBvcG92ZXJUcmlnZ2VyTGlzdC5tYXAoZnVuY3Rpb24gKHBvcG92ZXJUcmlnZ2VyRWwpIHtcblx0XHRyZXR1cm4gbmV3IGJvb3RzdHJhcC5Qb3BvdmVyKHBvcG92ZXJUcmlnZ2VyRWwpO1xuXHR9KTtcbn07XG5cblxuXG4vKiAwNy4gSGFuZGxlIFNjcm9sbCB0byBUb3AgQnV0dG9uXG4tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi9cbnZhciBoYW5kbGVTY3JvbGxUb1RvcEJ1dHRvbiA9IGZ1bmN0aW9uKCkge1xuXHRcInVzZSBzdHJpY3RcIjtcblx0XG5cdHZhciBlbG1UcmlnZ2VyTGlzdCA9IFtdLnNsaWNlLmNhbGwoZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnWycrIGFwcC5zY3JvbGxUb1RvcEJ0bi50b2dnbGVBdHRyICsnXScpKTtcblx0XG5cdGRvY3VtZW50Lm9uc2Nyb2xsID0gZnVuY3Rpb24oKSB7XG5cdFx0dmFyIGRvYyA9IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudDtcblx0XHR2YXIgdG90YWxTY3JvbGwgPSAod2luZG93LnBhZ2VZT2Zmc2V0IHx8IGRvYy5zY3JvbGxUb3ApICAtIChkb2MuY2xpZW50VG9wIHx8IDApO1xuXHRcdHZhciBlbG1MaXN0ID0gZWxtVHJpZ2dlckxpc3QubWFwKGZ1bmN0aW9uKGVsbSkge1xuXHRcdFx0aWYgKHRvdGFsU2Nyb2xsID49IGFwcC5zY3JvbGxUb1RvcEJ0bi5oZWlnaHRTaG93KSB7XG5cdFx0XHRcdGlmICghZWxtLmNsYXNzTGlzdC5jb250YWlucyhhcHAuc2Nyb2xsVG9Ub3BCdG4uc2hvd0NsYXNzKSkge1xuXHRcdFx0XHRcdGVsbS5jbGFzc0xpc3QuYWRkKGFwcC5zY3JvbGxUb1RvcEJ0bi5zaG93Q2xhc3MpO1xuXHRcdFx0XHR9XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRlbG0uY2xhc3NMaXN0LnJlbW92ZShhcHAuc2Nyb2xsVG9Ub3BCdG4uc2hvd0NsYXNzKTtcblx0XHRcdH1cblx0XHR9KTtcblx0XHRcblx0XHR2YXIgZWxtID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbChhcHAuaWQpWzBdO1xuXHRcblx0XHRpZiAodG90YWxTY3JvbGwgPiAwKSB7XG5cdFx0XHRlbG0uY2xhc3NMaXN0LmFkZChhcHAuaGVhZGVyLmhhc1Njcm9sbENsYXNzKTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0ZWxtLmNsYXNzTGlzdC5yZW1vdmUoYXBwLmhlYWRlci5oYXNTY3JvbGxDbGFzcyk7XG5cdFx0fVxuXHR9XG5cdFxuXHR2YXIgZWxtTGlzdCA9IGVsbVRyaWdnZXJMaXN0Lm1hcChmdW5jdGlvbihlbG0pIHtcblx0XHRlbG0ub25jbGljayA9IGZ1bmN0aW9uKGUpIHtcblx0XHRcdGUucHJldmVudERlZmF1bHQoKTtcblx0XHRcdFxuXHRcdFx0d2luZG93LnNjcm9sbFRvKHt0b3A6IDAsIGJlaGF2aW9yOiAnc21vb3RoJ30pO1xuXHRcdH1cblx0fSk7XG59O1xuXG5cblxuLyogMDguIEhhbmRsZSBoZXhUb1JnYmFcbi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqL1xudmFyIGhleFRvUmdiYSA9IGZ1bmN0aW9uKGhleCwgdHJhbnNwYXJlbnQgPSAxKSB7XG5cdHZhciBjO1xuXHRpZigvXiMoW0EtRmEtZjAtOV17M30pezEsMn0kLy50ZXN0KGhleCkpe1xuXHRcdGM9IGhleC5zdWJzdHJpbmcoMSkuc3BsaXQoJycpO1xuXHRcdGlmKGMubGVuZ3RoPT0gMyl7XG5cdFx0XHRcdGM9IFtjWzBdLCBjWzBdLCBjWzFdLCBjWzFdLCBjWzJdLCBjWzJdXTtcblx0XHR9XG5cdFx0Yz0gJzB4JytjLmpvaW4oJycpO1xuXHRcdHJldHVybiAncmdiYSgnK1soYz4+MTYpJjI1NSwgKGM+PjgpJjI1NSwgYyYyNTVdLmpvaW4oJywnKSsnLCcrIHRyYW5zcGFyZW50ICsnKSc7XG5cdH1cbiAgdGhyb3cgbmV3IEVycm9yKCdCYWQgSGV4Jyk7XG59O1xuXG5cblxuLyogMDkuIEhhbmRsZSBTY3JvbGwgVG9cbi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqL1xudmFyIGhhbmRsZVNjcm9sbFRvID0gZnVuY3Rpb24oKSB7XG5cdHZhciBlbG1UcmlnZ2VyTGlzdCA9IFtdLnNsaWNlLmNhbGwoZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnWycrIGFwcC5zY3JvbGxUby5hdHRyICsnXScpKTtcblx0dmFyIGVsbUxpc3QgPSBlbG1UcmlnZ2VyTGlzdC5tYXAoZnVuY3Rpb24oZWxtKSB7XG5cdFx0ZWxtLm9uY2xpY2sgPSBmdW5jdGlvbihlKSB7XG5cdFx0XHRlLnByZXZlbnREZWZhdWx0KCk7XG5cdFx0XG5cdFx0XHR2YXIgdGFyZ2V0QXR0ciA9IChlbG0uZ2V0QXR0cmlidXRlKGFwcC5zY3JvbGxUby50YXJnZXQpKSA/IHRoaXMuZ2V0QXR0cmlidXRlKGFwcC5zY3JvbGxUby50YXJnZXQpIDogdGhpcy5nZXRBdHRyaWJ1dGUoYXBwLnNjcm9sbFRvLmxpbmtUYXJnZXQpO1xuXHRcdFx0dmFyIHRhcmdldEVsbSA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwodGFyZ2V0QXR0cilbMF07XG5cdFx0XHR2YXIgdGFyZ2V0SGVhZGVyID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbChhcHAuaGVhZGVyLmlkKVswXTtcblx0XHRcdHZhciB0YXJnZXRIZWlnaHQgPSB0YXJnZXRIZWFkZXIub2Zmc2V0SGVpZ2h0O1xuXHRcdFx0aWYgKHRhcmdldEVsbSkge1xuXHRcdFx0XHR2YXIgdGFyZ2V0VG9wID0gdGFyZ2V0RWxtLm9mZnNldFRvcCAtIHRhcmdldEhlaWdodCAtIDI0O1xuXHRcdFx0XHR3aW5kb3cuc2Nyb2xsVG8oe3RvcDogdGFyZ2V0VG9wLCBiZWhhdmlvcjogJ3Ntb290aCd9KTtcblx0XHRcdH1cblx0XHR9XG5cdH0pO1xufTtcblxuXG5cbi8qIDEwLiBIYW5kbGUgVG9nZ2xlIENsYXNzXG4tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi9cbnZhciBoYW5kbGVUb2dnbGVDbGFzcyA9IGZ1bmN0aW9uKCkge1xuXHR2YXIgZWxtTGlzdCA9IFtdLnNsaWNlLmNhbGwoZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnWycrIGFwcC50b2dnbGVDbGFzcy50b2dnbGVBdHRyICsnXScpKTtcblx0XG5cdGVsbUxpc3QubWFwKGZ1bmN0aW9uKGVsbSkge1xuXHRcdGVsbS5vbmNsaWNrID0gZnVuY3Rpb24oZSkge1xuXHRcdFx0ZS5wcmV2ZW50RGVmYXVsdCgpO1xuXHRcdFx0XG5cdFx0XHR2YXIgdGFyZ2V0VG9nZ2xlQ2xhc3MgPSB0aGlzLmdldEF0dHJpYnV0ZShhcHAudG9nZ2xlQ2xhc3MudG9nZ2xlQXR0cik7XG5cdFx0XHR2YXIgdGFyZ2V0RGlzbWlzc0NsYXNzID0gdGhpcy5nZXRBdHRyaWJ1dGUoYXBwLmRpc21pc3NDbGFzcy50b2dnbGVBdHRyKTtcblx0XHRcdHZhciB0YXJnZXRUb2dnbGVFbG0gPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKHRoaXMuZ2V0QXR0cmlidXRlKGFwcC50b2dnbGVDbGFzcy50YXJnZXRBdHRyKSk7XG5cdFx0XG5cdFx0XHRpZiAoIXRhcmdldERpc21pc3NDbGFzcykge1xuXHRcdFx0XHRpZiAodGFyZ2V0VG9nZ2xlRWxtLmNsYXNzTGlzdC5jb250YWlucyh0YXJnZXRUb2dnbGVDbGFzcykpIHtcblx0XHRcdFx0XHR0YXJnZXRUb2dnbGVFbG0uY2xhc3NMaXN0LnJlbW92ZSh0YXJnZXRUb2dnbGVDbGFzcyk7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0dGFyZ2V0VG9nZ2xlRWxtLmNsYXNzTGlzdC5hZGQodGFyZ2V0VG9nZ2xlQ2xhc3MpO1xuXHRcdFx0XHR9XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRpZiAoIXRhcmdldFRvZ2dsZUVsbS5jbGFzc0xpc3QuY29udGFpbnModGFyZ2V0VG9nZ2xlQ2xhc3MpICYmICF0YXJnZXRUb2dnbGVFbG0uY2xhc3NMaXN0LmNvbnRhaW5zKHRhcmdldERpc21pc3NDbGFzcykpIHtcblx0XHRcdFx0XHRpZiAodGFyZ2V0VG9nZ2xlRWxtLmNsYXNzTGlzdC5jb250YWlucyh0YXJnZXRUb2dnbGVDbGFzcykpIHtcblx0XHRcdFx0XHRcdHRhcmdldFRvZ2dsZUVsbS5jbGFzc0xpc3QucmVtb3ZlKHRhcmdldFRvZ2dsZUNsYXNzKTtcblx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0dGFyZ2V0VG9nZ2xlRWxtLmNsYXNzTGlzdC5hZGQodGFyZ2V0VG9nZ2xlQ2xhc3MpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRpZiAodGFyZ2V0VG9nZ2xlRWxtLmNsYXNzTGlzdC5jb250YWlucyh0YXJnZXRUb2dnbGVDbGFzcykpIHtcblx0XHRcdFx0XHRcdHRhcmdldFRvZ2dsZUVsbS5jbGFzc0xpc3QucmVtb3ZlKHRhcmdldFRvZ2dsZUNsYXNzKTtcblx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0dGFyZ2V0VG9nZ2xlRWxtLmNsYXNzTGlzdC5hZGQodGFyZ2V0VG9nZ2xlQ2xhc3MpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRpZiAodGFyZ2V0VG9nZ2xlRWxtLmNsYXNzTGlzdC5jb250YWlucyh0YXJnZXREaXNtaXNzQ2xhc3MpKSB7XG5cdFx0XHRcdFx0XHR0YXJnZXRUb2dnbGVFbG0uY2xhc3NMaXN0LnJlbW92ZSh0YXJnZXREaXNtaXNzQ2xhc3MpO1xuXHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHR0YXJnZXRUb2dnbGVFbG0uY2xhc3NMaXN0LmFkZCh0YXJnZXREaXNtaXNzQ2xhc3MpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblx0fSk7XG59XG5cblxuXG4vKiAxMS4gSGFuZGxlIFRoZW1lIFBhbmVsXG4tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi9cbnZhciBoYW5kbGVUaGVtZVBhbmVsID0gZnVuY3Rpb24oKSB7XG5cdFwidXNlIHN0cmljdFwiO1xuXHRcblx0Ly8gMTIuMSBUaGVtZSBQYW5lbCAtIFRvZ2dsZSAvIERpc21pc3Ncblx0dmFyIGVsbUxpc3QgPSBbXS5zbGljZS5jYWxsKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJ1snKyBhcHAudGhlbWVQYW5lbC50b2dnbGVBdHRyICsnXScpKTtcblx0XG5cdGVsbUxpc3QubWFwKGZ1bmN0aW9uKGVsbSkge1xuXHRcdGVsbS5vbmNsaWNrID0gZnVuY3Rpb24oZSkge1xuXHRcdFx0ZS5wcmV2ZW50RGVmYXVsdCgpO1xuXHRcdFx0XG5cdFx0XHR2YXIgdGFyZ2V0Q29udGFpbmVyID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLicrIGFwcC50aGVtZVBhbmVsLmNsYXNzKTtcblx0XHRcdHZhciB0YXJnZXRFeHBhbmQgPSBmYWxzZTtcblx0XHRcblx0XHRcdGlmICh0YXJnZXRDb250YWluZXIuY2xhc3NMaXN0LmNvbnRhaW5zKGFwcC50aGVtZVBhbmVsLmFjdGl2ZUNsYXNzKSkge1xuXHRcdFx0XHR0YXJnZXRDb250YWluZXIuY2xhc3NMaXN0LnJlbW92ZShhcHAudGhlbWVQYW5lbC5hY3RpdmVDbGFzcyk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHR0YXJnZXRDb250YWluZXIuY2xhc3NMaXN0LmFkZChhcHAudGhlbWVQYW5lbC5hY3RpdmVDbGFzcyk7XG5cdFx0XHRcdHRhcmdldEV4cGFuZCA9IHRydWU7XG5cdFx0XHR9XG5cdFx0XHRpZiAoQ29va2llcykge1xuXHRcdFx0XHRDb29raWVzLnNldChhcHAudGhlbWVQYW5lbC5jb29raWVOYW1lLCB0YXJnZXRFeHBhbmQpO1xuXHRcdFx0fVxuXHRcdH1cblx0fSk7XG5cdFxuXHQvLyAxMi4yIFRoZW1lIFBhbmVsIC0gUGFnZSBMb2FkIENvb2tpZXMgXG5cdGlmIChDb29raWVzKSB7XG5cdFx0dmFyIHRoZW1lUGFuZWxFeHBhbmQgPSBDb29raWVzLmdldChhcHAudGhlbWVQYW5lbC5jb29raWVOYW1lKTtcblx0XHRcblx0XHRpZiAodGhlbWVQYW5lbEV4cGFuZCA9PSAndHJ1ZScgfHwgdHlwZW9mIHRoZW1lUGFuZWxFeHBhbmQgPT0gJ3VuZGVmaW5lZCcpIHtcblx0XHRcdHZhciBlbG0gPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdbJysgYXBwLnRoZW1lUGFuZWwudG9nZ2xlQXR0ciArJ10nKTtcblx0XHRcdGlmIChlbG0pIHtcblx0XHRcdFx0ZWxtLmNsaWNrKCk7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cdFxuXHRcblx0Ly8gMTIuMyBUaGVtZSBQYW5lbCAtIFRoZW1lIFNlbGVjdG9yXG5cdHZhciBlbG1MaXN0ID0gW10uc2xpY2UuY2FsbChkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCcuJysgYXBwLnRoZW1lUGFuZWwuY2xhc3MgKycgWycrIGFwcC50aGVtZVBhbmVsLnRoZW1lLnRvZ2dsZUF0dHIgKyddJykpO1xuXHRlbG1MaXN0Lm1hcChmdW5jdGlvbihlbG0pIHtcblx0XHRlbG0ub25jbGljayA9IGZ1bmN0aW9uKCkge1xuXHRcdFx0Zm9yICh2YXIgeCA9IDA7IHggPCBkb2N1bWVudC5ib2R5LmNsYXNzTGlzdC5sZW5ndGg7IHgrKykge1xuXHRcdFx0XHR2YXIgdGFyZ2V0Q2xhc3MgPSBkb2N1bWVudC5ib2R5LmNsYXNzTGlzdFt4XTtcblx0XHRcdFx0aWYgKHRhcmdldENsYXNzLnNlYXJjaCgndGhlbWUtJykgPiAtMSkge1xuXHRcdFx0XHRcdGRvY3VtZW50LmJvZHkuY2xhc3NMaXN0LnJlbW92ZSh0YXJnZXRDbGFzcyk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRcblx0XHRcdHZhciB0YXJnZXRUaGVtZSA9IHRoaXMuZ2V0QXR0cmlidXRlKGFwcC50aGVtZVBhbmVsLnRoZW1lLmNsYXNzQXR0cik7XG5cdFx0XHR2YXIgdGFyZ2V0VGhlbWVMaXN0ID0gW10uc2xpY2UuY2FsbChkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCcuJysgYXBwLnRoZW1lUGFuZWwuY2xhc3MgKycgWycrIGFwcC50aGVtZVBhbmVsLnRoZW1lLnRvZ2dsZUF0dHIgKyddJykpO1xuXHRcdFx0XG5cdFx0XHRpZiAodGFyZ2V0VGhlbWUpIHtcblx0XHRcdFx0ZG9jdW1lbnQuYm9keS5jbGFzc0xpc3QuYWRkKHRhcmdldFRoZW1lKTtcblx0XHRcdH1cblx0XHRcdHRhcmdldFRoZW1lTGlzdC5tYXAoZnVuY3Rpb24odGFyZ2V0RWxtKSB7XG5cdFx0XHRcdGlmICh0YXJnZXRFbG0uZ2V0QXR0cmlidXRlKGFwcC50aGVtZVBhbmVsLnRoZW1lLmNsYXNzQXR0cikgIT0gdGFyZ2V0VGhlbWUpIHtcblx0XHRcdFx0XHR0YXJnZXRFbG0uY2xvc2VzdCgnLicrIGFwcC50aGVtZVBhbmVsLnRoZW1lTGlzdEl0ZW1DTGFzcykuY2xhc3NMaXN0LnJlbW92ZShhcHAudGhlbWVQYW5lbC50aGVtZS5hY3RpdmVDbGFzcyk7XG5cdFx0XHRcdH1cblx0XHRcdH0pO1xuXHRcdFx0XG5cdFx0XHR0aGlzLmNsb3Nlc3QoJy4nKyBhcHAudGhlbWVQYW5lbC50aGVtZUxpc3RJdGVtQ0xhc3MpLmNsYXNzTGlzdC5hZGQoYXBwLnRoZW1lUGFuZWwudGhlbWUuYWN0aXZlQ2xhc3MpO1xuXHRcdFx0XG5cdFx0XHRpZiAoQ29va2llcykge1xuXHRcdFx0XHRDb29raWVzLnNldChhcHAudGhlbWVQYW5lbC50aGVtZS5jb29raWVOYW1lLCB0YXJnZXRUaGVtZSk7XG5cdFx0XHRcdGFwcC5jb2xvci50aGVtZSA9IChnZXRDb21wdXRlZFN0eWxlKGRvY3VtZW50LmJvZHkpLmdldFByb3BlcnR5VmFsdWUoJy0tYnMtdGhlbWUnKSkudHJpbSgpO1xuXHRcdFx0XHRhcHAuY29sb3IudGhlbWVSZ2IgPSAoZ2V0Q29tcHV0ZWRTdHlsZShkb2N1bWVudC5ib2R5KS5nZXRQcm9wZXJ0eVZhbHVlKCctLWJzLXRoZW1lLXJnYicpKS50cmltKCk7XG5cdFx0XHRcdFxuXHRcdFx0XHRkb2N1bWVudC5kaXNwYXRjaEV2ZW50KG5ldyBFdmVudCgndGhlbWUtcmVsb2FkJykpO1xuXHRcdFx0fVxuXHRcdH1cblx0fSk7XG5cdFxuXHRpZiAoQ29va2llcykge1xuXHRcdGlmIChDb29raWVzLmdldChhcHAudGhlbWVQYW5lbC50aGVtZS5jb29raWVOYW1lKSkge1xuXHRcdFx0dmFyIHRhcmdldEVsbSA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy4nKyBhcHAudGhlbWVQYW5lbC5jbGFzcyArJyBbJysgYXBwLnRoZW1lUGFuZWwudGhlbWUudG9nZ2xlQXR0ciArJ10nICsgJ1snKyBhcHAudGhlbWVQYW5lbC50aGVtZS5jbGFzc0F0dHIgKyc9XCInKyBDb29raWVzLmdldChhcHAudGhlbWVQYW5lbC50aGVtZS5jb29raWVOYW1lKSArJ1wiXScpO1xuXHRcdFx0XG5cdFx0XHRpZiAodGFyZ2V0RWxtKSB7XG5cdFx0XHRcdHRhcmdldEVsbS5jbGljaygpO1xuXHRcdFx0XG5cdFx0XHRcdGFwcC5jb2xvci50aGVtZSA9IChnZXRDb21wdXRlZFN0eWxlKGRvY3VtZW50LmJvZHkpLmdldFByb3BlcnR5VmFsdWUoJy0tYnMtdGhlbWUnKSkudHJpbSgpO1xuXHRcdFx0XHRhcHAuY29sb3IudGhlbWVSZ2IgPSAoZ2V0Q29tcHV0ZWRTdHlsZShkb2N1bWVudC5ib2R5KS5nZXRQcm9wZXJ0eVZhbHVlKCctLWJzLXRoZW1lLXJnYicpKS50cmltKCk7XG5cdFx0XHRcblx0XHRcdFx0ZG9jdW1lbnQuZGlzcGF0Y2hFdmVudChuZXcgRXZlbnQoJ3RoZW1lLXJlbG9hZCcpKTtcblx0XHRcdH1cblx0XHR9XG5cdH1cblx0XG5cdFxuXHQvLyAxMi40IFRoZW1lIFBhbmVsIC0gQmFja2dyb3VuZCBTZWxlY3RvclxuXHR2YXIgZWxtTGlzdCA9IFtdLnNsaWNlLmNhbGwoZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnLicrIGFwcC50aGVtZVBhbmVsLmNsYXNzICsnIFsnKyBhcHAudGhlbWVQYW5lbC50aGVtZUNvdmVyLnRvZ2dsZUF0dHIgKyddJykpO1xuXHRlbG1MaXN0Lm1hcChmdW5jdGlvbihlbG0pIHtcblx0XHRlbG0ub25jbGljayA9IGZ1bmN0aW9uKGUpIHtcblx0XHRcdGUucHJldmVudERlZmF1bHQoKTtcblx0XHRcdFxuXHRcdFx0dmFyIGh0bWxFbG0gPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdodG1sJyk7XG5cdFx0XHR2YXIgdGFyZ2V0VGhlbWUgPSB0aGlzLmdldEF0dHJpYnV0ZShhcHAudGhlbWVQYW5lbC50aGVtZUNvdmVyLmNsYXNzQXR0cik7XG5cdFx0XHRmb3IgKHZhciB4ID0gMDsgeCA8IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5jbGFzc0xpc3QubGVuZ3RoOyB4KyspIHtcblx0XHRcdFx0dmFyIHRhcmdldENsYXNzID0gZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmNsYXNzTGlzdFt4XTtcblx0XHRcdFx0aWYgKHRhcmdldENsYXNzLnNlYXJjaCgnYmctY292ZXItJykgPiAtMSkge1xuXHRcdFx0XHRcdGh0bWxFbG0uY2xhc3NMaXN0LnJlbW92ZSh0YXJnZXRDbGFzcyk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRcdFxuXHRcdFx0aWYgKHRhcmdldFRoZW1lKSB7XG5cdFx0XHRcdGh0bWxFbG0uY2xhc3NMaXN0LmFkZCh0YXJnZXRUaGVtZSk7XG5cdFx0XHR9XG5cdFx0XHRcblx0XHRcdHZhciB0YXJnZXRDb3Zlckxpc3QgPSBbXS5zbGljZS5jYWxsKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJy4nKyBhcHAudGhlbWVQYW5lbC5jbGFzcyArJyBbJysgYXBwLnRoZW1lUGFuZWwudGhlbWVDb3Zlci50b2dnbGVBdHRyICsnXScpKTtcblx0XHRcdHRhcmdldENvdmVyTGlzdC5tYXAoZnVuY3Rpb24odGFyZ2V0RWxtKSB7XG5cdFx0XHRcdGlmICh0YXJnZXRFbG0uZ2V0QXR0cmlidXRlKGFwcC50aGVtZVBhbmVsLnRoZW1lQ292ZXIudG9nZ2xlQXR0cikgIT0gdGFyZ2V0VGhlbWUpIHtcblx0XHRcdFx0XHR0YXJnZXRFbG0uY2xvc2VzdCgnLicrIGFwcC50aGVtZVBhbmVsLnRoZW1lQ292ZXJJdGVtQ2xhc3MpLmNsYXNzTGlzdC5yZW1vdmUoYXBwLnRoZW1lUGFuZWwudGhlbWVDb3Zlci5hY3RpdmVDbGFzcyk7XG5cdFx0XHRcdH1cblx0XHRcdH0pO1xuXHRcdFx0XG5cdFx0XHR0aGlzLmNsb3Nlc3QoJy4nKyBhcHAudGhlbWVQYW5lbC50aGVtZUNvdmVySXRlbUNsYXNzKS5jbGFzc0xpc3QuYWRkKGFwcC50aGVtZVBhbmVsLnRoZW1lQ292ZXIuYWN0aXZlQ2xhc3MpO1xuXHRcdFx0aWYgKENvb2tpZXMpIHtcblx0XHRcdFx0Q29va2llcy5zZXQoYXBwLnRoZW1lUGFuZWwudGhlbWVDb3Zlci5jb29raWVOYW1lLCB0YXJnZXRUaGVtZSk7XG5cdFx0XHR9XG5cdFx0fTtcblx0fSk7XG5cdFxuXHRpZiAoQ29va2llcykge1xuXHRcdGlmIChDb29raWVzLmdldChhcHAudGhlbWVQYW5lbC50aGVtZUNvdmVyLmNvb2tpZU5hbWUpKSB7XG5cdFx0XHR2YXIgdGFyZ2V0RWxtID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLicrIGFwcC50aGVtZVBhbmVsLmNsYXNzICsnIFsnKyBhcHAudGhlbWVQYW5lbC50aGVtZUNvdmVyLnRvZ2dsZUF0dHIgKyddJyArICdbJysgYXBwLnRoZW1lUGFuZWwudGhlbWVDb3Zlci5jbGFzc0F0dHIgKyc9XCInKyBDb29raWVzLmdldChhcHAudGhlbWVQYW5lbC50aGVtZUNvdmVyLmNvb2tpZU5hbWUpICsnXCJdJyk7XG5cdFx0XHRpZiAodGFyZ2V0RWxtKSB7XG5cdFx0XHRcdHRhcmdldEVsbS5jbGljaygpO1xuXHRcdFx0fVxuXHRcdH1cblx0fVxufTtcblxuXG5cbi8qIDEyLiBBcHBsaWNhdGlvbiBDb250cm9sbGVyXG4tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi9cbnZhciBBcHAgPSBmdW5jdGlvbiAoKSB7XG5cdFwidXNlIHN0cmljdFwiO1xuXHRcblx0cmV0dXJuIHtcblx0XHQvL21haW4gZnVuY3Rpb25cblx0XHRpbml0OiBmdW5jdGlvbiAoKSB7XG5cdFx0XHR0aGlzLmluaXRDb21wb25lbnQoKTtcblx0XHRcdHRoaXMuaW5pdFNpZGViYXIoKTtcblx0XHRcdHRoaXMuaW5pdEFwcExvYWQoKTtcblx0XHR9LFxuXHRcdGluaXRBcHBMb2FkOiBmdW5jdGlvbigpIHtcblx0XHRcdGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ2JvZHknKS5jbGFzc0xpc3QuYWRkKGFwcC5pbml0LmNsYXNzKTtcblx0XHR9LFxuXHRcdGluaXRTaWRlYmFyOiBmdW5jdGlvbigpIHtcblx0XHRcdGhhbmRsZVNpZGViYXJNZW51KCk7XG5cdFx0XHRoYW5kbGVTaWRlYmFyU2Nyb2xsTWVtb3J5KCk7XG5cdFx0fSxcblx0XHRpbml0Q29tcG9uZW50OiBmdW5jdGlvbigpIHtcblx0XHRcdGhhbmRsZVNjcm9sbGJhcigpO1xuXHRcdFx0aGFuZGxlU2Nyb2xsVG9Ub3BCdXR0b24oKTtcblx0XHRcdGhhbmRsZVNjcm9sbFRvKCk7XG5cdFx0XHRoYW5kbGVDYXJkQWN0aW9uKCk7XG5cdFx0XHRoYW5kZWxUb29sdGlwUG9wb3ZlckFjdGl2YXRpb24oKTtcblx0XHRcdGhhbmRsZVRvZ2dsZUNsYXNzKCk7XG5cdFx0XHRoYW5kbGVUaGVtZVBhbmVsKCk7XG5cdFx0fSxcblx0XHRzY3JvbGxUb3A6IGZ1bmN0aW9uKCkge1xuXHRcdFx0d2luZG93LnNjcm9sbFRvKHt0b3A6IDAsIGJlaGF2aW9yOiAnc21vb3RoJ30pO1xuXHRcdH1cblx0fTtcbn0oKTtcblxuXG5cbi8qIDEzLiBJbml0aWFsaXNlXG4tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi9cbmRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ0RPTUNvbnRlbnRMb2FkZWQnLCBmdW5jdGlvbigpIHtcblx0QXBwLmluaXQoKTtcbn0pOyJdfQ== 769 | -------------------------------------------------------------------------------- /static/js/zoom.js: -------------------------------------------------------------------------------- 1 | +function ($) { "use strict"; 2 | 3 | /** 4 | * The zoom service 5 | */ 6 | function ZoomService () { 7 | this._activeZoom = 8 | this._initialScrollPosition = 9 | this._initialTouchPosition = 10 | this._touchMoveListener = null 11 | 12 | this._$document = $(document) 13 | this._$window = $(window) 14 | this._$body = $(document.body) 15 | 16 | this._boundClick = $.proxy(this._clickHandler, this) 17 | } 18 | 19 | ZoomService.prototype.listen = function () { 20 | this._$body.on('click', '[data-action="zoom"]', $.proxy(this._zoom, this)) 21 | } 22 | 23 | ZoomService.prototype._zoom = function (e) { 24 | var target = e.target 25 | 26 | if (!target || target.tagName != 'IMG') return 27 | 28 | if (this._$body.hasClass('zoom-overlay-open')) return 29 | 30 | if (e.metaKey || e.ctrlKey) { 31 | return window.open((e.target.getAttribute('data-original') || e.target.src), '_blank') 32 | } 33 | 34 | if (target.width >= ($(window).width() - Zoom.OFFSET)) return 35 | 36 | this._activeZoomClose(true) 37 | 38 | this._activeZoom = new Zoom(target) 39 | this._activeZoom.zoomImage() 40 | 41 | // todo(fat): probably worth throttling this 42 | this._$window.on('scroll.zoom', $.proxy(this._scrollHandler, this)) 43 | 44 | this._$document.on('keyup.zoom', $.proxy(this._keyHandler, this)) 45 | this._$document.on('touchstart.zoom', $.proxy(this._touchStart, this)) 46 | 47 | // we use a capturing phase here to prevent unintended js events 48 | // sadly no useCapture in jquery api (http://bugs.jquery.com/ticket/14953) 49 | if (document.addEventListener) { 50 | document.addEventListener('click', this._boundClick, true) 51 | } else { 52 | document.attachEvent('onclick', this._boundClick, true) 53 | } 54 | 55 | if ('bubbles' in e) { 56 | if (e.bubbles) e.stopPropagation() 57 | } else { 58 | // Internet Explorer before version 9 59 | e.cancelBubble = true 60 | } 61 | } 62 | 63 | ZoomService.prototype._activeZoomClose = function (forceDispose) { 64 | if (!this._activeZoom) return 65 | 66 | if (forceDispose) { 67 | this._activeZoom.dispose() 68 | } else { 69 | this._activeZoom.close() 70 | } 71 | 72 | this._$window.off('.zoom') 73 | this._$document.off('.zoom') 74 | 75 | document.removeEventListener('click', this._boundClick, true) 76 | 77 | this._activeZoom = null 78 | } 79 | 80 | ZoomService.prototype._scrollHandler = function (e) { 81 | if (this._initialScrollPosition === null) this._initialScrollPosition = $(window).scrollTop() 82 | var deltaY = this._initialScrollPosition - $(window).scrollTop() 83 | if (Math.abs(deltaY) >= 40) this._activeZoomClose() 84 | } 85 | 86 | ZoomService.prototype._keyHandler = function (e) { 87 | if (e.keyCode == 27) this._activeZoomClose() 88 | } 89 | 90 | ZoomService.prototype._clickHandler = function (e) { 91 | if (e.preventDefault) e.preventDefault() 92 | else event.returnValue = false 93 | 94 | if ('bubbles' in e) { 95 | if (e.bubbles) e.stopPropagation() 96 | } else { 97 | // Internet Explorer before version 9 98 | e.cancelBubble = true 99 | } 100 | 101 | this._activeZoomClose() 102 | } 103 | 104 | ZoomService.prototype._touchStart = function (e) { 105 | this._initialTouchPosition = e.touches[0].pageY 106 | $(e.target).on('touchmove.zoom', $.proxy(this._touchMove, this)) 107 | } 108 | 109 | ZoomService.prototype._touchMove = function (e) { 110 | if (Math.abs(e.touches[0].pageY - this._initialTouchPosition) > 10) { 111 | this._activeZoomClose() 112 | $(e.target).off('touchmove.zoom') 113 | } 114 | } 115 | 116 | 117 | /** 118 | * The zoom object 119 | */ 120 | function Zoom (img) { 121 | this._fullHeight = 122 | this._fullWidth = 123 | this._overlay = 124 | this._targetImageWrap = null 125 | 126 | this._targetImage = img 127 | 128 | this._$body = $(document.body) 129 | } 130 | 131 | Zoom.OFFSET = 80 132 | Zoom._MAX_WIDTH = 2560 133 | Zoom._MAX_HEIGHT = 4096 134 | 135 | Zoom.prototype.zoomImage = function () { 136 | var img = document.createElement('img') 137 | img.onload = $.proxy(function () { 138 | this._fullHeight = Number(img.height) 139 | this._fullWidth = Number(img.width) 140 | this._zoomOriginal() 141 | }, this) 142 | img.src = this._targetImage.src 143 | } 144 | 145 | Zoom.prototype._zoomOriginal = function () { 146 | this._targetImageWrap = document.createElement('div') 147 | this._targetImageWrap.className = 'zoom-img-wrap' 148 | 149 | this._targetImage.parentNode.insertBefore(this._targetImageWrap, this._targetImage) 150 | this._targetImageWrap.appendChild(this._targetImage) 151 | 152 | $(this._targetImage) 153 | .addClass('zoom-img') 154 | .attr('data-action', 'zoom-out') 155 | 156 | this._overlay = document.createElement('div') 157 | this._overlay.className = 'zoom-overlay' 158 | 159 | document.body.appendChild(this._overlay) 160 | 161 | this._calculateZoom() 162 | this._triggerAnimation() 163 | } 164 | 165 | Zoom.prototype._calculateZoom = function () { 166 | this._targetImage.offsetWidth // repaint before animating 167 | 168 | var originalFullImageWidth = this._fullWidth 169 | var originalFullImageHeight = this._fullHeight 170 | 171 | var scrollTop = $(window).scrollTop() 172 | 173 | var maxScaleFactor = originalFullImageWidth / this._targetImage.width 174 | 175 | var viewportHeight = ($(window).height() - Zoom.OFFSET) 176 | var viewportWidth = ($(window).width() - Zoom.OFFSET) 177 | 178 | var imageAspectRatio = originalFullImageWidth / originalFullImageHeight 179 | var viewportAspectRatio = viewportWidth / viewportHeight 180 | 181 | if (originalFullImageWidth < viewportWidth && originalFullImageHeight < viewportHeight) { 182 | this._imgScaleFactor = maxScaleFactor 183 | 184 | } else if (imageAspectRatio < viewportAspectRatio) { 185 | this._imgScaleFactor = (viewportHeight / originalFullImageHeight) * maxScaleFactor 186 | 187 | } else { 188 | this._imgScaleFactor = (viewportWidth / originalFullImageWidth) * maxScaleFactor 189 | } 190 | } 191 | 192 | Zoom.prototype._triggerAnimation = function () { 193 | this._targetImage.offsetWidth // repaint before animating 194 | 195 | var imageOffset = $(this._targetImage).offset() 196 | var scrollTop = $(window).scrollTop() 197 | 198 | var viewportY = scrollTop + ($(window).height() / 2) 199 | var viewportX = ($(window).width() / 2) 200 | 201 | var imageCenterY = imageOffset.top + (this._targetImage.height / 2) 202 | var imageCenterX = imageOffset.left + (this._targetImage.width / 2) 203 | 204 | this._translateY = viewportY - imageCenterY 205 | this._translateX = viewportX - imageCenterX 206 | 207 | var targetTransform = 'scale(' + this._imgScaleFactor + ')' 208 | var imageWrapTransform = 'translate(' + this._translateX + 'px, ' + this._translateY + 'px)' 209 | 210 | if ($.support.transition) { 211 | imageWrapTransform += ' translateZ(0)' 212 | } 213 | 214 | $(this._targetImage) 215 | .css({ 216 | '-webkit-transform': targetTransform, 217 | '-ms-transform': targetTransform, 218 | 'transform': targetTransform 219 | }) 220 | 221 | $(this._targetImageWrap) 222 | .css({ 223 | '-webkit-transform': imageWrapTransform, 224 | '-ms-transform': imageWrapTransform, 225 | 'transform': imageWrapTransform 226 | }) 227 | 228 | this._$body.addClass('zoom-overlay-open') 229 | } 230 | 231 | Zoom.prototype.close = function () { 232 | this._$body 233 | .removeClass('zoom-overlay-open') 234 | .addClass('zoom-overlay-transitioning') 235 | 236 | // we use setStyle here so that the correct vender prefix for transform is used 237 | $(this._targetImage) 238 | .css({ 239 | '-webkit-transform': '', 240 | '-ms-transform': '', 241 | 'transform': '' 242 | }) 243 | 244 | $(this._targetImageWrap) 245 | .css({ 246 | '-webkit-transform': '', 247 | '-ms-transform': '', 248 | 'transform': '' 249 | }) 250 | 251 | if (!$.support.transition) { 252 | return this.dispose() 253 | } 254 | 255 | $(this._targetImage) 256 | .one($.support.transition.end, $.proxy(this.dispose, this)) 257 | .emulateTransitionEnd(300) 258 | } 259 | 260 | Zoom.prototype.dispose = function () { 261 | if (this._targetImageWrap && this._targetImageWrap.parentNode) { 262 | $(this._targetImage) 263 | .removeClass('zoom-img') 264 | .attr('data-action', 'zoom') 265 | 266 | this._targetImageWrap.parentNode.replaceChild(this._targetImage, this._targetImageWrap) 267 | this._overlay.parentNode.removeChild(this._overlay) 268 | 269 | this._$body.removeClass('zoom-overlay-transitioning') 270 | } 271 | } 272 | 273 | // wait for dom ready (incase script included before body) 274 | $(function () { 275 | new ZoomService().listen() 276 | }) 277 | 278 | }(jQuery) 279 | -------------------------------------------------------------------------------- /static/webfonts/fa-brands-400.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maks-Ars1/Django-simple-page/b907442acc963b7145b1c981938e2865fb814caa/static/webfonts/fa-brands-400.ttf -------------------------------------------------------------------------------- /static/webfonts/fa-brands-400.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maks-Ars1/Django-simple-page/b907442acc963b7145b1c981938e2865fb814caa/static/webfonts/fa-brands-400.woff2 -------------------------------------------------------------------------------- /static/webfonts/fa-regular-400.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maks-Ars1/Django-simple-page/b907442acc963b7145b1c981938e2865fb814caa/static/webfonts/fa-regular-400.ttf -------------------------------------------------------------------------------- /static/webfonts/fa-regular-400.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maks-Ars1/Django-simple-page/b907442acc963b7145b1c981938e2865fb814caa/static/webfonts/fa-regular-400.woff2 -------------------------------------------------------------------------------- /static/webfonts/fa-solid-900.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maks-Ars1/Django-simple-page/b907442acc963b7145b1c981938e2865fb814caa/static/webfonts/fa-solid-900.ttf -------------------------------------------------------------------------------- /static/webfonts/fa-solid-900.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maks-Ars1/Django-simple-page/b907442acc963b7145b1c981938e2865fb814caa/static/webfonts/fa-solid-900.woff2 -------------------------------------------------------------------------------- /static/webfonts/fa-v4compatibility.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maks-Ars1/Django-simple-page/b907442acc963b7145b1c981938e2865fb814caa/static/webfonts/fa-v4compatibility.ttf -------------------------------------------------------------------------------- /static/webfonts/fa-v4compatibility.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Maks-Ars1/Django-simple-page/b907442acc963b7145b1c981938e2865fb814caa/static/webfonts/fa-v4compatibility.woff2 --------------------------------------------------------------------------------