From 0de8ed74de160d324966bfd811bdde7aa503b193 Mon Sep 17 00:00:00 2001 From: mutantsan Date: Thu, 25 Apr 2024 17:04:13 +0300 Subject: [PATCH] feature: add settings, update logic, add docs --- README.md | 80 +-- ckanext/tour/assets/css/style.css | 8 +- ckanext/tour/assets/css/style.css.map | 2 +- .../tour/assets/css/vendor/introjs.min.css | 476 ------------------ ckanext/tour/assets/js/tour-htmx.js | 39 -- ckanext/tour/assets/js/tour-image-upload.js | 57 +-- ckanext/tour/assets/js/tour-init-intro.js | 104 ---- ckanext/tour/assets/js/tour-init.js | 22 +- ckanext/tour/assets/js/tour-steps.js | 18 +- ckanext/tour/assets/js/vendor/htmx.min.js | 1 - ckanext/tour/assets/js/vendor/intro.min.js | 17 - .../tour/assets/js/vendor/sweetalert.min.js | 1 - ckanext/tour/assets/webassets.yml | 9 - ckanext/tour/config.py | 17 + ckanext/tour/config_declaration.yaml | 20 + ckanext/tour/config_schema.yaml | 34 ++ ckanext/tour/helpers.py | 18 + ckanext/tour/logic/action.py | 25 +- ckanext/tour/logic/schema.py | 3 +- ckanext/tour/logic/validators.py | 24 +- ckanext/tour/model.py | 8 +- ckanext/tour/plugin.py | 47 +- ckanext/tour/templates/base.html | 2 +- .../templates/tour/snippets/tour_form.html | 43 ++ .../tour/snippets/tour_image_upload.html | 2 +- .../templates/tour/snippets/tour_step.html | 23 +- ckanext/tour/templates/tour/tour_404.html | 8 +- ckanext/tour/templates/tour/tour_add.html | 58 +-- ckanext/tour/templates/tour/tour_edit.html | 44 +- ckanext/tour/tests/factories.py | 2 +- ckanext/tour/theme/elements.scss | 15 +- ckanext/tour/views/__init__.py | 11 +- ckanext/tour/views/tour_add.py | 6 +- ckanext/tour/views/tour_config.py | 12 +- ckanext/tour/views/tour_update.py | 8 +- package-lock.json | 6 + 36 files changed, 312 insertions(+), 958 deletions(-) delete mode 100644 ckanext/tour/assets/css/vendor/introjs.min.css delete mode 100644 ckanext/tour/assets/js/tour-htmx.js delete mode 100644 ckanext/tour/assets/js/tour-init-intro.js delete mode 100644 ckanext/tour/assets/js/vendor/htmx.min.js delete mode 100644 ckanext/tour/assets/js/vendor/intro.min.js delete mode 100644 ckanext/tour/assets/js/vendor/sweetalert.min.js create mode 100644 ckanext/tour/config.py create mode 100644 ckanext/tour/config_declaration.yaml create mode 100644 ckanext/tour/config_schema.yaml create mode 100644 ckanext/tour/templates/tour/snippets/tour_form.html create mode 100644 package-lock.json diff --git a/README.md b/README.md index 1ffcbc6..41e4715 100644 --- a/README.md +++ b/README.md @@ -2,39 +2,38 @@ # ckanext-tour -**TODO:** Put a description of your extension here: What does it do? What features does it have? Consider including some screenshots or embedding a video! +ckanext-tour is a CKAN extension that provides a guided tour feature for CKAN instances. It allows users to create interactive tours to showcase different features and functionalities of a CKAN instance. +## Features +- Create interactive tours with step-by-step instructions +- Highlight specific elements on CKAN pages +- Customize tour appearance and behavior +- Easily manage and edit tours through the CKAN admin interface -## Requirements +Once the extension is installed and enabled, you can start creating tours through the CKAN admin interface. Tours can be associated with specific pages or sections of your CKAN portal, and you can define multiple steps for each tour. + +To start a tour, users can click on a tour trigger button or it can be started automatically, when user visits the specified page. The tour will guide them through the specified steps, highlighting the relevant elements on each page. + +Each step contains next information: -**TODO:** For example, you might want to mention here which versions of CKAN this -extension works with. +- Title: A brief, engaging headline that summarizes the step. +- Query: Query to specify which element we're highlighting +- Intro: Text, that will be displayed on a step card +- Position: Specifies the placement of step card (top, right, bottom, left). +- Image: Visuals to complement the text, illustrate points, or add visual interest. GIF animation could be used here. -If your extension works across different versions you can add the following table: +## Requirements Compatibility with core CKAN versions: | CKAN version | Compatible? | | --------------- | ------------- | -| 2.6 and earlier | not tested | -| 2.7 | not tested | -| 2.8 | not tested | | 2.9 | not tested | - -Suggested values: - -* "yes" -* "not tested" - I can't think of a reason why it wouldn't work -* "not yet" - there is an intention to get it working -* "no" +| 2.10+ | yes | ## Installation -**TODO:** Add any additional install steps to the list below. - For example installing any non-Python dependencies or adding any required - config settings. - To install ckanext-tour: 1. Activate your CKAN virtual environment, for example: @@ -59,18 +58,11 @@ To install ckanext-tour: ## Config settings -None at present - -**TODO:** Document any optional config settings here. For example: - - # The minimum number of hours to wait before re-checking a resource - # (optional, default: 24). - ckanext.tour.some_setting = some_default_value - +To modify the configuration of the extension, please make the changes through the site's user interface. ## Developer installation -To install ckanext-tour for development, activate your CKAN virtualenv and +To install `ckanext-tour` for development, activate your CKAN virtualenv and do: git clone https://github.com/mutantsan/ckanext-tour.git @@ -86,38 +78,6 @@ To run the tests, do: pytest --ckan-ini=test.ini -## Releasing a new version of ckanext-tour - -If ckanext-tour should be available on PyPI you can follow these steps to publish a new version: - -1. Update the version number in the `setup.py` file. See [PEP 440](http://legacy.python.org/dev/peps/pep-0440/#public-version-identifiers) for how to choose version numbers. - -2. Make sure you have the latest version of necessary packages: - - pip install --upgrade setuptools wheel twine - -3. Create a source and binary distributions of the new version: - - python setup.py sdist bdist_wheel && twine check dist/* - - Fix any errors you get. - -4. Upload the source distribution to PyPI: - - twine upload dist/* - -5. Commit any outstanding changes: - - git commit -a - git push - -6. Tag the new release of the project on GitHub with the version number from - the `setup.py` file. For example if the version number in `setup.py` is - 0.0.1 then do: - - git tag 0.0.1 - git push --tags - ## License [AGPL](https://www.gnu.org/licenses/agpl-3.0.en.html) diff --git a/ckanext/tour/assets/css/style.css b/ckanext/tour/assets/css/style.css index ebf7ec4..f93d2b3 100644 --- a/ckanext/tour/assets/css/style.css +++ b/ckanext/tour/assets/css/style.css @@ -40,8 +40,8 @@ margin-right: auto; } .accordion.tour-accordion .accordion-header .accordion-header--text .step-number { - border: 1px solid black; - color: black; + border: 1px solid var(--ap-color); + color: var(--ap-color); padding: 5px 11px; border-radius: 50%; } @@ -140,4 +140,8 @@ pointer-events: none; } +body[admin-panel=true] .tour-accordion .image-upload #field-image-upload { + width: 100px; +} + /*# sourceMappingURL=style.css.map */ diff --git a/ckanext/tour/assets/css/style.css.map b/ckanext/tour/assets/css/style.css.map index 6a52390..2fdbb98 100644 --- a/ckanext/tour/assets/css/style.css.map +++ b/ckanext/tour/assets/css/style.css.map @@ -1 +1 @@ -{"version":3,"sourceRoot":"","sources":["../../theme/elements.scss","../../theme/variables.scss"],"names":[],"mappings":"AAAA;EACI;;AAEA;EACI;EACA;EACA;EACA;;AAEA;EACI;;AAEA;EACI;;AAIA;EACI;;AAIR;EACI;EACA;EACA;;AAGJ;EACI;;;AAMhB;EACI;;AAEA;EACI;;AAGJ;EACI;EACA;EACA;;AAEA;EACI;;AAEA;EACI;EACA,OCpDR;EDqDQ;EACA;;AAIR;EACI;EACA;EACA;EACA;EACA;EACA;EACA;;AAGJ;EACI;EACA;;AAGJ;EACI;;;AAOZ;EACI;;;AAGJ;EACI;;AAEA;EACI;;AAKA;EACI,kBC9FJ;;ADgGI;EACI;;AAKJ;EACI;EACA;;AAIR;EACI;EACA;EACA;EACA;EACA;EACA;;AAEA;EACI;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACI;EACA;;AAKZ;EACI;EACA;EACA;EACA;;AAEA;EACI;EACA,OC/IR;EDgJQ;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EAGI;EACA;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;EACA;EACA;EACA;EACA","file":"style.css"} \ No newline at end of file +{"version":3,"sourceRoot":"","sources":["../../theme/elements.scss","../../theme/variables.scss"],"names":[],"mappings":"AAAA;EACI;;AAEA;EACI;EACA;EACA;EACA;;AAEA;EACI;;AAEA;EACI;;AAIA;EACI;;AAIR;EACI;EACA;EACA;;AAGJ;EACI;;;AAMhB;EACI;;AAEA;EACI;;AAGJ;EACI;EACA;EACA;;AAEA;EACI;;AAEA;EACI;EACA;EACA;EACA;;AAIR;EACI;EACA;EACA;EACA;EACA;EACA;EACA;;AAGJ;EACI;EACA;;AAGJ;EACI;;;AAOZ;EACI;;;AAGJ;EACI;;AAEA;EACI;;AAKA;EACI,kBC9FJ;;ADgGI;EACI;;AAKJ;EACI;EACA;;AAIR;EACI;EACA;EACA;EACA;EACA;EACA;;AAEA;EACI;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EAII;EACA;;AAKZ;EACI;EACA;EACA;EACA;;AAEA;EACI;EACA,OClJR;EDmJQ;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EAGI;EACA;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAQhB;EACI","file":"style.css"} \ No newline at end of file diff --git a/ckanext/tour/assets/css/vendor/introjs.min.css b/ckanext/tour/assets/css/vendor/introjs.min.css deleted file mode 100644 index 29666c1..0000000 --- a/ckanext/tour/assets/css/vendor/introjs.min.css +++ /dev/null @@ -1,476 +0,0 @@ -.introjs-overlay { - position: absolute; - box-sizing: content-box; - z-index: 999999; - opacity: 0; - transition: all .3s ease-out -} - -.introjs-showElement { - z-index: 9999999 !important -} - -tr.introjs-showElement>td { - z-index: 9999999 !important; - position: relative -} - -tr.introjs-showElement>th { - z-index: 9999999 !important; - position: relative -} - -.introjs-disableInteraction { - z-index: 99999999 !important; - position: absolute; - background-color: #fff; - opacity: 0 -} - -.introjs-relativePosition { - position: relative -} - -.introjs-helperLayer { - box-sizing: content-box; - position: absolute; - z-index: 9999998; - border-radius: 4px; - transition: all .3s ease-out -} - -.introjs-helperLayer * { - box-sizing: content-box -} - -.introjs-helperLayer :before { - box-sizing: content-box -} - -.introjs-helperLayer :after { - box-sizing: content-box -} - -.introjs-tooltipReferenceLayer { - font-family: "Helvetica Neue", Inter, ui-sans-serif, "Apple Color Emoji", Helvetica, Arial, sans-serif; - box-sizing: content-box; - position: absolute; - visibility: hidden; - z-index: 100000000; - background-color: transparent; - transition: all .3s ease-out -} - -.introjs-tooltipReferenceLayer * { - font-family: "Helvetica Neue", Inter, ui-sans-serif, "Apple Color Emoji", Helvetica, Arial, sans-serif -} - -.introjs-helperNumberLayer { - font-family: "Helvetica Neue", Inter, ui-sans-serif, "Apple Color Emoji", Helvetica, Arial, sans-serif; - color: #9e9e9e; - text-align: center; - padding-top: 10px; - padding-bottom: 10px -} - -.introjs-arrow { - border: 5px solid transparent; - content: ""; - position: absolute -} - -.introjs-arrow.top { - top: -10px; - left: 10px; - border-bottom-color: #fff -} - -.introjs-arrow.top-right { - top: -10px; - right: 10px; - border-bottom-color: #fff -} - -.introjs-arrow.top-middle { - top: -10px; - left: 50%; - margin-left: -5px; - border-bottom-color: #fff -} - -.introjs-arrow.right { - right: -10px; - top: 10px; - border-left-color: #fff -} - -.introjs-arrow.right-bottom { - bottom: 10px; - right: -10px; - border-left-color: #fff -} - -.introjs-arrow.bottom { - bottom: -10px; - left: 10px; - border-top-color: #fff -} - -.introjs-arrow.bottom-right { - bottom: -10px; - right: 10px; - border-top-color: #fff -} - -.introjs-arrow.bottom-middle { - bottom: -10px; - left: 50%; - margin-left: -5px; - border-top-color: #fff -} - -.introjs-arrow.left { - left: -10px; - top: 10px; - border-right-color: #fff -} - -.introjs-arrow.left-bottom { - left: -10px; - bottom: 10px; - border-right-color: #fff -} - -.introjs-tooltip { - box-sizing: content-box; - position: absolute; - visibility: visible; - background-color: #fff; - min-width: 250px; - max-width: 300px; - border-radius: 5px; - box-shadow: 0 3px 30px rgba(33, 33, 33, .3); - transition: opacity .1s ease-out -} - -.introjs-tooltiptext { - padding: 20px; -} - -.introjs-tooltiptext img { - width: 100%; -} - -.introjs-dontShowAgain { - padding-left: 20px; - padding-right: 20px -} - -.introjs-dontShowAgain input { - padding: 0; - margin: 0; - margin-bottom: 2px; - display: inline; - width: 10px; - height: 10px -} - -.introjs-dontShowAgain label { - font-size: 14px; - display: inline-block; - font-weight: 400; - margin: 0 0 0 5px; - padding: 0; - background-color: #fff; - color: #616161; - -webkit-user-select: none; - user-select: none -} - -.introjs-tooltip-title { - font-size: 18px; - width: 90%; - min-height: 1.5em; - margin: 0; - padding: 0; - font-weight: 700; - line-height: 1.5 -} - -.introjs-tooltip-header { - position: relative; - padding-left: 20px; - padding-right: 20px; - padding-top: 10px; - min-height: 1.5em -} - -.introjs-tooltipbuttons { - border-top: 1px solid #e0e0e0; - padding: 10px; - text-align: right; - white-space: nowrap -} - -.introjs-tooltipbuttons:after { - content: ""; - visibility: hidden; - display: block; - height: 0; - clear: both -} - -.introjs-button { - box-sizing: content-box; - position: relative; - overflow: visible; - padding: .5rem 1rem; - border: 1px solid #bdbdbd; - text-decoration: none; - text-shadow: 1px 1px 0 #fff; - font-size: 14px; - color: #424242; - white-space: nowrap; - cursor: pointer; - outline: 0; - background-color: #f4f4f4; - border-radius: .2em; - zoom: 1; - display: inline -} - -.introjs-button:hover { - outline: 0; - text-decoration: none; - border-color: #9e9e9e; - background-color: #e0e0e0; - color: #212121 -} - -.introjs-button:focus { - outline: 0; - text-decoration: none; - background-color: #eee; - box-shadow: 0 0 0 .2rem rgba(158, 158, 158, .5); - border: 1px solid #616161; - color: #212121 -} - -.introjs-button:active { - outline: 0; - text-decoration: none; - background-color: #e0e0e0; - border-color: #9e9e9e; - color: #212121 -} - -.introjs-button::-moz-focus-inner { - padding: 0; - border: 0 -} - -.introjs-skipbutton { - position: absolute; - top: 0; - right: 10px; - display: inline-block; - width: 45px; - height: 45px; - line-height: 45px; - color: #ef0000; - font-size: 18px; - cursor: pointer; - font-weight: 700; - text-align: center; - text-decoration: none -} - -.introjs-skipbutton:focus, -.introjs-skipbutton:hover { - color: #212121; - outline: 0; - text-decoration: none -} - -.introjs-prevbutton { - float: left -} - -.introjs-nextbutton { - float: right -} - -.introjs-disabled { - color: #9e9e9e; - border-color: #bdbdbd; - box-shadow: none; - cursor: default; - background-color: #f4f4f4; - background-image: none; - text-decoration: none -} - -.introjs-disabled:focus, -.introjs-disabled:hover { - color: #9e9e9e; - border-color: #bdbdbd; - box-shadow: none; - cursor: default; - background-color: #f4f4f4; - background-image: none; - text-decoration: none -} - -.introjs-hidden { - display: none -} - -.introjs-bullets { - text-align: center; - padding-top: 10px; - padding-bottom: 10px -} - -.introjs-bullets ul { - box-sizing: content-box; - clear: both; - margin: 0 auto 0; - padding: 0; - display: inline-block -} - -.introjs-bullets ul li { - box-sizing: content-box; - list-style: none; - float: left; - margin: 0 2px -} - -.introjs-bullets ul li a { - transition: width .1s ease-in; - box-sizing: content-box; - display: block; - width: 6px; - height: 6px; - background: #ccc; - border-radius: 10px; - text-decoration: none; - cursor: pointer -} - -.introjs-bullets ul li a:focus, -.introjs-bullets ul li a:hover { - width: 15px; - background: #999; - text-decoration: none; - outline: 0 -} - -.introjs-bullets ul li a.active { - width: 15px; - background: #999 -} - -.introjs-progress { - box-sizing: content-box; - overflow: hidden; - height: 10px; - margin: 10px; - border-radius: 4px; - background-color: #e0e0e0 -} - -.introjs-progressbar { - box-sizing: content-box; - float: left; - width: 0%; - height: 100%; - font-size: 10px; - line-height: 10px; - text-align: center; - background-color: #08c -} - -.introjsFloatingElement { - position: absolute; - height: 0; - width: 0; - left: 50%; - top: 50% -} - -.introjs-fixedTooltip { - position: fixed -} - -.introjs-hint { - box-sizing: content-box; - position: absolute; - background: 0 0; - width: 20px; - height: 15px; - cursor: pointer -} - -.introjs-hint:focus { - border: 0; - outline: 0 -} - -.introjs-hint:hover>.introjs-hint-pulse { - background-color: rgba(60, 60, 60, .57) -} - -.introjs-hidehint { - display: none -} - -.introjs-fixedhint { - position: fixed -} - -@keyframes introjspulse { - 0% { - transform: scale(.95); - box-shadow: 0 0 0 0 rgba(0, 0, 0, .7) - } - - 70% { - transform: scale(1); - box-shadow: 0 0 0 10px transparent - } - - 100% { - transform: scale(.95); - box-shadow: 0 0 0 0 transparent - } -} - -.introjs-hint-pulse { - box-sizing: content-box; - width: 15px; - height: 15px; - border-radius: 30px; - background-color: rgba(136, 136, 136, .24); - z-index: 10; - position: absolute; - transition: all .2s ease-out; - animation: introjspulse 2s infinite -} - -.introjs-hint-no-anim .introjs-hint-pulse { - animation: none -} - -.introjs-hint-dot { - box-sizing: content-box; - background: 0 0; - border-radius: 60px; - height: 50px; - width: 50px; - position: absolute; - top: -18px; - left: -18px; - z-index: 1; - opacity: 0 -} diff --git a/ckanext/tour/assets/js/tour-htmx.js b/ckanext/tour/assets/js/tour-htmx.js deleted file mode 100644 index ea7156f..0000000 --- a/ckanext/tour/assets/js/tour-htmx.js +++ /dev/null @@ -1,39 +0,0 @@ -/** - * A hack script to properly load CKAN modules on an AJAX loaded HTML - */ -ckan.module("tour-htmx", function ($) { - return { - initialize: function () { - $.proxyAll(this, /_on/); - - document.addEventListener('htmx:beforeRequest', this._onHTMXbeforeRequest); - document.addEventListener('htmx:afterSettle', this._onHTMXafterSettle); - document.addEventListener('htmx:pushedIntoHistory', this._onHTMXpushedIntoHistory); - }, - - _onHTMXbeforeRequest: function (e) { - $(e.detail.target).find("[data-module]").unbind() - - for (const [key, _] of Object.entries(ckan.module.instances)) { - ckan.module.instances[key] = null; - } - }, - - _onHTMXafterSettle: function (e) { - const doNotInitialize = ["tour-htmx"] - - if (e.detail.pathInfo.requestPath === "/admin_panel/config/tour/add_step") { - var newStep = $(".tour-steps__steps .tour-step").last(); - - newStep.find("[data-module]").each(function (_, element) { - const moduleName = $(element).attr("data-module"); - - if (!doNotInitialize.includes(moduleName)) { - ckan.module.initializeElement(element); - } - }) - } - - }, - }; -}); diff --git a/ckanext/tour/assets/js/tour-image-upload.js b/ckanext/tour/assets/js/tour-image-upload.js index 7a822fd..b351233 100644 --- a/ckanext/tour/assets/js/tour-image-upload.js +++ b/ckanext/tour/assets/js/tour-image-upload.js @@ -47,8 +47,6 @@ this.ckan.module('tour-image-upload', function ($) { // this is the location for the upload/link data/image label this.label_location = this.scope.find('label[for="field-image-url"]'); - // determines if the resource is a data resource - this.is_data_resource = (this.options.field_url === 'url') && (this.options.field_upload === 'upload'); this.previousUpload = this.options.previous_upload; // Is there a clear checkbox on the form already? @@ -81,8 +79,8 @@ this.ckan.module('tour-image-upload', function ($) { } // Button for resetting the form when there is a URL set - var removeText = this._('Remove'); - $('' + var removeText = this._('Clear'); + $('' + removeText + '') .prop('title', removeText) .on('click', this._onRemove) @@ -97,7 +95,6 @@ this.ckan.module('tour-image-upload', function ($) { .on('mouseout', this._onInputMouseOut) .on('change', this._onInputChange) .prop('title', this._('Upload a file on your computer')) - .css('width', this.button_upload.outerWidth()); // Fields storage. Used in this.changeState this.fields = $('') @@ -108,8 +105,7 @@ this.ckan.module('tour-image-upload', function ($) { .add(this.field_image); // Disables autoName if user modifies name field - this.field_name - .on('change', this._onModifyName); + this.field_name.on('change', this._onModifyName); // Disables autoName if resource name already has value, // i.e. we on edit page if (this.field_name.val()) { @@ -118,59 +114,16 @@ this.ckan.module('tour-image-upload', function ($) { if (options.is_url) { this._showOnlyFieldUrl(); - - this._updateUrlLabel(this._('URL')); } else if (options.is_upload) { this._showOnlyFieldUrl(); this.field_url_input.prop('readonly', true); this.field_url_input.val(this.field_url_input.val()); - - this._updateUrlLabel(this._('File')); } else { this._showOnlyButtons(); } }, - /* Quick way of getting just the filename from the uri of the resource data - * - * url - The url of the uploaded data file - * - * Returns String. - */ - _fileNameFromUpload: function (url) { - // If it's a local CKAN image return the entire URL. - if (/^\/base\/images/.test(url)) { - return url; - } - - // remove fragment (#) - url = url.substring(0, (url.indexOf("#") === -1) ? url.length : url.indexOf("#")); - // remove query string - url = url.substring(0, (url.indexOf("?") === -1) ? url.length : url.indexOf("?")); - // extract the filename - url = url.substring(url.lastIndexOf("/") + 1, url.length); - - return url; // filename - }, - - /* Update the `this.label_location` text - * - * If the upload/link is for a data resource, rather than an image, - * the text for label[for="field-image-url"] will be updated. - * - * label_text - The text for the label of an uploaded/linked resource - * - * Returns nothing. - */ - _updateUrlLabel: function (label_text) { - if (!this.is_data_resource) { - return; - } - - this.label_location.text(label_text); - }, - /* Event listener for when someone sets the field to URL mode * * Returns nothing. @@ -184,8 +137,6 @@ this.ckan.module('tour-image-upload', function ($) { if (this.options.is_upload) { this.field_clear.val('true'); } - - this._updateUrlLabel(this._('URL')); }, /* Event listener for resetting the field back to the blank state @@ -225,8 +176,6 @@ this.ckan.module('tour-image-upload', function ($) { this._showOnlyFieldUrl(); this._autoName(file_name); - - this._updateUrlLabel(this._('File')); }, /* Show only the buttons, hiding all others diff --git a/ckanext/tour/assets/js/tour-init-intro.js b/ckanext/tour/assets/js/tour-init-intro.js deleted file mode 100644 index b0eb2a1..0000000 --- a/ckanext/tour/assets/js/tour-init-intro.js +++ /dev/null @@ -1,104 +0,0 @@ -/** - * This is a first implementation of tour with intro.js library. - * Unfortunately, the license of this library is not suitable for us, since it's - * not free for commercial use. Leaving it there for a while, maybe the new implementation - * with shepherd.js has some significant flaws. - */ -this.ckan.module('tour-init', function (jQuery) { - return { - options: { - template: [ - '', - '', - '', - '' - ].join('\n') - }, - - initialize: function () { - $.proxyAll(this, /_/); - - this.intro = null; - this.isMobile = this._isMobile() - - $.ajax({ - url: this.sandbox.url("/api/action/tour_list"), - success: this._onSuccessRequest - }); - }, - - _isMobile: function () { - var md = new MobileDetect(window.navigator.userAgent); - return md.mobile() ? true : false; - }, - - /** - * Creates a tour mark if not exist - * - * @returns - */ - createMark: function () { - if (!this.mark) { - this.mark = jQuery(this.options.template); - } - return this.mark; - }, - - _onSuccessRequest: function (data) { - data.result.forEach(element => this._initIntro(element)); - }, - - _initIntro: function (introData) { - console.log(introData); - var showed = localStorage.getItem('intro-' + introData.id); - var shouldAttach = introData.state === "active"; - var shouldStart = !showed && !this.isMobile && window.location.pathname == introData.page; - var anchorExists = $(introData.anchor).length; - - this.intro = introJs(); - this.intro.setOptions({ - overlayOpacity: 0.7, - nextLabel: ' → ', - prevLabel: '← ', - skipLabel: this._('Skip'), - doneLabel: this._('Got it!'), - showStepNumbers: false, - exitOnEsc: true, // default - exitOnOverlayClick: true, // default - keyboardNavigation: true, // default - showButtons: true, // default - showBullets: true, // default, - showProgress: false, // default - steps: this._prepareSteps(introData.steps), - }); - - if (shouldAttach && !shouldStart) { - this.createMark(); - - this.mark.insertAfter(anchorExists ? introData.anchor : '.breadcrumb .active'); - this.mark.on('click', this._onClick); - } - - if (shouldStart) { - localStorage.setItem('intro-' + introData.id, 1); - this.intro.start(); - } - }, - - _prepareSteps: function (steps) { - steps.forEach(step => { - if (step.image) { - step.intro = step.intro + "

" + $("", { - src: step.image.url - })[0].outerHTML; - } - }); - - return steps; - }, - - _onClick: function (e) { - this.intro.start(); - } - } -}); diff --git a/ckanext/tour/assets/js/tour-init.js b/ckanext/tour/assets/js/tour-init.js index 33cae57..1442fc6 100644 --- a/ckanext/tour/assets/js/tour-init.js +++ b/ckanext/tour/assets/js/tour-init.js @@ -2,11 +2,15 @@ this.ckan.module('tour-init', function (jQuery) { return { options: { template: [ - '', + '', '', '', '' - ].join('\n') + ].join('\n'), + config: { + autoplay: false, + default_anchor: ".breadcrumb .active" + } }, initialize: function () { @@ -43,15 +47,17 @@ this.ckan.module('tour-init', function (jQuery) { }, _initIntro: function (introData) { + var isActive = introData.state === "active"; var showed = localStorage.getItem('intro-' + introData.id); - var shouldAttach = introData.state === "active"; - var shouldStart = !showed && !this.isMobile && window.location.pathname == introData.page; + + var shouldAttach = isActive && (!introData.page || window.location.pathname == introData.page); + var shouldStart = isActive && !showed && !this.isMobile && window.location.pathname == introData.page; var anchorExists = $(introData.anchor).length; this.tour = new Shepherd.Tour({ useModalOverlay: true, defaultStepOptions: { - floatingUIOptions: { middleware: [FloatingUICore.offset(20)]}, + floatingUIOptions: { middleware: [FloatingUICore.offset(20)] }, cancelIcon: { enabled: true, label: "Skip tour" @@ -100,14 +106,14 @@ this.ckan.module('tour-init', function (jQuery) { this.tour.addSteps(this._prepareSteps(introData.steps)); - if (shouldAttach && !shouldStart) { + if (shouldAttach) { this.createMark(); - this.mark.insertAfter(anchorExists ? introData.anchor : '.breadcrumb .active'); + this.mark.insertAfter(anchorExists ? introData.anchor : this.options.config.default_anchor); this.mark.on('click', this._onClick); } - if (shouldStart) { + if (shouldStart && this.options.config.autoplay) { localStorage.setItem('intro-' + introData.id, 1); this.tour.start(); } diff --git a/ckanext/tour/assets/js/tour-steps.js b/ckanext/tour/assets/js/tour-steps.js index f47d148..2097444 100644 --- a/ckanext/tour/assets/js/tour-steps.js +++ b/ckanext/tour/assets/js/tour-steps.js @@ -11,7 +11,6 @@ ckan.module("tour-steps", function ($) { this.addStepBtn = $(".add-step"); // add event listeners - $(document).on('click', '.add-step', this._afterStepAdded); $(document).on('click', '.btn-collapse-steps', this._onCollapseAllSteps); // HTMX events @@ -57,10 +56,6 @@ ckan.module("tour-steps", function ($) { }); }, - _afterStepAdded: function (e) { - // - }, - /** * Remove a step node from DOM * @@ -110,7 +105,18 @@ ckan.module("tour-steps", function ($) { _onCollapseAllSteps: function (e) { e.preventDefault(); - $(".tour-steps__steps .accordion-collapse").collapse("hide"); + + if ($('.btn-collapse-steps').attr("collapsed") == 1) { + $(".tour-steps__steps .accordion-collapse").collapse("show"); + + $('.btn-collapse-steps').text("Collapse all steps"); + $('.btn-collapse-steps').attr("collapsed", 0); + } else { + $(".tour-steps__steps .accordion-collapse").collapse("hide"); + + $('.btn-collapse-steps').text("Expand all steps"); + $('.btn-collapse-steps').attr("collapsed", 1); + } } }; }); diff --git a/ckanext/tour/assets/js/vendor/htmx.min.js b/ckanext/tour/assets/js/vendor/htmx.min.js deleted file mode 100644 index cc0d236..0000000 --- a/ckanext/tour/assets/js/vendor/htmx.min.js +++ /dev/null @@ -1 +0,0 @@ -(function(e,t){if(typeof define==="function"&&define.amd){define([],t)}else if(typeof module==="object"&&module.exports){module.exports=t()}else{e.htmx=e.htmx||t()}})(typeof self!=="undefined"?self:this,function(){return function(){"use strict";var G={onLoad:t,process:Nt,on:ue,off:fe,trigger:oe,ajax:mr,find:b,findAll:f,closest:d,values:function(e,t){var r=Qt(e,t||"post");return r.values},remove:B,addClass:V,removeClass:n,toggleClass:j,takeClass:W,defineExtension:Er,removeExtension:Cr,logAll:F,logNone:U,logger:null,config:{historyEnabled:true,historyCacheSize:10,refreshOnHistoryMiss:false,defaultSwapStyle:"innerHTML",defaultSwapDelay:0,defaultSettleDelay:20,includeIndicatorStyles:true,indicatorClass:"htmx-indicator",requestClass:"htmx-request",addedClass:"htmx-added",settlingClass:"htmx-settling",swappingClass:"htmx-swapping",allowEval:true,inlineScriptNonce:"",attributesToSettle:["class","style","width","height"],withCredentials:false,timeout:0,wsReconnectDelay:"full-jitter",wsBinaryType:"blob",disableSelector:"[hx-disable], [data-hx-disable]",useTemplateFragments:false,scrollBehavior:"smooth",defaultFocusScroll:false,getCacheBusterParam:false,globalViewTransitions:false,methodsThatUseUrlParams:["get"]},parseInterval:v,_:e,createEventSource:function(e){return new EventSource(e,{withCredentials:true})},createWebSocket:function(e){var t=new WebSocket(e,[]);t.binaryType=G.config.wsBinaryType;return t},version:"1.9.3"};var C={addTriggerHandler:bt,bodyContains:re,canAccessLocalStorage:D,findThisElement:de,filterValues:ir,hasAttribute:q,getAttributeValue:Z,getClosestAttributeValue:Y,getClosestMatch:c,getExpressionVars:vr,getHeaders:nr,getInputValues:Qt,getInternalData:ee,getSwapSpecification:or,getTriggerSpecs:Ge,getTarget:ve,makeFragment:l,mergeObjects:ne,makeSettleInfo:S,oobSwap:xe,querySelectorExt:ie,selectAndSwap:Xe,settleImmediately:Wt,shouldCancel:Qe,triggerEvent:oe,triggerErrorEvent:ae,withExtensions:w};var R=["get","post","put","delete","patch"];var O=R.map(function(e){return"[hx-"+e+"], [data-hx-"+e+"]"}).join(", ");function v(e){if(e==undefined){return undefined}if(e.slice(-2)=="ms"){return parseFloat(e.slice(0,-2))||undefined}if(e.slice(-1)=="s"){return parseFloat(e.slice(0,-1))*1e3||undefined}if(e.slice(-1)=="m"){return parseFloat(e.slice(0,-1))*1e3*60||undefined}return parseFloat(e)||undefined}function J(e,t){return e.getAttribute&&e.getAttribute(t)}function q(e,t){return e.hasAttribute&&(e.hasAttribute(t)||e.hasAttribute("data-"+t))}function Z(e,t){return J(e,t)||J(e,"data-"+t)}function u(e){return e.parentElement}function K(){return document}function c(e,t){while(e&&!t(e)){e=u(e)}return e?e:null}function T(e,t,r){var n=Z(t,r);var i=Z(t,"hx-disinherit");if(e!==t&&i&&(i==="*"||i.split(" ").indexOf(r)>=0)){return"unset"}else{return n}}function Y(t,r){var n=null;c(t,function(e){return n=T(t,e,r)});if(n!=="unset"){return n}}function h(e,t){var r=e.matches||e.matchesSelector||e.msMatchesSelector||e.mozMatchesSelector||e.webkitMatchesSelector||e.oMatchesSelector;return r&&r.call(e,t)}function H(e){var t=/<([a-z][^\/\0>\x20\t\r\n\f]*)/i;var r=t.exec(e);if(r){return r[1].toLowerCase()}else{return""}}function i(e,t){var r=new DOMParser;var n=r.parseFromString(e,"text/html");var i=n.body;while(t>0){t--;i=i.firstChild}if(i==null){i=K().createDocumentFragment()}return i}function L(e){return e.match(/",0);return r.querySelector("template").content}else{var n=H(e);switch(n){case"thead":case"tbody":case"tfoot":case"colgroup":case"caption":return i(""+e+"
",1);case"col":return i(""+e+"
",2);case"tr":return i(""+e+"
",2);case"td":case"th":return i(""+e+"
",3);case"script":return i("
"+e+"
",1);default:return i(e,0)}}}function Q(e){if(e){e()}}function A(e,t){return Object.prototype.toString.call(e)==="[object "+t+"]"}function N(e){return A(e,"Function")}function I(e){return A(e,"Object")}function ee(e){var t="htmx-internal-data";var r=e[t];if(!r){r=e[t]={}}return r}function k(e){var t=[];if(e){for(var r=0;r=0}function re(e){if(e.getRootNode&&e.getRootNode()instanceof ShadowRoot){return K().body.contains(e.getRootNode().host)}else{return K().body.contains(e)}}function M(e){return e.trim().split(/\s+/)}function ne(e,t){for(var r in t){if(t.hasOwnProperty(r)){e[r]=t[r]}}return e}function y(e){try{return JSON.parse(e)}catch(e){x(e);return null}}function D(){var e="htmx:localStorageTest";try{localStorage.setItem(e,e);localStorage.removeItem(e);return true}catch(e){return false}}function X(t){try{var e=new URL(t);if(e){t=e.pathname+e.search}if(!t.match("^/$")){t=t.replace(/\/+$/,"")}return t}catch(e){return t}}function e(e){return cr(K().body,function(){return eval(e)})}function t(t){var e=G.on("htmx:load",function(e){t(e.detail.elt)});return e}function F(){G.logger=function(e,t,r){if(console){console.log(t,e,r)}}}function U(){G.logger=null}function b(e,t){if(t){return e.querySelector(t)}else{return b(K(),e)}}function f(e,t){if(t){return e.querySelectorAll(t)}else{return f(K(),e)}}function B(e,t){e=s(e);if(t){setTimeout(function(){B(e);e=null},t)}else{e.parentElement.removeChild(e)}}function V(e,t,r){e=s(e);if(r){setTimeout(function(){V(e,t);e=null},r)}else{e.classList&&e.classList.add(t)}}function n(e,t,r){e=s(e);if(r){setTimeout(function(){n(e,t);e=null},r)}else{if(e.classList){e.classList.remove(t);if(e.classList.length===0){e.removeAttribute("class")}}}}function j(e,t){e=s(e);e.classList.toggle(t)}function W(e,t){e=s(e);te(e.parentElement.children,function(e){n(e,t)});V(e,t)}function d(e,t){e=s(e);if(e.closest){return e.closest(t)}else{do{if(e==null||h(e,t)){return e}}while(e=e&&u(e));return null}}function r(e){var t=e.trim();if(t.startsWith("<")&&t.endsWith("/>")){return t.substring(1,t.length-2)}else{return t}}function _(e,t){if(t.indexOf("closest ")===0){return[d(e,r(t.substr(8)))]}else if(t.indexOf("find ")===0){return[b(e,r(t.substr(5)))]}else if(t.indexOf("next ")===0){return[z(e,r(t.substr(5)))]}else if(t.indexOf("previous ")===0){return[$(e,r(t.substr(9)))]}else if(t==="document"){return[document]}else if(t==="window"){return[window]}else{return K().querySelectorAll(r(t))}}var z=function(e,t){var r=K().querySelectorAll(t);for(var n=0;n=0;n--){var i=r[n];if(i.compareDocumentPosition(e)===Node.DOCUMENT_POSITION_FOLLOWING){return i}}};function ie(e,t){if(t){return _(e,t)[0]}else{return _(K().body,e)[0]}}function s(e){if(A(e,"String")){return b(e)}else{return e}}function le(e,t,r){if(N(t)){return{target:K().body,event:e,listener:t}}else{return{target:s(e),event:t,listener:r}}}function ue(t,r,n){Or(function(){var e=le(t,r,n);e.target.addEventListener(e.event,e.listener)});var e=N(r);return e?r:n}function fe(t,r,n){Or(function(){var e=le(t,r,n);e.target.removeEventListener(e.event,e.listener)});return N(r)?r:n}var ce=K().createElement("output");function he(e,t){var r=Y(e,t);if(r){if(r==="this"){return[de(e,t)]}else{var n=_(e,r);if(n.length===0){x('The selector "'+r+'" on '+t+" returned no matches!");return[ce]}else{return n}}}}function de(e,t){return c(e,function(e){return Z(e,t)!=null})}function ve(e){var t=Y(e,"hx-target");if(t){if(t==="this"){return de(e,"hx-target")}else{return ie(e,t)}}else{var r=ee(e);if(r.boosted){return K().body}else{return e}}}function ge(e){var t=G.config.attributesToSettle;for(var r=0;r0){o=e.substr(0,e.indexOf(":"));t=e.substr(e.indexOf(":")+1,e.length)}else{o=e}var r=K().querySelectorAll(t);if(r){te(r,function(e){var t;var r=i.cloneNode(true);t=K().createDocumentFragment();t.appendChild(r);if(!me(o,e)){t=r}var n={shouldSwap:true,target:e,fragment:t};if(!oe(e,"htmx:oobBeforeSwap",n))return;e=n.target;if(n["shouldSwap"]){Me(o,e,e,t,a)}te(a.elts,function(e){oe(e,"htmx:oobAfterSwap",n)})});i.parentNode.removeChild(i)}else{i.parentNode.removeChild(i);ae(K().body,"htmx:oobErrorNoTarget",{content:i})}return e}function ye(e,t,r){var n=Y(e,"hx-select-oob");if(n){var i=n.split(",");for(let e=0;e0){var t=e.id.replace("'","\\'");var r=e.tagName.replace(":","\\:");var n=a.querySelector(r+"[id='"+t+"']");if(n&&n!==a){var i=e.cloneNode();pe(e,n);o.tasks.push(function(){pe(e,i)})}}})}function Se(e){return function(){n(e,G.config.addedClass);Nt(e);St(e);Ee(e);oe(e,"htmx:load")}}function Ee(e){var t="[autofocus]";var r=h(e,t)?e:e.querySelector(t);if(r!=null){r.focus()}}function a(e,t,r,n){we(e,r,n);while(r.childNodes.length>0){var i=r.firstChild;V(i,G.config.addedClass);e.insertBefore(i,t);if(i.nodeType!==Node.TEXT_NODE&&i.nodeType!==Node.COMMENT_NODE){n.tasks.push(Se(i))}}}function Ce(e,t){var r=0;while(re!=t);while(n&&n!==t){if(n.nodeType===Node.ELEMENT_NODE){r.elts.push(n)}n=n.nextElementSibling}o(t);u(t).removeChild(t)}}function He(e,t,r){return a(e,e.firstChild,t,r)}function Le(e,t,r){return a(u(e),e,t,r)}function Ae(e,t,r){return a(e,null,t,r)}function Ne(e,t,r){return a(u(e),e.nextSibling,t,r)}function Ie(e,t,r){o(e);return u(e).removeChild(e)}function ke(e,t,r){var n=e.firstChild;a(e,n,t,r);if(n){while(n.nextSibling){o(n.nextSibling);e.removeChild(n.nextSibling)}o(n);e.removeChild(n)}}function Pe(e,t,r){var n=r||Y(e,"hx-select");if(n){var i=K().createDocumentFragment();te(t.querySelectorAll(n),function(e){i.appendChild(e)});t=i}return t}function Me(e,t,r,n,i){switch(e){case"none":return;case"outerHTML":Te(r,n,i);return;case"afterbegin":He(r,n,i);return;case"beforebegin":Le(r,n,i);return;case"beforeend":Ae(r,n,i);return;case"afterend":Ne(r,n,i);return;case"delete":Ie(r,n,i);return;default:var a=Rr(t);for(var o=0;o-1){var t=e.replace(/]*>|>)([\s\S]*?)<\/svg>/gim,"");var r=t.match(/]*>|>)([\s\S]*?)<\/title>/im);if(r){return r[2]}}}function Xe(e,t,r,n,i,a){i.title=De(n);var o=l(n);if(o){ye(r,o,i);o=Pe(r,o,a);be(o);return Me(e,r,t,o,i)}}function Fe(e,t,r){var n=e.getResponseHeader(t);if(n.indexOf("{")===0){var i=y(n);for(var a in i){if(i.hasOwnProperty(a)){var o=i[a];if(!I(o)){o={value:o}}oe(r,a,o)}}}else{oe(r,n,[])}}var Ue=/\s/;var g=/[\s,]/;var Be=/[_$a-zA-Z]/;var Ve=/[_$a-zA-Z0-9]/;var je=['"',"'","/"];var p=/[^\s]/;function We(e){var t=[];var r=0;while(r0){var o=t[0];if(o==="]"){n--;if(n===0){if(a===null){i=i+"true"}t.shift();i+=")})";try{var s=cr(e,function(){return Function(i)()},function(){return true});s.source=i;return s}catch(e){ae(K().body,"htmx:syntax:error",{error:e,source:i});return null}}}else if(o==="["){n++}if(_e(o,a,r)){i+="(("+r+"."+o+") ? ("+r+"."+o+") : (window."+o+"))"}else{i=i+o}a=t.shift()}}}function m(e,t){var r="";while(e.length>0&&!e[0].match(t)){r+=e.shift()}return r}var $e="input, textarea, select";function Ge(e){var t=Z(e,"hx-trigger");var r=[];if(t){var n=We(t);do{m(n,p);var i=n.length;var a=m(n,/[,\[\s]/);if(a!==""){if(a==="every"){var o={trigger:"every"};m(n,p);o.pollInterval=v(m(n,/[,\[\s]/));m(n,p);var s=ze(e,n,"event");if(s){o.eventFilter=s}r.push(o)}else if(a.indexOf("sse:")===0){r.push({trigger:"sse",sseEvent:a.substr(4)})}else{var l={trigger:a};var s=ze(e,n,"event");if(s){l.eventFilter=s}while(n.length>0&&n[0]!==","){m(n,p);var u=n.shift();if(u==="changed"){l.changed=true}else if(u==="once"){l.once=true}else if(u==="consume"){l.consume=true}else if(u==="delay"&&n[0]===":"){n.shift();l.delay=v(m(n,g))}else if(u==="from"&&n[0]===":"){n.shift();var f=m(n,g);if(f==="closest"||f==="find"||f==="next"||f==="previous"){n.shift();f+=" "+m(n,g)}l.from=f}else if(u==="target"&&n[0]===":"){n.shift();l.target=m(n,g)}else if(u==="throttle"&&n[0]===":"){n.shift();l.throttle=v(m(n,g))}else if(u==="queue"&&n[0]===":"){n.shift();l.queue=m(n,g)}else if((u==="root"||u==="threshold")&&n[0]===":"){n.shift();l[u]=m(n,g)}else{ae(e,"htmx:syntax:error",{token:n.shift()})}}r.push(l)}}if(n.length===i){ae(e,"htmx:syntax:error",{token:n.shift()})}m(n,p)}while(n[0]===","&&n.shift())}if(r.length>0){return r}else if(h(e,"form")){return[{trigger:"submit"}]}else if(h(e,'input[type="button"]')){return[{trigger:"click"}]}else if(h(e,$e)){return[{trigger:"change"}]}else{return[{trigger:"click"}]}}function Je(e){ee(e).cancelled=true}function Ze(e,t,r){var n=ee(e);n.timeout=setTimeout(function(){if(re(e)&&n.cancelled!==true){if(!tt(r,e,kt("hx:poll:trigger",{triggerSpec:r,target:e}))){t(e)}Ze(e,t,r)}},r.pollInterval)}function Ke(e){return location.hostname===e.hostname&&J(e,"href")&&J(e,"href").indexOf("#")!==0}function Ye(t,r,e){if(t.tagName==="A"&&Ke(t)&&(t.target===""||t.target==="_self")||t.tagName==="FORM"){r.boosted=true;var n,i;if(t.tagName==="A"){n="get";i=t.href}else{var a=J(t,"method");n=a?a.toLowerCase():"get";if(n==="get"){}i=J(t,"action")}e.forEach(function(e){rt(t,function(e,t){se(n,i,e,t)},r,e,true)})}}function Qe(e,t){if(e.type==="submit"||e.type==="click"){if(t.tagName==="FORM"){return true}if(h(t,'input[type="submit"], button')&&d(t,"form")!==null){return true}if(t.tagName==="A"&&t.href&&(t.getAttribute("href")==="#"||t.getAttribute("href").indexOf("#")!==0)){return true}}return false}function et(e,t){return ee(e).boosted&&e.tagName==="A"&&t.type==="click"&&(t.ctrlKey||t.metaKey)}function tt(e,t,r){var n=e.eventFilter;if(n){try{return n.call(t,r)!==true}catch(e){ae(K().body,"htmx:eventFilter:error",{error:e,source:n.source});return true}}return false}function rt(i,a,e,o,s){var l=ee(i);var t;if(o.from){t=_(i,o.from)}else{t=[i]}if(o.changed){l.lastValue=i.value}te(t,function(r){var n=function(e){if(!re(i)){r.removeEventListener(o.trigger,n);return}if(et(i,e)){return}if(s||Qe(e,i)){e.preventDefault()}if(tt(o,i,e)){return}var t=ee(e);t.triggerSpec=o;if(t.handledFor==null){t.handledFor=[]}if(t.handledFor.indexOf(i)<0){t.handledFor.push(i);if(o.consume){e.stopPropagation()}if(o.target&&e.target){if(!h(e.target,o.target)){return}}if(o.once){if(l.triggeredOnce){return}else{l.triggeredOnce=true}}if(o.changed){if(l.lastValue===i.value){return}else{l.lastValue=i.value}}if(l.delayed){clearTimeout(l.delayed)}if(l.throttle){return}if(o.throttle){if(!l.throttle){a(i,e);l.throttle=setTimeout(function(){l.throttle=null},o.throttle)}}else if(o.delay){l.delayed=setTimeout(function(){a(i,e)},o.delay)}else{oe(i,"htmx:trigger");a(i,e)}}};if(e.listenerInfos==null){e.listenerInfos=[]}e.listenerInfos.push({trigger:o.trigger,listener:n,on:r});r.addEventListener(o.trigger,n)})}var nt=false;var it=null;function at(){if(!it){it=function(){nt=true};window.addEventListener("scroll",it);setInterval(function(){if(nt){nt=false;te(K().querySelectorAll("[hx-trigger='revealed'],[data-hx-trigger='revealed']"),function(e){ot(e)})}},200)}}function ot(t){if(!q(t,"data-hx-revealed")&&P(t)){t.setAttribute("data-hx-revealed","true");var e=ee(t);if(e.initHash){oe(t,"revealed")}else{t.addEventListener("htmx:afterProcessNode",function(e){oe(t,"revealed")},{once:true})}}}function st(e,t,r){var n=M(r);for(var i=0;i=0){var t=ct(n);setTimeout(function(){lt(s,r,n+1)},t)}};t.onopen=function(e){n=0};ee(s).webSocket=t;t.addEventListener("message",function(e){if(ut(s)){return}var t=e.data;w(s,function(e){t=e.transformResponse(t,null,s)});var r=S(s);var n=l(t);var i=k(n.children);for(var a=0;a0){oe(u,"htmx:validation:halted",i);return}t.send(JSON.stringify(l));if(Qe(e,u)){e.preventDefault()}})}else{ae(u,"htmx:noWebSocketSourceError")}}function ct(e){var t=G.config.wsReconnectDelay;if(typeof t==="function"){return t(e)}if(t==="full-jitter"){var r=Math.min(e,6);var n=1e3*Math.pow(2,r);return n*Math.random()}x('htmx.config.wsReconnectDelay must either be a function or the string "full-jitter"')}function ht(e,t,r){var n=M(r);for(var i=0;i0){var o=n.shift();var s=o.match(/^\s*([a-zA-Z:\-]+:)(.*)/);if(a===0&&s){o.split(":");i=s[1].slice(0,-1);r[i]=s[2]}else{r[i]+=o}a+=qt(o)}for(var l in r){Tt(e,l,r[l])}}}function Lt(t){Oe(t);for(const e of t.attributes){const{name:r,value:n}=e;if(r.startsWith("hx-on:")||r.startsWith("data-hx-on:")){let e=r.slice(r.indexOf(":")+1);if(e.startsWith(":"))e="htmx"+e;Tt(t,e,n)}}}function At(t){if(t.closest&&t.closest(G.config.disableSelector)){return}var r=ee(t);if(r.initHash!==Re(t)){r.initHash=Re(t);qe(t);Ht(t);oe(t,"htmx:beforeProcessNode");if(t.value){r.lastValue=t.value}var e=Ge(t);var n=yt(t,r,e);if(!n){if(Y(t,"hx-boost")==="true"){Ye(t,r,e)}else if(q(t,"hx-trigger")){e.forEach(function(e){bt(t,e,r,function(){})})}}if(t.tagName==="FORM"){Ot(t)}var i=Z(t,"hx-sse");if(i){ht(t,r,i)}var a=Z(t,"hx-ws");if(a){st(t,r,a)}oe(t,"htmx:afterProcessNode")}}function Nt(e){e=s(e);At(e);te(Rt(e),function(e){At(e)});te(Ct(e),Lt)}function It(e){return e.replace(/([a-z0-9])([A-Z])/g,"$1-$2").toLowerCase()}function kt(e,t){var r;if(window.CustomEvent&&typeof window.CustomEvent==="function"){r=new CustomEvent(e,{bubbles:true,cancelable:true,detail:t})}else{r=K().createEvent("CustomEvent");r.initCustomEvent(e,true,true,t)}return r}function ae(e,t,r){oe(e,t,ne({error:t},r))}function Pt(e){return e==="htmx:afterProcessNode"}function w(e,t){te(Rr(e),function(e){try{t(e)}catch(e){x(e)}})}function x(e){if(console.error){console.error(e)}else if(console.log){console.log("ERROR: ",e)}}function oe(e,t,r){e=s(e);if(r==null){r={}}r["elt"]=e;var n=kt(t,r);if(G.logger&&!Pt(t)){G.logger(e,t,r)}if(r.error){x(r.error);oe(e,"htmx:error",{errorInfo:r})}var i=e.dispatchEvent(n);var a=It(t);if(i&&a!==t){var o=kt(a,n.detail);i=i&&e.dispatchEvent(o)}w(e,function(e){i=i&&e.onEvent(t,n)!==false});return i}var Mt=location.pathname+location.search;function Dt(){var e=K().querySelector("[hx-history-elt],[data-hx-history-elt]");return e||K().body}function Xt(e,t,r,n){if(!D()){return}e=X(e);var i=y(localStorage.getItem("htmx-history-cache"))||[];for(var a=0;aG.config.historyCacheSize){i.shift()}while(i.length>0){try{localStorage.setItem("htmx-history-cache",JSON.stringify(i));break}catch(e){ae(K().body,"htmx:historyCacheError",{cause:e,cache:i});i.shift()}}}function Ft(e){if(!D()){return null}e=X(e);var t=y(localStorage.getItem("htmx-history-cache"))||[];for(var r=0;r=200&&this.status<400){oe(K().body,"htmx:historyCacheMissLoad",o);var e=l(this.response);e=e.querySelector("[hx-history-elt],[data-hx-history-elt]")||e;var t=Dt();var r=S(t);var n=De(this.response);if(n){var i=b("title");if(i){i.innerHTML=n}else{window.document.title=n}}ke(t,e,r);Wt(r.tasks);Mt=a;oe(K().body,"htmx:historyRestore",{path:a,cacheMiss:true,serverResponse:this.response})}else{ae(K().body,"htmx:historyCacheMissLoadError",o)}};e.send()}function zt(e){Bt();e=e||location.pathname+location.search;var t=Ft(e);if(t){var r=l(t.content);var n=Dt();var i=S(n);ke(n,r,i);Wt(i.tasks);document.title=t.title;setTimeout(function(){window.scrollTo(0,t.scroll)},0);Mt=e;oe(K().body,"htmx:historyRestore",{path:e,item:t})}else{if(G.config.refreshOnHistoryMiss){window.location.reload(true)}else{_t(e)}}}function $t(e){var t=he(e,"hx-indicator");if(t==null){t=[e]}te(t,function(e){var t=ee(e);t.requestCount=(t.requestCount||0)+1;e.classList["add"].call(e.classList,G.config.requestClass)});return t}function Gt(e){te(e,function(e){var t=ee(e);t.requestCount=(t.requestCount||0)-1;if(t.requestCount===0){e.classList["remove"].call(e.classList,G.config.requestClass)}})}function Jt(e,t){for(var r=0;r=0}function or(e,t){var r=t?t:Y(e,"hx-swap");var n={swapStyle:ee(e).boosted?"innerHTML":G.config.defaultSwapStyle,swapDelay:G.config.defaultSwapDelay,settleDelay:G.config.defaultSettleDelay};if(ee(e).boosted&&!ar(e)){n["show"]="top"}if(r){var i=M(r);if(i.length>0){n["swapStyle"]=i[0];for(var a=1;a0?l.join(":"):null;n["scroll"]=u;n["scrollTarget"]=f}if(o.indexOf("show:")===0){var c=o.substr(5);var l=c.split(":");var h=l.pop();var f=l.length>0?l.join(":"):null;n["show"]=h;n["showTarget"]=f}if(o.indexOf("focus-scroll:")===0){var d=o.substr("focus-scroll:".length);n["focusScroll"]=d=="true"}}}}return n}function sr(e){return Y(e,"hx-encoding")==="multipart/form-data"||h(e,"form")&&J(e,"enctype")==="multipart/form-data"}function lr(t,r,n){var i=null;w(r,function(e){if(i==null){i=e.encodeParameters(t,n,r)}});if(i!=null){return i}else{if(sr(r)){return rr(n)}else{return tr(n)}}}function S(e){return{tasks:[],elts:[e]}}function ur(e,t){var r=e[0];var n=e[e.length-1];if(t.scroll){var i=null;if(t.scrollTarget){i=ie(r,t.scrollTarget)}if(t.scroll==="top"&&(r||i)){i=i||r;i.scrollTop=0}if(t.scroll==="bottom"&&(n||i)){i=i||n;i.scrollTop=i.scrollHeight}}if(t.show){var i=null;if(t.showTarget){var a=t.showTarget;if(t.showTarget==="window"){a="body"}i=ie(r,a)}if(t.show==="top"&&(r||i)){i=i||r;i.scrollIntoView({block:"start",behavior:G.config.scrollBehavior})}if(t.show==="bottom"&&(n||i)){i=i||n;i.scrollIntoView({block:"end",behavior:G.config.scrollBehavior})}}}function fr(e,t,r,n){if(n==null){n={}}if(e==null){return n}var i=Z(e,t);if(i){var a=i.trim();var o=r;if(a==="unset"){return null}if(a.indexOf("javascript:")===0){a=a.substr(11);o=true}else if(a.indexOf("js:")===0){a=a.substr(3);o=true}if(a.indexOf("{")!==0){a="{"+a+"}"}var s;if(o){s=cr(e,function(){return Function("return ("+a+")")()},{})}else{s=y(a)}for(var l in s){if(s.hasOwnProperty(l)){if(n[l]==null){n[l]=s[l]}}}}return fr(u(e),t,r,n)}function cr(e,t,r){if(G.config.allowEval){return t()}else{ae(e,"htmx:evalDisallowedError");return r}}function hr(e,t){return fr(e,"hx-vars",true,t)}function dr(e,t){return fr(e,"hx-vals",false,t)}function vr(e){return ne(hr(e),dr(e))}function gr(t,r,n){if(n!==null){try{t.setRequestHeader(r,n)}catch(e){t.setRequestHeader(r,encodeURIComponent(n));t.setRequestHeader(r+"-URI-AutoEncoded","true")}}}function pr(t){if(t.responseURL&&typeof URL!=="undefined"){try{var e=new URL(t.responseURL);return e.pathname+e.search}catch(e){ae(K().body,"htmx:badResponseUrl",{url:t.responseURL})}}}function E(e,t){return e.getAllResponseHeaders().match(t)}function mr(e,t,r){e=e.toLowerCase();if(r){if(r instanceof Element||A(r,"String")){return se(e,t,null,null,{targetOverride:s(r),returnPromise:true})}else{return se(e,t,s(r.source),r.event,{handler:r.handler,headers:r.headers,values:r.values,targetOverride:s(r.target),swapOverride:r.swap,returnPromise:true})}}else{return se(e,t,null,null,{returnPromise:true})}}function xr(e){var t=[];while(e){t.push(e);e=e.parentElement}return t}function se(e,t,n,r,i,M){var a=null;var o=null;i=i!=null?i:{};if(i.returnPromise&&typeof Promise!=="undefined"){var s=new Promise(function(e,t){a=e;o=t})}if(n==null){n=K().body}var D=i.handler||br;if(!re(n)){return}var l=i.targetOverride||ve(n);if(l==null||l==ce){ae(n,"htmx:targetError",{target:Z(n,"hx-target")});return}if(!M){var X=function(){return se(e,t,n,r,i,true)};var F={target:l,elt:n,path:t,verb:e,triggeringEvent:r,etc:i,issueRequest:X};if(oe(n,"htmx:confirm",F)===false){return}}var u=n;var f=ee(n);var c=Y(n,"hx-sync");var h=null;var d=false;if(c){var v=c.split(":");var g=v[0].trim();if(g==="this"){u=de(n,"hx-sync")}else{u=ie(n,g)}c=(v[1]||"drop").trim();f=ee(u);if(c==="drop"&&f.xhr&&f.abortable!==true){return}else if(c==="abort"){if(f.xhr){return}else{d=true}}else if(c==="replace"){oe(u,"htmx:abort")}else if(c.indexOf("queue")===0){var U=c.split(" ");h=(U[1]||"last").trim()}}if(f.xhr){if(f.abortable){oe(u,"htmx:abort")}else{if(h==null){if(r){var p=ee(r);if(p&&p.triggerSpec&&p.triggerSpec.queue){h=p.triggerSpec.queue}}if(h==null){h="last"}}if(f.queuedRequests==null){f.queuedRequests=[]}if(h==="first"&&f.queuedRequests.length===0){f.queuedRequests.push(function(){se(e,t,n,r,i)})}else if(h==="all"){f.queuedRequests.push(function(){se(e,t,n,r,i)})}else if(h==="last"){f.queuedRequests=[];f.queuedRequests.push(function(){se(e,t,n,r,i)})}return}}var m=new XMLHttpRequest;f.xhr=m;f.abortable=d;var x=function(){f.xhr=null;f.abortable=false;if(f.queuedRequests!=null&&f.queuedRequests.length>0){var e=f.queuedRequests.shift();e()}};var y=Y(n,"hx-prompt");if(y){var b=prompt(y);if(b===null||!oe(n,"htmx:prompt",{prompt:b,target:l})){Q(a);x();return s}}var w=Y(n,"hx-confirm");if(w){if(!confirm(w)){Q(a);x();return s}}var S=nr(n,l,b);if(i.headers){S=ne(S,i.headers)}var E=Qt(n,e);var C=E.errors;var R=E.values;if(i.values){R=ne(R,i.values)}var B=vr(n);var O=ne(R,B);var q=ir(O,n);if(e!=="get"&&!sr(n)){S["Content-Type"]="application/x-www-form-urlencoded"}if(G.config.getCacheBusterParam&&e==="get"){q["org.htmx.cache-buster"]=J(l,"id")||"true"}if(t==null||t===""){t=K().location.href}var T=fr(n,"hx-request");var V=ee(n).boosted;var H=G.config.methodsThatUseUrlParams.indexOf(e)>=0;var L={boosted:V,useUrlParams:H,parameters:q,unfilteredParameters:O,headers:S,target:l,verb:e,errors:C,withCredentials:i.credentials||T.credentials||G.config.withCredentials,timeout:i.timeout||T.timeout||G.config.timeout,path:t,triggeringEvent:r};if(!oe(n,"htmx:configRequest",L)){Q(a);x();return s}t=L.path;e=L.verb;S=L.headers;q=L.parameters;C=L.errors;H=L.useUrlParams;if(C&&C.length>0){oe(n,"htmx:validation:halted",L);Q(a);x();return s}var j=t.split("#");var W=j[0];var A=j[1];var N=t;if(H){N=W;var _=Object.keys(q).length!==0;if(_){if(N.indexOf("?")<0){N+="?"}else{N+="&"}N+=tr(q);if(A){N+="#"+A}}}m.open(e.toUpperCase(),N,true);m.overrideMimeType("text/html");m.withCredentials=L.withCredentials;m.timeout=L.timeout;if(T.noHeaders){}else{for(var I in S){if(S.hasOwnProperty(I)){var z=S[I];gr(m,I,z)}}}var k={xhr:m,target:l,requestConfig:L,etc:i,boosted:V,pathInfo:{requestPath:t,finalRequestPath:N,anchor:A}};m.onload=function(){try{var e=xr(n);k.pathInfo.responsePath=pr(m);D(n,k);Gt(P);oe(n,"htmx:afterRequest",k);oe(n,"htmx:afterOnLoad",k);if(!re(n)){var t=null;while(e.length>0&&t==null){var r=e.shift();if(re(r)){t=r}}if(t){oe(t,"htmx:afterRequest",k);oe(t,"htmx:afterOnLoad",k)}}Q(a);x()}catch(e){ae(n,"htmx:onLoadError",ne({error:e},k));throw e}};m.onerror=function(){Gt(P);ae(n,"htmx:afterRequest",k);ae(n,"htmx:sendError",k);Q(o);x()};m.onabort=function(){Gt(P);ae(n,"htmx:afterRequest",k);ae(n,"htmx:sendAbort",k);Q(o);x()};m.ontimeout=function(){Gt(P);ae(n,"htmx:afterRequest",k);ae(n,"htmx:timeout",k);Q(o);x()};if(!oe(n,"htmx:beforeRequest",k)){Q(a);x();return s}var P=$t(n);te(["loadstart","loadend","progress","abort"],function(t){te([m,m.upload],function(e){e.addEventListener(t,function(e){oe(n,"htmx:xhr:"+t,{lengthComputable:e.lengthComputable,loaded:e.loaded,total:e.total})})})});oe(n,"htmx:beforeSend",k);var $=H?null:lr(m,n,q);m.send($);return s}function yr(e,t){var r=t.xhr;var n=null;var i=null;if(E(r,/HX-Push:/i)){n=r.getResponseHeader("HX-Push");i="push"}else if(E(r,/HX-Push-Url:/i)){n=r.getResponseHeader("HX-Push-Url");i="push"}else if(E(r,/HX-Replace-Url:/i)){n=r.getResponseHeader("HX-Replace-Url");i="replace"}if(n){if(n==="false"){return{}}else{return{type:i,path:n}}}var a=t.pathInfo.finalRequestPath;var o=t.pathInfo.responsePath;var s=Y(e,"hx-push-url");var l=Y(e,"hx-replace-url");var u=ee(e).boosted;var f=null;var c=null;if(s){f="push";c=s}else if(l){f="replace";c=l}else if(u){f="push";c=o||a}if(c){if(c==="false"){return{}}if(c==="true"){c=o||a}if(t.pathInfo.anchor&&c.indexOf("#")===-1){c=c+"#"+t.pathInfo.anchor}return{type:f,path:c}}else{return{}}}function br(l,u){var f=u.xhr;var c=u.target;var e=u.etc;if(!oe(l,"htmx:beforeOnLoad",u))return;if(E(f,/HX-Trigger:/i)){Fe(f,"HX-Trigger",l)}if(E(f,/HX-Location:/i)){Bt();var t=f.getResponseHeader("HX-Location");var h;if(t.indexOf("{")===0){h=y(t);t=h["path"];delete h["path"]}mr("GET",t,h).then(function(){Vt(t)});return}if(E(f,/HX-Redirect:/i)){location.href=f.getResponseHeader("HX-Redirect");return}if(E(f,/HX-Refresh:/i)){if("true"===f.getResponseHeader("HX-Refresh")){location.reload();return}}if(E(f,/HX-Retarget:/i)){u.target=K().querySelector(f.getResponseHeader("HX-Retarget"))}var d=yr(l,u);var r=f.status>=200&&f.status<400&&f.status!==204;var v=f.response;var n=f.status>=400;var i=ne({shouldSwap:r,serverResponse:v,isError:n},u);if(!oe(c,"htmx:beforeSwap",i))return;c=i.target;v=i.serverResponse;n=i.isError;u.target=c;u.failed=n;u.successful=!n;if(i.shouldSwap){if(f.status===286){Je(l)}w(l,function(e){v=e.transformResponse(v,f,l)});if(d.type){Bt()}var a=e.swapOverride;if(E(f,/HX-Reswap:/i)){a=f.getResponseHeader("HX-Reswap")}var h=or(l,a);c.classList.add(G.config.swappingClass);var g=null;var p=null;var o=function(){try{var e=document.activeElement;var t={};try{t={elt:e,start:e?e.selectionStart:null,end:e?e.selectionEnd:null}}catch(e){}var r;if(E(f,/HX-Reselect:/i)){r=f.getResponseHeader("HX-Reselect")}var n=S(c);Xe(h.swapStyle,c,l,v,n,r);if(t.elt&&!re(t.elt)&&t.elt.id){var i=document.getElementById(t.elt.id);var a={preventScroll:h.focusScroll!==undefined?!h.focusScroll:!G.config.defaultFocusScroll};if(i){if(t.start&&i.setSelectionRange){try{i.setSelectionRange(t.start,t.end)}catch(e){}}i.focus(a)}}c.classList.remove(G.config.swappingClass);te(n.elts,function(e){if(e.classList){e.classList.add(G.config.settlingClass)}oe(e,"htmx:afterSwap",u)});if(E(f,/HX-Trigger-After-Swap:/i)){var o=l;if(!re(l)){o=K().body}Fe(f,"HX-Trigger-After-Swap",o)}var s=function(){te(n.tasks,function(e){e.call()});te(n.elts,function(e){if(e.classList){e.classList.remove(G.config.settlingClass)}oe(e,"htmx:afterSettle",u)});if(d.type){if(d.type==="push"){Vt(d.path);oe(K().body,"htmx:pushedIntoHistory",{path:d.path})}else{jt(d.path);oe(K().body,"htmx:replacedInHistory",{path:d.path})}}if(u.pathInfo.anchor){var e=b("#"+u.pathInfo.anchor);if(e){e.scrollIntoView({block:"start",behavior:"auto"})}}if(n.title){var t=b("title");if(t){t.innerHTML=n.title}else{window.document.title=n.title}}ur(n.elts,h);if(E(f,/HX-Trigger-After-Settle:/i)){var r=l;if(!re(l)){r=K().body}Fe(f,"HX-Trigger-After-Settle",r)}Q(g)};if(h.settleDelay>0){setTimeout(s,h.settleDelay)}else{s()}}catch(e){ae(l,"htmx:swapError",u);Q(p);throw e}};var s=G.config.globalViewTransitions;if(h.hasOwnProperty("transition")){s=h.transition}if(s&&oe(l,"htmx:beforeTransition",u)&&typeof Promise!=="undefined"&&document.startViewTransition){var m=new Promise(function(e,t){g=e;p=t});var x=o;o=function(){document.startViewTransition(function(){x();return m})}}if(h.swapDelay>0){setTimeout(o,h.swapDelay)}else{o()}}if(n){ae(l,"htmx:responseError",ne({error:"Response Status Error Code "+f.status+" from "+u.pathInfo.requestPath},u))}}var wr={};function Sr(){return{init:function(e){return null},onEvent:function(e,t){return true},transformResponse:function(e,t,r){return e},isInlineSwap:function(e){return false},handleSwap:function(e,t,r,n){return false},encodeParameters:function(e,t,r){return null}}}function Er(e,t){if(t.init){t.init(C)}wr[e]=ne(Sr(),t)}function Cr(e){delete wr[e]}function Rr(e,r,n){if(e==undefined){return r}if(r==undefined){r=[]}if(n==undefined){n=[]}var t=Z(e,"hx-ext");if(t){te(t.split(","),function(e){e=e.replace(/ /g,"");if(e.slice(0,7)=="ignore:"){n.push(e.slice(7));return}if(n.indexOf(e)<0){var t=wr[e];if(t&&r.indexOf(t)<0){r.push(t)}}})}return Rr(u(e),r,n)}function Or(e){if(K().readyState!=="loading"){e()}else{K().addEventListener("DOMContentLoaded",e)}}function qr(){if(G.config.includeIndicatorStyles!==false){K().head.insertAdjacentHTML("beforeend","")}}function Tr(){var e=K().querySelector('meta[name="htmx-config"]');if(e){return y(e.content)}else{return null}}function Hr(){var e=Tr();if(e){G.config=ne(G.config,e)}}Or(function(){Hr();qr();var e=K().body;Nt(e);var t=K().querySelectorAll("[hx-trigger='restored'],[data-hx-trigger='restored']");e.addEventListener("htmx:abort",function(e){var t=e.target;var r=ee(t);if(r&&r.xhr){r.xhr.abort()}});var r=window.onpopstate;window.onpopstate=function(e){if(e.state&&e.state.htmx){zt();te(t,function(e){oe(e,"htmx:restored",{document:K(),triggerEvent:oe})})}else{if(r){r(e)}}};setTimeout(function(){oe(e,"htmx:load",{});e=null},0)});return G}()}); diff --git a/ckanext/tour/assets/js/vendor/intro.min.js b/ckanext/tour/assets/js/vendor/intro.min.js deleted file mode 100644 index 1ce1060..0000000 --- a/ckanext/tour/assets/js/vendor/intro.min.js +++ /dev/null @@ -1,17 +0,0 @@ -/** - * Skipped minification because the original files appears to be already minified. - * Original file: /npm/intro.js@7.0.1/intro.js - * - * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files - */ -/*! - * Intro.js v7.0.1 - * https://introjs.com - * - * Copyright (C) 2012-2023 Afshin Mehrabani (@afshinmeh). - * https://introjs.com - * - * Date: Sat, 25 Mar 2023 14:24:34 GMT - */ -!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).introJs=e()}(this,(function(){"use strict";function t(){t=function(){return e};var e={},n=Object.prototype,r=n.hasOwnProperty,i=Object.defineProperty||function(t,e,n){t[e]=n.value},o="function"==typeof Symbol?Symbol:{},a=o.iterator||"@@iterator",s=o.asyncIterator||"@@asyncIterator",l=o.toStringTag||"@@toStringTag";function c(t,e,n){return Object.defineProperty(t,e,{value:n,enumerable:!0,configurable:!0,writable:!0}),t[e]}try{c({},"")}catch(t){c=function(t,e,n){return t[e]=n}}function u(t,e,n,r){var o=e&&e.prototype instanceof f?e:f,a=Object.create(o.prototype),s=new j(r||[]);return i(a,"_invoke",{value:x(t,n,s)}),a}function h(t,e,n){try{return{type:"normal",arg:t.call(e,n)}}catch(t){return{type:"throw",arg:t}}}e.wrap=u;var p={};function f(){}function d(){}function m(){}var b={};c(b,a,(function(){return this}));var v=Object.getPrototypeOf,y=v&&v(v(A([])));y&&y!==n&&r.call(y,a)&&(b=y);var g=m.prototype=f.prototype=Object.create(b);function w(t){["next","throw","return"].forEach((function(e){c(t,e,(function(t){return this._invoke(e,t)}))}))}function _(t,e){function n(i,o,a,s){var l=h(t[i],t,o);if("throw"!==l.type){var c=l.arg,u=c.value;return u&&"object"==typeof u&&r.call(u,"__await")?e.resolve(u.__await).then((function(t){n("next",t,a,s)}),(function(t){n("throw",t,a,s)})):e.resolve(u).then((function(t){c.value=t,a(c)}),(function(t){return n("throw",t,a,s)}))}s(l.arg)}var o;i(this,"_invoke",{value:function(t,r){function i(){return new e((function(e,i){n(t,r,e,i)}))}return o=o?o.then(i,i):i()}})}function x(t,e,n){var r="suspendedStart";return function(i,o){if("executing"===r)throw new Error("Generator is already running");if("completed"===r){if("throw"===i)throw o;return E()}for(n.method=i,n.arg=o;;){var a=n.delegate;if(a){var s=k(a,n);if(s){if(s===p)continue;return s}}if("next"===n.method)n.sent=n._sent=n.arg;else if("throw"===n.method){if("suspendedStart"===r)throw r="completed",n.arg;n.dispatchException(n.arg)}else"return"===n.method&&n.abrupt("return",n.arg);r="executing";var l=h(t,e,n);if("normal"===l.type){if(r=n.done?"completed":"suspendedYield",l.arg===p)continue;return{value:l.arg,done:n.done}}"throw"===l.type&&(r="completed",n.method="throw",n.arg=l.arg)}}}function k(t,e){var n=t.iterator[e.method];if(void 0===n){if(e.delegate=null,"throw"===e.method){if(t.iterator.return&&(e.method="return",e.arg=void 0,k(t,e),"throw"===e.method))return p;e.method="throw",e.arg=new TypeError("The iterator does not provide a 'throw' method")}return p}var r=h(n,t.iterator,e.arg);if("throw"===r.type)return e.method="throw",e.arg=r.arg,e.delegate=null,p;var i=r.arg;return i?i.done?(e[t.resultName]=i.value,e.next=t.nextLoc,"return"!==e.method&&(e.method="next",e.arg=void 0),e.delegate=null,p):i:(e.method="throw",e.arg=new TypeError("iterator result is not an object"),e.delegate=null,p)}function C(t){var e={tryLoc:t[0]};1 in t&&(e.catchLoc=t[1]),2 in t&&(e.finallyLoc=t[2],e.afterLoc=t[3]),this.tryEntries.push(e)}function S(t){var e=t.completion||{};e.type="normal",delete e.arg,t.completion=e}function j(t){this.tryEntries=[{tryLoc:"root"}],t.forEach(C,this),this.reset(!0)}function A(t){if(t){var e=t[a];if(e)return e.call(t);if("function"==typeof t.next)return t;if(!isNaN(t.length)){var n=-1,i=function e(){for(;++n=0;--i){var o=this.tryEntries[i],a=o.completion;if("root"===o.tryLoc)return n("end");if(o.tryLoc<=this.prev){var s=r.call(o,"catchLoc"),l=r.call(o,"finallyLoc");if(s&&l){if(this.prev=0;--n){var i=this.tryEntries[n];if(i.tryLoc<=this.prev&&r.call(i,"finallyLoc")&&this.prev=0;--e){var n=this.tryEntries[e];if(n.finallyLoc===t)return this.complete(n.completion,n.afterLoc),S(n),p}},catch:function(t){for(var e=this.tryEntries.length-1;e>=0;--e){var n=this.tryEntries[e];if(n.tryLoc===t){var r=n.completion;if("throw"===r.type){var i=r.arg;S(n)}return i}}throw new Error("illegal catch attempt")},delegateYield:function(t,e,n){return this.delegate={iterator:A(t),resultName:e,nextLoc:n},"next"===this.method&&(this.arg=void 0),p}},e}function e(t){return e="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},e(t)}function n(t,e,n,r,i,o,a){try{var s=t[o](a),l=s.value}catch(t){return void n(t)}s.done?e(l):Promise.resolve(l).then(r,i)}function r(t){return function(){var e=this,r=arguments;return new Promise((function(i,o){var a=t.apply(e,r);function s(t){n(a,i,o,s,l,"next",t)}function l(t){n(a,i,o,s,l,"throw",t)}s(void 0)}))}}function i(t,e){for(var n=0;nt.length)&&(e=t.length);for(var n=0,r=new Array(e);n1&&void 0!==arguments[1]?arguments[1]:"introjs-stamp";return l[e]=l[e]||0,void 0===t[e]&&(t[e]=l[e]++),t[e]});function u(t,e,n){if(t)for(var r=0,i=t.length;r=0&&e.left>=0&&e.bottom+80<=window.innerHeight&&e.right<=window.innerWidth}(e)))){var i=b().height;r.bottom-(r.bottom-r.top)<0||e.clientHeight>i?window.scrollBy(0,r.top-(i/2-r.height/2)-this._options.scrollPadding):window.scrollBy(0,r.top-(i/2-r.height/2)+this._options.scrollPadding)}}function y(t){t.setAttribute("role","button"),t.tabIndex=0}function g(t){var e=t.parentElement;return!(!e||"HTML"===e.nodeName)&&("fixed"===f(t,"position")||g(e))}function w(t,e){var n=document.body,r=document.documentElement,i=window.pageYOffset||r.scrollTop||n.scrollTop,o=window.pageXOffset||r.scrollLeft||n.scrollLeft;e=e||n;var a=t.getBoundingClientRect(),s=e.getBoundingClientRect(),l=f(e,"position"),c={width:a.width,height:a.height};return"body"!==e.tagName.toLowerCase()&&"relative"===l||"sticky"===l?Object.assign(c,{top:a.top-s.top,left:a.left-s.left}):g(t)?Object.assign(c,{top:a.top,left:a.left}):Object.assign(c,{top:a.top+i,left:a.left+o})}function _(t,e){if(t instanceof SVGElement){var n=t.getAttribute("class")||"";t.setAttribute("class",n.replace(e,"").replace(/^\s+|\s+$/g,""))}else t.className=t.className.replace(e,"").replace(/^\s+|\s+$/g,"")}function x(t,e){var n="";if(t.style.cssText&&(n+=t.style.cssText),"string"==typeof e)n+=e;else for(var r in e)n+="".concat(r,":").concat(e[r],";");t.style.cssText=n}function k(t){if(t){if(!this._introItems[this._currentStep])return;var e=this._introItems[this._currentStep],n=w(e.element,this._targetElement),r=this._options.helperElementPadding;g(e.element)?p(t,"introjs-fixedTooltip"):_(t,"introjs-fixedTooltip"),"floating"===e.position&&(r=0),x(t,{width:"".concat(n.width+r,"px"),height:"".concat(n.height+r,"px"),top:"".concat(n.top-r/2,"px"),left:"".concat(n.left-r/2,"px")})}}function C(t,e,n,r,i){return t.left+e+n.width>r.width?(i.style.left="".concat(r.width-n.width-t.left,"px"),!1):(i.style.left="".concat(e,"px"),!0)}function S(t,e,n,r){return t.left+t.width-e-n.width<0?(r.style.left="".concat(-t.left,"px"),!1):(r.style.right="".concat(e,"px"),!0)}function j(t,e){t.includes(e)&&t.splice(t.indexOf(e),1)}function A(t,e,n){var r=this._options.positionPrecedence.slice(),i=b(),o=w(e).height+10,a=w(e).width+20,s=t.getBoundingClientRect(),l="floating";s.bottom+o>i.height&&j(r,"bottom"),s.top-o<0&&j(r,"top"),s.right+a>i.width&&j(r,"right"),s.left-a<0&&j(r,"left");var c,u,h=-1!==(u=(c=n||"").indexOf("-"))?c.substr(u):"";return n&&(n=n.split("-")[0]),r.length&&(l=r.includes(n)?n:r[0]),["top","bottom"].includes(l)&&(l+=function(t,e,n,r){var i=e/2,o=Math.min(n,window.screen.width),a=["-left-aligned","-middle-aligned","-right-aligned"];return o-ts.height?(n.className="introjs-arrow left-bottom",e.style.top="-".concat(o.height-a.height-20,"px")):n.className="introjs-arrow left";break;case"left":r||!0!==this._options.showStepNumbers||(e.style.top="15px"),a.top+o.height>s.height?(e.style.top="-".concat(o.height-a.height-20,"px"),n.className="introjs-arrow right-bottom"):n.className="introjs-arrow right",e.style.right="".concat(a.width+20,"px");break;case"floating":n.style.display="none",e.style.left="50%",e.style.top="50%",e.style.marginLeft="-".concat(o.width/2,"px"),e.style.marginTop="-".concat(o.height/2,"px");break;case"bottom-right-aligned":n.className="introjs-arrow top-right",S(a,h=0,o,e),e.style.top="".concat(a.height+20,"px");break;case"bottom-middle-aligned":n.className="introjs-arrow top-middle",r&&(u+=5),S(a,u,o,e)&&(e.style.right=null,C(a,u,o,s,e)),e.style.top="".concat(a.height+20,"px");break;default:n.className="introjs-arrow top",C(a,0,o,s,e),e.style.top="".concat(a.height+20,"px")}}}function N(){u(Array.from(document.querySelectorAll(".introjs-showElement")),(function(t){_(t,/introjs-[a-zA-Z]+/g)}))}function L(t,e){var n=document.createElement(t);e=e||{};var r=/^(?:role|data-|aria-)/;for(var i in e){var o=e[i];"style"===i?x(n,o):i.match(r)?n.setAttribute(i,o):n[i]=o}return n}function T(t,e){var n=arguments.length>2&&void 0!==arguments[2]&&arguments[2];if(n){var r=e.style.opacity||"1";x(e,{opacity:"0"}),window.setTimeout((function(){x(e,{opacity:r})}),10)}t.appendChild(e)}function I(){return parseInt(this._currentStep+1,10)/this._introItems.length*100}function P(){var t=document.querySelector(".introjs-disableInteraction");null===t&&(t=L("div",{className:"introjs-disableInteraction"}),this._targetElement.appendChild(t)),k.call(this,t)}function q(t){var e=this,n=L("div",{className:"introjs-bullets"});!1===this._options.showBullets&&(n.style.display="none");var r=L("ul");r.setAttribute("role","tablist");var i=function(){e.goToStep(this.getAttribute("data-step-number"))};return u(this._introItems,(function(e,n){var o=e.step,a=L("li"),s=L("a");a.setAttribute("role","presentation"),s.setAttribute("role","tab"),s.onclick=i,n===t.step-1&&(s.className="active"),y(s),s.innerHTML=" ",s.setAttribute("data-step-number",o),a.appendChild(s),r.appendChild(a)})),n.appendChild(r),n}function O(t){if(this._options.showBullets){var e=document.querySelector(".introjs-bullets");e&&e.parentNode.replaceChild(q.call(this,t),e)}}function B(t,e){this._options.showBullets&&(t.querySelector(".introjs-bullets li > a.active").className="",t.querySelector('.introjs-bullets li > a[data-step-number="'.concat(e.step,'"]')).className="active")}function H(){var t=L("div");t.className="introjs-progress",!1===this._options.showProgress&&(t.style.display="none");var e=L("div",{className:"introjs-progressbar"});return this._options.progressBarAdditionalClass&&(e.className+=" "+this._options.progressBarAdditionalClass),e.setAttribute("role","progress"),e.setAttribute("aria-valuemin","0"),e.setAttribute("aria-valuemax","100"),e.setAttribute("aria-valuenow",I.call(this)),e.style.cssText="width:".concat(I.call(this),"%;"),t.appendChild(e),t}function R(t){t.querySelector(".introjs-progress .introjs-progressbar").style.cssText="width:".concat(I.call(this),"%;"),t.querySelector(".introjs-progress .introjs-progressbar").setAttribute("aria-valuenow",I.call(this))}function M(t){return F.apply(this,arguments)}function F(){return(F=r(t().mark((function e(n){var i,o,a,s,l,c,u,h,f,b,g,w,_,C,S,j,A,I,O,M,F,D,G,V,z,Y=this;return t().wrap((function(e){for(;;)switch(e.prev=e.next){case 0:if(void 0===this._introChangeCallback){e.next=3;break}return e.next=3,this._introChangeCallback.call(this,n.element);case 3:if(i=this,o=document.querySelector(".introjs-helperLayer"),a=document.querySelector(".introjs-tooltipReferenceLayer"),s="introjs-helperLayer","string"==typeof n.highlightClass&&(s+=" ".concat(n.highlightClass)),"string"==typeof this._options.highlightClass&&(s+=" ".concat(this._options.highlightClass)),null!==o&&null!==a?(h=a.querySelector(".introjs-helperNumberLayer"),f=a.querySelector(".introjs-tooltiptext"),b=a.querySelector(".introjs-tooltip-title"),g=a.querySelector(".introjs-arrow"),w=a.querySelector(".introjs-tooltip"),u=a.querySelector(".introjs-skipbutton"),c=a.querySelector(".introjs-prevbutton"),l=a.querySelector(".introjs-nextbutton"),o.className=s,w.style.opacity="0",w.style.display="none",m.call(i,n.element),k.call(i,o),k.call(i,a),N(),i._lastShowElementTimer&&window.clearTimeout(i._lastShowElementTimer),i._lastShowElementTimer=window.setTimeout((function(){null!==h&&(h.innerHTML="".concat(n.step," ").concat(Y._options.stepNumbersOfLabel," ").concat(Y._introItems.length)),f.innerHTML=n.intro,b.innerHTML=n.title,w.style.display="block",E.call(i,n.element,w,g),B.call(i,a,n),R.call(i,a),w.style.opacity="1",(null!=l&&/introjs-donebutton/gi.test(l.className)||null!=l)&&l.focus(),v.call(i,n.scrollTo,n.element,f)}),350)):(_=L("div",{className:s}),C=L("div",{className:"introjs-tooltipReferenceLayer"}),S=L("div",{className:"introjs-arrow"}),j=L("div",{className:"introjs-tooltip"}),A=L("div",{className:"introjs-tooltiptext"}),I=L("div",{className:"introjs-tooltip-header"}),O=L("h1",{className:"introjs-tooltip-title"}),M=L("div"),x(_,{"box-shadow":"0 0 1px 2px rgba(33, 33, 33, 0.8), rgba(33, 33, 33, ".concat(i._options.overlayOpacity.toString(),") 0 0 0 5000px")}),m.call(i,n.element),k.call(i,_),k.call(i,C),T(this._targetElement,_,!0),T(this._targetElement,C),A.innerHTML=n.intro,O.innerHTML=n.title,M.className="introjs-tooltipbuttons",!1===this._options.showButtons&&(M.style.display="none"),I.appendChild(O),j.appendChild(I),j.appendChild(A),this._options.dontShowAgain&&(F=L("div",{className:"introjs-dontShowAgain"}),(D=L("input",{type:"checkbox",id:"introjs-dontShowAgain",name:"introjs-dontShowAgain"})).onchange=function(t){Y.setDontShowAgain(t.target.checked)},(G=L("label",{htmlFor:"introjs-dontShowAgain"})).innerText=this._options.dontShowAgainLabel,F.appendChild(D),F.appendChild(G),j.appendChild(F)),j.appendChild(q.call(this,n)),j.appendChild(H.call(this)),V=L("div"),!0===this._options.showStepNumbers&&(V.className="introjs-helperNumberLayer",V.innerHTML="".concat(n.step," ").concat(this._options.stepNumbersOfLabel," ").concat(this._introItems.length),j.appendChild(V)),j.appendChild(S),C.appendChild(j),(l=L("a")).onclick=r(t().mark((function e(){return t().wrap((function(t){for(;;)switch(t.prev=t.next){case 0:if(i._introItems.length-1===i._currentStep){t.next=5;break}return t.next=3,W.call(i);case 3:t.next=11;break;case 5:if(!/introjs-donebutton/gi.test(l.className)){t.next=11;break}if("function"!=typeof i._introCompleteCallback){t.next=9;break}return t.next=9,i._introCompleteCallback.call(i,i._currentStep,"done");case 9:return t.next=11,xt.call(i,i._targetElement);case 11:case"end":return t.stop()}}),e)}))),y(l),l.innerHTML=this._options.nextLabel,(c=L("a")).onclick=r(t().mark((function e(){return t().wrap((function(t){for(;;)switch(t.prev=t.next){case 0:if(0===i._currentStep){t.next=3;break}return t.next=3,$.call(i);case 3:case"end":return t.stop()}}),e)}))),y(c),c.innerHTML=this._options.prevLabel,y(u=L("a",{className:"introjs-skipbutton"})),u.innerHTML=this._options.skipLabel,u.onclick=r(t().mark((function e(){return t().wrap((function(t){for(;;)switch(t.prev=t.next){case 0:if(i._introItems.length-1!==i._currentStep||"function"!=typeof i._introCompleteCallback){t.next=3;break}return t.next=3,i._introCompleteCallback.call(i,i._currentStep,"skip");case 3:if("function"!=typeof i._introSkipCallback){t.next=6;break}return t.next=6,i._introSkipCallback.call(i);case 6:return t.next=8,xt.call(i,i._targetElement);case 8:case"end":return t.stop()}}),e)}))),I.appendChild(u),this._introItems.length>1&&M.appendChild(c),M.appendChild(l),j.appendChild(M),E.call(i,n.element,j,S),v.call(this,n.scrollTo,n.element,j)),(z=i._targetElement.querySelector(".introjs-disableInteraction"))&&z.parentNode.removeChild(z),n.disableInteraction&&P.call(i),0===this._currentStep&&this._introItems.length>1?(null!=l&&(l.className="".concat(this._options.buttonClass," introjs-nextbutton"),l.innerHTML=this._options.nextLabel),!0===this._options.hidePrev?(null!=c&&(c.className="".concat(this._options.buttonClass," introjs-prevbutton introjs-hidden")),null!=l&&p(l,"introjs-fullbutton")):null!=c&&(c.className="".concat(this._options.buttonClass," introjs-prevbutton introjs-disabled"))):this._introItems.length-1===this._currentStep||1===this._introItems.length?(null!=c&&(c.className="".concat(this._options.buttonClass," introjs-prevbutton")),!0===this._options.hideNext?(null!=l&&(l.className="".concat(this._options.buttonClass," introjs-nextbutton introjs-hidden")),null!=c&&p(c,"introjs-fullbutton")):null!=l&&(!0===this._options.nextToDone?(l.innerHTML=this._options.doneLabel,p(l,"".concat(this._options.buttonClass," introjs-nextbutton introjs-donebutton"))):l.className="".concat(this._options.buttonClass," introjs-nextbutton introjs-disabled"))):(null!=c&&(c.className="".concat(this._options.buttonClass," introjs-prevbutton")),null!=l&&(l.className="".concat(this._options.buttonClass," introjs-nextbutton"),l.innerHTML=this._options.nextLabel)),null!=c&&c.setAttribute("role","button"),null!=l&&l.setAttribute("role","button"),null!=u&&u.setAttribute("role","button"),null!=l&&l.focus(),d(n.element),void 0===this._introAfterChangeCallback){e.next=22;break}return e.next=22,this._introAfterChangeCallback.call(this,n.element);case 22:case"end":return e.stop()}}),e,this)})))).apply(this,arguments)}function D(t){return G.apply(this,arguments)}function G(){return(G=r(t().mark((function e(n){return t().wrap((function(t){for(;;)switch(t.prev=t.next){case 0:if(this._currentStep=n-2,void 0===this._introItems){t.next=4;break}return t.next=4,W.call(this);case 4:case"end":return t.stop()}}),e,this)})))).apply(this,arguments)}function V(t){return z.apply(this,arguments)}function z(){return(z=r(t().mark((function e(n){return t().wrap((function(t){for(;;)switch(t.prev=t.next){case 0:if(this._currentStepNumber=n,void 0===this._introItems){t.next=4;break}return t.next=4,W.call(this);case 4:case"end":return t.stop()}}),e,this)})))).apply(this,arguments)}function W(){return Y.apply(this,arguments)}function Y(){return Y=r(t().mark((function e(){var n,r,i=this;return t().wrap((function(t){for(;;)switch(t.prev=t.next){case 0:if(this._direction="forward",void 0!==this._currentStepNumber&&u(this._introItems,(function(t,e){t.step===i._currentStepNumber&&(i._currentStep=e-1,i._currentStepNumber=void 0)})),void 0===this._currentStep?this._currentStep=0:++this._currentStep,n=this._introItems[this._currentStep],r=!0,void 0===this._introBeforeChangeCallback){t.next=9;break}return t.next=8,this._introBeforeChangeCallback.call(this,n&&n.element);case 8:r=t.sent;case 9:if(!1!==r){t.next=12;break}return--this._currentStep,t.abrupt("return",!1);case 12:if(!(this._introItems.length<=this._currentStep)){t.next=19;break}if("function"!=typeof this._introCompleteCallback){t.next=16;break}return t.next=16,this._introCompleteCallback.call(this,this._currentStep,"end");case 16:return t.next=18,xt.call(this,this._targetElement);case 18:return t.abrupt("return",!1);case 19:return t.next=21,M.call(this,n);case 21:return t.abrupt("return",!0);case 22:case"end":return t.stop()}}),e,this)}))),Y.apply(this,arguments)}function $(){return Q.apply(this,arguments)}function Q(){return Q=r(t().mark((function e(){var n,r;return t().wrap((function(t){for(;;)switch(t.prev=t.next){case 0:if(this._direction="backward",0!==this._currentStep){t.next=3;break}return t.abrupt("return",!1);case 3:if(--this._currentStep,n=this._introItems[this._currentStep],r=!0,void 0===this._introBeforeChangeCallback){t.next=10;break}return t.next=9,this._introBeforeChangeCallback.call(this,n&&n.element);case 9:r=t.sent;case 10:if(!1!==r){t.next=13;break}return++this._currentStep,t.abrupt("return",!1);case 13:return t.next=15,M.call(this,n);case 15:return t.abrupt("return",!0);case 16:case"end":return t.stop()}}),e,this)}))),Q.apply(this,arguments)}function U(){return this._currentStep}function X(t){return J.apply(this,arguments)}function J(){return(J=r(t().mark((function e(n){var r,i;return t().wrap((function(t){for(;;)switch(t.prev=t.next){case 0:if(null===(r=void 0===n.code?n.which:n.code)&&(r=null===n.charCode?n.keyCode:n.charCode),"Escape"!==r&&27!==r||!0!==this._options.exitOnEsc){t.next=7;break}return t.next=5,xt.call(this,this._targetElement);case 5:t.next=39;break;case 7:if("ArrowLeft"!==r&&37!==r){t.next=12;break}return t.next=10,$.call(this);case 10:t.next=39;break;case 12:if("ArrowRight"!==r&&39!==r){t.next=17;break}return t.next=15,W.call(this);case 15:t.next=39;break;case 17:if("Enter"!==r&&"NumpadEnter"!==r&&13!==r){t.next=39;break}if(!(i=n.target||n.srcElement)||!i.className.match("introjs-prevbutton")){t.next=24;break}return t.next=22,$.call(this);case 22:t.next=38;break;case 24:if(!i||!i.className.match("introjs-skipbutton")){t.next=32;break}if(this._introItems.length-1!==this._currentStep||"function"!=typeof this._introCompleteCallback){t.next=28;break}return t.next=28,this._introCompleteCallback.call(this,this._currentStep,"skip");case 28:return t.next=30,xt.call(this,this._targetElement);case 30:t.next=38;break;case 32:if(!i||!i.getAttribute("data-step-number")){t.next=36;break}i.click(),t.next=38;break;case 36:return t.next=38,W.call(this);case 38:n.preventDefault?n.preventDefault():n.returnValue=!1;case 39:case"end":return t.stop()}}),e,this)})))).apply(this,arguments)}function Z(t){if(null===t||"object"!==e(t)||"nodeType"in t)return t;var n={};for(var r in t)"jQuery"in window&&t[r]instanceof window.jQuery?n[r]=t[r]:n[r]=Z(t[r]);return n}function K(t,e){var n,r=this;return function(){for(var i=arguments.length,o=new Array(i),a=0;a=0&&(this._hintsAutoRefreshFunction=K((function(){return vt.call(o)}),this._options.hintAutoRefreshInterval),h.on(window,"scroll",this._hintsAutoRefreshFunction,this,!0));case 10:case"end":return t.stop()}}),e,this)})))).apply(this,arguments)}function ht(t,e,n){var r=w.call(this,n),i=20,o=20;switch(t){default:case"top-left":e.style.left="".concat(r.left,"px"),e.style.top="".concat(r.top,"px");break;case"top-right":e.style.left="".concat(r.left+r.width-i,"px"),e.style.top="".concat(r.top,"px");break;case"bottom-left":e.style.left="".concat(r.left,"px"),e.style.top="".concat(r.top+r.height-o,"px");break;case"bottom-right":e.style.left="".concat(r.left+r.width-i,"px"),e.style.top="".concat(r.top+r.height-o,"px");break;case"middle-left":e.style.left="".concat(r.left,"px"),e.style.top="".concat(r.top+(r.height-o)/2,"px");break;case"middle-right":e.style.left="".concat(r.left+r.width-i,"px"),e.style.top="".concat(r.top+(r.height-o)/2,"px");break;case"middle-middle":e.style.left="".concat(r.left+(r.width-i)/2,"px"),e.style.top="".concat(r.top+(r.height-o)/2,"px");break;case"bottom-middle":e.style.left="".concat(r.left+(r.width-i)/2,"px"),e.style.top="".concat(r.top+r.height-o,"px");break;case"top-middle":e.style.left="".concat(r.left+(r.width-i)/2,"px"),e.style.top="".concat(r.top,"px")}}function pt(t){return ft.apply(this,arguments)}function ft(){return(ft=r(t().mark((function e(n){var r,i,o,a,s,l,c,u,h;return t().wrap((function(t){for(;;)switch(t.prev=t.next){case 0:if(r=document.querySelector('.introjs-hint[data-step="'.concat(n,'"]')),i=this._introItems[n],void 0===this._hintClickCallback){t.next=5;break}return t.next=5,this._hintClickCallback.call(this,r,i,n);case 5:if(o=dt.call(this),parseInt(o,10)!==n){t.next=8;break}return t.abrupt("return");case 8:a=L("div",{className:"introjs-tooltip"}),s=L("div"),l=L("div"),c=L("div"),a.onclick=function(t){t.stopPropagation?t.stopPropagation():t.cancelBubble=!0},s.className="introjs-tooltiptext",(u=L("p")).innerHTML=i.hint,s.appendChild(u),this._options.hintShowButton&&((h=L("a")).className=this._options.buttonClass,h.setAttribute("role","button"),h.innerHTML=this._options.hintButtonLabel,h.onclick=et.bind(this,n),s.appendChild(h)),l.className="introjs-arrow",a.appendChild(l),a.appendChild(s),this._currentStep=r.getAttribute("data-step"),c.className="introjs-tooltipReferenceLayer introjs-hintReference",c.setAttribute("data-step",r.getAttribute("data-step")),k.call(this,c),c.appendChild(a),document.body.appendChild(c),E.call(this,r,a,l,!0);case 28:case"end":return t.stop()}}),e,this)})))).apply(this,arguments)}function dt(){var t=document.querySelector(".introjs-hintReference");if(t){var e=t.getAttribute("data-step");return t.parentNode.removeChild(t),e}}function mt(t){return bt.apply(this,arguments)}function bt(){return(bt=r(t().mark((function e(n){var r,i=this;return t().wrap((function(t){for(;;)switch(t.prev=t.next){case 0:if(this._introItems=[],!this._options.hints){t.next=5;break}u(this._options.hints,(function(t){var e=Z(t);"string"==typeof e.element&&(e.element=document.querySelector(e.element)),e.hintPosition=e.hintPosition||i._options.hintPosition,e.hintAnimation=e.hintAnimation||i._options.hintAnimation,null!==e.element&&i._introItems.push(e)})),t.next=9;break;case 5:if((r=Array.from(n.querySelectorAll("*[data-hint]")))&&r.length){t.next=8;break}return t.abrupt("return",!1);case 8:u(r,(function(t){var e=t.getAttribute("data-hint-animation");e=e?"true"===e:i._options.hintAnimation,i._introItems.push({element:t,hint:t.getAttribute("data-hint"),hintPosition:t.getAttribute("data-hint-position")||i._options.hintPosition,hintAnimation:e,tooltipClass:t.getAttribute("data-tooltip-class"),position:t.getAttribute("data-position")||i._options.tooltipPosition})}));case 9:return t.next=11,ct.call(this);case 11:return h.on(document,"click",dt,this,!1),h.on(window,"resize",vt,this,!0),t.abrupt("return",!0);case 14:case"end":return t.stop()}}),e,this)})))).apply(this,arguments)}function vt(){var t=this;u(this._introItems,(function(e){var n=e.targetElement,r=e.hintPosition,i=e.element;void 0!==n&&ht.call(t,r,i,n)}))}function yt(t){var e=this,n=Array.from(t.querySelectorAll("*[data-intro]")),r=[];if(this._options.steps)u(this._options.steps,(function(t){var n=Z(t);if(n.step=r.length+1,n.title=n.title||"","string"==typeof n.element&&(n.element=document.querySelector(n.element)),void 0===n.element||null===n.element){var i=document.querySelector(".introjsFloatingElement");null===i&&(i=L("div",{className:"introjsFloatingElement"}),document.body.appendChild(i)),n.element=i,n.position="floating"}n.position=n.position||e._options.tooltipPosition,n.scrollTo=n.scrollTo||e._options.scrollTo,void 0===n.disableInteraction&&(n.disableInteraction=e._options.disableInteraction),null!==n.element&&r.push(n)}));else{var i;if(n.length<1)return[];u(n,(function(t){if((!e._options.group||t.getAttribute("data-intro-group")===e._options.group)&&"none"!==t.style.display){var n=parseInt(t.getAttribute("data-step"),10);i=t.hasAttribute("data-disable-interaction")?!!t.getAttribute("data-disable-interaction"):e._options.disableInteraction,n>0&&(r[n-1]={element:t,title:t.getAttribute("data-title")||"",intro:t.getAttribute("data-intro"),step:parseInt(t.getAttribute("data-step"),10),tooltipClass:t.getAttribute("data-tooltip-class"),highlightClass:t.getAttribute("data-highlight-class"),position:t.getAttribute("data-position")||e._options.tooltipPosition,scrollTo:t.getAttribute("data-scroll-to")||e._options.scrollTo,disableInteraction:i})}}));var o=0;u(n,(function(t){if((!e._options.group||t.getAttribute("data-intro-group")===e._options.group)&&null===t.getAttribute("data-step")){for(;void 0!==r[o];)o++;i=t.hasAttribute("data-disable-interaction")?!!t.getAttribute("data-disable-interaction"):e._options.disableInteraction,r[o]={element:t,title:t.getAttribute("data-title")||"",intro:t.getAttribute("data-intro"),step:o+1,tooltipClass:t.getAttribute("data-tooltip-class"),highlightClass:t.getAttribute("data-highlight-class"),position:t.getAttribute("data-position")||e._options.tooltipPosition,scrollTo:t.getAttribute("data-scroll-to")||e._options.scrollTo,disableInteraction:i}}}))}for(var a=[],s=0;s1&&void 0!==arguments[1]&&arguments[1];if(t&&t.parentElement){var n=t.parentElement;e?(x(t,{opacity:"0"}),window.setTimeout((function(){try{n.removeChild(t)}catch(t){}}),500)):n.removeChild(t)}}function xt(t,e){return kt.apply(this,arguments)}function kt(){return(kt=r(t().mark((function e(n,r){var i,o;return t().wrap((function(t){for(;;)switch(t.prev=t.next){case 0:if(i=!0,void 0===this._introBeforeExitCallback){t.next=5;break}return t.next=4,this._introBeforeExitCallback.call(this);case 4:i=t.sent;case 5:if(r||!1!==i){t.next=7;break}return t.abrupt("return");case 7:if((o=Array.from(n.querySelectorAll(".introjs-overlay")))&&o.length&&u(o,(function(t){return _t(t)})),_t(n.querySelector(".introjs-helperLayer"),!0),_t(n.querySelector(".introjs-tooltipReferenceLayer")),_t(n.querySelector(".introjs-disableInteraction")),_t(document.querySelector(".introjsFloatingElement")),N(),h.off(window,"keydown",X,this,!0),h.off(window,"resize",wt,this,!0),void 0===this._introExitCallback){t.next=23;break}return t.next=23,this._introExitCallback.call(this);case 23:this._currentStep=void 0;case 24:case"end":return t.stop()}}),e,this)})))).apply(this,arguments)}function Ct(e){var n=this,i=L("div",{className:"introjs-overlay"});return x(i,{top:0,bottom:0,left:0,right:0,position:"fixed"}),e.appendChild(i),!0===this._options.exitOnOverlayClick&&(x(i,{cursor:"pointer"}),i.onclick=r(t().mark((function r(){return t().wrap((function(t){for(;;)switch(t.prev=t.next){case 0:return t.next=2,xt.call(n,e);case 2:case"end":return t.stop()}}),r)})))),!0}function St(t){return jt.apply(this,arguments)}function jt(){return(jt=r(t().mark((function e(n){var r;return t().wrap((function(t){for(;;)switch(t.prev=t.next){case 0:if(this.isActive()){t.next=2;break}return t.abrupt("return",!1);case 2:if(void 0===this._introStartCallback){t.next=5;break}return t.next=5,this._introStartCallback.call(this,n);case 5:if(0!==(r=yt.call(this,n)).length){t.next=8;break}return t.abrupt("return",!1);case 8:if(this._introItems=r,!Ct.call(this,n)){t.next=14;break}return t.next=12,W.call(this);case 12:this._options.keyboardNavigation&&h.on(window,"keydown",X,this,!0),h.on(window,"resize",wt,this,!0);case 14:return t.abrupt("return",!1);case 15:case"end":return t.stop()}}),e,this)})))).apply(this,arguments)}function At(t,e,n){var r,i=(o(r={},t,e),o(r,"path","/"),o(r,"expires",void 0),r);if(n){var a=new Date;a.setTime(a.getTime()+24*n*60*60*1e3),i.expires=a.toUTCString()}var s=[];for(var l in i)s.push("".concat(l,"=").concat(i[l]));return document.cookie=s.join("; "),Et(t)}function Et(t){return(e={},document.cookie.split(";").forEach((function(t){var n=a(t.split("="),2),r=n[0],i=n[1];e[r.trim()]=i})),e)[t];var e}var Nt="true";function Lt(t){t?At(this._options.dontShowAgainCookie,Nt,this._options.dontShowAgainCookieDays):At(this._options.dontShowAgainCookie,"",-1)}function Tt(){var t=Et(this._options.dontShowAgainCookie);return t&&t===Nt}var It=function(){function e(t){!function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}(this,e),o(this,"_targetElement",void 0),o(this,"_introItems",[]),o(this,"_options",void 0),o(this,"_introBeforeChangeCallback",void 0),o(this,"_introChangeCallback",void 0),o(this,"_introAfterChangeCallback",void 0),o(this,"_introCompleteCallback",void 0),o(this,"_hintsAddedCallback",void 0),o(this,"_hintClickCallback",void 0),o(this,"_hintCloseCallback",void 0),o(this,"_introStartCallback",void 0),o(this,"_introExitCallback",void 0),o(this,"_introSkipCallback",void 0),o(this,"_introBeforeExitCallback",void 0),this._targetElement=t,this._options={isActive:!0,nextLabel:"Next",prevLabel:"Back",skipLabel:"×",doneLabel:"Done",hidePrev:!1,hideNext:!1,nextToDone:!0,tooltipPosition:"bottom",tooltipClass:"",group:"",highlightClass:"",exitOnEsc:!0,exitOnOverlayClick:!0,showStepNumbers:!1,stepNumbersOfLabel:"of",keyboardNavigation:!0,showButtons:!0,showBullets:!0,showProgress:!1,scrollToElement:!0,scrollTo:"element",scrollPadding:30,overlayOpacity:.5,autoPosition:!0,positionPrecedence:["bottom","top","right","left"],disableInteraction:!1,dontShowAgain:!1,dontShowAgainLabel:"Don't show this again",dontShowAgainCookie:"introjs-dontShowAgain",dontShowAgainCookieDays:365,helperElementPadding:10,hintPosition:"top-middle",hintButtonLabel:"Got it",hintShowButton:!0,hintAutoRefreshInterval:10,hintAnimation:!0,buttonClass:"introjs-button",progressBarAdditionalClass:!1}}var n,a,s,l,c,u,h,p,f,d,m,b,v;return n=e,a=[{key:"isActive",value:function(){return(!this._options.dontShowAgain||!Tt.call(this))&&this._options.isActive}},{key:"clone",value:function(){return new e(this._targetElement)}},{key:"setOption",value:function(t,e){return this._options[t]=e,this}},{key:"setOptions",value:function(t){return this._options=function(t,e){var n,r={};for(n in t)r[n]=t[n];for(n in e)r[n]=e[n];return r}(this._options,t),this}},{key:"start",value:(v=r(t().mark((function e(){return t().wrap((function(t){for(;;)switch(t.prev=t.next){case 0:return t.next=2,St.call(this,this._targetElement);case 2:return t.abrupt("return",this);case 3:case"end":return t.stop()}}),e,this)}))),function(){return v.apply(this,arguments)})},{key:"goToStep",value:(b=r(t().mark((function e(n){return t().wrap((function(t){for(;;)switch(t.prev=t.next){case 0:return t.next=2,D.call(this,n);case 2:return t.abrupt("return",this);case 3:case"end":return t.stop()}}),e,this)}))),function(t){return b.apply(this,arguments)})},{key:"addStep",value:function(t){return this._options.steps||(this._options.steps=[]),this._options.steps.push(t),this}},{key:"addSteps",value:function(t){if(!t.length)return this;for(var e=0;e',e.titleMarkup='\n
\n',e.textMarkup='\n
',e.footerMarkup='\n
\n'},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var o=n(1);e.CONFIRM_KEY="confirm",e.CANCEL_KEY="cancel";var r={visible:!0,text:null,value:null,className:"",closeModal:!0},i=Object.assign({},r,{visible:!1,text:"Cancel",value:null}),a=Object.assign({},r,{text:"OK",value:!0});e.defaultButtonList={cancel:i,confirm:a};var s=function(t){switch(t){case e.CONFIRM_KEY:return a;case e.CANCEL_KEY:return i;default:var n=t.charAt(0).toUpperCase()+t.slice(1);return Object.assign({},r,{text:n,value:t})}},c=function(t,e){var n=s(t);return!0===e?Object.assign({},n,{visible:!0}):"string"==typeof e?Object.assign({},n,{visible:!0,text:e}):o.isPlainObject(e)?Object.assign({visible:!0},n,e):Object.assign({},n,{visible:!1})},l=function(t){for(var e={},n=0,o=Object.keys(t);n=0&&w.splice(e,1)}function s(t){var e=document.createElement("style");return t.attrs.type="text/css",l(e,t.attrs),i(t,e),e}function c(t){var e=document.createElement("link");return t.attrs.type="text/css",t.attrs.rel="stylesheet",l(e,t.attrs),i(t,e),e}function l(t,e){Object.keys(e).forEach(function(n){t.setAttribute(n,e[n])})}function u(t,e){var n,o,r,i;if(e.transform&&t.css){if(!(i=e.transform(t.css)))return function(){};t.css=i}if(e.singleton){var l=h++;n=g||(g=s(e)),o=f.bind(null,n,l,!1),r=f.bind(null,n,l,!0)}else t.sourceMap&&"function"==typeof URL&&"function"==typeof URL.createObjectURL&&"function"==typeof URL.revokeObjectURL&&"function"==typeof Blob&&"function"==typeof btoa?(n=c(e),o=p.bind(null,n,e),r=function(){a(n),n.href&&URL.revokeObjectURL(n.href)}):(n=s(e),o=d.bind(null,n),r=function(){a(n)});return o(t),function(e){if(e){if(e.css===t.css&&e.media===t.media&&e.sourceMap===t.sourceMap)return;o(t=e)}else r()}}function f(t,e,n,o){var r=n?"":o.css;if(t.styleSheet)t.styleSheet.cssText=x(e,r);else{var i=document.createTextNode(r),a=t.childNodes;a[e]&&t.removeChild(a[e]),a.length?t.insertBefore(i,a[e]):t.appendChild(i)}}function d(t,e){var n=e.css,o=e.media;if(o&&t.setAttribute("media",o),t.styleSheet)t.styleSheet.cssText=n;else{for(;t.firstChild;)t.removeChild(t.firstChild);t.appendChild(document.createTextNode(n))}}function p(t,e,n){var o=n.css,r=n.sourceMap,i=void 0===e.convertToAbsoluteUrls&&r;(e.convertToAbsoluteUrls||i)&&(o=y(o)),r&&(o+="\n/*# sourceMappingURL=data:application/json;base64,"+btoa(unescape(encodeURIComponent(JSON.stringify(r))))+" */");var a=new Blob([o],{type:"text/css"}),s=t.href;t.href=URL.createObjectURL(a),s&&URL.revokeObjectURL(s)}var m={},b=function(t){var e;return function(){return void 0===e&&(e=t.apply(this,arguments)),e}}(function(){return window&&document&&document.all&&!window.atob}),v=function(t){var e={};return function(n){return void 0===e[n]&&(e[n]=t.call(this,n)),e[n]}}(function(t){return document.querySelector(t)}),g=null,h=0,w=[],y=n(15);t.exports=function(t,e){if("undefined"!=typeof DEBUG&&DEBUG&&"object"!=typeof document)throw new Error("The style-loader cannot be used in a non-browser environment");e=e||{},e.attrs="object"==typeof e.attrs?e.attrs:{},e.singleton||(e.singleton=b()),e.insertInto||(e.insertInto="head"),e.insertAt||(e.insertAt="bottom");var n=r(t,e);return o(n,e),function(t){for(var i=[],a=0;athis.length)&&-1!==this.indexOf(t,e)}),Array.prototype.includes||Object.defineProperty(Array.prototype,"includes",{value:function(t,e){if(null==this)throw new TypeError('"this" is null or not defined');var n=Object(this),o=n.length>>>0;if(0===o)return!1;for(var r=0|e,i=Math.max(r>=0?r:o-Math.abs(r),0);i=0&&(t._idleTimeoutId=setTimeout(function(){t._onTimeout&&t._onTimeout()},e))},n(19),e.setImmediate=setImmediate,e.clearImmediate=clearImmediate},function(t,e,n){(function(t,e){!function(t,n){"use strict";function o(t){"function"!=typeof t&&(t=new Function(""+t));for(var e=new Array(arguments.length-1),n=0;n1)for(var n=1;n',e.default=e.modalMarkup},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var o=n(0),r=o.default.OVERLAY,i='
\n
';e.default=i},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var o=n(0),r=o.default.ICON;e.errorIconMarkup=function(){var t=r+"--error",e=t+"__line";return'\n
\n \n \n
\n '},e.warningIconMarkup=function(){var t=r+"--warning";return'\n \n \n \n '},e.successIconMarkup=function(){var t=r+"--success";return'\n \n \n\n
\n
\n '}},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var o=n(0),r=o.default.CONTENT;e.contentMarkup='\n
\n\n
\n'},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var o=n(0),r=o.default.BUTTON_CONTAINER,i=o.default.BUTTON,a=o.default.BUTTON_LOADER;e.buttonMarkup='\n
\n\n \n\n
\n
\n
\n
\n
\n\n
\n'},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var o=n(4),r=n(2),i=n(0),a=i.default.ICON,s=i.default.ICON_CUSTOM,c=["error","warning","success","info"],l={error:r.errorIconMarkup(),warning:r.warningIconMarkup(),success:r.successIconMarkup()},u=function(t,e){var n=a+"--"+t;e.classList.add(n);var o=l[t];o&&(e.innerHTML=o)},f=function(t,e){e.classList.add(s);var n=document.createElement("img");n.src=t,e.appendChild(n)},d=function(t){if(t){var e=o.injectElIntoModal(r.iconMarkup);c.includes(t)?u(t,e):f(t,e)}};e.default=d},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var o=n(2),r=n(4),i=function(t){navigator.userAgent.includes("AppleWebKit")&&(t.style.display="none",t.offsetHeight,t.style.display="")};e.initTitle=function(t){if(t){var e=r.injectElIntoModal(o.titleMarkup);e.textContent=t,i(e)}},e.initText=function(t){if(t){var e=document.createDocumentFragment();t.split("\n").forEach(function(t,n,o){e.appendChild(document.createTextNode(t)),n0}).forEach(function(t){b.classList.add(t)})}n&&t===c.CONFIRM_KEY&&b.classList.add(s),b.textContent=r;var g={};return g[t]=i,f.setActionValue(g),f.setActionOptionsFor(t,{closeModal:p}),b.addEventListener("click",function(){return u.onAction(t)}),m},p=function(t,e){var n=r.injectElIntoModal(l.footerMarkup);for(var o in t){var i=t[o],a=d(o,i,e);i.visible&&n.appendChild(a)}0===n.children.length&&n.remove()};e.default=p},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var o=n(3),r=n(4),i=n(2),a=n(5),s=n(6),c=n(0),l=c.default.CONTENT,u=function(t){t.addEventListener("input",function(t){var e=t.target,n=e.value;a.setActionValue(n)}),t.addEventListener("keyup",function(t){if("Enter"===t.key)return s.onAction(o.CONFIRM_KEY)}),setTimeout(function(){t.focus(),a.setActionValue("")},0)},f=function(t,e,n){var o=document.createElement(e),r=l+"__"+e;o.classList.add(r);for(var i in n){var a=n[i];o[i]=a}"input"===e&&u(o),t.appendChild(o)},d=function(t){if(t){var e=r.injectElIntoModal(i.contentMarkup),n=t.element,o=t.attributes;"string"==typeof n?f(e,n,o):e.appendChild(n)}};e.default=d},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var o=n(1),r=n(2),i=function(){var t=o.stringToNode(r.overlayMarkup);document.body.appendChild(t)};e.default=i},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var o=n(5),r=n(6),i=n(1),a=n(3),s=n(0),c=s.default.MODAL,l=s.default.BUTTON,u=s.default.OVERLAY,f=function(t){t.preventDefault(),v()},d=function(t){t.preventDefault(),g()},p=function(t){if(o.default.isOpen)switch(t.key){case"Escape":return r.onAction(a.CANCEL_KEY)}},m=function(t){if(o.default.isOpen)switch(t.key){case"Tab":return f(t)}},b=function(t){if(o.default.isOpen)return"Tab"===t.key&&t.shiftKey?d(t):void 0},v=function(){var t=i.getNode(l);t&&(t.tabIndex=0,t.focus())},g=function(){var t=i.getNode(c),e=t.querySelectorAll("."+l),n=e.length-1,o=e[n];o&&o.focus()},h=function(t){t[t.length-1].addEventListener("keydown",m)},w=function(t){t[0].addEventListener("keydown",b)},y=function(){var t=i.getNode(c),e=t.querySelectorAll("."+l);e.length&&(h(e),w(e))},x=function(t){if(i.getNode(u)===t.target)return r.onAction(a.CANCEL_KEY)},_=function(t){var e=i.getNode(u);e.removeEventListener("click",x),t&&e.addEventListener("click",x)},k=function(t){o.default.timer&&clearTimeout(o.default.timer),t&&(o.default.timer=window.setTimeout(function(){return r.onAction(a.CANCEL_KEY)},t))},O=function(t){t.closeOnEsc?document.addEventListener("keyup",p):document.removeEventListener("keyup",p),t.dangerMode?v():g(),y(),_(t.closeOnClickOutside),k(t.timer)};e.default=O},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var o=n(1),r=n(3),i=n(37),a=n(38),s={title:null,text:null,icon:null,buttons:r.defaultButtonList,content:null,className:null,closeOnClickOutside:!0,closeOnEsc:!0,dangerMode:!1,timer:null},c=Object.assign({},s);e.setDefaults=function(t){c=Object.assign({},s,t)};var l=function(t){var e=t&&t.button,n=t&&t.buttons;return void 0!==e&&void 0!==n&&o.throwErr("Cannot set both 'button' and 'buttons' options!"),void 0!==e?{confirm:e}:n},u=function(t){return o.ordinalSuffixOf(t+1)},f=function(t,e){o.throwErr(u(e)+" argument ('"+t+"') is invalid")},d=function(t,e){var n=t+1,r=e[n];o.isPlainObject(r)||void 0===r||o.throwErr("Expected "+u(n)+" argument ('"+r+"') to be a plain object")},p=function(t,e){var n=t+1,r=e[n];void 0!==r&&o.throwErr("Unexpected "+u(n)+" argument ("+r+")")},m=function(t,e,n,r){var i=typeof e,a="string"===i,s=e instanceof Element;if(a){if(0===n)return{text:e};if(1===n)return{text:e,title:r[0]};if(2===n)return d(n,r),{icon:e};f(e,n)}else{if(s&&0===n)return d(n,r),{content:e};if(o.isPlainObject(e))return p(n,r),e;f(e,n)}};e.getOpts=function(){for(var t=[],e=0;e bool: + return tk.config[CONF_AUTOPLAY] + + +def get_default_anchor() -> str: + return tk.config[CONF_DEFAULT_ANCHOR] + + +def is_collapse_steps_enabled() -> bool: + return tk.config[CONF_COLLAPSE_STEPS] diff --git a/ckanext/tour/config_declaration.yaml b/ckanext/tour/config_declaration.yaml new file mode 100644 index 0000000..35227d4 --- /dev/null +++ b/ckanext/tour/config_declaration.yaml @@ -0,0 +1,20 @@ +version: 1 +groups: + - annotation: Admin panel example + options: + - key: ckanext.tour.autoplay + type: bool + default: false + description: If enabled, the tour will start automatically + editable: true + + - key: ckanext.tour.default_anchor + default: '.breadcrumb .active' + description: The default anchor for the tour to attach to + editable: true + + - key: ckanext.tour.collapse_steps + type: bool + default: true + description: If enabled, the tour steps will be collapsed on edit/create + editable: true diff --git a/ckanext/tour/config_schema.yaml b/ckanext/tour/config_schema.yaml new file mode 100644 index 0000000..3da9dbb --- /dev/null +++ b/ckanext/tour/config_schema.yaml @@ -0,0 +1,34 @@ +scheming_version: 2 +schema_id: tour_config +about: Configuration options for the DOI extension + +fields: + - field_name: ckanext.tour.autoplay + label: Autoplay + help_text: If enabled, the tour will start automatically when the page is loaded + validators: default(false), one_of([true, false]) + preset: select + required: true + choices: + - value: true + label: Enabled + - value: false + label: Disabled + + - field_name: ckanext.tour.default_anchor + label: Default Anchor + help_text: The default anchor for the tour to attach to + validators: default('.breadcrumb .active'), unicode_safe + required: true + + - field_name: ckanext.tour.collapse_steps + label: Collapse Steps + help_text: If enabled, the tour steps will be collapsed on edit/create + validators: default(true), one_of([true, false]) + preset: select + required: true + choices: + - value: true + label: Enabled + - value: false + label: Disabled diff --git a/ckanext/tour/helpers.py b/ckanext/tour/helpers.py index 87ce9a3..e0499c0 100644 --- a/ckanext/tour/helpers.py +++ b/ckanext/tour/helpers.py @@ -1,5 +1,10 @@ +from __future__ import annotations + +import json import uuid +from typing import Any +import ckanext.tour.config as config from ckanext.tour.model import TourStep @@ -17,3 +22,16 @@ def tour_get_position_options(): def tour_random_step_id() -> str: return str(uuid.uuid4()) + + +def tour_get_tour_config() -> str: + return json.dumps( + { + "autoplay": config.is_auto_play_enabled(), + "default_anchor": config.get_default_anchor(), + } + ) + + +def tour_collapse_steps() -> bool: + return config.is_collapse_steps_enabled() diff --git a/ckanext/tour/logic/action.py b/ckanext/tour/logic/action.py index 97e63e4..b70ae80 100644 --- a/ckanext/tour/logic/action.py +++ b/ckanext/tour/logic/action.py @@ -123,16 +123,6 @@ def tour_update(context, data_dict): steps: list[dict[str, Any]] = data_dict.pop("steps", []) - # TODO: how to delete steps?... Probably, with JS, add ID to some field - # form_steps: set[str] = {step["id"] for step in steps} - # tour_steps: set[str] = {step.id for step in tour.steps} - - # for step_id in tour_steps - form_steps: - # tk.get_action("tour_step_remove")( - # {"ignore_auth": True}, - # {"id": step_id}, - # ) - for step in steps: action = "tour_step_update" if step.get("id") else "tour_step_create" step["tour_id"] = tour.id @@ -162,18 +152,19 @@ def tour_step_update(context, data_dict): ) elif data_dict.get("image"): data_dict["image"][0]["tour_step_id"] = tour_step.id - action = ( - "tour_step_image_update" if tour_step.image else "tour_step_image_upload" - ) try: - tk.get_action(action)({"ignore_auth": True}, data_dict["image"][0]) + tk.get_action( + "tour_step_image_update" + if tour_step.image + else "tour_step_image_upload" + )({"ignore_auth": True}, data_dict["image"][0]) except tk.ValidationError as e: raise tk.ValidationError( {"image": [f"Error while uploading step image: {e}"]} ) - model.Session.commit() + # model.Session.commit() return tour_step.dictize(context) @@ -204,7 +195,7 @@ def tour_step_image_upload(context, data_dict): result = tk.get_action("files_file_create")( {"ignore_auth": True}, { - "name": f"Tour step image <{dt.utcnow().isoformat()}>", + "name": f"Tour step image <{tour_step_id}>", "upload": data_dict["upload"], }, ) @@ -239,7 +230,7 @@ def tour_step_image_update(context, data_dict): result = tk.get_action("files_file_create")( {"ignore_auth": True}, { - "id": tour_step_image.file_id, + "name": f"Tour step image <{data_dict['tour_step_id']}>", "upload": data_dict["upload"], }, ) diff --git a/ckanext/tour/logic/schema.py b/ckanext/tour/logic/schema.py index bb3d268..7e11d3d 100644 --- a/ckanext/tour/logic/schema.py +++ b/ckanext/tour/logic/schema.py @@ -23,13 +23,14 @@ def tour_create( user_id_or_name_exists, one_of, ignore, + tour_duplicate_anchor ) -> Schema: step_schema = tour_step_schema() step_schema["tour_id"] = [ignore_missing] return { "title": [not_empty, unicode_safe], - "anchor": [ignore_missing, unicode_safe], + "anchor": [ignore_missing, unicode_safe, tour_duplicate_anchor], "page": [ignore_missing, unicode_safe], "author_id": [not_empty, user_id_or_name_exists], "state": [ diff --git a/ckanext/tour/logic/validators.py b/ckanext/tour/logic/validators.py index d97c433..eeffe06 100644 --- a/ckanext/tour/logic/validators.py +++ b/ckanext/tour/logic/validators.py @@ -55,16 +55,6 @@ def tour_url_validator( if not url: return - # step_idx = key[1] - # try: - # image_idx = key[3] - # except IndexError: - # import ipdb; ipdb.set_trace() - # pass - - # if data.get(('steps', step_idx, 'image', image_idx, 'upload')): - # return - try: pieces = urlparse(url) if ( @@ -78,3 +68,17 @@ def tour_url_validator( pass errors[key].append(tk._("Please provide a valid URL")) + + +def tour_duplicate_anchor( + key: types.FlattenKey, + data: types.FlattenDataDict, + errors: types.FlattenErrorDict, + context: types.Context, +) -> Any: + """Ensures that the tour step with a given anchor doesn't exist""" + + result = tour_model.Tour.get_by_anchor(data[key]) + + if result and result.id != data.get(('id',)): + raise tk.Invalid(f"The tour step with an anchor `{data[key]}` already exists.") diff --git a/ckanext/tour/model.py b/ckanext/tour/model.py index 5b99593..0fd4988 100644 --- a/ckanext/tour/model.py +++ b/ckanext/tour/model.py @@ -37,7 +37,7 @@ class State: user = relationship(model.User) def __repr__(self): - return f"Tour(title={self.title}" + return f"Tour(title={self.title})" @classmethod def create(cls, data_dict) -> Self: @@ -78,6 +78,12 @@ def get(cls, tour_id: str) -> Self | None: return query.one_or_none() + @classmethod + def get_by_anchor(cls, tour_anchor: str) -> Self | None: + query: Query = model.Session.query(cls).filter(cls.anchor == tour_anchor) + + return query.one_or_none() + @classmethod def all(cls) -> list[Tour]: query: Query = model.Session.query(cls).order_by(cls.created_at.desc()) diff --git a/ckanext/tour/plugin.py b/ckanext/tour/plugin.py index 9feecdd..55fbfda 100644 --- a/ckanext/tour/plugin.py +++ b/ckanext/tour/plugin.py @@ -18,6 +18,7 @@ @tk.blanket.auth_functions @tk.blanket.blueprints @tk.blanket.validators +@tk.blanket.config_declarations class TourPlugin(plugins.SingletonPlugin): plugins.implements(plugins.IConfigurer) plugins.implements(ICollection, inherit=True) @@ -35,7 +36,10 @@ def update_config(self, config_): def get_signal_subscriptions(self) -> types.SignalMapping: return { tk.signals.ckanext.signal("ap_main:collect_config_sections"): [ - collect_config_sections_subs + self.collect_config_sections_subs + ], + tk.signals.ckanext.signal("ap_main:collect_config_schemas"): [ + self.collect_config_schemas_subs ], } @@ -44,20 +48,29 @@ def get_signal_subscriptions(self) -> types.SignalMapping: def get_collection_factories(self) -> dict[str, CollectionFactory]: return {"tour-list": TourListCollection} + @staticmethod + def collect_config_sections_subs(sender: None): + return SectionConfig( + name="Tour", + configs=[ + ConfigurationItem( + name="List of tours", + blueprint="tour.list", + info="Manage existing tours", + ), + ConfigurationItem( + name="Add tour", + blueprint="tour.add", + info="Add new tour", + ), + ConfigurationItem( + name="Settings", + blueprint="tour.config", + info="Extension settings", + ), + ], + ) -def collect_config_sections_subs(sender: None): - return SectionConfig( - name="Tour", - configs=[ - ConfigurationItem( - name="List of tours", - blueprint="tour.list", - info="Manage existing tours", - ), - ConfigurationItem( - name="Add tour", - blueprint="tour.add", - info="Add new tour", - ), - ], - ) + @staticmethod + def collect_config_schemas_subs(sender: None): + return ["ckanext.tour:config_schema.yaml"] diff --git a/ckanext/tour/templates/base.html b/ckanext/tour/templates/base.html index 641bc06..ac497df 100644 --- a/ckanext/tour/templates/base.html +++ b/ckanext/tour/templates/base.html @@ -3,7 +3,7 @@ {% block scripts %} {{ super() }} - + {% asset 'tour/tour-js' %} {% endblock %} diff --git a/ckanext/tour/templates/tour/snippets/tour_form.html b/ckanext/tour/templates/tour/snippets/tour_form.html new file mode 100644 index 0000000..9e523f9 --- /dev/null +++ b/ckanext/tour/templates/tour/snippets/tour_form.html @@ -0,0 +1,43 @@ +{% import 'macros/form.html' as form %} + +{% set collapse_step = h.tour_collapse_steps() %} + +
+ {% call form.input("title", label=_("Tour title"), value=data.title, error=errors.title, attrs={'required': 1, 'class': 'form-control'}) %} + {{ form.info(_("A tour title to explain what is it for")) }} + {% endcall %} + + {% call form.input("anchor", label=_("Query anchor"), value=".breadcrumb .active" or data.anchor, error=errors.anchor) %} + {{ form.info(_('An anchor element query that will trigger the tour. Could be a tooltip, button or any HTML element.', classes=['info-help-tight'])) }} + {% endcall %} + + {% call form.input("page", label=_("Page anchor"), value=data.page, error=errors.page) %} + {{ form.info(_('Optional. A path to a page, where tour will be applied. Note, that a page tour will be triggered automatically.', classes=['info-help-tight'])) }} + {% endcall %} + +
+ + + +
+ +

{{ _("Tour steps:") }}

+
+
+ + {% for step in data.steps %} + {% set step_errors = errors.steps | default({}) %} + {% snippet 'tour/snippets/tour_step.html', step=step, step_index=loop.index, errors=step_errors[loop.index - 1] | default({}), add_next_container=False, collapse_step=collapse_step %} + {% else %} + {% snippet 'tour/snippets/tour_step.html', step={}, errors={} %} + {% endfor %} +
+
+
+
diff --git a/ckanext/tour/templates/tour/snippets/tour_image_upload.html b/ckanext/tour/templates/tour/snippets/tour_image_upload.html index 48b567d..3150f6e 100644 --- a/ckanext/tour/templates/tour/snippets/tour_image_upload.html +++ b/ckanext/tour/templates/tour/snippets/tour_image_upload.html @@ -24,7 +24,7 @@ data-module-previous_upload="{{ 'true' if previous_upload else 'false' }}" data-module-scope="{{ scope or '.image-upload' }}"> - {{ input(field_url, label=url_label, id='field-image-url', type='url', placeholder=placeholder, value=data.image.url if data else "") }} + {{ input(field_url, label=url_label, id='field-image-url', type='url', placeholder=placeholder, value=data.image.url if data.image else "") }} {{ input(field_upload, label=upload_label, id='field-image-upload', type='file', placeholder='', value='', error='', attrs={"accept": "image/*", "class": "form-control"}) }} {% if data.image %} diff --git a/ckanext/tour/templates/tour/snippets/tour_step.html b/ckanext/tour/templates/tour/snippets/tour_step.html index 0fa8903..cc67fcd 100644 --- a/ckanext/tour/templates/tour/snippets/tour_step.html +++ b/ckanext/tour/templates/tour/snippets/tour_step.html @@ -3,6 +3,10 @@ {% set step_id = step.step_id or step.id or h.tour_random_step_id() %} +{% if errors %} + {% set collapse_step = false %} +{% endif %} +

@@ -12,7 +16,7 @@

{% snippet 'snippets/svg/drag.svg' %} -

-
{{ form.hidden("step_id", value=step.step_id or step.id) }} {{ form.hidden("step_index", value=step.step_index or step.index) }} - {{ form.input("step_title", label=_("Tour title"), value=step.step_title or step.title) }} + {{ form.input("step_title", label=_("Tour title"), value=step.step_title or step.title, error=errors.title, attrs={'required': 1, 'class': 'form-control'}) }} - {% call form.input("step_element", label=_("HTML element query"), value=step.step_element or step.element, attrs={'required': 1, 'class': 'form-control'}) %} + {% call form.input("step_element", label=_("HTML element query"), value=step.step_element or step.element, error=errors.element, attrs={'required': 1, 'class': 'form-control'}) %} {{ form.info(_('Example: .dataset-list or #map')) }} {% endcall %} - {% call form.input("step_intro", label=_("Intro"), value=step.step_intro or step.intro) %} + {% call form.input("step_intro", label=_("Intro"), value=step.step_intro or step.intro, error=errors.intro) %} {{ form.info(_('Supports HTML')) }} {% endcall %} - {{ form.select('step_position', label=_('Position'), options=h.tour_get_position_options(), selected=step.step_position or step.position, error=error or {}) }} + {{ form.select('step_position', label=_('Position'), options=h.tour_get_position_options(), selected=step.step_position or step.position, error=errors.position) }} {{ image_upload(step, scope="#step-" + step_id) }}
-
+ +{% set add_next_container = True if add_next_container is undefined else add_next_container %} + +{% if add_next_container %} +
+{% endif %} diff --git a/ckanext/tour/templates/tour/tour_404.html b/ckanext/tour/templates/tour/tour_404.html index 7b8677e..b257039 100644 --- a/ckanext/tour/templates/tour/tour_404.html +++ b/ckanext/tour/templates/tour/tour_404.html @@ -7,11 +7,5 @@ {% endblock breadcrumb_content %} {% block ap_content %} -

TOUR NOT FOUND - 404

+

{{ _("TOUR NOT FOUND - 404") }}

{% endblock ap_content %} - -{% block scripts %} - {{ super() }} - - {% asset 'tour/tour-htmx' %} -{% endblock %} diff --git a/ckanext/tour/templates/tour/tour_add.html b/ckanext/tour/templates/tour/tour_add.html index aa5390d..16285c2 100644 --- a/ckanext/tour/templates/tour/tour_add.html +++ b/ckanext/tour/templates/tour/tour_add.html @@ -3,70 +3,16 @@ {% import 'macros/form.html' as form %} {% block breadcrumb_content %} +
  • {% link_for _("Tour list"), named_route='tour.list' %}
  • {% link_for _("Tour add"), named_route='tour.add' %}
  • {% endblock breadcrumb_content %} {% block ap_content %} -
    - {% call form.input("title", label=_("Tour title"), value=data.title, attrs={'required': 1, 'class': 'form-control'}) %} - {{ form.info(_("A tour title to explain what is it for")) }} - {% endcall %} - - {% call form.input("anchor", label=_("Query anchor"), value=data.anchor) %} - {{ form.info(_('An anchor element query that will trigger the tour. Could be a tooltip, button or any HTML element.', classes=['info-help-tight'])) }} - {% endcall %} - - {% call form.input("page", label=_("Page anchor"), value=data.page) %} - {{ form.info(_('Optional. A path to a page, where tour will be applied. Note, that a page tour will be triggered automatically.', classes=['info-help-tight'])) }} - {% endcall %} - - -
    - - -
    - -

    {{ _("Tour steps:") }}

    - - {#} it's a temporary solution {#} - {% if errors %} -
    - {{ errors }} -
    - {% endif %} - -
    - -
    - {% for step in data.steps %} - {% snippet 'tour/snippets/tour_step.html', step=step, step_index=loop.index %} - {% else %} - {% snippet 'tour/snippets/tour_step.html', step={} %} - {% endfor %} -
    - -
    - -
    -
    -
    + {% snippet 'tour/snippets/tour_form.html', data=data, errors=errors, form_action=h.url_for('tour.add') %} {% endblock ap_content %} {% block scripts %} {{ super() }} {% asset 'tour/tour-draggable' %} - {% asset 'tour/tour-htmx' %} {% endblock %} diff --git a/ckanext/tour/templates/tour/tour_edit.html b/ckanext/tour/templates/tour/tour_edit.html index cf250ea..6992b20 100644 --- a/ckanext/tour/templates/tour/tour_edit.html +++ b/ckanext/tour/templates/tour/tour_edit.html @@ -4,55 +4,15 @@ {% block breadcrumb_content %}
  • {% link_for _("Tour list"), named_route='tour.list' %}
  • -
  • {% link_for _("Tour edit"), named_route='tour.edit', tour_id=tour.id %}
  • +
  • {% link_for _("Tour edit"), named_route='tour.edit', tour_id=data.id %}
  • {% endblock breadcrumb_content %} {% block ap_content %} -
    - {% call form.input("title", label=_("Tour title"), value=tour.title, attrs={'required': 1, 'class': 'form-control'}) %} - {{ form.info(_("A tour title to explain what is it for")) }} - {% endcall %} - - {% call form.input("anchor", label=_("Query anchor"), value=tour.anchor) %} - {{ form.info(_('An anchor element query that will trigger the tour. Could be a tooltip, button or any HTML element.', classes=['info-help-tight'])) }} - {% endcall %} - - {% call form.input("page", label=_("Page anchor"), value=tour.page) %} - {{ form.info(_('Optional. A path to a page, where tour will be applied. Note, that a page tour will be triggered automatically.', classes=['info-help-tight'])) }} - {% endcall %} - -
    - - - -
    - -

    {{ _("Tour steps:") }}

    - - {#} it's a temporary solution {#} - {% if errors %} -
    - {{ errors }} -
    - {% endif %} - -
    -
    - {% for step in tour.steps %} - {% snippet 'tour/snippets/tour_step.html', step=step, step_index=loop.index %} - {% endfor %} -
    -
    -
    + {% snippet 'tour/snippets/tour_form.html', data=data, errors=errors, form_action=h.url_for('tour.edit', tour_id=data.id) %} {% endblock ap_content %} {% block scripts %} {{ super() }} {% asset 'tour/tour-draggable' %} - {% asset 'tour/tour-htmx' %} {% endblock %} diff --git a/ckanext/tour/tests/factories.py b/ckanext/tour/tests/factories.py index eb40cda..f2c84b9 100644 --- a/ckanext/tour/tests/factories.py +++ b/ckanext/tour/tests/factories.py @@ -42,7 +42,7 @@ class Meta: id = factory.Faker("uuid4") title = factory.Faker("sentence") - anchor = "#tour-tooltip" + anchor = factory.Faker("sentence") page = "/dataset" author_id = factory.LazyFunction(lambda: factories.User()["id"]) # type: ignore steps = factory.LazyAttribute( diff --git a/ckanext/tour/theme/elements.scss b/ckanext/tour/theme/elements.scss index 430a430..4c5dee8 100644 --- a/ckanext/tour/theme/elements.scss +++ b/ckanext/tour/theme/elements.scss @@ -49,8 +49,8 @@ margin-right: auto; .step-number { - border: 1px solid $black; - color: $black; + border: 1px solid var(--ap-color); + color: var(--ap-color); padding: 5px 11px; border-radius: 50%; } @@ -126,7 +126,10 @@ text-decoration: none; cursor: pointer; - &.active, &:hover, &:focus, &:active { + &.active, + &:hover, + &:focus, + &:active { width: 15px; background: #999; } @@ -174,3 +177,9 @@ } } } + +body[admin-panel="true"] { + .tour-accordion .image-upload #field-image-upload { + width: 100px; + } +} diff --git a/ckanext/tour/views/__init__.py b/ckanext/tour/views/__init__.py index 9e37005..c5665f6 100644 --- a/ckanext/tour/views/__init__.py +++ b/ckanext/tour/views/__init__.py @@ -1,12 +1,11 @@ from __future__ import annotations -from sys import prefix - from flask import Blueprint from ckanext.ap_main.utils import ap_before_request +from ckanext.ap_main.views.generics import ApConfigurationPageView + from ckanext.tour.views.tour_add import TourAddStepView, TourAddView -from ckanext.tour.views.tour_config import TourConfigView from ckanext.tour.views.tour_delete import TourDeleteView, TourStepDeleteView from ckanext.tour.views.tour_list import TourListView from ckanext.tour.views.tour_update import TourUpdateView @@ -15,7 +14,6 @@ tour.before_request(ap_before_request) -tour.add_url_rule("/", view_func=TourConfigView.as_view("config")) tour.add_url_rule("/list", view_func=TourListView.as_view("list")) tour.add_url_rule("/new", view_func=TourAddView.as_view("add")) tour.add_url_rule("/delete/", view_func=TourDeleteView.as_view("delete")) @@ -25,6 +23,11 @@ tour.add_url_rule("/edit/", view_func=TourUpdateView.as_view("edit")) tour.add_url_rule("/add_step", view_func=TourAddStepView.as_view("add_step")) +tour.add_url_rule( + "/config", + view_func=ApConfigurationPageView.as_view("config", "tour_config"), +) + def get_blueprints(): return [tour] diff --git a/ckanext/tour/views/tour_add.py b/ckanext/tour/views/tour_add.py index 3854791..ae30941 100644 --- a/ckanext/tour/views/tour_add.py +++ b/ckanext/tour/views/tour_add.py @@ -12,7 +12,7 @@ class TourAddView(MethodView): def get(self) -> str: - return tk.render("tour/tour_add.html", extra_vars={"data": {}}) + return tk.render("tour/tour_add.html", extra_vars={"data": {}, "errors": {}}) def post(self) -> Response | str: data_dict = self._prepare_payload() @@ -81,4 +81,6 @@ def _prepare_payload(self): class TourAddStepView(MethodView): def post(self) -> str: - return tk.render("tour/snippets/tour_step.html", extra_vars={"step": {}}) + return tk.render( + "tour/snippets/tour_step.html", extra_vars={"step": {}, "errors": {}} + ) diff --git a/ckanext/tour/views/tour_config.py b/ckanext/tour/views/tour_config.py index 471507f..76f938b 100644 --- a/ckanext/tour/views/tour_config.py +++ b/ckanext/tour/views/tour_config.py @@ -1,12 +1,12 @@ from __future__ import annotations +from flask import Blueprint + import ckan.plugins.toolkit as tk from flask.views import MethodView +from ckanext.ap_main.views.generics import ApConfigurationPageView +from ckanext.ap_main.utils import ap_before_request -class TourConfigView(MethodView): - def get(self) -> str: - return tk.render("tour/tour_list.html") - - def post(self) -> str: - return tk.render("tour/tour_list.html") +tour = Blueprint("tour_config", __name__) +tour.before_request(ap_before_request) diff --git a/ckanext/tour/views/tour_update.py b/ckanext/tour/views/tour_update.py index b7c319e..550f033 100644 --- a/ckanext/tour/views/tour_update.py +++ b/ckanext/tour/views/tour_update.py @@ -18,7 +18,7 @@ def get(self, tour_id: str) -> str: except tk.ValidationError: return tk.render("tour/tour_404.html") - return tk.render("tour/tour_edit.html", extra_vars={"tour": tour}) + return tk.render("tour/tour_edit.html", extra_vars={"data": tour, "errors": {}}) def post(self, tour_id: str) -> Response | str: try: @@ -34,7 +34,7 @@ def post(self, tour_id: str) -> Response | str: return tk.render( "tour/tour_edit.html", extra_vars={ - "tour": tour, + "data": tour, "errors": e.error_dict, "error_summary": e.error_summary, }, @@ -42,11 +42,11 @@ def post(self, tour_id: str) -> Response | str: tk.h.flash_success(tk._("The tour has been updated!")) - return tk.redirect_to("tour.edit", tour_id=tour_id) + return tk.redirect_to("tour.list") def _build_context(self) -> types.Context: return { - "user": tk.current_user.name, + "user": tk.current_user.name, # type: ignore "auth_user_obj": tk.current_user, } diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..d8cfa58 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,6 @@ +{ + "name": "ckanext-tour", + "lockfileVersion": 3, + "requires": true, + "packages": {} +}