diff --git a/.github/workflows/close_old_issues_and_prs.yml b/.github/workflows/close_old_issues_and_prs.yml index f9630618..cfb36037 100644 --- a/.github/workflows/close_old_issues_and_prs.yml +++ b/.github/workflows/close_old_issues_and_prs.yml @@ -2,9 +2,9 @@ name: 'Close stale issues and PRs' on: schedule: # Once every day at midnight UTC - - cron: "0 0 * * *" + - cron: "0 0 * * *" workflow_dispatch: # Allow to run workflow manually - issue_comment: # Run workflow on comments + issue_comment: # Run workflow on comments jobs: stale: @@ -16,7 +16,7 @@ jobs: - name: Mark/Close Stale Issues and Pull Requests 🗑️ uses: actions/stale@v4 with: - repo-token: ${{ secrets.GITHUB_TOKEN }} + repo-token: ${{ secrets.STALE_ACTION_PAT }} days-before-stale: 60 days-before-close: 7 stale-issue-message: > @@ -25,11 +25,11 @@ jobs: stale-pr-message: > This pull request has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. - exempt-issue-labels: "pinned,security,enhancement" - exempt-pr-labels: "pinned,security,enhancement" + exempt-issue-labels: "pinned,security,enhancement,investigating" + exempt-pr-labels: "pinned,security,enhancement,investigating" stale-issue-label: "stale" stale-pr-label: "stale" operations-per-run: "250" ascending: "true" #DRY-RUN - debug-only: "false" \ No newline at end of file + debug-only: "false" diff --git a/.gitignore b/.gitignore index 06328b85..4bb7ae26 100644 --- a/.gitignore +++ b/.gitignore @@ -51,6 +51,8 @@ data/hooks/postfix/* data/hooks/rspamd/* data/hooks/sogo/* data/hooks/unbound/* +data/web/templates/cache/* +!data/web/templates/cache/.gitkeep data/web/.well-known/acme-challenge data/web/css/build/0081-custom-mailcow.css data/web/inc/vars.local.inc.php @@ -62,3 +64,4 @@ mailcow.conf_backup rebuild-images.sh refresh_images.sh update_diffs/ +create_cold_standby.sh diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index e1bc1cdb..9cdc6d64 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -3,7 +3,7 @@ When a problem occurs, then always for a reason! What you want to do in such a c 1. Read your logs; follow them to see what the reason for your problem is. 2. Follow the leads given to you in your logfiles and start investigating. 3. Restarting the troubled service or the whole stack to see if the problem persists. -4. Read the [documentation](https://mailcow.github.io/mailcow-dockerized-docs/) of the troubled service and search it's bugtracker for your problem. +4. Read the [documentation](https://mailcow.github.io/mailcow-dockerized-docs/) of the troubled service and search its bugtracker for your problem. 5. Search our [issues](https://github.com/mailcow/mailcow-dockerized/issues) for your problem. -6. [Create an issue](https://github.com/mailcow/mailcow-dockerized/issues) over at our GitHub repository if you think your problem might be a bug or a missing feature you badly need. But please make sure, that you include **all the logs** and a full description to your problem. -8. Connect to IRC ([chat.freenode.net](https://webchat.freenode.net/)) and join our IRC channel #mailcow. +6. [Create an issue](https://github.com/mailcow/mailcow-dockerized/issues/new/choose) over at our GitHub repository if you think your problem might be a bug or a missing feature you badly need. But please make sure, that you include **all the logs** and a full description to your problem. +7. Ask your questions in our community-driven [support channels](https://mailcow.github.io/mailcow-dockerized-docs/#community-support-and-chat). diff --git a/create_cold_standby.sh b/create_cold_standby.sh new file mode 100644 index 00000000..924339af --- /dev/null +++ b/create_cold_standby.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +export REMOTE_SSH_KEY=/root/.ssh/id_rsa +export REMOTE_SSH_PORT=22 +export REMOTE_SSH_HOST=my.remote.host + +/opt/mailcow-dockerized/helper-scripts/_cold-standby.sh diff --git a/data/Dockerfiles/acme/Dockerfile b/data/Dockerfiles/acme/Dockerfile index a19c4347..82369a88 100644 --- a/data/Dockerfiles/acme/Dockerfile +++ b/data/Dockerfiles/acme/Dockerfile @@ -1,4 +1,4 @@ -FROM alpine:3.13 +FROM alpine:3.14 LABEL maintainer "Andre Peters " diff --git a/data/Dockerfiles/clamd/Dockerfile b/data/Dockerfiles/clamd/Dockerfile index b251d968..4c7d609d 100644 --- a/data/Dockerfiles/clamd/Dockerfile +++ b/data/Dockerfiles/clamd/Dockerfile @@ -2,7 +2,7 @@ FROM debian:buster-slim LABEL maintainer "André Peters " -ARG CLAMAV=0.103.2 +ARG CLAMAV=0.103.3 RUN apt-get update && apt-get install -y --no-install-recommends \ ca-certificates \ diff --git a/data/Dockerfiles/dockerapi/Dockerfile b/data/Dockerfiles/dockerapi/Dockerfile index 645503a2..b6eef462 100644 --- a/data/Dockerfiles/dockerapi/Dockerfile +++ b/data/Dockerfiles/dockerapi/Dockerfile @@ -1,4 +1,4 @@ -FROM alpine:3.13 +FROM alpine:3.14 LABEL maintainer "Andre Peters " diff --git a/data/Dockerfiles/dovecot/Dockerfile b/data/Dockerfiles/dovecot/Dockerfile index 19900973..44cae1af 100644 --- a/data/Dockerfiles/dovecot/Dockerfile +++ b/data/Dockerfiles/dovecot/Dockerfile @@ -2,7 +2,7 @@ FROM debian:buster-slim LABEL maintainer "Andre Peters " ARG DEBIAN_FRONTEND=noninteractive -ARG DOVECOT=2.3.14.1 +ARG DOVECOT=2.3.16 ENV LC_ALL C ENV GOSU_VERSION 1.12 diff --git a/data/Dockerfiles/dovecot/docker-entrypoint.sh b/data/Dockerfiles/dovecot/docker-entrypoint.sh index 5ea1609d..9ac2dc64 100755 --- a/data/Dockerfiles/dovecot/docker-entrypoint.sh +++ b/data/Dockerfiles/dovecot/docker-entrypoint.sh @@ -155,34 +155,47 @@ function auth_password_verify(req, pass) local row = cur:fetch ({}, "a") while row do if req.password_verify(req, row.password, pass) == 1 then - cur:close() con:execute(string.format([[REPLACE INTO sasl_log (service, app_password, username, real_rip) VALUES ("%s", 0, "%s", "%s")]], con:escape(req.service), con:escape(req.user), con:escape(req.real_rip))) + cur:close() + con:close() return dovecot.auth.PASSDB_RESULT_OK, "password=" .. pass end row = cur:fetch (row, "a") end - -- check against app passwds - local cur,errorString = con:execute(string.format([[SELECT app_passwd.id, app_passwd.password FROM app_passwd - INNER JOIN mailbox ON mailbox.username = app_passwd.mailbox - WHERE mailbox = '%s' - AND IFNULL(JSON_UNQUOTE(JSON_VALUE(mailbox.attributes, '$.%s_access')), 1) = '1' - AND IFNULL(JSON_UNQUOTE(JSON_VALUE(mailbox.attributes, '$.force_pw_update')), 0) != '1' - AND app_passwd.active = '1' - AND mailbox.active = '1' - AND app_passwd.domain IN (SELECT domain FROM domain WHERE domain='%s' AND active='1')]], con:escape(req.user), con:escape(req.service), con:escape(req.domain))) - local row = cur:fetch ({}, "a") - while row do - if req.password_verify(req, row.password, pass) == 1 then - cur:close() - con:execute(string.format([[REPLACE INTO sasl_log (service, app_password, username, real_rip) - VALUES ("%s", %d, "%s", "%s")]], con:escape(req.service), row.id, con:escape(req.user), con:escape(req.real_rip))) - return dovecot.auth.PASSDB_RESULT_OK, "password=" .. pass + -- check against app passwds for imap and smtp + -- app passwords are only available for imap, smtp, sieve and pop3 when using sasl + if req.service == "smtp" or req.service == "imap" or req.service == "sieve" or req.service == "pop3" then + local cur,errorString = con:execute(string.format([[SELECT app_passwd.id, %s_access AS has_prot_access, app_passwd.password FROM app_passwd + INNER JOIN mailbox ON mailbox.username = app_passwd.mailbox + WHERE mailbox = '%s' + AND app_passwd.active = '1' + AND mailbox.active = '1' + AND app_passwd.domain IN (SELECT domain FROM domain WHERE domain='%s' AND active='1')]], con:escape(req.service), con:escape(req.user), con:escape(req.domain))) + local row = cur:fetch ({}, "a") + while row do + if req.password_verify(req, row.password, pass) == 1 then + -- if password is valid and protocol access is 1 OR real_rip matches SOGo, proceed + if tostring(req.real_rip) == "__IPV4_SOGO__" then + cur:close() + con:close() + return dovecot.auth.PASSDB_RESULT_OK, "password=" .. pass + elseif row.has_prot_access == "1" then + con:execute(string.format([[REPLACE INTO sasl_log (service, app_password, username, real_rip) + VALUES ("%s", %d, "%s", "%s")]], con:escape(req.service), row.id, con:escape(req.user), con:escape(req.real_rip))) + cur:close() + con:close() + return dovecot.auth.PASSDB_RESULT_OK, "password=" .. pass + end + end + row = cur:fetch (row, "a") end - row = cur:fetch (row, "a") end + cur:close() + con:close() + return dovecot.auth.PASSDB_RESULT_PASSWORD_MISMATCH, "Failed to authenticate" -- PoC @@ -230,6 +243,7 @@ EOF sed -i "s/__DBUSER__/${DBUSER}/g" /etc/dovecot/lua/passwd-verify.lua sed -i "s/__DBPASS__/${DBPASS}/g" /etc/dovecot/lua/passwd-verify.lua sed -i "s/__DBNAME__/${DBNAME}/g" /etc/dovecot/lua/passwd-verify.lua +sed -i "s/__IPV4_SOGO__/${IPV4_NETWORK}.248/g" /etc/dovecot/lua/passwd-verify.lua # Migrate old sieve_after file diff --git a/data/Dockerfiles/dovecot/imapsync_runner.pl b/data/Dockerfiles/dovecot/imapsync_runner.pl index 0f01a971..5b297abd 100644 --- a/data/Dockerfiles/dovecot/imapsync_runner.pl +++ b/data/Dockerfiles/dovecot/imapsync_runner.pl @@ -152,18 +152,28 @@ while ($row = $sth->fetchrow_arrayref()) { '--noreleasecheck']; try { - $is_running = $dbh->prepare("UPDATE imapsync SET is_running = 1 WHERE id = ?"); + $is_running = $dbh->prepare("UPDATE imapsync SET is_running = 1, success = NULL, exit_status = NULL WHERE id = ?"); $is_running->bind_param( 1, ${id} ); $is_running->execute(); - + run [@$generated_cmds, @$custom_params_ref], '&>', \my $stdout; - - $update = $dbh->prepare("UPDATE imapsync SET returned_text = ? WHERE id = ?"); + + # check exit code and status + ($exit_code, $exit_status) = ($stdout =~ m/Exiting\swith\sreturn\svalue\s(\d+)\s\(([^:)]+)/); + + $success = 0; + if (defined $exit_code && $exit_code == 0) { + $success = 1; + } + + $update = $dbh->prepare("UPDATE imapsync SET returned_text = ?, success = ?, exit_status = ? WHERE id = ?"); $update->bind_param( 1, ${stdout} ); - $update->bind_param( 2, ${id} ); + $update->bind_param( 2, ${success} ); + $update->bind_param( 3, ${exit_status} ); + $update->bind_param( 4, ${id} ); $update->execute(); } catch { - $update = $dbh->prepare("UPDATE imapsync SET returned_text = 'Could not start or finish imapsync' WHERE id = ?"); + $update = $dbh->prepare("UPDATE imapsync SET returned_text = 'Could not start or finish imapsync', success = 0 WHERE id = ?"); $update->bind_param( 1, ${id} ); $update->execute(); } finally { diff --git a/data/Dockerfiles/ejabberd/Dockerfile b/data/Dockerfiles/ejabberd/Dockerfile deleted file mode 100644 index 7758df27..00000000 --- a/data/Dockerfiles/ejabberd/Dockerfile +++ /dev/null @@ -1,33 +0,0 @@ -FROM ejabberd/ecs:21.01 - -LABEL maintainer "Andre Peters " - -ENV GOSU_VERSION 1.11 - -# We need to copy cert files, dropping rights at a later point -USER root - -RUN apk add --update --no-cache su-exec \ - bash \ - tini \ - jq \ - mariadb-client \ - redis \ - tzdata \ - curl \ - openssl \ - bind-tools \ - composer \ - php7-pdo \ - php7-pdo_mysql \ - php7-ctype - -RUN mkdir -p /var/www/authentication && \ - cd /var/www/authentication && \ - composer require leesherwood/ejabberd-php-auth monolog/monolog - -COPY docker-entrypoint.sh /docker-entrypoint.sh -COPY authenticator /var/www/authentication/authenticator -COPY mailcowCommandExecutor.php /var/www/authentication/vendor/leesherwood/ejabberd-php-auth/src/CommandExecutors/mailcowCommandExecutor.php - -ENTRYPOINT ["/docker-entrypoint.sh"] diff --git a/data/Dockerfiles/ejabberd/authenticator b/data/Dockerfiles/ejabberd/authenticator deleted file mode 100755 index 96a6b8eb..00000000 --- a/data/Dockerfiles/ejabberd/authenticator +++ /dev/null @@ -1,19 +0,0 @@ -#!/usr/bin/env php -pushHandler($stdoutHandler); - -$executor = new mailcowCommandExecutor(); - -$application = new AuthenticationService($logger, $executor); - -$application->run(); diff --git a/data/Dockerfiles/ejabberd/docker-entrypoint.sh b/data/Dockerfiles/ejabberd/docker-entrypoint.sh deleted file mode 100755 index 1777315f..00000000 --- a/data/Dockerfiles/ejabberd/docker-entrypoint.sh +++ /dev/null @@ -1,100 +0,0 @@ -#!/bin/bash -set -e - -until dig +short mailcow.email > /dev/null; do - echo "Waiting for DNS..." - sleep 1 -done - -until nc phpfpm 9001 -z; do - echo "Waiting for PHP on port 9001..." - sleep 3 -done - -until nc phpfpm 9002 -z; do - echo "Waiting for PHP on port 9002..." - sleep 3 -done - -# Wait for MySQL to warm-up -while ! mysqladmin status --socket=/var/run/mysqld/mysqld.sock -u${DBUSER} -p${DBPASS} --silent; do - echo "Waiting for database to come up..." - sleep 2 -done - -# We dont want to give global write access to ejabberd in this directory -chown -R root:root /var/www/authentication - -[ ! -f /sqlite/sqlite.db ] && cp /sqlite/sqlite_template.db /sqlite/sqlite.db - -[ ! -d /ejabberd_ssl ] && mkdir /ejabberd_ssl -cp /ssl/cert.pem /ejabberd_ssl/cert.pem -cp /ssl/key.pem /ejabberd_ssl/key.pem - -# Write access to upload directory and log file for authenticator -touch /var/www/authentication/auth.log -chown -R ejabberd:ejabberd /var/www/upload \ - /var/www/authentication/auth.log \ - /sqlite \ - /ejabberd_ssl - -# ACL file for vhosts, hosts file for vhosts -touch /ejabberd/ejabberd_acl.yml \ - /ejabberd/ejabberd_hosts.yml \ - /ejabberd/ejabberd_macros.yml -chmod 644 /ejabberd/ejabberd_acl.yml \ - /ejabberd/ejabberd_hosts.yml \ - /ejabberd/ejabberd_macros.yml -chown 82:82 /ejabberd/ejabberd_acl.yml \ - /ejabberd/ejabberd_hosts.yml -chown 82:82 /ejabberd - -cat < /ejabberd/ejabberd_api.yml -# Autogenerated by mailcow -api_permissions: - "Reload by mailcow": - who: - - ip: "${IPV4_NETWORK}.0/24" - what: - - "reload_config" - - "restart" - - "list_certificates" - - "list_cluster" - - "join_cluster" - - "leave_cluster" - - "backup" - - "status" - - "stats" - - "muc_online_rooms" -EOF - -cat < /ejabberd/ejabberd_macros.yml -# Autogenerated by mailcow -define_macro: - 'MAILCOW_HOSTNAME': "${MAILCOW_HOSTNAME}" - 'EJABBERD_HTTPS': ${XMPP_HTTPS_PORT} -EOF - -# Set open_basedir -sed -i 's/;open_basedir =/open_basedir = \/var\/www\/authentication/g' /etc/php7/php.ini - -sed -i "s/__DBUSER__/${DBUSER}/g" /var/www/authentication/vendor/leesherwood/ejabberd-php-auth/src/CommandExecutors/mailcowCommandExecutor.php -sed -i "s/__DBPASS__/${DBPASS}/g" /var/www/authentication/vendor/leesherwood/ejabberd-php-auth/src/CommandExecutors/mailcowCommandExecutor.php -sed -i "s/__DBNAME__/${DBNAME}/g" /var/www/authentication/vendor/leesherwood/ejabberd-php-auth/src/CommandExecutors/mailcowCommandExecutor.php - -# Run hooks -for file in /hooks/*; do - if [ -x "${file}" ]; then - echo "Running hook ${file}" - "${file}" - fi -done - -alias ejabberdctl="su-exec ejabberd /home/ejabberd/bin/ejabberdctl --node ejabberd@${MAILCOW_HOSTNAME}" - -if [[ -z "$(mysql --socket=/var/run/mysqld/mysqld.sock -u ${DBUSER} -p${DBPASS} ${DBNAME} -B -e 'SELECT domain FROM domain WHERE xmpp = 1')" ]]; then - echo "No XMPP host configured, sleeping the sleep of the righteous, waiting for someone to wake me up..." - exec su-exec ejabberd tini -g -- sleep 365d -fi - -exec su-exec ejabberd tini -g -- /home/ejabberd/bin/ejabberdctl --node ejabberd@${MAILCOW_HOSTNAME} foreground diff --git a/data/Dockerfiles/ejabberd/mailcowCommandExecutor.php b/data/Dockerfiles/ejabberd/mailcowCommandExecutor.php deleted file mode 100644 index 390783af..00000000 --- a/data/Dockerfiles/ejabberd/mailcowCommandExecutor.php +++ /dev/null @@ -1,229 +0,0 @@ - 1) { - $trunc_len = $components[0]; - $trunc_password = $components[1]; - - return substr($password, 0, $trunc_len) == $trunc_password; - } else { - return $password == $hash; - } - - case "SHA": - case "SHA1": - case "SHA256": - case "SHA512": - // SHA is an alias for SHA1 - $scheme = $scheme == "SHA" ? "sha1" : strtolower($scheme); - $hash = base64_decode($hash); - return hash_equals(hash($scheme, $password, true), $hash); - - case "SMD5": - return self::verify_salted_hash($hash, $password, 'md5', 16); - - case "SSHA": - return self::verify_salted_hash($hash, $password, 'sha1', 20); - - case "SSHA256": - return self::verify_salted_hash($hash, $password, 'sha256', 32); - - case "SSHA512": - return self::verify_salted_hash($hash, $password, 'sha512', 64); - - default: - return false; - } - } - return false; - } - - public function authenticate($username, $servername, $password) - { - $database_type = 'mysql'; - $database_sock = '/var/run/mysqld/mysqld.sock'; - $database_user = '__DBUSER__'; - $database_pass = '__DBPASS__'; - $database_name = '__DBNAME__'; - - $dsn = $database_type . ":unix_socket=" . $database_sock . ";dbname=" . $database_name; - $opt = [ - PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, - PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, - PDO::ATTR_EMULATE_PREPARES => false - ]; - try { - $pdo = new PDO($dsn, $database_user, $database_pass, $opt); - } - catch (PDOException $e) { - return false; - } - if (!filter_var($username, FILTER_VALIDATE_EMAIL) && !ctype_alnum(str_replace(array('_', '.', '-'), '', $username))) { - return false; - } - $username = strtolower(trim($username)); - $stmt = $pdo->prepare("SELECT `password` FROM `mailbox` - INNER JOIN domain on mailbox.domain = domain.domain - WHERE `kind` NOT REGEXP 'location|thing|group' - AND `mailbox`.`active`= '1' - AND `domain`.`active`= '1' - AND `domain`.`xmpp` = '1' - AND JSON_UNQUOTE(JSON_VALUE(`mailbox`.`attributes`, '$.xmpp_access')) = '1' - AND CONCAT(`domain`.`xmpp_prefix`, '.', `domain`.`domain`) = :servername - AND `username` = CONCAT(:local_part, '@', `domain`.`domain`)"); - $stmt->execute(array(':local_part' => $username, ':servername' => $servername)); - $rows = $stmt->fetchAll(PDO::FETCH_ASSOC); - foreach ($rows as $row) { - if (self::verify_hash($row['password'], $password) !== false) { - return true; - } - } - return false; - } - - /** - * Check if a user exists - * - * @param string $username - * @param string $servername - * - * @return bool - */ - public function userExists($username, $servername) - { - return true; - } - - /** - * Set a password for a user - * - * @param string $username - * @param string $servername - * @param string $password - * - * @return bool - */ - public function setPassword($username, $servername, $password) - { - return false; - } - - /** - * Register a user - * - * @param string $username - * @param string $servername - * @param string $password - * - * @return bool - */ - public function register($username, $servername, $password) - { - return false; - } - - /** - * Delete a user - * - * @param string $username - * @param string $servername - * - * @return bool - */ - public function removeUser($username, $servername) - { - return false; - } - - /** - * Delete a user with password validation - * - * @param string $username - * @param string $servername - * @param string $password - * - * @return bool - */ - public function removeUserWithPassword($username, $servername, $password) - { - return false; - } -} \ No newline at end of file diff --git a/data/Dockerfiles/netfilter/Dockerfile b/data/Dockerfiles/netfilter/Dockerfile index 007bd641..c63e99bc 100644 --- a/data/Dockerfiles/netfilter/Dockerfile +++ b/data/Dockerfiles/netfilter/Dockerfile @@ -1,4 +1,4 @@ -FROM alpine:3.13 +FROM alpine:3.14 LABEL maintainer "Andre Peters " ENV XTABLES_LIBDIR /usr/lib/xtables diff --git a/data/Dockerfiles/netfilter/server.py b/data/Dockerfiles/netfilter/server.py index 88fc5f25..08c87271 100644 --- a/data/Dockerfiles/netfilter/server.py +++ b/data/Dockerfiles/netfilter/server.py @@ -92,15 +92,16 @@ def refreshF2bregex(): global exit_code if not r.get('F2B_REGEX'): f2bregex = {} - f2bregex[1] = 'warning: .*\[([0-9a-f\.:]+)\]: SASL .+ authentication failed' - f2bregex[2] = '-login: Disconnected \(auth failed, .+\): user=.*, method=.+, rip=([0-9a-f\.:]+),' - f2bregex[3] = '-login: Aborted login \(tried to use disallowed .+\): user=.+, rip=([0-9a-f\.:]+), lip.+' - f2bregex[4] = 'SOGo.+ Login from \'([0-9a-f\.:]+)\' for user .+ might not have worked' - f2bregex[5] = 'mailcow UI: Invalid password for .+ by ([0-9a-f\.:]+)' - f2bregex[6] = '([0-9a-f\.:]+) \"GET \/SOGo\/.* HTTP.+\" 403 .+' - f2bregex[7] = 'Rspamd UI: Invalid password by ([0-9a-f\.:]+)' - f2bregex[8] = '-login: Aborted login \(auth failed .+\): user=.+, rip=([0-9a-f\.:]+), lip.+' - f2bregex[9] = 'NOQUEUE: reject: RCPT from \[([0-9a-f\.:]+)].+Protocol error.+' + f2bregex[1] = 'mailcow UI: Invalid password for .+ by ([0-9a-f\.:]+)' + f2bregex[2] = 'Rspamd UI: Invalid password by ([0-9a-f\.:]+)' + f2bregex[3] = 'warning: .*\[([0-9a-f\.:]+)\]: SASL .+ authentication failed' + f2bregex[4] = 'warning: non-SMTP command from .*\[([0-9a-f\.:]+)]:.+' + f2bregex[5] = 'NOQUEUE: reject: RCPT from \[([0-9a-f\.:]+)].+Protocol error.+' + f2bregex[6] = '-login: Disconnected \(auth failed, .+\): user=.*, method=.+, rip=([0-9a-f\.:]+),' + f2bregex[7] = '-login: Aborted login \(auth failed .+\): user=.+, rip=([0-9a-f\.:]+), lip.+' + f2bregex[8] = '-login: Aborted login \(tried to use disallowed .+\): user=.+, rip=([0-9a-f\.:]+), lip.+' + f2bregex[9] = 'SOGo.+ Login from \'([0-9a-f\.:]+)\' for user .+ might not have worked' + f2bregex[10] = '([0-9a-f\.:]+) \"GET \/SOGo\/.* HTTP.+\" 403 .+' r.set('F2B_REGEX', json.dumps(f2bregex, ensure_ascii=False)) else: try: diff --git a/data/Dockerfiles/olefy/Dockerfile b/data/Dockerfiles/olefy/Dockerfile index 3cacabba..6d9727c0 100644 --- a/data/Dockerfiles/olefy/Dockerfile +++ b/data/Dockerfiles/olefy/Dockerfile @@ -1,4 +1,4 @@ -FROM alpine:3.13 +FROM alpine:3.14 LABEL maintainer "Andre Peters " WORKDIR /app diff --git a/data/Dockerfiles/phpfpm/docker-entrypoint.sh b/data/Dockerfiles/phpfpm/docker-entrypoint.sh index 9a2b5829..cefebcdf 100755 --- a/data/Dockerfiles/phpfpm/docker-entrypoint.sh +++ b/data/Dockerfiles/phpfpm/docker-entrypoint.sh @@ -181,8 +181,10 @@ fi # Fix permissions for global filters chown -R 82:82 /global_sieve/* -[[ ! -f /etc/nginx/conf.d/ZZZ-ejabberd.conf ]] && echo '# Autogenerated by mailcow' > /etc/nginx/conf.d/ZZZ-ejabberd.conf -chown 82:82 /etc/nginx/conf.d/ZZZ-ejabberd.conf +# Fix permissions on twig cache folder +chown -R 82:82 /web/templates/cache +# Clear cache +find /web/templates/cache/* -not -name '.gitkeep' -delete # Run hooks for file in /hooks/*; do diff --git a/data/Dockerfiles/rspamd/Dockerfile b/data/Dockerfiles/rspamd/Dockerfile index 888bdcb2..ee08f8d2 100644 --- a/data/Dockerfiles/rspamd/Dockerfile +++ b/data/Dockerfiles/rspamd/Dockerfile @@ -1,8 +1,8 @@ -FROM debian:buster-slim -LABEL maintainer "Andre Peters " +FROM debian:bullseye-slim +LABEL maintainer "Andre Peters " ARG DEBIAN_FRONTEND=noninteractive -ARG CODENAME=buster +ARG CODENAME=bullseye ENV LC_ALL C RUN apt-get update && apt-get install -y \ @@ -15,12 +15,13 @@ RUN apt-get update && apt-get install -y \ && apt-key adv --fetch-keys https://rspamd.com/apt-stable/gpg.key \ && echo "deb [arch=amd64] https://rspamd.com/apt-stable/ $CODENAME main" > /etc/apt/sources.list.d/rspamd.list \ && apt-get update \ - && apt-get --no-install-recommends -y install rspamd redis-tools \ + && apt-get --no-install-recommends -y install rspamd redis-tools procps nano \ && rm -rf /var/lib/apt/lists/* \ && apt-get autoremove --purge \ && apt-get clean \ && mkdir -p /run/rspamd \ - && chown _rspamd:_rspamd /run/rspamd + && chown _rspamd:_rspamd /run/rspamd \ + && echo 'alias ll="ls -la --color"' >> ~/.bashrc COPY settings.conf /etc/rspamd/settings.conf COPY metadata_exporter.lua /usr/share/rspamd/plugins/metadata_exporter.lua diff --git a/data/Dockerfiles/unbound/Dockerfile b/data/Dockerfiles/unbound/Dockerfile index cce2c00b..a937e7e6 100644 --- a/data/Dockerfiles/unbound/Dockerfile +++ b/data/Dockerfiles/unbound/Dockerfile @@ -1,4 +1,4 @@ -FROM alpine:3.13 +FROM alpine:3.14 LABEL maintainer "Andre Peters " diff --git a/data/Dockerfiles/watchdog/Dockerfile b/data/Dockerfiles/watchdog/Dockerfile index e82bc5d0..00cb8e99 100644 --- a/data/Dockerfiles/watchdog/Dockerfile +++ b/data/Dockerfiles/watchdog/Dockerfile @@ -1,4 +1,4 @@ -FROM alpine:3.11 +FROM alpine:3.14 LABEL maintainer "André Peters " # Installation @@ -36,4 +36,4 @@ RUN apk add --update \ COPY watchdog.sh /watchdog.sh COPY check_mysql_slavestatus.sh /usr/lib/nagios/plugins/check_mysql_slavestatus.sh -CMD /watchdog.sh 2> /dev/null +CMD /watchdog.sh diff --git a/data/Dockerfiles/watchdog/watchdog.sh b/data/Dockerfiles/watchdog/watchdog.sh index ade99f2a..231d0ecd 100755 --- a/data/Dockerfiles/watchdog/watchdog.sh +++ b/data/Dockerfiles/watchdog/watchdog.sh @@ -6,7 +6,10 @@ trap "kill 0" EXIT # Prepare BACKGROUND_TASKS=() echo "Waiting for containers to settle..." -sleep 30 +for i in {30..1}; do + echo "${i}" + sleep 1 +done if [[ "${USE_WATCHDOG}" =~ ^([nN][oO]|[nN])+$ ]]; then echo -e "$(date) - USE_WATCHDOG=n, skipping watchdog..." @@ -14,6 +17,14 @@ if [[ "${USE_WATCHDOG}" =~ ^([nN][oO]|[nN])+$ ]]; then exec $(readlink -f "$0") fi +if [[ "${WATCHDOG_VERBOSE}" =~ ^([yY][eE][sS]|[yY])+$ ]]; then + SMTP_VERBOSE="--verbose" + set -xv +else + SMTP_VERBOSE="" + exec 2>/dev/null +fi + # Checks pipe their corresponding container name in this pipe if [[ ! -p /tmp/com_pipe ]]; then mkfifo /tmp/com_pipe @@ -114,16 +125,16 @@ function mail_error() { IFS=',' read -r -a MAIL_RCPTS <<< "${WATCHDOG_NOTIFY_EMAIL}" for rcpt in "${MAIL_RCPTS[@]}"; do RCPT_DOMAIN= - #RCPT_MX= + RCPT_MX= RCPT_DOMAIN=$(echo ${rcpt} | awk -F @ {'print $NF'}) - # Latest smtp-cli looks up mx via dns - #RCPT_MX=$(dig +short ${RCPT_DOMAIN} mx | sort -n | awk '{print $2; exit}') - #if [[ -z ${RCPT_MX} ]]; then - # log_msg "Cannot determine MX for ${rcpt}, skipping email notification..." - # return 1 - #fi + CHECK_FOR_VALID_MX=$(dig +short ${RCPT_DOMAIN} mx) + if [[ -z ${CHECK_FOR_VALID_MX} ]]; then + log_msg "Cannot determine MX for ${rcpt}, skipping email notification..." + return 1 + fi [ -f "/tmp/${1}" ] && BODY="/tmp/${1}" timeout 10s ./smtp-cli --missing-modules-ok \ + "${SMTP_VERBOSE}" \ --charset=UTF-8 \ --subject="${SUBJECT}" \ --body-plain="${BODY}" \ @@ -132,8 +143,15 @@ function mail_error() { --from="watchdog@${MAILCOW_HOSTNAME}" \ --hello-host=${MAILCOW_HOSTNAME} \ --ipv4 - #--server="${RCPT_MX}" - log_msg "Sent notification email to ${rcpt}" + if [[ $? -eq 1 ]]; then # exit code 1 is fine + log_msg "Sent notification email to ${rcpt}" + else + if [[ "${SMTP_VERBOSE}" == "" ]]; then + log_msg "Error while sending notification email to ${rcpt}. You can enable verbose logging by setting 'WATCHDOG_VERBOSE=y' in mailcow.conf." + else + log_msg "Error while sending notification email to ${rcpt}." + fi + fi done } @@ -154,7 +172,7 @@ get_container_ip() { CONTAINER_ID=($(printf "%s\n" "${CONTAINER_ID[@]}" | shuf)) if [[ ! -z ${CONTAINER_ID} ]]; then for matched_container in "${CONTAINER_ID[@]}"; do - CONTAINER_IPS=($(curl --silent --insecure https://dockerapi/containers/${matched_container}/json | jq -r '.NetworkSettings.Networks[].IPAddress')) + CONTAINER_IPS=($(curl --silent --insecure https://dockerapi/containers/${matched_container}/json | jq -r '.NetworkSettings.Networks[].IPAddress')) for ip_match in "${CONTAINER_IPS[@]}"; do # grep will do nothing if one of these vars is empty [[ -z ${ip_match} ]] && continue @@ -358,7 +376,7 @@ sogo_checks() { touch /tmp/sogo-mailcow; echo "$(tail -50 /tmp/sogo-mailcow)" > /tmp/sogo-mailcow host_ip=$(get_container_ip sogo-mailcow) err_c_cur=${err_count} - /usr/lib/nagios/plugins/check_http -4 -H ${host_ip} -u /SOGo.index/ -p 20000 -R "SOGo\.MainUI" 2>> /tmp/sogo-mailcow 1>&2; err_count=$(( ${err_count} + $? )) + /usr/lib/nagios/plugins/check_http -4 -H ${host_ip} -u /SOGo.index/ -p 20000 2>> /tmp/sogo-mailcow 1>&2; err_count=$(( ${err_count} + $? )) [ ${err_c_cur} -eq ${err_count} ] && [ ! $((${err_count} - 1)) -lt 0 ] && err_count=$((${err_count} - 1)) diff_c=1 [ ${err_c_cur} -ne ${err_count} ] && diff_c=$(( ${err_c_cur} - ${err_count} )) progress "SOGo" ${THRESHOLD} $(( ${THRESHOLD} - ${err_count} )) ${diff_c} diff --git a/data/conf/mysql/my.cnf b/data/conf/mysql/my.cnf index 9f520686..efbf5845 100644 --- a/data/conf/mysql/my.cnf +++ b/data/conf/mysql/my.cnf @@ -25,6 +25,8 @@ skip-host-cache skip-name-resolve log-warnings = 0 event_scheduler = 1 +interactive_timeout = 3610 +wait_timeout = 3610 [client] default-character-set = utf8mb4 diff --git a/data/conf/postfix/main.cf b/data/conf/postfix/main.cf index 00eb8a93..a445b60c 100644 --- a/data/conf/postfix/main.cf +++ b/data/conf/postfix/main.cf @@ -27,7 +27,7 @@ maximal_backoff_time = 1800s maximal_queue_lifetime = 5d delay_warning_time = 4h message_size_limit = 104857600 -milter_default_action = accept +milter_default_action = tempfail milter_protocol = 6 minimal_backoff_time = 300s plaintext_reject_code = 550 diff --git a/data/conf/rspamd/custom/bulk_header.map b/data/conf/rspamd/custom/bulk_header.map index e9dc206f..39aa7fea 100644 --- a/data/conf/rspamd/custom/bulk_header.map +++ b/data/conf/rspamd/custom/bulk_header.map @@ -17,3 +17,4 @@ /.*light-house-traffic.*/i /.*newsletterplus.*/i /.*X-Chpo.*/i +/.*List-Unsubscribe:.*@nl\..*/i diff --git a/data/conf/rspamd/dynmaps/settings.php b/data/conf/rspamd/dynmaps/settings.php index 0569db90..274e9da2 100644 --- a/data/conf/rspamd/dynmaps/settings.php +++ b/data/conf/rspamd/dynmaps/settings.php @@ -26,9 +26,8 @@ catch (PDOException $e) { } // Check if db changed and return header -/* -$stmt = $pdo->prepare("SELECT MAX(UNIX_TIMESTAMP(UPDATE_TIME)) AS `db_update_time` FROM information_schema.tables - WHERE (`TABLE_NAME` = 'filterconf' OR `TABLE_NAME` = 'settingsmap') +$stmt = $pdo->prepare("SELECT GREATEST(COALESCE(MAX(UNIX_TIMESTAMP(UPDATE_TIME)), 1), COALESCE(MAX(UNIX_TIMESTAMP(CREATE_TIME)), 1)) AS `db_update_time` FROM `information_schema`.`tables` + WHERE (`TABLE_NAME` = 'filterconf' OR `TABLE_NAME` = 'settingsmap' OR `TABLE_NAME` = 'sogo_quick_contact' OR `TABLE_NAME` = 'alias') AND TABLE_SCHEMA = :dbname;"); $stmt->execute(array( ':dbname' => $database_name @@ -43,7 +42,6 @@ if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) && (strtotime($_SERVER['HTTP_IF_MO } else { header('Last-Modified: '.gmdate('D, d M Y H:i:s', $db_update_time).' GMT', true, 200); } -*/ function parse_email($email) { if (!filter_var($email, FILTER_VALIDATE_EMAIL)) return false; @@ -51,6 +49,30 @@ function parse_email($email) { return array('local' => substr($email, 0, $a), 'domain' => substr($email, $a)); } +function normalize_email($email) { + $email = strtolower(str_replace('/', '\/', $email)); + $gm = "@gmail.com"; + if (substr_compare($email, $gm, -strlen($gm)) == 0) { + $email = explode('@', $email); + $email[0] = str_replace('.', '', $email[0]); + $email = implode('@', $email); + } + $gm_alt = "@googlemail.com"; + if (substr_compare($email, $gm_alt, -strlen($gm_alt)) == 0) { + $email = explode('@', $email); + $email[0] = str_replace('.', '', $email[0]); + $email[1] = str_replace('@', '', $gm); + $email = implode('@', $email); + } + if (str_contains($email, "+")) { + $email = explode('@', $email); + $user = explode('+', $email[0]); + $email[0] = $user[0]; + $email = implode('@', $email); + } + return $email; +} + function wl_by_sogo() { global $pdo; $rcpt = array(); @@ -65,7 +87,7 @@ function wl_by_sogo() { } // Explicit from, no mime_from, no regex - envelope must match // mailcow white and blacklists also cover mime_from - $rcpt[$row['user']][] = str_replace('/', '\/', $contact); + $rcpt[$row['user']][] = normalize_email($contact); } } return $rcpt; diff --git a/data/conf/rspamd/local.d/metadata_exporter.conf b/data/conf/rspamd/local.d/metadata_exporter.conf index b6aa1507..47373d99 100644 --- a/data/conf/rspamd/local.d/metadata_exporter.conf +++ b/data/conf/rspamd/local.d/metadata_exporter.conf @@ -26,7 +26,7 @@ custom_select { mailcow_rcpt = < "get_friendly_names")); if (!isset($_SESSION['gal']) && $license_cache = $redis->Get('LICENSE_STATUS_CACHE')) { $_SESSION['gal'] = json_decode($license_cache, true); } -?> -
- - -
-
-
-
-
-
-
-
-
-
-
-
- - -
- - -
-
- - - - - -
-
:
-
-

-
- -
- -
- - [] -
-
- -
-
-
-
-
-
:
-
- -
-
- - - - - -
-
:
-
-
- - - - - - - - - - - -
ID
- ' : NULL; ?> - -
- -
-
-
-
-
-
-
-
- -
-
-
-
-
:
-
-
-
-
-
-
- - - - -
-
-
- -
-
- - "> - - -
-

- : - - : - - : -

-
-
-
-
-

-
- -
-
-
-
-
- - - API - -
-
- -
-

-
-
-
-
-

-
-
-
-
- -
- -
-
-
-
- -
-
-
- -
-
-
-
-
-
- -
-
-
-
-
- - -
-
-
-
-
-
-
-
-
-
-

-
-
-
-
- -
- -
-
-
-
- -
-
-
- -
-
-
-
-
-
- -
-
-
-
-
- - -
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
- - - -
- -
-
-
-
-
- -
-
-
-
-
-
-
- -
-
-
-
-

-
-
-
-
-
- - - -
- -
-
-
-
-
- -
-
-
-

Rspamd UI

-
-
-
-
- Rspamd UI -
-
-
-
-
- -
-
-
- -
- -
-
-
- -
- -
-
-
-
- -
-
-
-
- -
-
-
-
- -
-
-
-
-

-
-
-
-
-
- - - -
-
-
- -

-
-
-
-
- - -
-
- - -
-
- - -
- -
-
-
-
-
- -
-
-
-

-
-
-
-
-
- - - -
-
-
- -

-
-
-
-
- - ' required> -
-
- - -
-
- - -
-
- - -
-
- -
-
- -
-

- -
-
-
-
-
-
- -
-
-
-
-
- - - -
-
- -
-
-
-

: -

-

''

-

bit

-

-
-
-
-

-
-
-
- -
-
-
-

:

-
-
-
-
-
- -
-
-
-

↳ Alias-Domain: -

-

Selector ''

-

bit

-

-
-
-
-

Private key

-
-
-
- -
-
-
-

↳ Alias-Domain:

-
-
-
-
-
- -
-
-
-

: -

-

Selector ''

-

bit

-

-
-
-
-

Private key

-
-
-
- -
-
- - -
-
-
- - -
-
- - - -
-
- - -
-
- -
- -
- - - - -
-
-
- - -
-
- - -
-
- - -
-
- -
- -
-
- - - - -
-
-
- -
- -
-
-
- -
- -
-
- -
-
-
-
-
- -
-
-
-
-

-
-
-
-
- -
- -

-
-
- - -
-
- -
- -
-
-
-
- -
-
-
-
- -
-
- - -
-
- - -
-
- - -
-
- -
- / - -
-
-
- -
- / - -
-
-
-

-
- - -
-
- - -
-
- - -
-
-
- - - -
-

-
- - - - - - - $regex_val) { - ?> - - - - - - -
IDRegExp 
-

- - - -

-
-
- -

- - - -

() - - - [] - [whitelist] - [blacklist (needs restart)] - - - -

- -
- - - -
-
-
- -
-
-
-
- -
- -
-
- -
- -
-
-
- -
- -
-
-
- -
- -
-
-
- -
- -
-
-
-
- -
- -
-
-
- -
- -
-
-
-
- -
- -
-
-
- -
- -
-
-
-
- -
- -
-
-
- -
- -
-
-
- - - -
- -
- -
-
-
-
- -
-
-
-
-

- -
-
-
-
- - -
-
-
-
- - -
-
-
-
-
- - - -
- - -
-
-
-
-
-
-
- -
-
-
-
-
-
-
- -
-
-
-
- - - -
- -
-
- -
-
-
-
- - - - (ID #) - - -
-
-
-
- -
-

-
- -
-

-
- -
- - -
- - -
-
- - -
-
- -
- - - -
- -
-
-
- -
-
-
- -
-
-
-
- -

-
-

-
- -

-
- -
-
-
- mailcow logo -
- x px - - -
-
-
-
-

-
-
-
- - -

-
- - - - - - - $val) { - ?> - - - - - - - - - - - - - -

- - -
-

-
- -
- -
-
- - -
-
- - -
-
- - -
-
- - -
-
-
-

- -

-

-
- -
-
-
-
- - -
- -
-
-
-
-
- -
-
-
-
- -
- $value) { - if ($name == 'length') { - ?> -
- -
- -
-
- - -
-
- -
-
- -
-
-
- -
-
-
-
-
-
-
- -
-
-
-
-
-
- -
- -
-
-
- -
- -
-
- -
- -
- - -
-
- - -
-
-
- -
- -
-
-
- -
- -

-
-
-
-
- -
-
-
-
- -
-
-
-
-
-
- -
-
-
- -
- -
-
-
-
-
-
-
-
- - - -
- - -
-
-
-
-
- -
-
-
- -
-
-

-
-
-
- -
-
-
-
-
- -

-

-
    - $rspamd_regex_map): - ?> -
  • ()
  • - -
- $rspamd_regex_map): - ?> -
- -
-
- -
- -
-
-
-
- - -
-
-
- -
-
-
-
- -
-
-
-
- - -add('/web/js/site/admin.js'); $js_minifier->add('/web/js/presets/rspamd.js'); $js_minifier->add('/web/js/site/pwgen.js'); -require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/footer.inc.php'; -} else { - header('Location: /'); - exit(); + +// all domains +$domains = mailbox('get', 'domains'); +$all_domains = array_merge($domains, mailbox('get', 'alias_domains')); + +// mailboxes +$mailboxes = []; +foreach ($all_domains as $domain) { + foreach (mailbox('get', 'mailboxes', $domain) as $mailbox) { + $mailboxes[] = $mailbox; + } } -?> +$mailboxes = array_filter($mailboxes); + +// DKIM domains +$dkim_domains = []; +$dkim_domains_with_keys = []; +foreach($domains as $domain) { + $dkim_domains[$domain] = ['dkim' => null, 'alias_domains' => []]; + if (!empty($dkim = dkim('details', $domain))) { + $dkim_domains_with_keys[] = $domain; + if ($GLOBALS['SHOW_DKIM_PRIV_KEYS'] !== true) { + $dkim['privkey'] = base64_encode('Please set $SHOW_DKIM_PRIV_KEYS to true to show DKIM private keys.'); + } + $dkim_domains[$domain]['dkim'] = $dkim; + } + + // get alias domains + foreach (mailbox('get', 'alias_domains', $domain) as $alias_domain) { + $dkim_domains[$domain]['alias_domains'][$alias_domain] = ['dkim' => null]; + if (!empty($dkim = dkim('details', $alias_domain))) { + $dkim_domains_with_keys[] = $alias_domain; + if ($GLOBALS['SHOW_DKIM_PRIV_KEYS'] !== true) { + $dkim['privkey'] = base64_encode('Please set $SHOW_DKIM_PRIV_KEYS to true to show DKIM private keys.'); + } + $dkim_domains[$domain]['alias_domains'][$alias_domain]['dkim'] = $dkim; + } + } +} +$dkim_blind_domains = []; +foreach(dkim('blind') as $blind) { + $dkim_blind_domains[$blind] = ['dkim' => null]; + if (!empty($dkim = dkim('details', $blind))) { + $dkim_domains_with_keys[] = $blind; + if ($GLOBALS['SHOW_DKIM_PRIV_KEYS'] !== true) { + $dkim['privkey'] = base64_encode('Please set $SHOW_DKIM_PRIV_KEYS to true to show DKIM private keys.'); + } + $dkim_blind_domains[$blind]['dkim'] = $dkim; + } +} + +// rsettings +$rsettings = array_map(function ($rsetting){ + $rsetting['details'] = rsettings('details', $rsetting['id']); + return $rsetting; +}, rsettings('get')); + +// rspamd regex maps +$rspamd_regex_maps = []; +foreach ($RSPAMD_MAPS['regex'] as $rspamd_regex_desc => $rspamd_regex_map) { + $rspamd_regex_maps[$rspamd_regex_desc] = [ + 'map' => $rspamd_regex_map, + 'data' => file_get_contents('/rspamd_custom_maps/' . $rspamd_regex_map) + ]; +} + + +$template = 'admin.twig'; +$template_data = [ + 'tfa_data' => $tfa_data, + 'tfa_id' => @$_SESSION['tfa_id'], + 'fido2_cid' => @$_SESSION['fido2_cid'], + 'fido2_data' => $fido2_data, + 'gal' => @$_SESSION['gal'], + 'license_guid' => license('guid'), + 'api' => [ + 'ro' => admin_api('ro', 'get'), + 'rw' => admin_api('rw', 'get'), + ], + 'dkim_domains' => $dkim_domains, + 'dkim_domains_with_keys' => $dkim_domains_with_keys, + 'dkim_blind_domains' => $dkim_blind_domains, + 'domains' => $domains, + 'all_domains' => $all_domains, + 'mailboxes' => $mailboxes, + 'f2b_data' => fail2ban('get'), + 'q_data' => quarantine('settings'), + 'qn_data' => quota_notification('get'), + 'rsettings_map' => file_get_contents('http://nginx:8081/settings.php'), + 'rsettings' => $rsettings, + 'rspamd_regex_maps' => $rspamd_regex_maps, + 'logo_specs' => customize('get', 'main_logo_specs'), + 'password_complexity' => password_complexity('get'), + 'show_rspamd_global_filters' => @$_SESSION['show_rspamd_global_filters'], + 'lang_admin' => json_encode($lang['admin']), +]; + +require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/footer.inc.php'; diff --git a/data/web/api/index.html b/data/web/api/index.html index 29c4e68a..907470da 100644 --- a/data/web/api/index.html +++ b/data/web/api/index.html @@ -4,7 +4,7 @@ Swagger UI - + ",returnEnd:!0,subLanguage:["css","xml"]}},{className:"tag",begin:")",end:">",keywords:{name:"script"},contains:[l],starts:{end:/<\/script>/,returnEnd:!0,subLanguage:["javascript","handlebars","xml"]}},{className:"tag",begin:/<>|<\/>/},{className:"tag",begin:o(//,/>/,/\s/)))),end:/\/?>/,contains:[{className:"name",begin:t,relevance:0,starts:l}]},{className:"tag",begin:o(/<\//,r(o(t,/>/))),contains:[{className:"name",begin:t,relevance:0},{begin:/>/,relevance:0}]}]}}},function(e,t){e.exports=function(e){var t="true false yes no null",n="[\\w#;/?:@&=+$,.~*'()[\\]]+",r={className:"string",relevance:0,variants:[{begin:/'/,end:/'/},{begin:/"/,end:/"/},{begin:/\S+/}],contains:[e.BACKSLASH_ESCAPE,{className:"template-variable",variants:[{begin:/\{\{/,end:/\}\}/},{begin:/%\{/,end:/\}/}]}]},o=e.inherit(r,{variants:[{begin:/'/,end:/'/},{begin:/"/,end:/"/},{begin:/[^\s,{}[\]]+/}]}),a={className:"number",begin:"\\b[0-9]{4}(-[0-9][0-9]){0,2}([Tt \\t][0-9][0-9]?(:[0-9][0-9]){2})?(\\.[0-9]*)?([ \\t])*(Z|[-+][0-9][0-9]?(:[0-9][0-9])?)?\\b"},i={end:",",endsWithParent:!0,excludeEnd:!0,contains:[],keywords:t,relevance:0},s={begin:/\{/,end:/\}/,contains:[i],illegal:"\\n",relevance:0},u={begin:"\\[",end:"\\]",contains:[i],illegal:"\\n",relevance:0},c=[{className:"attr",variants:[{begin:"\\w[\\w :\\/.-]*:(?=[ \t]|$)"},{begin:'"\\w[\\w :\\/.-]*":(?=[ \t]|$)'},{begin:"'\\w[\\w :\\/.-]*':(?=[ \t]|$)"}]},{className:"meta",begin:"^---\\s*$",relevance:10},{className:"string",begin:"[\\|>]([1-9]?[+-])?[ ]*\\n( +)[^ ][^\\n]*\\n(\\2[^\\n]+\\n?)*"},{begin:"<%[%=-]?",end:"[%-]?%>",subLanguage:"ruby",excludeBegin:!0,excludeEnd:!0,relevance:0},{className:"type",begin:"!\\w+!"+n},{className:"type",begin:"!<"+n+">"},{className:"type",begin:"!"+n},{className:"type",begin:"!!"+n},{className:"meta",begin:"&"+e.UNDERSCORE_IDENT_RE+"$"},{className:"meta",begin:"\\*"+e.UNDERSCORE_IDENT_RE+"$"},{className:"bullet",begin:"-(?=[ ]|$)",relevance:0},e.HASH_COMMENT_MODE,{beginKeywords:t,keywords:{literal:t}},a,{className:"number",begin:e.C_NUMBER_RE+"\\b",relevance:0},s,u,r],l=[...c];return l.pop(),l.push(o),i.contains=l,{name:"YAML",case_insensitive:!0,aliases:["yml","YAML"],contains:c}}},function(e,t){e.exports=function(e){var t="HTTP/[0-9\\.]+";return{name:"HTTP",aliases:["https"],illegal:"\\S",contains:[{begin:"^"+t,end:"$",contains:[{className:"number",begin:"\\b\\d{3}\\b"}]},{begin:"^[A-Z]+ (.*?) "+t+"$",returnBegin:!0,end:"$",contains:[{className:"string",begin:" ",end:" ",excludeBegin:!0,excludeEnd:!0},{begin:t},{className:"keyword",begin:"[A-Z]+"}]},{className:"attribute",begin:"^\\w",end:": ",excludeEnd:!0,illegal:"\\n|\\s|=",starts:{end:"$",relevance:0}},{begin:"\\n\\n",starts:{subLanguage:[],endsWithParent:!0}}]}}},function(e,t){function n(...e){return e.map((e=>{return(t=e)?"string"==typeof t?t:t.source:null;var t})).join("")}e.exports=function(e){const t={},r={begin:/\$\{/,end:/\}/,contains:["self",{begin:/:-/,contains:[t]}]};Object.assign(t,{className:"variable",variants:[{begin:n(/\$[\w\d#@][\w\d_]*/,"(?![\\w\\d])(?![$])")},r]});const o={className:"subst",begin:/\$\(/,end:/\)/,contains:[e.BACKSLASH_ESCAPE]},a={begin:/<<-?\s*(?=\w+)/,starts:{contains:[e.END_SAME_AS_BEGIN({begin:/(\w+)/,end:/(\w+)/,className:"string"})]}},i={className:"string",begin:/"/,end:/"/,contains:[e.BACKSLASH_ESCAPE,t,o]};o.contains.push(i);const s={begin:/\$\(\(/,end:/\)\)/,contains:[{begin:/\d+#[0-9a-f]+/,className:"number"},e.NUMBER_MODE,t]},u=e.SHEBANG({binary:`(${["fish","bash","zsh","sh","csh","ksh","tcsh","dash","scsh"].join("|")})`,relevance:10}),c={className:"function",begin:/\w[\w\d_]*\s*\(\s*\)\s*\{/,returnBegin:!0,contains:[e.inherit(e.TITLE_MODE,{begin:/\w[\w\d_]*/})],relevance:0};return{name:"Bash",aliases:["sh","zsh"],keywords:{$pattern:/\b[a-z._-]+\b/,keyword:"if then else elif fi for while in do done case esac function",literal:"true false",built_in:"break cd continue eval exec exit export getopts hash pwd readonly return shift test times trap umask unset alias bind builtin caller command declare echo enable help let local logout mapfile printf read readarray source type typeset ulimit unalias set shopt autoload bg bindkey bye cap chdir clone comparguments compcall compctl compdescribe compfiles compgroups compquote comptags comptry compvalues dirs disable disown echotc echoti emulate fc fg float functions getcap getln history integer jobs kill limit log noglob popd print pushd pushln rehash sched setcap setopt stat suspend ttyctl unfunction unhash unlimit unsetopt vared wait whence where which zcompile zformat zftp zle zmodload zparseopts zprof zpty zregexparse zsocket zstyle ztcp"},contains:[u,e.SHEBANG(),c,s,e.HASH_COMMENT_MODE,a,i,{className:"",begin:/\\"/},{className:"string",begin:/'/,end:/'/},t]}}},function(e,t){e.exports=function(e){const t={$pattern:/-?[A-z\.\-]+\b/,keyword:"if else foreach return do while until elseif begin for trap data dynamicparam end break throw param continue finally in switch exit filter try process catch hidden static parameter",built_in:"ac asnp cat cd CFS chdir clc clear clhy cli clp cls clv cnsn compare copy cp cpi cpp curl cvpa dbp del diff dir dnsn ebp echo|0 epal epcsv epsn erase etsn exsn fc fhx fl ft fw gal gbp gc gcb gci gcm gcs gdr gerr ghy gi gin gjb gl gm gmo gp gps gpv group gsn gsnp gsv gtz gu gv gwmi h history icm iex ihy ii ipal ipcsv ipmo ipsn irm ise iwmi iwr kill lp ls man md measure mi mount move mp mv nal ndr ni nmo npssc nsn nv ogv oh popd ps pushd pwd r rbp rcjb rcsn rd rdr ren ri rjb rm rmdir rmo rni rnp rp rsn rsnp rujb rv rvpa rwmi sajb sal saps sasv sbp sc scb select set shcm si sl sleep sls sort sp spjb spps spsv start stz sujb sv swmi tee trcm type wget where wjb write"},n={begin:"`[\\s\\S]",relevance:0},r={className:"variable",variants:[{begin:/\$\B/},{className:"keyword",begin:/\$this/},{begin:/\$[\w\d][\w\d_:]*/}]},o={className:"string",variants:[{begin:/"/,end:/"/},{begin:/@"/,end:/^"@/}],contains:[n,r,{className:"variable",begin:/\$[A-z]/,end:/[^A-z]/}]},a={className:"string",variants:[{begin:/'/,end:/'/},{begin:/@'/,end:/^'@/}]},i=e.inherit(e.COMMENT(null,null),{variants:[{begin:/#/,end:/$/},{begin:/<#/,end:/#>/}],contains:[{className:"doctag",variants:[{begin:/\.(synopsis|description|example|inputs|outputs|notes|link|component|role|functionality)/},{begin:/\.(parameter|forwardhelptargetname|forwardhelpcategory|remotehelprunspace|externalhelp)\s+\S+/}]}]}),s={className:"built_in",variants:[{begin:"(".concat("Add|Clear|Close|Copy|Enter|Exit|Find|Format|Get|Hide|Join|Lock|Move|New|Open|Optimize|Pop|Push|Redo|Remove|Rename|Reset|Resize|Search|Select|Set|Show|Skip|Split|Step|Switch|Undo|Unlock|Watch|Backup|Checkpoint|Compare|Compress|Convert|ConvertFrom|ConvertTo|Dismount|Edit|Expand|Export|Group|Import|Initialize|Limit|Merge|Out|Publish|Restore|Save|Sync|Unpublish|Update|Approve|Assert|Complete|Confirm|Deny|Disable|Enable|Install|Invoke|Register|Request|Restart|Resume|Start|Stop|Submit|Suspend|Uninstall|Unregister|Wait|Debug|Measure|Ping|Repair|Resolve|Test|Trace|Connect|Disconnect|Read|Receive|Send|Write|Block|Grant|Protect|Revoke|Unblock|Unprotect|Use|ForEach|Sort|Tee|Where",")+(-)[\\w\\d]+")}]},u={className:"class",beginKeywords:"class enum",end:/\s*[{]/,excludeEnd:!0,relevance:0,contains:[e.TITLE_MODE]},c={className:"function",begin:/function\s+/,end:/\s*\{|$/,excludeEnd:!0,returnBegin:!0,relevance:0,contains:[{begin:"function",relevance:0,className:"keyword"},{className:"title",begin:/\w[\w\d]*((-)[\w\d]+)*/,relevance:0},{begin:/\(/,end:/\)/,className:"params",relevance:0,contains:[r]}]},l={begin:/using\s/,end:/$/,returnBegin:!0,contains:[o,a,{className:"keyword",begin:/(using|assembly|command|module|namespace|type)/}]},p={variants:[{className:"operator",begin:"(".concat("-and|-as|-band|-bnot|-bor|-bxor|-casesensitive|-ccontains|-ceq|-cge|-cgt|-cle|-clike|-clt|-cmatch|-cne|-cnotcontains|-cnotlike|-cnotmatch|-contains|-creplace|-csplit|-eq|-exact|-f|-file|-ge|-gt|-icontains|-ieq|-ige|-igt|-ile|-ilike|-ilt|-imatch|-in|-ine|-inotcontains|-inotlike|-inotmatch|-ireplace|-is|-isnot|-isplit|-join|-le|-like|-lt|-match|-ne|-not|-notcontains|-notin|-notlike|-notmatch|-or|-regex|-replace|-shl|-shr|-split|-wildcard|-xor",")\\b")},{className:"literal",begin:/(-)[\w\d]+/,relevance:0}]},f={className:"function",begin:/\[.*\]\s*[\w]+[ ]??\(/,end:/$/,returnBegin:!0,relevance:0,contains:[{className:"keyword",begin:"(".concat(t.keyword.toString().replace(/\s/g,"|"),")\\b"),endsParent:!0,relevance:0},e.inherit(e.TITLE_MODE,{endsParent:!0})]},h=[f,i,n,e.NUMBER_MODE,o,a,s,r,{className:"literal",begin:/\$(null|true|false)\b/},{className:"selector-tag",begin:/@\B/,relevance:0}],d={begin:/\[/,end:/\]/,excludeBegin:!0,excludeEnd:!0,relevance:0,contains:[].concat("self",h,{begin:"("+["string","char","byte","int","long","bool","decimal","single","double","DateTime","xml","array","hashtable","void"].join("|")+")",className:"built_in",relevance:0},{className:"type",begin:/[\.\w\d]+/,relevance:0})};return f.contains.unshift(d),{name:"PowerShell",aliases:["ps","ps1"],case_insensitive:!0,keywords:t,contains:h.concat(u,c,l,p,d)}}},function(e,t,n){var r=n(489);e.exports=function(e){return r(e,5)}},function(e,t){var n=e.exports=function(e){return new r(e)};function r(e){this.value=e}function o(e,t,n){var r=[],o=[],s=!0;return function e(p){var f=n?a(p):p,h={},d=!0,m={node:f,node_:p,path:[].concat(r),parent:o[o.length-1],parents:o,key:r.slice(-1)[0],isRoot:0===r.length,level:r.length,circular:null,update:function(e,t){m.isRoot||(m.parent.node[m.key]=e),m.node=e,t&&(d=!1)},delete:function(e){delete m.parent.node[m.key],e&&(d=!1)},remove:function(e){u(m.parent.node)?m.parent.node.splice(m.key,1):delete m.parent.node[m.key],e&&(d=!1)},keys:null,before:function(e){h.before=e},after:function(e){h.after=e},pre:function(e){h.pre=e},post:function(e){h.post=e},stop:function(){s=!1},block:function(){d=!1}};if(!s)return m;function v(){if("object"==typeof m.node&&null!==m.node){m.keys&&m.node_===m.node||(m.keys=i(m.node)),m.isLeaf=0==m.keys.length;for(var e=0;el?c(e,n,o):i+r>f?u(i-l+r,n,o):o&&o()},p=function(e,n,r,o){u(Math.max(0,t.getTopOf(e)-t.getHeight()/2+(r||e.getBoundingClientRect().height/2)),n,o)};return{setup:function(e,t){return(0===e||e)&&(n=e),(0===t||t)&&(r=t),{defaultDuration:n,edgeOffset:r}},to:c,toY:u,intoView:l,center:p,stop:i,moving:function(){return!!o},getY:t.getY,getTopOf:t.getTopOf}},n=document.documentElement,r=function(){return window.scrollY||n.scrollTop},o=t({body:document.scrollingElement||document.body,toY:function(e){window.scrollTo(0,e)},getY:r,getHeight:function(){return window.innerHeight||n.clientHeight},getTopOf:function(e){return e.getBoundingClientRect().top+r()-n.offsetTop}});if(o.createScroller=function(e,r,o){return t({body:e,toY:function(t){e.scrollTop=t},getY:function(){return e.scrollTop},getHeight:function(){return Math.min(e.clientHeight,window.innerHeight||n.clientHeight)},getTopOf:function(e){return e.offsetTop}},r,o)},"addEventListener"in window&&!window.noZensmooth&&!e(document.body)){var a="history"in window&&"pushState"in history,i=a&&"scrollRestoration"in history;i&&(history.scrollRestoration="auto"),window.addEventListener("load",(function(){i&&(setTimeout((function(){history.scrollRestoration="manual"}),9),window.addEventListener("popstate",(function(e){e.state&&"zenscrollY"in e.state&&o.toY(e.state.zenscrollY)}),!1)),window.location.hash&&setTimeout((function(){var e=o.setup().edgeOffset;if(e){var t=document.getElementById(window.location.href.split("#")[1]);if(t){var n=Math.max(0,o.getTopOf(t)-e),r=o.getY()-n;0<=r&&r<9&&window.scrollTo(0,n)}}}),9)}),!1);var s=new RegExp("(^|\\s)noZensmooth(\\s|$)");window.addEventListener("click",(function(e){for(var t=e.target;t&&"A"!==t.tagName;)t=t.parentNode;if(!(!t||1!==e.which||e.shiftKey||e.metaKey||e.ctrlKey||e.altKey)){if(i){var n=history.state&&"object"==typeof history.state?history.state:{};n.zenscrollY=o.getY();try{history.replaceState(n,"")}catch(e){}}var r=t.getAttribute("href")||"";if(0===r.indexOf("#")&&!s.test(t.className)){var u=0,c=document.getElementById(r.substring(1));if("#"!==r){if(!c)return;u=o.getTopOf(c)}e.preventDefault();var l=function(){window.location=r},p=o.setup().edgeOffset;p&&(u=Math.max(0,u-p),a&&(l=function(){history.pushState({},"",r)})),o.toY(u,null,l)}}}),!1)}return o}(),void 0===(a="function"==typeof r?r.apply(t,o):r)||(e.exports=a)},function(e,t,n){e.exports=n(1087)},function(e,t){e.exports=function(e,t,n,r){var o=new Blob(void 0!==r?[r,e]:[e],{type:n||"application/octet-stream"});if(void 0!==window.navigator.msSaveBlob)window.navigator.msSaveBlob(o,t);else{var a=window.URL&&window.URL.createObjectURL?window.URL.createObjectURL(o):window.webkitURL.createObjectURL(o),i=document.createElement("a");i.style.display="none",i.href=a,i.setAttribute("download",t),void 0===i.download&&i.setAttribute("target","_blank"),document.body.appendChild(i),i.click(),setTimeout((function(){document.body.removeChild(i),window.URL.revokeObjectURL(a)}),200)}}},function(e,t,n){e.exports=n(1096)},function(e,t,n){e.exports=n(1099)},function(e,t,n){"use strict";var r=n(1104),o=function(e){return/<\/+[^>]+>/.test(e)},a=function(e){return/<[^>]+\/>/.test(e)};function i(e){return e.split(/(<\/?[^>]+>)/g).filter((function(e){return""!==e.trim()})).map((function(e){return{value:e,type:s(e)}}))}function s(e){return o(e)?"ClosingTag":function(e){return function(e){return/<[^>!]+>/.test(e)}(e)&&!o(e)&&!a(e)}(e)?"OpeningTag":a(e)?"SelfClosingTag":"Text"}e.exports=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=t.indentor,o=t.textNodesOnSameLine,a=0,s=[];n=n||" ";var u=i(e).map((function(e,t,i){var u=e.value,c=e.type;"ClosingTag"===c&&a--;var l=r(n,a),p=l+u;if("OpeningTag"===c&&a++,o){var f=i[t-1],h=i[t-2];"ClosingTag"===c&&"Text"===f.type&&"OpeningTag"===h.type&&(p=""+l+h.value+f.value+u,s.push(t-2,t-1))}return p}));return s.forEach((function(e){return u[e]=null})),u.filter((function(e){return!!e})).join("\n")}},function(e,t,n){e.exports=n(1108)},function(e,t,n){var r=n(536);n(556),n(557),n(558),n(559),n(560),n(561),n(562),e.exports=r},function(e,t,n){n(359),n(182),n(363),n(540),n(541),n(542),n(543),n(368),n(544),n(545),n(546),n(547),n(548),n(549),n(550),n(551),n(552),n(553),n(554),n(555);var r=n(33);e.exports=r.Symbol},function(e,t,n){var r=n(40),o=n(67);e.exports=function(e,t){try{o(r,e,t)}catch(n){r[e]=t}return t}},function(e,t,n){var r=n(66),o=n(232).f,a={}.toString,i="object"==typeof window&&window&&Object.getOwnPropertyNames?Object.getOwnPropertyNames(window):[];e.exports.f=function(e){return i&&"[object Window]"==a.call(e)?function(e){try{return o(e)}catch(e){return i.slice()}}(e):o(r(e))}},function(e,t,n){"use strict";var r=n(235),o=n(98);e.exports=r?{}.toString:function(){return"[object "+o(this)+"]"}},function(e,t,n){n(44)("asyncIterator")},function(e,t){},function(e,t,n){n(44)("hasInstance")},function(e,t,n){n(44)("isConcatSpreadable")},function(e,t,n){n(44)("match")},function(e,t,n){n(44)("matchAll")},function(e,t,n){n(44)("replace")},function(e,t,n){n(44)("search")},function(e,t,n){n(44)("species")},function(e,t,n){n(44)("split")},function(e,t,n){n(44)("toPrimitive")},function(e,t,n){n(44)("toStringTag")},function(e,t,n){n(44)("unscopables")},function(e,t,n){var r=n(40);n(97)(r.JSON,"JSON",!0)},function(e,t){},function(e,t){},function(e,t,n){n(44)("asyncDispose")},function(e,t,n){n(44)("dispose")},function(e,t,n){n(44)("matcher")},function(e,t,n){n(44)("metadata")},function(e,t,n){n(44)("observable")},function(e,t,n){n(44)("patternMatch")},function(e,t,n){n(44)("replaceAll")},function(e,t,n){e.exports=n(564)},function(e,t,n){var r=n(565);e.exports=r},function(e,t,n){n(368),n(130),n(86);var r=n(234);e.exports=r.f("iterator")},function(e,t,n){var r=n(47);e.exports=function(e){if(!r(e)&&null!==e)throw TypeError("Can't set "+String(e)+" as a prototype");return e}},function(e,t){e.exports={CSSRuleList:0,CSSStyleDeclaration:0,CSSValueList:0,ClientRectList:0,DOMRectList:0,DOMStringList:0,DOMTokenList:1,DataTransferItemList:0,FileList:0,HTMLAllCollection:0,HTMLCollection:0,HTMLFormElement:0,HTMLSelectElement:0,MediaList:0,MimeTypeArray:0,NamedNodeMap:0,NodeList:1,PaintRequestList:0,Plugin:0,PluginArray:0,SVGLengthList:0,SVGNumberList:0,SVGPathSegList:0,SVGPointList:0,SVGStringList:0,SVGTransformList:0,SourceBufferList:0,StyleSheetList:0,TextTrackCueList:0,TextTrackList:0,TouchList:0}},function(e,t,n){var r=n(569);e.exports=r},function(e,t,n){var r=n(570),o=Array.prototype;e.exports=function(e){var t=e.concat;return e===o||e instanceof Array&&t===o.concat?r:t}},function(e,t,n){n(359);var r=n(42);e.exports=r("Array").concat},function(e,t,n){var r=n(373);e.exports=r},function(e,t,n){n(573);var r=n(42);e.exports=r("Array").filter},function(e,t,n){"use strict";var r=n(22),o=n(85).filter;r({target:"Array",proto:!0,forced:!n(155)("filter")},{filter:function(e){return o(this,e,arguments.length>1?arguments[1]:void 0)}})},function(e,t,n){var r=n(374);e.exports=r},function(e,t,n){var r=n(22),o=n(62),a=n(156);r({target:"Object",stat:!0,forced:n(37)((function(){a(1)}))},{keys:function(e){return a(o(e))}})},function(e,t,n){var r=n(577);e.exports=r},function(e,t,n){n(578);var r=n(33);r.JSON||(r.JSON={stringify:JSON.stringify}),e.exports=function(e,t,n){return r.JSON.stringify.apply(null,arguments)}},function(e,t,n){var r=n(22),o=n(70),a=n(37),i=o("JSON","stringify"),s=/[\uD800-\uDFFF]/g,u=/^[\uD800-\uDBFF]$/,c=/^[\uDC00-\uDFFF]$/,l=function(e,t,n){var r=n.charAt(t-1),o=n.charAt(t+1);return u.test(e)&&!c.test(o)||c.test(e)&&!u.test(r)?"\\u"+e.charCodeAt(0).toString(16):e},p=a((function(){return'"\\udf06\\ud834"'!==i("\udf06\ud834")||'"\\udead"'!==i("\udead")}));i&&r({target:"JSON",stat:!0,forced:p},{stringify:function(e,t,n){var r=i.apply(null,arguments);return"string"==typeof r?r.replace(s,l):r}})},function(e,t,n){"use strict";t.byteLength=function(e){var t=c(e),n=t[0],r=t[1];return 3*(n+r)/4-r},t.toByteArray=function(e){var t,n,r=c(e),i=r[0],s=r[1],u=new a(function(e,t,n){return 3*(t+n)/4-n}(0,i,s)),l=0,p=s>0?i-4:i;for(n=0;n>16&255,u[l++]=t>>8&255,u[l++]=255&t;2===s&&(t=o[e.charCodeAt(n)]<<2|o[e.charCodeAt(n+1)]>>4,u[l++]=255&t);1===s&&(t=o[e.charCodeAt(n)]<<10|o[e.charCodeAt(n+1)]<<4|o[e.charCodeAt(n+2)]>>2,u[l++]=t>>8&255,u[l++]=255&t);return u},t.fromByteArray=function(e){for(var t,n=e.length,o=n%3,a=[],i=16383,s=0,u=n-o;su?u:s+i));1===o?(t=e[n-1],a.push(r[t>>2]+r[t<<4&63]+"==")):2===o&&(t=(e[n-2]<<8)+e[n-1],a.push(r[t>>10]+r[t>>4&63]+r[t<<2&63]+"="));return a.join("")};for(var r=[],o=[],a="undefined"!=typeof Uint8Array?Uint8Array:Array,i="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",s=0,u=i.length;s0)throw new Error("Invalid string. Length must be a multiple of 4");var n=e.indexOf("=");return-1===n&&(n=t),[n,n===t?0:4-n%4]}function l(e,t,n){for(var o,a,i=[],s=t;s>18&63]+r[a>>12&63]+r[a>>6&63]+r[63&a]);return i.join("")}o["-".charCodeAt(0)]=62,o["_".charCodeAt(0)]=63},function(e,t){t.read=function(e,t,n,r,o){var a,i,s=8*o-r-1,u=(1<>1,l=-7,p=n?o-1:0,f=n?-1:1,h=e[t+p];for(p+=f,a=h&(1<<-l)-1,h>>=-l,l+=s;l>0;a=256*a+e[t+p],p+=f,l-=8);for(i=a&(1<<-l)-1,a>>=-l,l+=r;l>0;i=256*i+e[t+p],p+=f,l-=8);if(0===a)a=1-c;else{if(a===u)return i?NaN:1/0*(h?-1:1);i+=Math.pow(2,r),a-=c}return(h?-1:1)*i*Math.pow(2,a-r)},t.write=function(e,t,n,r,o,a){var i,s,u,c=8*a-o-1,l=(1<>1,f=23===o?Math.pow(2,-24)-Math.pow(2,-77):0,h=r?0:a-1,d=r?1:-1,m=t<0||0===t&&1/t<0?1:0;for(t=Math.abs(t),isNaN(t)||t===1/0?(s=isNaN(t)?1:0,i=l):(i=Math.floor(Math.log(t)/Math.LN2),t*(u=Math.pow(2,-i))<1&&(i--,u*=2),(t+=i+p>=1?f/u:f*Math.pow(2,1-p))*u>=2&&(i++,u/=2),i+p>=l?(s=0,i=l):i+p>=1?(s=(t*u-1)*Math.pow(2,o),i+=p):(s=t*Math.pow(2,p-1)*Math.pow(2,o),i=0));o>=8;e[n+h]=255&s,h+=d,s/=256,o-=8);for(i=i<0;e[n+h]=255&i,h+=d,i/=256,c-=8);e[n+h-d]|=128*m}},function(e,t,n){var r=n(376);e.exports=r},function(e,t,n){var r=n(22),o=n(48);r({target:"Object",stat:!0,forced:!o,sham:!o},{defineProperty:n(68).f})},function(e,t,n){var r=n(584);e.exports=r},function(e,t,n){var r=n(585),o=Function.prototype;e.exports=function(e){var t=e.bind;return e===o||e instanceof Function&&t===o.bind?r:t}},function(e,t,n){n(586);var r=n(42);e.exports=r("Function").bind},function(e,t,n){n(22)({target:"Function",proto:!0},{bind:n(377)})},function(e,t,n){var r=n(378);e.exports=r},function(e,t,n){var r=n(22),o=n(379);r({target:"Object",stat:!0,forced:Object.assign!==o},{assign:o})},function(e,t,n){var r=n(380);e.exports=r},function(e,t,n){n(591);var r=n(42);e.exports=r("Array").slice},function(e,t,n){"use strict";var r=n(22),o=n(47),a=n(153),i=n(230),s=n(69),u=n(66),c=n(154),l=n(41),p=n(155)("slice"),f=l("species"),h=[].slice,d=Math.max;r({target:"Array",proto:!0,forced:!p},{slice:function(e,t){var n,r,l,p=u(this),m=s(p.length),v=i(e,m),g=i(void 0===t?m:t,m);if(a(p)&&("function"!=typeof(n=p.constructor)||n!==Array&&!a(n.prototype)?o(n)&&null===(n=n[f])&&(n=void 0):n=void 0,n===Array||void 0===n))return h.call(p,v,g);for(r=new(void 0===n?Array:n)(d(g-v,0)),l=0;v79&&i<83},{reduce:function(e){return o(this,e,arguments.length,arguments.length>1?arguments[1]:void 0)}})},function(e,t,n){var r=n(76),o=n(62),a=n(179),i=n(69),s=function(e){return function(t,n,s,u){r(n);var c=o(t),l=a(c),p=i(c.length),f=e?p-1:0,h=e?-1:1;if(s<2)for(;;){if(f in l){u=l[f],f+=h;break}if(f+=h,e?f<0:p<=f)throw TypeError("Reduce of empty array with no initial value")}for(;e?f>=0:p>f;f+=h)f in l&&(u=n(u,l[f],f,c));return u}};e.exports={left:s(!1),right:s(!0)}},function(e,t,n){var r=n(600);e.exports=r},function(e,t,n){var r=n(601),o=Array.prototype;e.exports=function(e){var t=e.map;return e===o||e instanceof Array&&t===o.map?r:t}},function(e,t,n){n(602);var r=n(42);e.exports=r("Array").map},function(e,t,n){"use strict";var r=n(22),o=n(85).map;r({target:"Array",proto:!0,forced:!n(155)("map")},{map:function(e){return o(this,e,arguments.length>1?arguments[1]:void 0)}})},function(e,t,n){"use strict";e.exports=function(){}},function(e,t,n){"use strict";var r=n(605),o=n(134),a=n(78),i=n(606),s=r.twoArgumentPooler,u=r.fourArgumentPooler,c=/\/+/g;function l(e){return(""+e).replace(c,"$&/")}function p(e,t){this.func=e,this.context=t,this.count=0}function f(e,t,n){var r=e.func,o=e.context;r.call(o,t,e.count++)}function h(e,t,n,r){this.result=e,this.keyPrefix=t,this.func=n,this.context=r,this.count=0}function d(e,t,n){var r=e.result,i=e.keyPrefix,s=e.func,u=e.context,c=s.call(u,t,e.count++);Array.isArray(c)?m(c,r,n,a.thatReturnsArgument):null!=c&&(o.isValidElement(c)&&(c=o.cloneAndReplaceKey(c,i+(!c.key||t&&t.key===c.key?"":l(c.key)+"/")+n)),r.push(c))}function m(e,t,n,r,o){var a="";null!=n&&(a=l(n)+"/");var s=h.getPooled(t,a,r,o);i(e,d,s),h.release(s)}function v(e,t,n){return null}p.prototype.destructor=function(){this.func=null,this.context=null,this.count=0},r.addPoolingTo(p,s),h.prototype.destructor=function(){this.result=null,this.keyPrefix=null,this.func=null,this.context=null,this.count=0},r.addPoolingTo(h,u);var g={forEach:function(e,t,n){if(null==e)return e;var r=p.getPooled(t,n);i(e,f,r),p.release(r)},map:function(e,t,n){if(null==e)return e;var r=[];return m(e,r,null,t,n),r},mapIntoWithKeyPrefixInternal:m,count:function(e,t){return i(e,v,null)},toArray:function(e){var t=[];return m(e,t,null,a.thatReturnsArgument),t}};e.exports=g},function(e,t,n){"use strict";var r=n(159),o=(n(25),function(e){var t=this;if(t.instancePool.length){var n=t.instancePool.pop();return t.call(n,e),n}return new t(e)}),a=function(e){var t=this;e instanceof t||r("25"),e.destructor(),t.instancePool.length1&&void 0!==arguments[1]?arguments[1]:a.default.Map,n=Object.keys(e);return function(){var r=arguments.length>0&&void 0!==arguments[0]?arguments[0]:t(),o=arguments[1];return r.withMutations((function(t){n.forEach((function(n){var r=(0,e[n])(t.get(n),o);(0,i.validateNextState)(r,n,o),t.set(n,r)}))}))}},e.exports=t.default},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.validateNextState=t.getUnexpectedInvocationParameterMessage=t.getStateName=void 0;var r=i(n(389)),o=i(n(621)),a=i(n(622));function i(e){return e&&e.__esModule?e:{default:e}}t.getStateName=r.default,t.getUnexpectedInvocationParameterMessage=o.default,t.validateNextState=a.default},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=a(n(1)),o=a(n(389));function a(e){return e&&e.__esModule?e:{default:e}}t.default=function(e,t,n){var a=Object.keys(t);if(!a.length)return"Store does not have a valid reducer. Make sure the argument passed to combineReducers is an object whose values are reducers.";var i=(0,o.default)(n);if(!r.default.Iterable.isIterable(e))return"The "+i+' is of unexpected type. Expected argument to be an instance of Immutable.Iterable with the following properties: "'+a.join('", "')+'".';var s=e.keySeq().toArray().filter((function(e){return!t.hasOwnProperty(e)}));return s.length>0?"Unexpected "+(1===s.length?"property":"properties")+' "'+s.join('", "')+'" found in '+i+'. Expected to find one of the known reducer property names instead: "'+a.join('", "')+'". Unexpected properties will be ignored.':null},e.exports=t.default},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(e,t,n){if(void 0===e)throw new Error('Reducer "'+t+'" returned undefined when handling "'+n.type+'" action. To ignore an action, you must explicitly return the previous state.')},e.exports=t.default},function(e,t,n){var r=n(240),o=n(390);e.exports=function(e){if(r(e))return o(e)},e.exports.default=e.exports,e.exports.__esModule=!0},function(e,t,n){var r=n(381);e.exports=r},function(e,t,n){n(86),n(130);var r=n(160);e.exports=r},function(e,t,n){var r=n(393);e.exports=r},function(e,t,n){var r=n(22),o=n(394);r({target:"Array",stat:!0,forced:!n(397)((function(e){Array.from(e)}))},{from:o})},function(e,t,n){var r=n(52),o=n(395);e.exports=function(e,t,n,a){try{return a?t(r(n)[0],n[1]):t(n)}catch(t){throw o(e),t}}},function(e,t,n){e.exports=n(630)},function(e,t,n){var r=n(380);e.exports=r},function(e,t){e.exports=function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")},e.exports.default=e.exports,e.exports.__esModule=!0},function(e,t,n){var r=n(177),o=n(241);e.exports=function(e,t){var n=null==e?null:void 0!==r&&o(e)||e["@@iterator"];if(null!=n){var a,i,s=[],u=!0,c=!1;try{for(n=n.call(e);!(u=(a=n.next()).done)&&(s.push(a.value),!t||s.length!==t);u=!0);}catch(e){c=!0,i=e}finally{try{u||null==n.return||n.return()}finally{if(c)throw i}}return s}},e.exports.default=e.exports,e.exports.__esModule=!0},function(e,t,n){n(86);var r=n(634),o=n(98),a=Array.prototype,i={DOMTokenList:!0,NodeList:!0};e.exports=function(e){var t=e.entries;return e===a||e instanceof Array&&t===a.entries||i.hasOwnProperty(o(e))?r:t}},function(e,t,n){var r=n(635);e.exports=r},function(e,t,n){n(158);var r=n(42);e.exports=r("Array").entries},function(e,t,n){var r=n(637);e.exports=r},function(e,t,n){n(638);var r=n(42);e.exports=r("Array").forEach},function(e,t,n){"use strict";var r=n(22),o=n(639);r({target:"Array",proto:!0,forced:[].forEach!=o},{forEach:o})},function(e,t,n){"use strict";var r=n(85).forEach,o=n(113)("forEach");e.exports=o?[].forEach:function(e){return r(this,e,arguments.length>1?arguments[1]:void 0)}},function(e,t,n){var r=n(641);e.exports=r},function(e,t,n){var r=n(642),o=Array.prototype;e.exports=function(e){var t=e.sort;return e===o||e instanceof Array&&t===o.sort?r:t}},function(e,t,n){n(643);var r=n(42);e.exports=r("Array").sort},function(e,t,n){"use strict";var r=n(22),o=n(76),a=n(62),i=n(69),s=n(37),u=n(644),c=n(113),l=n(645),p=n(646),f=n(129),h=n(647),d=[],m=d.sort,v=s((function(){d.sort(void 0)})),g=s((function(){d.sort(null)})),y=c("sort"),b=!s((function(){if(f)return f<70;if(!(l&&l>3)){if(p)return!0;if(h)return h<603;var e,t,n,r,o="";for(e=65;e<76;e++){switch(t=String.fromCharCode(e),e){case 66:case 69:case 70:case 72:n=3;break;case 68:case 71:n=4;break;default:n=2}for(r=0;r<47;r++)d.push({k:t+r,v:n})}for(d.sort((function(e,t){return t.v-e.v})),r=0;rString(n)?1:-1}}(e))).length,r=0;r0;)e[r]=e[--r];r!==a++&&(e[r]=n)}return e},a=function(e,t,n){for(var r=e.length,o=t.length,a=0,i=0,s=[];a1?arguments[1]:void 0)}})},function(e,t,n){var r=n(653);e.exports=r},function(e,t,n){var r=n(654),o=n(656),a=Array.prototype,i=String.prototype;e.exports=function(e){var t=e.includes;return e===a||e instanceof Array&&t===a.includes?r:"string"==typeof e||e===i||e instanceof String&&t===i.includes?o:t}},function(e,t,n){n(655);var r=n(42);e.exports=r("Array").includes},function(e,t,n){"use strict";var r=n(22),o=n(229).includes,a=n(237);r({target:"Array",proto:!0},{includes:function(e){return o(this,e,arguments.length>1?arguments[1]:void 0)}}),a("includes")},function(e,t,n){n(657);var r=n(42);e.exports=r("String").includes},function(e,t,n){"use strict";var r=n(22),o=n(401),a=n(108);r({target:"String",proto:!0,forced:!n(402)("includes")},{includes:function(e){return!!~String(a(this)).indexOf(o(e),arguments.length>1?arguments[1]:void 0)}})},function(e,t,n){var r=n(47),o=n(152),a=n(41)("match");e.exports=function(e){var t;return r(e)&&(void 0!==(t=e[a])?!!t:"RegExp"==o(e))}},function(e,t,n){var r=n(403);e.exports=r},function(e,t,n){n(661);var r=n(42);e.exports=r("Array").indexOf},function(e,t,n){"use strict";var r=n(22),o=n(229).indexOf,a=n(113),i=[].indexOf,s=!!i&&1/[1].indexOf(1,-0)<0,u=a("indexOf");r({target:"Array",proto:!0,forced:s||!u},{indexOf:function(e){return s?i.apply(this,arguments)||0:o(this,e,arguments.length>1?arguments[1]:void 0)}})},function(e,t,n){var r=n(663);e.exports=r},function(e,t,n){var r=n(664),o=Array.prototype;e.exports=function(e){var t=e.find;return e===o||e instanceof Array&&t===o.find?r:t}},function(e,t,n){n(665);var r=n(42);e.exports=r("Array").find},function(e,t,n){"use strict";var r=n(22),o=n(85).find,a=n(237),i="find",s=!0;i in[]&&Array(1).find((function(){s=!1})),r({target:"Array",proto:!0,forced:s},{find:function(e){return o(this,e,arguments.length>1?arguments[1]:void 0)}}),a(i)},function(e,t,n){var r=n(667);e.exports=r},function(e,t,n){var r=n(668),o=String.prototype;e.exports=function(e){var t=e.startsWith;return"string"==typeof e||e===o||e instanceof String&&t===o.startsWith?r:t}},function(e,t,n){n(669);var r=n(42);e.exports=r("String").startsWith},function(e,t,n){"use strict";var r,o=n(22),a=n(127).f,i=n(69),s=n(401),u=n(108),c=n(402),l=n(96),p="".startsWith,f=Math.min,h=c("startsWith");o({target:"String",proto:!0,forced:!!(l||h||(r=a(String.prototype,"startsWith"),!r||r.writable))&&!h},{startsWith:function(e){var t=String(u(this));s(e);var n=i(f(arguments.length>1?arguments[1]:void 0,t.length)),r=String(e);return p?p.call(t,r,n):t.slice(n,n+r.length)===r}})},function(e,t,n){var r=n(671);e.exports=r},function(e,t,n){var r=n(672),o=String.prototype;e.exports=function(e){var t=e.trim;return"string"==typeof e||e===o||e instanceof String&&t===o.trim?r:t}},function(e,t,n){n(673);var r=n(42);e.exports=r("String").trim},function(e,t,n){"use strict";var r=n(22),o=n(674).trim;r({target:"String",proto:!0,forced:n(675)("trim")},{trim:function(){return o(this)}})},function(e,t,n){var r=n(108),o="["+n(404)+"]",a=RegExp("^"+o+o+"*"),i=RegExp(o+o+"*$"),s=function(e){return function(t){var n=String(r(t));return 1&e&&(n=n.replace(a,"")),2&e&&(n=n.replace(i,"")),n}};e.exports={start:s(1),end:s(2),trim:s(3)}},function(e,t,n){var r=n(37),o=n(404);e.exports=function(e){return r((function(){return!!o[e]()||"​…᠎"!="​…᠎"[e]()||o[e].name!==e}))}},function(e,t,n){var r=n(100),o=n(284);e.exports=function(e){return o(r(e).toLowerCase())}},function(e,t,n){var r=n(135),o=n(406),a=n(56),i=n(188),s=r?r.prototype:void 0,u=s?s.toString:void 0;e.exports=function e(t){if("string"==typeof t)return t;if(a(t))return o(t,e)+"";if(i(t))return u?u.call(t):"";var n=t+"";return"0"==n&&1/t==-Infinity?"-0":n}},function(e,t,n){var r=n(135),o=Object.prototype,a=o.hasOwnProperty,i=o.toString,s=r?r.toStringTag:void 0;e.exports=function(e){var t=a.call(e,s),n=e[s];try{e[s]=void 0;var r=!0}catch(e){}var o=i.call(e);return r&&(t?e[s]=n:delete e[s]),o}},function(e,t){var n=Object.prototype.toString;e.exports=function(e){return n.call(e)}},function(e,t,n){var r=n(681),o=n(408),a=n(682),i=n(100);e.exports=function(e){return function(t){t=i(t);var n=o(t)?a(t):void 0,s=n?n[0]:t.charAt(0),u=n?r(n,1).join(""):t.slice(1);return s[e]()+u}}},function(e,t,n){var r=n(407);e.exports=function(e,t,n){var o=e.length;return n=void 0===n?o:n,!t&&n>=o?e:r(e,t,n)}},function(e,t,n){var r=n(683),o=n(408),a=n(684);e.exports=function(e){return o(e)?a(e):r(e)}},function(e,t){e.exports=function(e){return e.split("")}},function(e,t){var n="[\\ud800-\\udfff]",r="[\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff]",o="\\ud83c[\\udffb-\\udfff]",a="[^\\ud800-\\udfff]",i="(?:\\ud83c[\\udde6-\\uddff]){2}",s="[\\ud800-\\udbff][\\udc00-\\udfff]",u="(?:"+r+"|"+o+")"+"?",c="[\\ufe0e\\ufe0f]?",l=c+u+("(?:\\u200d(?:"+[a,i,s].join("|")+")"+c+u+")*"),p="(?:"+[a+r+"?",r,i,s,n].join("|")+")",f=RegExp(o+"(?="+o+")|"+p+l,"g");e.exports=function(e){return e.match(f)||[]}},function(e,t,n){var r=n(409),o=n(686),a=n(689),i=RegExp("['’]","g");e.exports=function(e){return function(t){return r(a(o(t).replace(i,"")),e,"")}}},function(e,t,n){var r=n(687),o=n(100),a=/[\xc0-\xd6\xd8-\xf6\xf8-\xff\u0100-\u017f]/g,i=RegExp("[\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff]","g");e.exports=function(e){return(e=o(e))&&e.replace(a,r).replace(i,"")}},function(e,t,n){var r=n(688)({"À":"A","Á":"A","Â":"A","Ã":"A","Ä":"A","Å":"A","à":"a","á":"a","â":"a","ã":"a","ä":"a","å":"a","Ç":"C","ç":"c","Ð":"D","ð":"d","È":"E","É":"E","Ê":"E","Ë":"E","è":"e","é":"e","ê":"e","ë":"e","Ì":"I","Í":"I","Î":"I","Ï":"I","ì":"i","í":"i","î":"i","ï":"i","Ñ":"N","ñ":"n","Ò":"O","Ó":"O","Ô":"O","Õ":"O","Ö":"O","Ø":"O","ò":"o","ó":"o","ô":"o","õ":"o","ö":"o","ø":"o","Ù":"U","Ú":"U","Û":"U","Ü":"U","ù":"u","ú":"u","û":"u","ü":"u","Ý":"Y","ý":"y","ÿ":"y","Æ":"Ae","æ":"ae","Þ":"Th","þ":"th","ß":"ss","Ā":"A","Ă":"A","Ą":"A","ā":"a","ă":"a","ą":"a","Ć":"C","Ĉ":"C","Ċ":"C","Č":"C","ć":"c","ĉ":"c","ċ":"c","č":"c","Ď":"D","Đ":"D","ď":"d","đ":"d","Ē":"E","Ĕ":"E","Ė":"E","Ę":"E","Ě":"E","ē":"e","ĕ":"e","ė":"e","ę":"e","ě":"e","Ĝ":"G","Ğ":"G","Ġ":"G","Ģ":"G","ĝ":"g","ğ":"g","ġ":"g","ģ":"g","Ĥ":"H","Ħ":"H","ĥ":"h","ħ":"h","Ĩ":"I","Ī":"I","Ĭ":"I","Į":"I","İ":"I","ĩ":"i","ī":"i","ĭ":"i","į":"i","ı":"i","Ĵ":"J","ĵ":"j","Ķ":"K","ķ":"k","ĸ":"k","Ĺ":"L","Ļ":"L","Ľ":"L","Ŀ":"L","Ł":"L","ĺ":"l","ļ":"l","ľ":"l","ŀ":"l","ł":"l","Ń":"N","Ņ":"N","Ň":"N","Ŋ":"N","ń":"n","ņ":"n","ň":"n","ŋ":"n","Ō":"O","Ŏ":"O","Ő":"O","ō":"o","ŏ":"o","ő":"o","Ŕ":"R","Ŗ":"R","Ř":"R","ŕ":"r","ŗ":"r","ř":"r","Ś":"S","Ŝ":"S","Ş":"S","Š":"S","ś":"s","ŝ":"s","ş":"s","š":"s","Ţ":"T","Ť":"T","Ŧ":"T","ţ":"t","ť":"t","ŧ":"t","Ũ":"U","Ū":"U","Ŭ":"U","Ů":"U","Ű":"U","Ų":"U","ũ":"u","ū":"u","ŭ":"u","ů":"u","ű":"u","ų":"u","Ŵ":"W","ŵ":"w","Ŷ":"Y","ŷ":"y","Ÿ":"Y","Ź":"Z","Ż":"Z","Ž":"Z","ź":"z","ż":"z","ž":"z","IJ":"IJ","ij":"ij","Œ":"Oe","œ":"oe","ʼn":"'n","ſ":"s"});e.exports=r},function(e,t){e.exports=function(e){return function(t){return null==e?void 0:e[t]}}},function(e,t,n){var r=n(690),o=n(691),a=n(100),i=n(692);e.exports=function(e,t,n){return e=a(e),void 0===(t=n?void 0:t)?o(e)?i(e):r(e):e.match(t)||[]}},function(e,t){var n=/[^\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]+/g;e.exports=function(e){return e.match(n)||[]}},function(e,t){var n=/[a-z][A-Z]|[A-Z]{2}[a-z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/;e.exports=function(e){return n.test(e)}},function(e,t){var n="\\u2700-\\u27bf",r="a-z\\xdf-\\xf6\\xf8-\\xff",o="A-Z\\xc0-\\xd6\\xd8-\\xde",a="\\xac\\xb1\\xd7\\xf7\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf\\u2000-\\u206f \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000",i="["+a+"]",s="\\d+",u="[\\u2700-\\u27bf]",c="["+r+"]",l="[^\\ud800-\\udfff"+a+s+n+r+o+"]",p="(?:\\ud83c[\\udde6-\\uddff]){2}",f="[\\ud800-\\udbff][\\udc00-\\udfff]",h="["+o+"]",d="(?:"+c+"|"+l+")",m="(?:"+h+"|"+l+")",v="(?:['’](?:d|ll|m|re|s|t|ve))?",g="(?:['’](?:D|LL|M|RE|S|T|VE))?",y="(?:[\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff]|\\ud83c[\\udffb-\\udfff])?",b="[\\ufe0e\\ufe0f]?",_=b+y+("(?:\\u200d(?:"+["[^\\ud800-\\udfff]",p,f].join("|")+")"+b+y+")*"),w="(?:"+[u,p,f].join("|")+")"+_,x=RegExp([h+"?"+c+"+"+v+"(?="+[i,h,"$"].join("|")+")",m+"+"+g+"(?="+[i,h+d,"$"].join("|")+")",h+"?"+d+"+"+v,h+"+"+g,"\\d*(?:1ST|2ND|3RD|(?![123])\\dTH)(?=\\b|[a-z_])","\\d*(?:1st|2nd|3rd|(?![123])\\dth)(?=\\b|[A-Z_])",s,w].join("|"),"g");e.exports=function(e){return e.match(x)||[]}},function(e,t,n){var r=n(694),o=n(190),a=n(243);e.exports=function(){this.size=0,this.__data__={hash:new r,map:new(a||o),string:new r}}},function(e,t,n){var r=n(695),o=n(700),a=n(701),i=n(702),s=n(703);function u(e){var t=-1,n=null==e?0:e.length;for(this.clear();++t-1}},function(e,t,n){var r=n(191);e.exports=function(e,t){var n=this.__data__,o=r(n,e);return o<0?(++this.size,n.push([e,t])):n[o][1]=t,this}},function(e,t,n){var r=n(192);e.exports=function(e){var t=r(this,e).delete(e);return this.size-=t?1:0,t}},function(e,t){e.exports=function(e){var t=typeof e;return"string"==t||"number"==t||"symbol"==t||"boolean"==t?"__proto__"!==e:null===e}},function(e,t,n){var r=n(192);e.exports=function(e){return r(this,e).get(e)}},function(e,t,n){var r=n(192);e.exports=function(e){return r(this,e).has(e)}},function(e,t,n){var r=n(192);e.exports=function(e,t){var n=r(this,e),o=n.size;return n.set(e,t),this.size+=n.size==o?0:1,this}},function(e,t,n){var r=n(193),o=n(137),a=n(136);e.exports=function(e){return function(t,n,i){var s=Object(t);if(!o(t)){var u=r(n,3);t=a(t),n=function(e){return u(s[e],e,s)}}var c=e(t,n,i);return c>-1?s[u?t[c]:c]:void 0}}},function(e,t,n){var r=n(716),o=n(741),a=n(422);e.exports=function(e){var t=o(e);return 1==t.length&&t[0][2]?a(t[0][0],t[0][1]):function(n){return n===e||r(n,e,t)}}},function(e,t,n){var r=n(244),o=n(411);e.exports=function(e,t,n,a){var i=n.length,s=i,u=!a;if(null==e)return!s;for(e=Object(e);i--;){var c=n[i];if(u&&c[2]?c[1]!==e[c[0]]:!(c[0]in e))return!1}for(;++i":">"};e.exports=function(e){return e&&e.replace?e.replace(/([&"<>'])/g,(function(e,t){return n[t]})):e}},function(e,t,n){e.exports=o;var r=n(253).EventEmitter;function o(){r.call(this)}n(63)(o,r),o.Readable=n(254),o.Writable=n(771),o.Duplex=n(772),o.Transform=n(773),o.PassThrough=n(774),o.Stream=o,o.prototype.pipe=function(e,t){var n=this;function o(t){e.writable&&!1===e.write(t)&&n.pause&&n.pause()}function a(){n.readable&&n.resume&&n.resume()}n.on("data",o),e.on("drain",a),e._isStdio||t&&!1===t.end||(n.on("end",s),n.on("close",u));var i=!1;function s(){i||(i=!0,e.end())}function u(){i||(i=!0,"function"==typeof e.destroy&&e.destroy())}function c(e){if(l(),0===r.listenerCount(this,"error"))throw e}function l(){n.removeListener("data",o),e.removeListener("drain",a),n.removeListener("end",s),n.removeListener("close",u),n.removeListener("error",c),e.removeListener("error",c),n.removeListener("end",l),n.removeListener("close",l),e.removeListener("close",l)}return n.on("error",c),e.on("error",c),n.on("end",l),n.on("close",l),e.on("close",l),e.emit("pipe",n),e}},function(e,t){},function(e,t,n){"use strict";var r=n(64).Buffer,o=n(767);e.exports=function(){function e(){!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),this.head=null,this.tail=null,this.length=0}return e.prototype.push=function(e){var t={data:e,next:null};this.length>0?this.tail.next=t:this.head=t,this.tail=t,++this.length},e.prototype.unshift=function(e){var t={data:e,next:this.head};0===this.length&&(this.tail=t),this.head=t,++this.length},e.prototype.shift=function(){if(0!==this.length){var e=this.head.data;return 1===this.length?this.head=this.tail=null:this.head=this.head.next,--this.length,e}},e.prototype.clear=function(){this.head=this.tail=null,this.length=0},e.prototype.join=function(e){if(0===this.length)return"";for(var t=this.head,n=""+t.data;t=t.next;)n+=e+t.data;return n},e.prototype.concat=function(e){if(0===this.length)return r.alloc(0);if(1===this.length)return this.head.data;for(var t,n,o,a=r.allocUnsafe(e>>>0),i=this.head,s=0;i;)t=i.data,n=a,o=s,t.copy(n,o),s+=i.data.length,i=i.next;return a},e}(),o&&o.inspect&&o.inspect.custom&&(e.exports.prototype[o.inspect.custom]=function(){var e=o.inspect({length:this.length});return this.constructor.name+" "+e})},function(e,t){},function(e,t,n){(function(e,t){!function(e,n){"use strict";if(!e.setImmediate){var r,o,a,i,s,u=1,c={},l=!1,p=e.document,f=Object.getPrototypeOf&&Object.getPrototypeOf(e);f=f&&f.setTimeout?f:e,"[object process]"==={}.toString.call(e.process)?r=function(e){t.nextTick((function(){d(e)}))}:!function(){if(e.postMessage&&!e.importScripts){var t=!0,n=e.onmessage;return e.onmessage=function(){t=!1},e.postMessage("","*"),e.onmessage=n,t}}()?e.MessageChannel?((a=new MessageChannel).port1.onmessage=function(e){d(e.data)},r=function(e){a.port2.postMessage(e)}):p&&"onreadystatechange"in p.createElement("script")?(o=p.documentElement,r=function(e){var t=p.createElement("script");t.onreadystatechange=function(){d(e),t.onreadystatechange=null,o.removeChild(t),t=null},o.appendChild(t)}):r=function(e){setTimeout(d,0,e)}:(i="setImmediate$"+Math.random()+"$",s=function(t){t.source===e&&"string"==typeof t.data&&0===t.data.indexOf(i)&&d(+t.data.slice(i.length))},e.addEventListener?e.addEventListener("message",s,!1):e.attachEvent("onmessage",s),r=function(t){e.postMessage(i+t,"*")}),f.setImmediate=function(e){"function"!=typeof e&&(e=new Function(""+e));for(var t=new Array(arguments.length-1),n=0;n0?1:-1}},function(e,t,n){"use strict";var r=n(99),o=n(200),a=n(119),i=n(782),s=n(433);e.exports=function e(t){var n,u,c;if(r(t),(n=Object(arguments[1])).async&&n.promise)throw new Error("Options 'async' and 'promise' cannot be used together");return hasOwnProperty.call(t,"__memoized__")&&!n.force?t:(u=s(n.length,t.length,n.async&&a.async),c=i(t,u,n),o(a,(function(e,t){n[t]&&e(n[t],c,n)})),e.__profiler__&&e.__profiler__(c),c.updateEnv(),c.memoized)}},function(e,t,n){"use strict";var r=n(99),o=n(139),a=Function.prototype.bind,i=Function.prototype.call,s=Object.keys,u=Object.prototype.propertyIsEnumerable;e.exports=function(e,t){return function(n,c){var l,p=arguments[2],f=arguments[3];return n=Object(o(n)),r(c),l=s(n),f&&l.sort("function"==typeof f?a.call(f,n):void 0),"function"!=typeof e&&(e=l[e]),i.call(e,l,(function(e,r){return u.call(n,e)?i.call(c,p,n[e],e,n,r):t}))}}},function(e,t,n){"use strict";var r=n(783),o=n(435),a=n(120),i=n(797).methods,s=n(798),u=n(814),c=Function.prototype.apply,l=Function.prototype.call,p=Object.create,f=Object.defineProperties,h=i.on,d=i.emit;e.exports=function(e,t,n){var i,m,v,g,y,b,_,w,x,E,S,C,A,O,k,j=p(null);return m=!1!==t?t:isNaN(e.length)?1:e.length,n.normalizer&&(E=u(n.normalizer),v=E.get,g=E.set,y=E.delete,b=E.clear),null!=n.resolvers&&(k=s(n.resolvers)),O=v?o((function(t){var n,o,a=arguments;if(k&&(a=k(a)),null!==(n=v(a))&&hasOwnProperty.call(j,n))return S&&i.emit("get",n,a,this),j[n];if(o=1===a.length?l.call(e,this,a[0]):c.call(e,this,a),null===n){if(null!==(n=v(a)))throw r("Circular invocation","CIRCULAR_INVOCATION");n=g(a)}else if(hasOwnProperty.call(j,n))throw r("Circular invocation","CIRCULAR_INVOCATION");return j[n]=o,C&&i.emit("set",n,null,o),o}),m):0===t?function(){var t;if(hasOwnProperty.call(j,"data"))return S&&i.emit("get","data",arguments,this),j.data;if(t=arguments.length?c.call(e,this,arguments):l.call(e,this),hasOwnProperty.call(j,"data"))throw r("Circular invocation","CIRCULAR_INVOCATION");return j.data=t,C&&i.emit("set","data",null,t),t}:function(t){var n,o,a=arguments;if(k&&(a=k(arguments)),o=String(a[0]),hasOwnProperty.call(j,o))return S&&i.emit("get",o,a,this),j[o];if(n=1===a.length?l.call(e,this,a[0]):c.call(e,this,a),hasOwnProperty.call(j,o))throw r("Circular invocation","CIRCULAR_INVOCATION");return j[o]=n,C&&i.emit("set",o,null,n),n},i={original:e,memoized:O,profileName:n.profileName,get:function(e){return k&&(e=k(e)),v?v(e):String(e[0])},has:function(e){return hasOwnProperty.call(j,e)},delete:function(e){var t;hasOwnProperty.call(j,e)&&(y&&y(e),t=j[e],delete j[e],A&&i.emit("delete",e,t))},clear:function(){var e=j;b&&b(),j=p(null),i.emit("clear",e)},on:function(e,t){return"get"===e?S=!0:"set"===e?C=!0:"delete"===e&&(A=!0),h.call(this,e,t)},emit:d,updateEnv:function(){e=i.original}},_=v?o((function(e){var t,n=arguments;k&&(n=k(n)),null!==(t=v(n))&&i.delete(t)}),m):0===t?function(){return i.delete("data")}:function(e){return k&&(e=k(arguments)[0]),i.delete(e)},w=o((function(){var e,n=arguments;return 0===t?j.data:(k&&(n=k(n)),e=v?v(n):String(n[0]),j[e])})),x=o((function(){var e,n=arguments;return 0===t?i.has("data"):(k&&(n=k(n)),null!==(e=v?v(n):String(n[0]))&&i.has(e))})),f(O,{__memoized__:a(!0),delete:a(_),clear:a(i.clear),_get:a(w),_has:a(x)}),i}},function(e,t,n){"use strict";var r=n(434),o=n(789),a=n(117),i=Error.captureStackTrace;e.exports=function(t){var n=new Error(t),s=arguments[1],u=arguments[2];return a(u)||o(s)&&(u=s,s=null),a(u)&&r(n,u),a(s)&&(n.code=s),i&&i(n,e.exports),n}},function(e,t,n){"use strict";e.exports=function(){var e,t=Object.assign;return"function"==typeof t&&(t(e={foo:"raz"},{bar:"dwa"},{trzy:"trzy"}),e.foo+e.bar+e.trzy==="razdwatrzy")}},function(e,t,n){"use strict";var r=n(786),o=n(139),a=Math.max;e.exports=function(e,t){var n,i,s,u=a(arguments.length,2);for(e=Object(o(e)),s=function(r){try{e[r]=t[r]}catch(e){n||(n=e)}},i=1;i-1}},function(e,t,n){"use strict";var r,o,a,i,s,u,c,l=n(120),p=n(99),f=Function.prototype.apply,h=Function.prototype.call,d=Object.create,m=Object.defineProperty,v=Object.defineProperties,g=Object.prototype.hasOwnProperty,y={configurable:!0,enumerable:!1,writable:!0};o=function(e,t){var n,o;return p(t),o=this,r.call(this,e,n=function(){a.call(o,e,n),f.call(t,this,arguments)}),n.__eeOnceListener__=t,this},s={on:r=function(e,t){var n;return p(t),g.call(this,"__ee__")?n=this.__ee__:(n=y.value=d(null),m(this,"__ee__",y),y.value=null),n[e]?"object"==typeof n[e]?n[e].push(t):n[e]=[n[e],t]:n[e]=t,this},once:o,off:a=function(e,t){var n,r,o,a;if(p(t),!g.call(this,"__ee__"))return this;if(!(n=this.__ee__)[e])return this;if("object"==typeof(r=n[e]))for(a=0;o=r[a];++a)o!==t&&o.__eeOnceListener__!==t||(2===r.length?n[e]=r[a?0:1]:r.splice(a,1));else r!==t&&r.__eeOnceListener__!==t||delete n[e];return this},emit:i=function(e){var t,n,r,o,a;if(g.call(this,"__ee__")&&(o=this.__ee__[e]))if("object"==typeof o){for(n=arguments.length,a=new Array(n-1),t=1;t=55296&&y<=56319&&(x+=e[++n]),x=E?f.call(E,S,x,m):x,t?(h.value=x,d(v,m,h)):v[m]=x,++m;g=m}if(void 0===g)for(g=i(e.length),t&&(v=new t(g)),n=0;n100&&(t=t.slice(0,99)+"…"),t=t.replace(o,(function(e){return JSON.stringify(e).slice(1,-1)}))}},function(e,t,n){"use strict";var r=n(440);e.exports=function(e){try{return e&&r(e.toString)?e.toString():String(e)}catch(e){return""}}},function(e,t,n){"use strict";var r=n(99),o=n(200),a=n(119),i=Function.prototype.apply;a.dispose=function(e,t,n){var s;if(r(e),n.async&&a.async||n.promise&&a.promise)return t.on("deleteasync",s=function(t,n){i.call(e,null,n)}),void t.on("clearasync",(function(e){o(e,(function(e,t){s(t,e)}))}));t.on("delete",s=function(t,n){e(n)}),t.on("clear",(function(e){o(e,(function(e,t){s(t,e)}))}))}},function(e,t,n){"use strict";var r=n(256),o=n(200),a=n(258),i=n(441),s=n(832),u=n(119),c=Function.prototype,l=Math.max,p=Math.min,f=Object.create;u.maxAge=function(e,t,n){var h,d,m,v;(e=s(e))&&(h=f(null),d=n.async&&u.async||n.promise&&u.promise?"async":"",t.on("set"+d,(function(n){h[n]=setTimeout((function(){t.delete(n)}),e),"function"==typeof h[n].unref&&h[n].unref(),v&&(v[n]&&"nextTick"!==v[n]&&clearTimeout(v[n]),v[n]=setTimeout((function(){delete v[n]}),m),"function"==typeof v[n].unref&&v[n].unref())})),t.on("delete"+d,(function(e){clearTimeout(h[e]),delete h[e],v&&("nextTick"!==v[e]&&clearTimeout(v[e]),delete v[e])})),n.preFetch&&(m=!0===n.preFetch||isNaN(n.preFetch)?.333:l(p(Number(n.preFetch),1),0))&&(v={},m=(1-m)*e,t.on("get"+d,(function(e,o,s){v[e]||(v[e]="nextTick",a((function(){var a;"nextTick"===v[e]&&(delete v[e],t.delete(e),n.async&&(o=r(o)).push(c),a=t.memoized.apply(s,o),n.promise&&i(a)&&("function"==typeof a.done?a.done(c,c):a.then(c,c)))})))}))),t.on("clear"+d,(function(){o(h,(function(e){clearTimeout(e)})),h={},v&&(o(v,(function(e){"nextTick"!==e&&clearTimeout(e)})),v={})})))}},function(e,t,n){"use strict";var r=n(118),o=n(833);e.exports=function(e){if((e=r(e))>o)throw new TypeError(e+" exceeds maximum possible timeout");return e}},function(e,t,n){"use strict";e.exports=2147483647},function(e,t,n){"use strict";var r=n(118),o=n(835),a=n(119);a.max=function(e,t,n){var i,s,u;(e=r(e))&&(s=o(e),i=n.async&&a.async||n.promise&&a.promise?"async":"",t.on("set"+i,u=function(e){void 0!==(e=s.hit(e))&&t.delete(e)}),t.on("get"+i,u),t.on("delete"+i,s.delete),t.on("clear"+i,s.clear))}},function(e,t,n){"use strict";var r=n(118),o=Object.create,a=Object.prototype.hasOwnProperty;e.exports=function(e){var t,n=0,i=1,s=o(null),u=o(null),c=0;return e=r(e),{hit:function(r){var o=u[r],l=++c;if(s[l]=r,u[r]=l,!o){if(++n<=e)return;return r=s[i],t(r),r}if(delete s[o],i===o)for(;!a.call(s,++i);)continue},delete:t=function(e){var t=u[e];if(t&&(delete s[t],delete u[e],--n,i===t)){if(!n)return c=0,void(i=1);for(;!a.call(s,++i);)continue}},clear:function(){n=0,i=1,s=o(null),u=o(null),c=0}}}},function(e,t,n){"use strict";var r=n(120),o=n(119),a=Object.create,i=Object.defineProperties;o.refCounter=function(e,t,n){var s,u;s=a(null),u=n.async&&o.async||n.promise&&o.promise?"async":"",t.on("set"+u,(function(e,t){s[e]=t||1})),t.on("get"+u,(function(e){++s[e]})),t.on("delete"+u,(function(e){delete s[e]})),t.on("clear"+u,(function(){s={}})),i(t.memoized,{deleteRef:r((function(){var e=t.get(arguments);return null===e?null:s[e]?!--s[e]&&(t.delete(e),!0):null})),getRefCount:r((function(){var e=t.get(arguments);return null===e?0:s[e]?s[e]:0}))})}},function(e,t,n){var r=n(63),o=n(140),a=n(64).Buffer,i=[1518500249,1859775393,-1894007588,-899497514],s=new Array(80);function u(){this.init(),this._w=s,o.call(this,64,56)}function c(e){return e<<30|e>>>2}function l(e,t,n,r){return 0===e?t&n|~t&r:2===e?t&n|t&r|n&r:t^n^r}r(u,o),u.prototype.init=function(){return this._a=1732584193,this._b=4023233417,this._c=2562383102,this._d=271733878,this._e=3285377520,this},u.prototype._update=function(e){for(var t,n=this._w,r=0|this._a,o=0|this._b,a=0|this._c,s=0|this._d,u=0|this._e,p=0;p<16;++p)n[p]=e.readInt32BE(4*p);for(;p<80;++p)n[p]=n[p-3]^n[p-8]^n[p-14]^n[p-16];for(var f=0;f<80;++f){var h=~~(f/20),d=0|((t=r)<<5|t>>>27)+l(h,o,a,s)+u+n[f]+i[h];u=s,s=a,a=c(o),o=r,r=d}this._a=r+this._a|0,this._b=o+this._b|0,this._c=a+this._c|0,this._d=s+this._d|0,this._e=u+this._e|0},u.prototype._hash=function(){var e=a.allocUnsafe(20);return e.writeInt32BE(0|this._a,0),e.writeInt32BE(0|this._b,4),e.writeInt32BE(0|this._c,8),e.writeInt32BE(0|this._d,12),e.writeInt32BE(0|this._e,16),e},e.exports=u},function(e,t,n){var r=n(63),o=n(140),a=n(64).Buffer,i=[1518500249,1859775393,-1894007588,-899497514],s=new Array(80);function u(){this.init(),this._w=s,o.call(this,64,56)}function c(e){return e<<5|e>>>27}function l(e){return e<<30|e>>>2}function p(e,t,n,r){return 0===e?t&n|~t&r:2===e?t&n|t&r|n&r:t^n^r}r(u,o),u.prototype.init=function(){return this._a=1732584193,this._b=4023233417,this._c=2562383102,this._d=271733878,this._e=3285377520,this},u.prototype._update=function(e){for(var t,n=this._w,r=0|this._a,o=0|this._b,a=0|this._c,s=0|this._d,u=0|this._e,f=0;f<16;++f)n[f]=e.readInt32BE(4*f);for(;f<80;++f)n[f]=(t=n[f-3]^n[f-8]^n[f-14]^n[f-16])<<1|t>>>31;for(var h=0;h<80;++h){var d=~~(h/20),m=c(r)+p(d,o,a,s)+u+n[h]+i[d]|0;u=s,s=a,a=l(o),o=r,r=m}this._a=r+this._a|0,this._b=o+this._b|0,this._c=a+this._c|0,this._d=s+this._d|0,this._e=u+this._e|0},u.prototype._hash=function(){var e=a.allocUnsafe(20);return e.writeInt32BE(0|this._a,0),e.writeInt32BE(0|this._b,4),e.writeInt32BE(0|this._c,8),e.writeInt32BE(0|this._d,12),e.writeInt32BE(0|this._e,16),e},e.exports=u},function(e,t,n){var r=n(63),o=n(442),a=n(140),i=n(64).Buffer,s=new Array(64);function u(){this.init(),this._w=s,a.call(this,64,56)}r(u,o),u.prototype.init=function(){return this._a=3238371032,this._b=914150663,this._c=812702999,this._d=4144912697,this._e=4290775857,this._f=1750603025,this._g=1694076839,this._h=3204075428,this},u.prototype._hash=function(){var e=i.allocUnsafe(28);return e.writeInt32BE(this._a,0),e.writeInt32BE(this._b,4),e.writeInt32BE(this._c,8),e.writeInt32BE(this._d,12),e.writeInt32BE(this._e,16),e.writeInt32BE(this._f,20),e.writeInt32BE(this._g,24),e},e.exports=u},function(e,t,n){var r=n(63),o=n(443),a=n(140),i=n(64).Buffer,s=new Array(160);function u(){this.init(),this._w=s,a.call(this,128,112)}r(u,o),u.prototype.init=function(){return this._ah=3418070365,this._bh=1654270250,this._ch=2438529370,this._dh=355462360,this._eh=1731405415,this._fh=2394180231,this._gh=3675008525,this._hh=1203062813,this._al=3238371032,this._bl=914150663,this._cl=812702999,this._dl=4144912697,this._el=4290775857,this._fl=1750603025,this._gl=1694076839,this._hl=3204075428,this},u.prototype._hash=function(){var e=i.allocUnsafe(48);function t(t,n,r){e.writeInt32BE(t,r),e.writeInt32BE(n,r+4)}return t(this._ah,this._al,0),t(this._bh,this._bl,8),t(this._ch,this._cl,16),t(this._dh,this._dl,24),t(this._eh,this._el,32),t(this._fh,this._fl,40),e},e.exports=u},function(e,t,n){var r=n(842);e.exports=r},function(e,t,n){var r=n(843),o=Array.prototype;e.exports=function(e){var t=e.every;return e===o||e instanceof Array&&t===o.every?r:t}},function(e,t,n){n(844);var r=n(42);e.exports=r("Array").every},function(e,t,n){"use strict";var r=n(22),o=n(85).every;r({target:"Array",proto:!0,forced:!n(113)("every")},{every:function(e){return o(this,e,arguments.length>1?arguments[1]:void 0)}})},function(e,t){e.exports=function(e,t,n,r,o){return o(e,(function(e,o,a){n=r?(r=!1,e):t(n,e,o,a)})),n}},function(e,t,n){var r=n(374);e.exports=r},function(e,t,n){var r=n(848);e.exports=r},function(e,t,n){n(363);var r=n(33);e.exports=r.Object.getOwnPropertySymbols},function(e,t,n){e.exports=n(850)},function(e,t,n){var r=n(373);e.exports=r},function(e,t,n){e.exports=n(852)},function(e,t,n){var r=n(853);e.exports=r},function(e,t,n){n(854);var r=n(33).Object,o=e.exports=function(e,t){return r.getOwnPropertyDescriptor(e,t)};r.getOwnPropertyDescriptor.sham&&(o.sham=!0)},function(e,t,n){var r=n(22),o=n(37),a=n(66),i=n(127).f,s=n(48),u=o((function(){i(1)}));r({target:"Object",stat:!0,forced:!s||u,sham:!s},{getOwnPropertyDescriptor:function(e,t){return i(a(e),t)}})},function(e,t,n){e.exports=n(856)},function(e,t,n){var r=n(400);e.exports=r},function(e,t,n){e.exports=n(858)},function(e,t,n){var r=n(859);e.exports=r},function(e,t,n){n(860);var r=n(33);e.exports=r.Object.getOwnPropertyDescriptors},function(e,t,n){var r=n(22),o=n(48),a=n(861),i=n(66),s=n(127),u=n(154);r({target:"Object",stat:!0,sham:!o},{getOwnPropertyDescriptors:function(e){for(var t,n,r=i(e),o=s.f,c=a(r),l={},p=0;c.length>p;)void 0!==(n=o(r,t=c[p++]))&&u(l,t,n);return l}})},function(e,t,n){var r=n(70),o=n(232),a=n(233),i=n(52);e.exports=r("Reflect","ownKeys")||function(e){var t=o.f(i(e)),n=a.f;return n?t.concat(n(e)):t}},function(e,t,n){e.exports=n(863)},function(e,t,n){var r=n(864);e.exports=r},function(e,t,n){n(865);var r=n(33).Object,o=e.exports=function(e,t){return r.defineProperties(e,t)};r.defineProperties.sham&&(o.sham=!0)},function(e,t,n){var r=n(22),o=n(48);r({target:"Object",stat:!0,forced:!o,sham:!o},{defineProperties:n(228)})},function(e,t,n){var r=n(403);e.exports=r},function(e,t,n){var r=n(444),o=n(446);e.exports=function(e,t){if(null==e)return{};var n,a,i={},s=r(e);for(a=0;a=0||(i[n]=e[n]);return i},e.exports.default=e.exports,e.exports.__esModule=!0},function(e,t,n){e.exports=n(869)},function(e,t,n){var r=n(447);n(876),n(877),n(878),n(879),e.exports=r},function(e,t,n){"use strict";var r,o,a,i,s=n(22),u=n(96),c=n(40),l=n(70),p=n(449),f=n(112),h=n(164),d=n(185),m=n(97),v=n(450),g=n(47),y=n(76),b=n(141),_=n(367),w=n(121),x=n(397),E=n(451),S=n(452).set,C=n(871),A=n(454),O=n(873),k=n(165),j=n(202),T=n(77),I=n(361),P=n(41),N=n(874),M=n(186),R=n(129),D=P("species"),L="Promise",B=T.get,F=T.set,U=T.getterFor(L),q=p&&p.prototype,z=p,V=q,W=c.TypeError,H=c.document,$=c.process,J=k.f,K=J,Y=!!(H&&H.createEvent&&c.dispatchEvent),G="function"==typeof PromiseRejectionEvent,Z="unhandledrejection",X=!1,Q=I(L,(function(){var e=_(z)!==String(z);if(!e&&66===R)return!0;if(u&&!V.finally)return!0;if(R>=51&&/native code/.test(z))return!1;var t=new z((function(e){e(1)})),n=function(e){e((function(){}),(function(){}))};return(t.constructor={})[D]=n,!(X=t.then((function(){}))instanceof n)||!e&&N&&!G})),ee=Q||!x((function(e){z.all(e).catch((function(){}))})),te=function(e){var t;return!(!g(e)||"function"!=typeof(t=e.then))&&t},ne=function(e,t){if(!e.notified){e.notified=!0;var n=e.reactions;C((function(){for(var r=e.value,o=1==e.state,a=0;n.length>a;){var i,s,u,c=n[a++],l=o?c.ok:c.fail,p=c.resolve,f=c.reject,h=c.domain;try{l?(o||(2===e.rejection&&ie(e),e.rejection=1),!0===l?i=r:(h&&h.enter(),i=l(r),h&&(h.exit(),u=!0)),i===c.promise?f(W("Promise-chain cycle")):(s=te(i))?s.call(i,p,f):p(i)):f(r)}catch(e){h&&!u&&h.exit(),f(e)}}e.reactions=[],e.notified=!1,t&&!e.rejection&&oe(e)}))}},re=function(e,t,n){var r,o;Y?((r=H.createEvent("Event")).promise=t,r.reason=n,r.initEvent(e,!1,!0),c.dispatchEvent(r)):r={promise:t,reason:n},!G&&(o=c["on"+e])?o(r):e===Z&&O("Unhandled promise rejection",n)},oe=function(e){S.call(c,(function(){var t,n=e.facade,r=e.value;if(ae(e)&&(t=j((function(){M?$.emit("unhandledRejection",r,n):re(Z,n,r)})),e.rejection=M||ae(e)?2:1,t.error))throw t.value}))},ae=function(e){return 1!==e.rejection&&!e.parent},ie=function(e){S.call(c,(function(){var t=e.facade;M?$.emit("rejectionHandled",t):re("rejectionhandled",t,e.value)}))},se=function(e,t,n){return function(r){e(t,r,n)}},ue=function(e,t,n){e.done||(e.done=!0,n&&(e=n),e.value=t,e.state=2,ne(e,!0))},ce=function(e,t,n){if(!e.done){e.done=!0,n&&(e=n);try{if(e.facade===t)throw W("Promise can't be resolved itself");var r=te(t);r?C((function(){var n={done:!1};try{r.call(t,se(ce,n,e),se(ue,n,e))}catch(t){ue(n,t,e)}})):(e.value=t,e.state=1,ne(e,!1))}catch(t){ue({done:!1},t,e)}}};if(Q&&(V=(z=function(e){b(this,z,L),y(e),r.call(this);var t=B(this);try{e(se(ce,t),se(ue,t))}catch(e){ue(t,e)}}).prototype,(r=function(e){F(this,{type:L,done:!1,notified:!1,parent:!1,reactions:[],rejection:!1,state:0,value:void 0})}).prototype=h(V,{then:function(e,t){var n=U(this),r=J(E(this,z));return r.ok="function"!=typeof e||e,r.fail="function"==typeof t&&t,r.domain=M?$.domain:void 0,n.parent=!0,n.reactions.push(r),0!=n.state&&ne(n,!1),r.promise},catch:function(e){return this.then(void 0,e)}}),o=function(){var e=new r,t=B(e);this.promise=e,this.resolve=se(ce,t),this.reject=se(ue,t)},k.f=J=function(e){return e===z||e===a?new o(e):K(e)},!u&&"function"==typeof p&&q!==Object.prototype)){i=q.then,X||(f(q,"then",(function(e,t){var n=this;return new z((function(e,t){i.call(n,e,t)})).then(e,t)}),{unsafe:!0}),f(q,"catch",V.catch,{unsafe:!0}));try{delete q.constructor}catch(e){}d&&d(q,V)}s({global:!0,wrap:!0,forced:Q},{Promise:z}),m(z,L,!1,!0),v(L),a=l(L),s({target:L,stat:!0,forced:Q},{reject:function(e){var t=J(this);return t.reject.call(void 0,e),t.promise}}),s({target:L,stat:!0,forced:u||Q},{resolve:function(e){return A(u&&this===a?z:this,e)}}),s({target:L,stat:!0,forced:ee},{all:function(e){var t=this,n=J(t),r=n.resolve,o=n.reject,a=j((function(){var n=y(t.resolve),a=[],i=0,s=1;w(e,(function(e){var u=i++,c=!1;a.push(void 0),s++,n.call(t,e).then((function(e){c||(c=!0,a[u]=e,--s||r(a))}),o)})),--s||r(a)}));return a.error&&o(a.value),n.promise},race:function(e){var t=this,n=J(t),r=n.reject,o=j((function(){var o=y(t.resolve);w(e,(function(e){o.call(t,e).then(n.resolve,r)}))}));return o.error&&r(o.value),n.promise}})},function(e,t,n){var r,o,a,i,s,u,c,l,p=n(40),f=n(127).f,h=n(452).set,d=n(453),m=n(872),v=n(186),g=p.MutationObserver||p.WebKitMutationObserver,y=p.document,b=p.process,_=p.Promise,w=f(p,"queueMicrotask"),x=w&&w.value;x||(r=function(){var e,t;for(v&&(e=b.domain)&&e.exit();o;){t=o.fn,o=o.next;try{t()}catch(e){throw o?i():a=void 0,e}}a=void 0,e&&e.enter()},d||v||m||!g||!y?_&&_.resolve?((c=_.resolve(void 0)).constructor=_,l=c.then,i=function(){l.call(c,r)}):i=v?function(){b.nextTick(r)}:function(){h.call(p,r)}:(s=!0,u=y.createTextNode(""),new g(r).observe(u,{characterData:!0}),i=function(){u.data=s=!s})),e.exports=x||function(e){var t={fn:e,next:void 0};a&&(a.next=t),o||(o=t,i()),a=t}},function(e,t,n){var r=n(110);e.exports=/web0s(?!.*chrome)/i.test(r)},function(e,t,n){var r=n(40);e.exports=function(e,t){var n=r.console;n&&n.error&&(1===arguments.length?n.error(e):n.error(e,t))}},function(e,t){e.exports="object"==typeof window},function(e,t,n){"use strict";var r=n(22),o=n(96),a=n(449),i=n(37),s=n(70),u=n(451),c=n(454),l=n(112);if(r({target:"Promise",proto:!0,real:!0,forced:!!a&&i((function(){a.prototype.finally.call({then:function(){}},(function(){}))}))},{finally:function(e){var t=u(this,s("Promise")),n="function"==typeof e;return this.then(n?function(n){return c(t,e()).then((function(){return n}))}:e,n?function(n){return c(t,e()).then((function(){throw n}))}:e)}}),!o&&"function"==typeof a){var p=s("Promise").prototype.finally;a.prototype.finally!==p&&l(a.prototype,"finally",p,{unsafe:!0})}},function(e,t,n){n(448)},function(e,t,n){n(455)},function(e,t,n){"use strict";var r=n(22),o=n(165),a=n(202);r({target:"Promise",stat:!0},{try:function(e){var t=o.f(this),n=a(e);return(n.error?t.reject:t.resolve)(n.value),t.promise}})},function(e,t,n){n(456)},function(e,t,n){var r=function(e){"use strict";var t,n=Object.prototype,r=n.hasOwnProperty,o="function"==typeof Symbol?Symbol:{},a=o.iterator||"@@iterator",i=o.asyncIterator||"@@asyncIterator",s=o.toStringTag||"@@toStringTag";function u(e,t,n){return Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}),e[t]}try{u({},"")}catch(e){u=function(e,t,n){return e[t]=n}}function c(e,t,n,r){var o=t&&t.prototype instanceof v?t:v,a=Object.create(o.prototype),i=new k(r||[]);return a._invoke=function(e,t,n){var r=p;return function(o,a){if(r===h)throw new Error("Generator is already running");if(r===d){if("throw"===o)throw a;return T()}for(n.method=o,n.arg=a;;){var i=n.delegate;if(i){var s=C(i,n);if(s){if(s===m)continue;return s}}if("next"===n.method)n.sent=n._sent=n.arg;else if("throw"===n.method){if(r===p)throw r=d,n.arg;n.dispatchException(n.arg)}else"return"===n.method&&n.abrupt("return",n.arg);r=h;var u=l(e,t,n);if("normal"===u.type){if(r=n.done?d:f,u.arg===m)continue;return{value:u.arg,done:n.done}}"throw"===u.type&&(r=d,n.method="throw",n.arg=u.arg)}}}(e,n,i),a}function l(e,t,n){try{return{type:"normal",arg:e.call(t,n)}}catch(e){return{type:"throw",arg:e}}}e.wrap=c;var p="suspendedStart",f="suspendedYield",h="executing",d="completed",m={};function v(){}function g(){}function y(){}var b={};b[a]=function(){return this};var _=Object.getPrototypeOf,w=_&&_(_(j([])));w&&w!==n&&r.call(w,a)&&(b=w);var x=y.prototype=v.prototype=Object.create(b);function E(e){["next","throw","return"].forEach((function(t){u(e,t,(function(e){return this._invoke(t,e)}))}))}function S(e,t){function n(o,a,i,s){var u=l(e[o],e,a);if("throw"!==u.type){var c=u.arg,p=c.value;return p&&"object"==typeof p&&r.call(p,"__await")?t.resolve(p.__await).then((function(e){n("next",e,i,s)}),(function(e){n("throw",e,i,s)})):t.resolve(p).then((function(e){c.value=e,i(c)}),(function(e){return n("throw",e,i,s)}))}s(u.arg)}var o;this._invoke=function(e,r){function a(){return new t((function(t,o){n(e,r,t,o)}))}return o=o?o.then(a,a):a()}}function C(e,n){var r=e.iterator[n.method];if(r===t){if(n.delegate=null,"throw"===n.method){if(e.iterator.return&&(n.method="return",n.arg=t,C(e,n),"throw"===n.method))return m;n.method="throw",n.arg=new TypeError("The iterator does not provide a 'throw' method")}return m}var o=l(r,e.iterator,n.arg);if("throw"===o.type)return n.method="throw",n.arg=o.arg,n.delegate=null,m;var a=o.arg;return a?a.done?(n[e.resultName]=a.value,n.next=e.nextLoc,"return"!==n.method&&(n.method="next",n.arg=t),n.delegate=null,m):a:(n.method="throw",n.arg=new TypeError("iterator result is not an object"),n.delegate=null,m)}function A(e){var t={tryLoc:e[0]};1 in e&&(t.catchLoc=e[1]),2 in e&&(t.finallyLoc=e[2],t.afterLoc=e[3]),this.tryEntries.push(t)}function O(e){var t=e.completion||{};t.type="normal",delete t.arg,e.completion=t}function k(e){this.tryEntries=[{tryLoc:"root"}],e.forEach(A,this),this.reset(!0)}function j(e){if(e){var n=e[a];if(n)return n.call(e);if("function"==typeof e.next)return e;if(!isNaN(e.length)){var o=-1,i=function n(){for(;++o=0;--a){var i=this.tryEntries[a],s=i.completion;if("root"===i.tryLoc)return o("end");if(i.tryLoc<=this.prev){var u=r.call(i,"catchLoc"),c=r.call(i,"finallyLoc");if(u&&c){if(this.prev=0;--n){var o=this.tryEntries[n];if(o.tryLoc<=this.prev&&r.call(o,"finallyLoc")&&this.prev=0;--t){var n=this.tryEntries[t];if(n.finallyLoc===e)return this.complete(n.completion,n.afterLoc),O(n),m}},catch:function(e){for(var t=this.tryEntries.length-1;t>=0;--t){var n=this.tryEntries[t];if(n.tryLoc===e){var r=n.completion;if("throw"===r.type){var o=r.arg;O(n)}return o}}throw new Error("illegal catch attempt")},delegateYield:function(e,n,r){return this.delegate={iterator:j(e),resultName:n,nextLoc:r},"next"===this.method&&(this.arg=t),m}},e}(e.exports);try{regeneratorRuntime=r}catch(e){Function("r","regeneratorRuntime = r")(r)}},function(e,t,n){var r=n(376);e.exports=r},function(e,t,n){var r=n(447);e.exports=r},function(e,t,n){var r=n(884);e.exports=r},function(e,t,n){n(885);var r=n(33);e.exports=r.Object.values},function(e,t,n){var r=n(22),o=n(457).values;r({target:"Object",stat:!0},{values:function(e){return o(e)}})},function(e,t,n){var r=n(887);e.exports=r},function(e,t,n){n(888);var r=n(33);e.exports=r.Date.now},function(e,t,n){n(22)({target:"Date",stat:!0},{now:function(){return(new Date).getTime()}})},function(e,t,n){"use strict";e.exports=function(e,t){if(t=t.split(":")[0],!(e=+e))return!1;switch(t){case"http":case"ws":return 80!==e;case"https":case"wss":return 443!==e;case"ftp":return 21!==e;case"gopher":return 70!==e;case"file":return!1}return 0!==e}},function(e,t,n){"use strict";var r=Object.prototype.hasOwnProperty;function o(e){try{return decodeURIComponent(e.replace(/\+/g," "))}catch(e){return null}}function a(e){try{return encodeURIComponent(e)}catch(e){return null}}t.stringify=function(e,t){t=t||"";var n,o,i=[];for(o in"string"!=typeof t&&(t="?"),e)if(r.call(e,o)){if((n=e[o])||null!=n&&!isNaN(n)||(n=""),o=a(o),n=a(n),null===o||null===n)continue;i.push(o+"="+n)}return i.length?t+i.join("&"):""},t.parse=function(e){for(var t,n=/([^=?#&]+)=?([^&]*)/g,r={};t=n.exec(e);){var a=o(t[1]),i=o(t[2]);null===a||null===i||a in r||(r[a]=i)}return r}},function(e,t,n){var r=n(71);e.exports=function(){return r.Date.now()}},function(e,t,n){var r=n(259),o=n(162),a=n(197),i=n(59),s=n(138);e.exports=function(e,t,n,u){if(!i(e))return e;for(var c=-1,l=(t=o(t,e)).length,p=l-1,f=e;null!=f&&++c8&&l<=11);var d=String.fromCharCode(32),m={beforeInput:{phasedRegistrationNames:{bubbled:"onBeforeInput",captured:"onBeforeInputCapture"},dependencies:["topCompositionEnd","topKeyPress","topTextInput","topPaste"]},compositionEnd:{phasedRegistrationNames:{bubbled:"onCompositionEnd",captured:"onCompositionEndCapture"},dependencies:["topBlur","topCompositionEnd","topKeyDown","topKeyPress","topKeyUp","topMouseDown"]},compositionStart:{phasedRegistrationNames:{bubbled:"onCompositionStart",captured:"onCompositionStartCapture"},dependencies:["topBlur","topCompositionStart","topKeyDown","topKeyPress","topKeyUp","topMouseDown"]},compositionUpdate:{phasedRegistrationNames:{bubbled:"onCompositionUpdate",captured:"onCompositionUpdateCapture"},dependencies:["topBlur","topCompositionUpdate","topKeyDown","topKeyPress","topKeyUp","topMouseDown"]}},v=!1;function g(e,t){switch(e){case"topKeyUp":return-1!==u.indexOf(t.keyCode);case"topKeyDown":return 229!==t.keyCode;case"topKeyPress":case"topMouseDown":case"topBlur":return!0;default:return!1}}function y(e){var t=e.detail;return"object"==typeof t&&"data"in t?t.data:null}var b=null;function _(e,t,n,o){var s,u;if(c?s=function(e){switch(e){case"topCompositionStart":return m.compositionStart;case"topCompositionEnd":return m.compositionEnd;case"topCompositionUpdate":return m.compositionUpdate}}(e):b?g(e,n)&&(s=m.compositionEnd):function(e,t){return"topKeyDown"===e&&229===t.keyCode}(e,n)&&(s=m.compositionStart),!s)return null;h&&(b||s!==m.compositionStart?s===m.compositionEnd&&b&&(u=b.getData()):b=a.getPooled(o));var l=i.getPooled(s,t,n,o);if(u)l.data=u;else{var p=y(n);null!==p&&(l.data=p)}return r.accumulateTwoPhaseDispatches(l),l}function w(e,t,n,o){var i;if(!(i=f?function(e,t){switch(e){case"topCompositionEnd":return y(t);case"topKeyPress":return 32!==t.which?null:(v=!0,d);case"topTextInput":var n=t.data;return n===d&&v?null:n;default:return null}}(e,n):function(e,t){if(b){if("topCompositionEnd"===e||!c&&g(e,t)){var n=b.getData();return a.release(b),b=null,n}return null}switch(e){case"topPaste":return null;case"topKeyPress":return t.which&&!function(e){return(e.ctrlKey||e.altKey||e.metaKey)&&!(e.ctrlKey&&e.altKey)}(t)?String.fromCharCode(t.which):null;case"topCompositionEnd":return h?null:t.data;default:return null}}(e,n)))return null;var u=s.getPooled(m.beforeInput,t,n,o);return u.data=i,r.accumulateTwoPhaseDispatches(u),u}var x={eventTypes:m,extractEvents:function(e,t,n,r){return[_(e,t,n,r),w(e,t,n,r)]}};e.exports=x},function(e,t,n){"use strict";var r=n(38),o=n(122),a=n(465);function i(e){this._root=e,this._startText=this.getText(),this._fallbackText=null}r(i.prototype,{destructor:function(){this._root=null,this._startText=null,this._fallbackText=null},getText:function(){return"value"in this._root?this._root.value:this._root[a()]},getData:function(){if(this._fallbackText)return this._fallbackText;var e,t,n=this._startText,r=n.length,o=this.getText(),a=o.length;for(e=0;e1?1-t:void 0;return this._fallbackText=o.slice(e,s),this._fallbackText}}),o.addPoolingTo(i),e.exports=i},function(e,t,n){"use strict";var r=n(90);function o(e,t,n,o){return r.call(this,e,t,n,o)}r.augmentClass(o,{data:null}),e.exports=o},function(e,t,n){"use strict";var r=n(90);function o(e,t,n,o){return r.call(this,e,t,n,o)}r.augmentClass(o,{data:null}),e.exports=o},function(e,t,n){"use strict";var r=n(167),o=n(166),a=n(57),i=n(45),s=n(79),u=n(90),c=n(468),l=n(263),p=n(264),f=n(469),h={change:{phasedRegistrationNames:{bubbled:"onChange",captured:"onChangeCapture"},dependencies:["topBlur","topChange","topClick","topFocus","topInput","topKeyDown","topKeyUp","topSelectionChange"]}};function d(e,t,n){var r=u.getPooled(h.change,e,t,n);return r.type="change",o.accumulateTwoPhaseDispatches(r),r}var m=null,v=null;var g=!1;function y(e){var t=d(v,e,l(e));s.batchedUpdates(b,t)}function b(e){r.enqueueEvents(e),r.processEventQueue(!1)}function _(){m&&(m.detachEvent("onchange",y),m=null,v=null)}function w(e,t){var n=c.updateValueIfChanged(e),r=!0===t.simulated&&I._allowSimulatedPassThrough;if(n||r)return e}function x(e,t){if("topChange"===e)return t}function E(e,t,n){"topFocus"===e?(_(),function(e,t){v=t,(m=e).attachEvent("onchange",y)}(t,n)):"topBlur"===e&&_()}a.canUseDOM&&(g=p("change")&&(!document.documentMode||document.documentMode>8));var S=!1;function C(){m&&(m.detachEvent("onpropertychange",A),m=null,v=null)}function A(e){"value"===e.propertyName&&w(v,e)&&y(e)}function O(e,t,n){"topFocus"===e?(C(),function(e,t){v=t,(m=e).attachEvent("onpropertychange",A)}(t,n)):"topBlur"===e&&C()}function k(e,t,n){if("topSelectionChange"===e||"topKeyUp"===e||"topKeyDown"===e)return w(v,n)}function j(e,t,n){if("topClick"===e)return w(t,n)}function T(e,t,n){if("topInput"===e||"topChange"===e)return w(t,n)}a.canUseDOM&&(S=p("input")&&(!document.documentMode||document.documentMode>9));var I={eventTypes:h,_allowSimulatedPassThrough:!0,_isInputEventSupported:S,extractEvents:function(e,t,n,r){var o,a,s,u,c=t?i.getNodeFromInstance(t):window;if("select"===(u=(s=c).nodeName&&s.nodeName.toLowerCase())||"input"===u&&"file"===s.type?g?o=x:a=E:f(c)?S?o=T:(o=k,a=O):function(e){var t=e.nodeName;return t&&"input"===t.toLowerCase()&&("checkbox"===e.type||"radio"===e.type)}(c)&&(o=j),o){var l=o(e,t,n);if(l)return d(l,n,r)}a&&a(e,c,t),"topBlur"===e&&function(e,t){if(null!=e){var n=e._wrapperState||t._wrapperState;if(n&&n.controlled&&"number"===t.type){var r=""+t.value;t.getAttribute("value")!==r&&t.setAttribute("value",r)}}}(t,c)}};e.exports=I},function(e,t,n){"use strict";var r=n(922),o={};o.attachRefs=function(e,t){if(null!==t&&"object"==typeof t){var n=t.ref;null!=n&&function(e,t,n){"function"==typeof e?e(t.getPublicInstance()):r.addComponentAsRefTo(t,e,n)}(n,e,t._owner)}},o.shouldUpdateRefs=function(e,t){var n=null,r=null;null!==e&&"object"==typeof e&&(n=e.ref,r=e._owner);var o=null,a=null;return null!==t&&"object"==typeof t&&(o=t.ref,a=t._owner),n!==o||"string"==typeof o&&a!==r},o.detachRefs=function(e,t){if(null!==t&&"object"==typeof t){var n=t.ref;null!=n&&function(e,t,n){"function"==typeof e?e(null):r.removeComponentAsRefFrom(t,e,n)}(n,e,t._owner)}},e.exports=o},function(e,t,n){"use strict";var r=n(30);n(25);function o(e){return!(!e||"function"!=typeof e.attachRef||"function"!=typeof e.detachRef)}var a={addComponentAsRefTo:function(e,t,n){o(n)||r("119"),n.attachRef(t,e)},removeComponentAsRefFrom:function(e,t,n){o(n)||r("120");var a=n.getPublicInstance();a&&a.refs[t]===e.getPublicInstance()&&n.detachRef(t)}};e.exports=a},function(e,t,n){"use strict";e.exports=["ResponderEventPlugin","SimpleEventPlugin","TapEventPlugin","EnterLeaveEventPlugin","ChangeEventPlugin","SelectEventPlugin","BeforeInputEventPlugin"]},function(e,t,n){"use strict";var r=n(166),o=n(45),a=n(204),i={mouseEnter:{registrationName:"onMouseEnter",dependencies:["topMouseOut","topMouseOver"]},mouseLeave:{registrationName:"onMouseLeave",dependencies:["topMouseOut","topMouseOver"]}},s={eventTypes:i,extractEvents:function(e,t,n,s){if("topMouseOver"===e&&(n.relatedTarget||n.fromElement))return null;if("topMouseOut"!==e&&"topMouseOver"!==e)return null;var u,c,l;if(s.window===s)u=s;else{var p=s.ownerDocument;u=p?p.defaultView||p.parentWindow:window}if("topMouseOut"===e){c=t;var f=n.relatedTarget||n.toElement;l=f?o.getClosestInstanceFromNode(f):null}else c=null,l=t;if(c===l)return null;var h=null==c?u:o.getNodeFromInstance(c),d=null==l?u:o.getNodeFromInstance(l),m=a.getPooled(i.mouseLeave,c,n,s);m.type="mouseleave",m.target=h,m.relatedTarget=d;var v=a.getPooled(i.mouseEnter,l,n,s);return v.type="mouseenter",v.target=d,v.relatedTarget=h,r.accumulateEnterLeaveDispatches(m,v,c,l),[m,v]}};e.exports=s},function(e,t,n){"use strict";var r=n(142),o=r.injection.MUST_USE_PROPERTY,a=r.injection.HAS_BOOLEAN_VALUE,i=r.injection.HAS_NUMERIC_VALUE,s=r.injection.HAS_POSITIVE_NUMERIC_VALUE,u=r.injection.HAS_OVERLOADED_BOOLEAN_VALUE,c={isCustomAttribute:RegExp.prototype.test.bind(new RegExp("^(data|aria)-["+r.ATTRIBUTE_NAME_CHAR+"]*$")),Properties:{accept:0,acceptCharset:0,accessKey:0,action:0,allowFullScreen:a,allowTransparency:0,alt:0,as:0,async:a,autoComplete:0,autoPlay:a,capture:a,cellPadding:0,cellSpacing:0,charSet:0,challenge:0,checked:o|a,cite:0,classID:0,className:0,cols:s,colSpan:0,content:0,contentEditable:0,contextMenu:0,controls:a,controlsList:0,coords:0,crossOrigin:0,data:0,dateTime:0,default:a,defer:a,dir:0,disabled:a,download:u,draggable:0,encType:0,form:0,formAction:0,formEncType:0,formMethod:0,formNoValidate:a,formTarget:0,frameBorder:0,headers:0,height:0,hidden:a,high:0,href:0,hrefLang:0,htmlFor:0,httpEquiv:0,icon:0,id:0,inputMode:0,integrity:0,is:0,keyParams:0,keyType:0,kind:0,label:0,lang:0,list:0,loop:a,low:0,manifest:0,marginHeight:0,marginWidth:0,max:0,maxLength:0,media:0,mediaGroup:0,method:0,min:0,minLength:0,multiple:o|a,muted:o|a,name:0,nonce:0,noValidate:a,open:a,optimum:0,pattern:0,placeholder:0,playsInline:a,poster:0,preload:0,profile:0,radioGroup:0,readOnly:a,referrerPolicy:0,rel:0,required:a,reversed:a,role:0,rows:s,rowSpan:i,sandbox:0,scope:0,scoped:a,scrolling:0,seamless:a,selected:o|a,shape:0,size:s,sizes:0,span:s,spellCheck:0,src:0,srcDoc:0,srcLang:0,srcSet:0,start:i,step:0,style:0,summary:0,tabIndex:0,target:0,title:0,type:0,useMap:0,value:0,width:0,wmode:0,wrap:0,about:0,datatype:0,inlist:0,prefix:0,property:0,resource:0,typeof:0,vocab:0,autoCapitalize:0,autoCorrect:0,autoSave:0,color:0,itemProp:0,itemScope:a,itemType:0,itemID:0,itemRef:0,results:0,security:0,unselectable:0},DOMAttributeNames:{acceptCharset:"accept-charset",className:"class",htmlFor:"for",httpEquiv:"http-equiv"},DOMPropertyNames:{},DOMMutationMethods:{value:function(e,t){if(null==t)return e.removeAttribute("value");("number"!==e.type||!1===e.hasAttribute("value")||e.validity&&!e.validity.badInput&&e.ownerDocument.activeElement!==e)&&e.setAttribute("value",""+t)}}};e.exports=c},function(e,t,n){"use strict";var r=n(266),o={processChildrenUpdates:n(931).dangerouslyProcessChildrenUpdates,replaceNodeWithMarkup:r.dangerouslyReplaceNodeWithMarkup};e.exports=o},function(e,t,n){"use strict";var r=n(30),o=n(144),a=n(57),i=n(928),s=n(78),u=(n(25),{dangerouslyReplaceNodeWithMarkup:function(e,t){if(a.canUseDOM||r("56"),t||r("57"),"HTML"===e.nodeName&&r("58"),"string"==typeof t){var n=i(t,s)[0];e.parentNode.replaceChild(n,e)}else o.replaceChildWithTree(e,t)}});e.exports=u},function(e,t,n){"use strict";var r=n(57),o=n(929),a=n(930),i=n(25),s=r.canUseDOM?document.createElement("div"):null,u=/^\s*<(\w+)/;e.exports=function(e,t){var n=s;s||i(!1);var r=function(e){var t=e.match(u);return t&&t[1].toLowerCase()}(e),c=r&&a(r);if(c){n.innerHTML=c[1]+e+c[2];for(var l=c[0];l--;)n=n.lastChild}else n.innerHTML=e;var p=n.getElementsByTagName("script");p.length&&(t||i(!1),o(p).forEach(t));for(var f=Array.from(n.childNodes);n.lastChild;)n.removeChild(n.lastChild);return f}},function(e,t,n){"use strict";var r=n(25);e.exports=function(e){return function(e){return!!e&&("object"==typeof e||"function"==typeof e)&&"length"in e&&!("setInterval"in e)&&"number"!=typeof e.nodeType&&(Array.isArray(e)||"callee"in e||"item"in e)}(e)?Array.isArray(e)?e.slice():function(e){var t=e.length;if((Array.isArray(e)||"object"!=typeof e&&"function"!=typeof e)&&r(!1),"number"!=typeof t&&r(!1),0===t||t-1 in e||r(!1),"function"==typeof e.callee&&r(!1),e.hasOwnProperty)try{return Array.prototype.slice.call(e)}catch(e){}for(var n=Array(t),o=0;o',""],u=[1,"","
"],c=[3,"","
"],l=[1,'',""],p={"*":[1,"?
","
"],area:[1,"",""],col:[2,"","
"],legend:[1,"
","
"],param:[1,"",""],tr:[2,"","
"],optgroup:s,option:s,caption:u,colgroup:u,tbody:u,tfoot:u,thead:u,td:c,th:c};["circle","clipPath","defs","ellipse","g","image","line","linearGradient","mask","path","pattern","polygon","polyline","radialGradient","rect","stop","text","tspan"].forEach((function(e){p[e]=l,i[e]=!0})),e.exports=function(e){return a||o(!1),p.hasOwnProperty(e)||(e="*"),i.hasOwnProperty(e)||(a.innerHTML="*"===e?"":"<"+e+">",i[e]=!a.firstChild),i[e]?p[e]:null}},function(e,t,n){"use strict";var r=n(266),o=n(45),a={dangerouslyProcessChildrenUpdates:function(e,t){var n=o.getNodeFromInstance(e);r.processUpdates(n,t)}};e.exports=a},function(e,t,n){"use strict";var r=n(30),o=n(38),a=n(933),i=n(934),s=n(144),u=n(267),c=n(142),l=n(474),p=n(167),f=n(260),h=n(207),d=n(462),m=n(45),v=n(944),g=n(946),y=n(475),b=n(947),_=(n(72),n(948)),w=n(955),x=(n(78),n(206)),E=(n(25),n(264),n(271),n(468)),S=(n(275),n(34),d),C=p.deleteListener,A=m.getNodeFromInstance,O=h.listenTo,k=f.registrationNameModules,j={string:!0,number:!0},T="style",I={children:null,dangerouslySetInnerHTML:null,suppressContentEditableWarning:null};function P(e,t){t&&(W[e._tag]&&(null!=t.children||null!=t.dangerouslySetInnerHTML)&&r("137",e._tag,e._currentElement._owner?" Check the render method of "+e._currentElement._owner.getName()+".":""),null!=t.dangerouslySetInnerHTML&&(null!=t.children&&r("60"),"object"==typeof t.dangerouslySetInnerHTML&&"__html"in t.dangerouslySetInnerHTML||r("61")),null!=t.style&&"object"!=typeof t.style&&r("62",function(e){if(e){var t=e._currentElement._owner||null;if(t){var n=t.getName();if(n)return" This DOM node was rendered by `"+n+"`."}}return""}(e)))}function N(e,t,n,r){if(!(r instanceof w)){0;var o=e._hostContainerInfo,a=o._node&&11===o._node.nodeType?o._node:o._ownerDocument;O(t,a),r.getReactMountReady().enqueue(M,{inst:e,registrationName:t,listener:n})}}function M(){var e=this;p.putListener(e.inst,e.registrationName,e.listener)}function R(){v.postMountWrapper(this)}function D(){b.postMountWrapper(this)}function L(){g.postMountWrapper(this)}var B={topAbort:"abort",topCanPlay:"canplay",topCanPlayThrough:"canplaythrough",topDurationChange:"durationchange",topEmptied:"emptied",topEncrypted:"encrypted",topEnded:"ended",topError:"error",topLoadedData:"loadeddata",topLoadedMetadata:"loadedmetadata",topLoadStart:"loadstart",topPause:"pause",topPlay:"play",topPlaying:"playing",topProgress:"progress",topRateChange:"ratechange",topSeeked:"seeked",topSeeking:"seeking",topStalled:"stalled",topSuspend:"suspend",topTimeUpdate:"timeupdate",topVolumeChange:"volumechange",topWaiting:"waiting"};function F(){E.track(this)}function U(){var e=this;e._rootNodeID||r("63");var t=A(e);switch(t||r("64"),e._tag){case"iframe":case"object":e._wrapperState.listeners=[h.trapBubbledEvent("topLoad","load",t)];break;case"video":case"audio":for(var n in e._wrapperState.listeners=[],B)B.hasOwnProperty(n)&&e._wrapperState.listeners.push(h.trapBubbledEvent(n,B[n],t));break;case"source":e._wrapperState.listeners=[h.trapBubbledEvent("topError","error",t)];break;case"img":e._wrapperState.listeners=[h.trapBubbledEvent("topError","error",t),h.trapBubbledEvent("topLoad","load",t)];break;case"form":e._wrapperState.listeners=[h.trapBubbledEvent("topReset","reset",t),h.trapBubbledEvent("topSubmit","submit",t)];break;case"input":case"select":case"textarea":e._wrapperState.listeners=[h.trapBubbledEvent("topInvalid","invalid",t)]}}function q(){y.postUpdateWrapper(this)}var z={area:!0,base:!0,br:!0,col:!0,embed:!0,hr:!0,img:!0,input:!0,keygen:!0,link:!0,meta:!0,param:!0,source:!0,track:!0,wbr:!0},V={listing:!0,pre:!0,textarea:!0},W=o({menuitem:!0},z),H=/^[a-zA-Z][a-zA-Z:_\.\-\d]*$/,$={},J={}.hasOwnProperty;function K(e,t){return e.indexOf("-")>=0||null!=t.is}var Y=1;function G(e){var t=e.type;!function(e){J.call($,e)||(H.test(e)||r("65",e),$[e]=!0)}(t),this._currentElement=e,this._tag=t.toLowerCase(),this._namespaceURI=null,this._renderedChildren=null,this._previousStyle=null,this._previousStyleCopy=null,this._hostNode=null,this._hostParent=null,this._rootNodeID=0,this._domID=0,this._hostContainerInfo=null,this._wrapperState=null,this._topLevelWrapper=null,this._flags=0}G.displayName="ReactDOMComponent",G.Mixin={mountComponent:function(e,t,n,r){this._rootNodeID=Y++,this._domID=n._idCounter++,this._hostParent=t,this._hostContainerInfo=n;var o,i,c,p=this._currentElement.props;switch(this._tag){case"audio":case"form":case"iframe":case"img":case"link":case"object":case"source":case"video":this._wrapperState={listeners:null},e.getReactMountReady().enqueue(U,this);break;case"input":v.mountWrapper(this,p,t),p=v.getHostProps(this,p),e.getReactMountReady().enqueue(F,this),e.getReactMountReady().enqueue(U,this);break;case"option":g.mountWrapper(this,p,t),p=g.getHostProps(this,p);break;case"select":y.mountWrapper(this,p,t),p=y.getHostProps(this,p),e.getReactMountReady().enqueue(U,this);break;case"textarea":b.mountWrapper(this,p,t),p=b.getHostProps(this,p),e.getReactMountReady().enqueue(F,this),e.getReactMountReady().enqueue(U,this)}if(P(this,p),null!=t?(o=t._namespaceURI,i=t._tag):n._tag&&(o=n._namespaceURI,i=n._tag),(null==o||o===u.svg&&"foreignobject"===i)&&(o=u.html),o===u.html&&("svg"===this._tag?o=u.svg:"math"===this._tag&&(o=u.mathml)),this._namespaceURI=o,e.useCreateElement){var f,h=n._ownerDocument;if(o===u.html)if("script"===this._tag){var d=h.createElement("div"),_=this._currentElement.type;d.innerHTML="<"+_+">",f=d.removeChild(d.firstChild)}else f=p.is?h.createElement(this._currentElement.type,p.is):h.createElement(this._currentElement.type);else f=h.createElementNS(o,this._currentElement.type);m.precacheNode(this,f),this._flags|=S.hasCachedChildNodes,this._hostParent||l.setAttributeForRoot(f),this._updateDOMProperties(null,p,e);var w=s(f);this._createInitialChildren(e,p,r,w),c=w}else{var x=this._createOpenTagMarkupAndPutListeners(e,p),E=this._createContentMarkup(e,p,r);c=!E&&z[this._tag]?x+"/>":x+">"+E+""}switch(this._tag){case"input":e.getReactMountReady().enqueue(R,this),p.autoFocus&&e.getReactMountReady().enqueue(a.focusDOMComponent,this);break;case"textarea":e.getReactMountReady().enqueue(D,this),p.autoFocus&&e.getReactMountReady().enqueue(a.focusDOMComponent,this);break;case"select":case"button":p.autoFocus&&e.getReactMountReady().enqueue(a.focusDOMComponent,this);break;case"option":e.getReactMountReady().enqueue(L,this)}return c},_createOpenTagMarkupAndPutListeners:function(e,t){var n="<"+this._currentElement.type;for(var r in t)if(t.hasOwnProperty(r)){var a=t[r];if(null!=a)if(k.hasOwnProperty(r))a&&N(this,r,a,e);else{r===T&&(a&&(a=this._previousStyleCopy=o({},t.style)),a=i.createMarkupForStyles(a,this));var s=null;null!=this._tag&&K(this._tag,t)?I.hasOwnProperty(r)||(s=l.createMarkupForCustomAttribute(r,a)):s=l.createMarkupForProperty(r,a),s&&(n+=" "+s)}}return e.renderToStaticMarkup?n:(this._hostParent||(n+=" "+l.createMarkupForRoot()),n+=" "+l.createMarkupForID(this._domID))},_createContentMarkup:function(e,t,n){var r="",o=t.dangerouslySetInnerHTML;if(null!=o)null!=o.__html&&(r=o.__html);else{var a=j[typeof t.children]?t.children:null,i=null!=a?null:t.children;if(null!=a)r=x(a);else if(null!=i){r=this.mountChildren(i,e,n).join("")}}return V[this._tag]&&"\n"===r.charAt(0)?"\n"+r:r},_createInitialChildren:function(e,t,n,r){var o=t.dangerouslySetInnerHTML;if(null!=o)null!=o.__html&&s.queueHTML(r,o.__html);else{var a=j[typeof t.children]?t.children:null,i=null!=a?null:t.children;if(null!=a)""!==a&&s.queueText(r,a);else if(null!=i)for(var u=this.mountChildren(i,e,n),c=0;c0;)e=e._hostParent,n--;for(;a-n>0;)t=t._hostParent,a--;for(var s=n;s--;){if(e===t)return e;e=e._hostParent,t=t._hostParent}return null}e.exports={isAncestor:function(e,t){"_hostNode"in e||r("35"),"_hostNode"in t||r("35");for(;t;){if(t===e)return!0;t=t._hostParent}return!1},getLowestCommonAncestor:o,getParentInstance:function(e){return"_hostNode"in e||r("36"),e._hostParent},traverseTwoPhase:function(e,t,n){for(var r,o=[];e;)o.push(e),e=e._hostParent;for(r=o.length;r-- >0;)t(o[r],"captured",n);for(r=0;r0;)n(c[u],"captured",a)}}},function(e,t,n){"use strict";var r=n(30),o=n(38),a=n(266),i=n(144),s=n(45),u=n(206),c=(n(25),n(275),function(e){this._currentElement=e,this._stringText=""+e,this._hostNode=null,this._hostParent=null,this._domID=0,this._mountIndex=0,this._closingComment=null,this._commentNodes=null});o(c.prototype,{mountComponent:function(e,t,n,r){var o=n._idCounter++,a=" react-text: "+o+" ",c=" /react-text ";if(this._domID=o,this._hostParent=t,e.useCreateElement){var l=n._ownerDocument,p=l.createComment(a),f=l.createComment(c),h=i(l.createDocumentFragment());return i.queueChild(h,i(p)),this._stringText&&i.queueChild(h,i(l.createTextNode(this._stringText))),i.queueChild(h,i(f)),s.precacheNode(this,p),this._closingComment=f,h}var d=u(this._stringText);return e.renderToStaticMarkup?d:"\x3c!--"+a+"--\x3e"+d+"\x3c!--"+" /react-text --\x3e"},receiveComponent:function(e,t){if(e!==this._currentElement){this._currentElement=e;var n=""+e;if(n!==this._stringText){this._stringText=n;var r=this.getHostNode();a.replaceDelimitedText(r[0],r[1],n)}}},getHostNode:function(){var e=this._commentNodes;if(e)return e;if(!this._closingComment)for(var t=s.getNodeFromInstance(this).nextSibling;;){if(null==t&&r("67",this._domID),8===t.nodeType&&" /react-text "===t.nodeValue){this._closingComment=t;break}t=t.nextSibling}return e=[this._hostNode,this._closingComment],this._commentNodes=e,e},unmountComponent:function(){this._closingComment=null,this._commentNodes=null,s.uncacheNode(this)}}),e.exports=c},function(e,t,n){"use strict";var r=n(38),o=n(79),a=n(203),i=n(78),s={initialize:i,close:function(){p.isBatchingUpdates=!1}},u=[{initialize:i,close:o.flushBatchedUpdates.bind(o)},s];function c(){this.reinitializeTransaction()}r(c.prototype,a,{getTransactionWrappers:function(){return u}});var l=new c,p={isBatchingUpdates:!1,batchedUpdates:function(e,t,n,r,o,a){var i=p.isBatchingUpdates;return p.isBatchingUpdates=!0,i?e(t,n,r,o,a):l.perform(e,null,t,n,r,o,a)}};e.exports=p},function(e,t,n){"use strict";var r=n(38),o=n(482),a=n(57),i=n(122),s=n(45),u=n(79),c=n(263),l=n(962);function p(e){for(;e._hostParent;)e=e._hostParent;var t=s.getNodeFromInstance(e).parentNode;return s.getClosestInstanceFromNode(t)}function f(e,t){this.topLevelType=e,this.nativeEvent=t,this.ancestors=[]}function h(e){var t=c(e.nativeEvent),n=s.getClosestInstanceFromNode(t),r=n;do{e.ancestors.push(r),r=r&&p(r)}while(r);for(var o=0;ot.end?(n=t.end,r=t.start):(n=t.start,r=t.end),o.moveToElementText(e),o.moveStart("character",n),o.setEndPoint("EndToStart",o),o.moveEnd("character",r-n),o.select()}:function(e,t){if(window.getSelection){var n=window.getSelection(),r=e[a()].length,i=Math.min(t.start,r),s=void 0===t.end?i:Math.min(t.end,r);if(!n.extend&&i>s){var u=s;s=i,i=u}var c=o(e,i),l=o(e,s);if(c&&l){var p=document.createRange();p.setStart(c.node,c.offset),n.removeAllRanges(),i>s?(n.addRange(p),n.extend(l.node,l.offset)):(p.setEnd(l.node,l.offset),n.addRange(p))}}}};e.exports=u},function(e,t,n){"use strict";function r(e){for(;e&&e.firstChild;)e=e.firstChild;return e}function o(e){for(;e;){if(e.nextSibling)return e.nextSibling;e=e.parentNode}}e.exports=function(e,t){for(var n=r(e),a=0,i=0;n;){if(3===n.nodeType){if(i=a+n.textContent.length,a<=t&&i>=t)return{node:n,offset:t-a};a=i}n=r(o(n))}}},function(e,t,n){"use strict";var r=n(968);e.exports=function e(t,n){return!(!t||!n)&&(t===n||!r(t)&&(r(n)?e(t,n.parentNode):"contains"in t?t.contains(n):!!t.compareDocumentPosition&&!!(16&t.compareDocumentPosition(n))))}},function(e,t,n){"use strict";var r=n(969);e.exports=function(e){return r(e)&&3==e.nodeType}},function(e,t,n){"use strict";e.exports=function(e){var t=(e?e.ownerDocument||e:document).defaultView||window;return!(!e||!("function"==typeof t.Node?e instanceof t.Node:"object"==typeof e&&"number"==typeof e.nodeType&&"string"==typeof e.nodeName))}},function(e,t,n){"use strict";var r="http://www.w3.org/1999/xlink",o="http://www.w3.org/XML/1998/namespace",a={accentHeight:"accent-height",accumulate:0,additive:0,alignmentBaseline:"alignment-baseline",allowReorder:"allowReorder",alphabetic:0,amplitude:0,arabicForm:"arabic-form",ascent:0,attributeName:"attributeName",attributeType:"attributeType",autoReverse:"autoReverse",azimuth:0,baseFrequency:"baseFrequency",baseProfile:"baseProfile",baselineShift:"baseline-shift",bbox:0,begin:0,bias:0,by:0,calcMode:"calcMode",capHeight:"cap-height",clip:0,clipPath:"clip-path",clipRule:"clip-rule",clipPathUnits:"clipPathUnits",colorInterpolation:"color-interpolation",colorInterpolationFilters:"color-interpolation-filters",colorProfile:"color-profile",colorRendering:"color-rendering",contentScriptType:"contentScriptType",contentStyleType:"contentStyleType",cursor:0,cx:0,cy:0,d:0,decelerate:0,descent:0,diffuseConstant:"diffuseConstant",direction:0,display:0,divisor:0,dominantBaseline:"dominant-baseline",dur:0,dx:0,dy:0,edgeMode:"edgeMode",elevation:0,enableBackground:"enable-background",end:0,exponent:0,externalResourcesRequired:"externalResourcesRequired",fill:0,fillOpacity:"fill-opacity",fillRule:"fill-rule",filter:0,filterRes:"filterRes",filterUnits:"filterUnits",floodColor:"flood-color",floodOpacity:"flood-opacity",focusable:0,fontFamily:"font-family",fontSize:"font-size",fontSizeAdjust:"font-size-adjust",fontStretch:"font-stretch",fontStyle:"font-style",fontVariant:"font-variant",fontWeight:"font-weight",format:0,from:0,fx:0,fy:0,g1:0,g2:0,glyphName:"glyph-name",glyphOrientationHorizontal:"glyph-orientation-horizontal",glyphOrientationVertical:"glyph-orientation-vertical",glyphRef:"glyphRef",gradientTransform:"gradientTransform",gradientUnits:"gradientUnits",hanging:0,horizAdvX:"horiz-adv-x",horizOriginX:"horiz-origin-x",ideographic:0,imageRendering:"image-rendering",in:0,in2:0,intercept:0,k:0,k1:0,k2:0,k3:0,k4:0,kernelMatrix:"kernelMatrix",kernelUnitLength:"kernelUnitLength",kerning:0,keyPoints:"keyPoints",keySplines:"keySplines",keyTimes:"keyTimes",lengthAdjust:"lengthAdjust",letterSpacing:"letter-spacing",lightingColor:"lighting-color",limitingConeAngle:"limitingConeAngle",local:0,markerEnd:"marker-end",markerMid:"marker-mid",markerStart:"marker-start",markerHeight:"markerHeight",markerUnits:"markerUnits",markerWidth:"markerWidth",mask:0,maskContentUnits:"maskContentUnits",maskUnits:"maskUnits",mathematical:0,mode:0,numOctaves:"numOctaves",offset:0,opacity:0,operator:0,order:0,orient:0,orientation:0,origin:0,overflow:0,overlinePosition:"overline-position",overlineThickness:"overline-thickness",paintOrder:"paint-order",panose1:"panose-1",pathLength:"pathLength",patternContentUnits:"patternContentUnits",patternTransform:"patternTransform",patternUnits:"patternUnits",pointerEvents:"pointer-events",points:0,pointsAtX:"pointsAtX",pointsAtY:"pointsAtY",pointsAtZ:"pointsAtZ",preserveAlpha:"preserveAlpha",preserveAspectRatio:"preserveAspectRatio",primitiveUnits:"primitiveUnits",r:0,radius:0,refX:"refX",refY:"refY",renderingIntent:"rendering-intent",repeatCount:"repeatCount",repeatDur:"repeatDur",requiredExtensions:"requiredExtensions",requiredFeatures:"requiredFeatures",restart:0,result:0,rotate:0,rx:0,ry:0,scale:0,seed:0,shapeRendering:"shape-rendering",slope:0,spacing:0,specularConstant:"specularConstant",specularExponent:"specularExponent",speed:0,spreadMethod:"spreadMethod",startOffset:"startOffset",stdDeviation:"stdDeviation",stemh:0,stemv:0,stitchTiles:"stitchTiles",stopColor:"stop-color",stopOpacity:"stop-opacity",strikethroughPosition:"strikethrough-position",strikethroughThickness:"strikethrough-thickness",string:0,stroke:0,strokeDasharray:"stroke-dasharray",strokeDashoffset:"stroke-dashoffset",strokeLinecap:"stroke-linecap",strokeLinejoin:"stroke-linejoin",strokeMiterlimit:"stroke-miterlimit",strokeOpacity:"stroke-opacity",strokeWidth:"stroke-width",surfaceScale:"surfaceScale",systemLanguage:"systemLanguage",tableValues:"tableValues",targetX:"targetX",targetY:"targetY",textAnchor:"text-anchor",textDecoration:"text-decoration",textRendering:"text-rendering",textLength:"textLength",to:0,transform:0,u1:0,u2:0,underlinePosition:"underline-position",underlineThickness:"underline-thickness",unicode:0,unicodeBidi:"unicode-bidi",unicodeRange:"unicode-range",unitsPerEm:"units-per-em",vAlphabetic:"v-alphabetic",vHanging:"v-hanging",vIdeographic:"v-ideographic",vMathematical:"v-mathematical",values:0,vectorEffect:"vector-effect",version:0,vertAdvY:"vert-adv-y",vertOriginX:"vert-origin-x",vertOriginY:"vert-origin-y",viewBox:"viewBox",viewTarget:"viewTarget",visibility:0,widths:0,wordSpacing:"word-spacing",writingMode:"writing-mode",x:0,xHeight:"x-height",x1:0,x2:0,xChannelSelector:"xChannelSelector",xlinkActuate:"xlink:actuate",xlinkArcrole:"xlink:arcrole",xlinkHref:"xlink:href",xlinkRole:"xlink:role",xlinkShow:"xlink:show",xlinkTitle:"xlink:title",xlinkType:"xlink:type",xmlBase:"xml:base",xmlns:0,xmlnsXlink:"xmlns:xlink",xmlLang:"xml:lang",xmlSpace:"xml:space",y:0,y1:0,y2:0,yChannelSelector:"yChannelSelector",z:0,zoomAndPan:"zoomAndPan"},i={Properties:{},DOMAttributeNamespaces:{xlinkActuate:r,xlinkArcrole:r,xlinkHref:r,xlinkRole:r,xlinkShow:r,xlinkTitle:r,xlinkType:r,xmlBase:o,xmlLang:o,xmlSpace:o},DOMAttributeNames:{}};Object.keys(a).forEach((function(e){i.Properties[e]=0,a[e]&&(i.DOMAttributeNames[e]=a[e])})),e.exports=i},function(e,t,n){"use strict";var r=n(166),o=n(57),a=n(45),i=n(483),s=n(90),u=n(484),c=n(469),l=n(271),p=o.canUseDOM&&"documentMode"in document&&document.documentMode<=11,f={select:{phasedRegistrationNames:{bubbled:"onSelect",captured:"onSelectCapture"},dependencies:["topBlur","topContextMenu","topFocus","topKeyDown","topKeyUp","topMouseDown","topMouseUp","topSelectionChange"]}},h=null,d=null,m=null,v=!1,g=!1;function y(e,t){if(v||null==h||h!==u())return null;var n=function(e){if("selectionStart"in e&&i.hasSelectionCapabilities(e))return{start:e.selectionStart,end:e.selectionEnd};if(window.getSelection){var t=window.getSelection();return{anchorNode:t.anchorNode,anchorOffset:t.anchorOffset,focusNode:t.focusNode,focusOffset:t.focusOffset}}if(document.selection){var n=document.selection.createRange();return{parentElement:n.parentElement(),text:n.text,top:n.boundingTop,left:n.boundingLeft}}}(h);if(!m||!l(m,n)){m=n;var o=s.getPooled(f.select,d,e,t);return o.type="select",o.target=h,r.accumulateTwoPhaseDispatches(o),o}return null}var b={eventTypes:f,extractEvents:function(e,t,n,r){if(!g)return null;var o=t?a.getNodeFromInstance(t):window;switch(e){case"topFocus":(c(o)||"true"===o.contentEditable)&&(h=o,d=t,m=null);break;case"topBlur":h=null,d=null,m=null;break;case"topMouseDown":v=!0;break;case"topContextMenu":case"topMouseUp":return v=!1,y(n,r);case"topSelectionChange":if(p)break;case"topKeyDown":case"topKeyUp":return y(n,r)}return null},didPutListener:function(e,t,n){"onSelect"===t&&(g=!0)}};e.exports=b},function(e,t,n){"use strict";var r=n(30),o=n(482),a=n(166),i=n(45),s=n(973),u=n(974),c=n(90),l=n(975),p=n(976),f=n(204),h=n(978),d=n(979),m=n(980),v=n(168),g=n(981),y=n(78),b=n(276),_=(n(25),{}),w={};["abort","animationEnd","animationIteration","animationStart","blur","canPlay","canPlayThrough","click","contextMenu","copy","cut","doubleClick","drag","dragEnd","dragEnter","dragExit","dragLeave","dragOver","dragStart","drop","durationChange","emptied","encrypted","ended","error","focus","input","invalid","keyDown","keyPress","keyUp","load","loadedData","loadedMetadata","loadStart","mouseDown","mouseMove","mouseOut","mouseOver","mouseUp","paste","pause","play","playing","progress","rateChange","reset","scroll","seeked","seeking","stalled","submit","suspend","timeUpdate","touchCancel","touchEnd","touchMove","touchStart","transitionEnd","volumeChange","waiting","wheel"].forEach((function(e){var t=e[0].toUpperCase()+e.slice(1),n="on"+t,r="top"+t,o={phasedRegistrationNames:{bubbled:n,captured:n+"Capture"},dependencies:[r]};_[e]=o,w[r]=o}));var x={};function E(e){return"."+e._rootNodeID}function S(e){return"button"===e||"input"===e||"select"===e||"textarea"===e}var C={eventTypes:_,extractEvents:function(e,t,n,o){var i,y=w[e];if(!y)return null;switch(e){case"topAbort":case"topCanPlay":case"topCanPlayThrough":case"topDurationChange":case"topEmptied":case"topEncrypted":case"topEnded":case"topError":case"topInput":case"topInvalid":case"topLoad":case"topLoadedData":case"topLoadedMetadata":case"topLoadStart":case"topPause":case"topPlay":case"topPlaying":case"topProgress":case"topRateChange":case"topReset":case"topSeeked":case"topSeeking":case"topStalled":case"topSubmit":case"topSuspend":case"topTimeUpdate":case"topVolumeChange":case"topWaiting":i=c;break;case"topKeyPress":if(0===b(n))return null;case"topKeyDown":case"topKeyUp":i=p;break;case"topBlur":case"topFocus":i=l;break;case"topClick":if(2===n.button)return null;case"topDoubleClick":case"topMouseDown":case"topMouseMove":case"topMouseUp":case"topMouseOut":case"topMouseOver":case"topContextMenu":i=f;break;case"topDrag":case"topDragEnd":case"topDragEnter":case"topDragExit":case"topDragLeave":case"topDragOver":case"topDragStart":case"topDrop":i=h;break;case"topTouchCancel":case"topTouchEnd":case"topTouchMove":case"topTouchStart":i=d;break;case"topAnimationEnd":case"topAnimationIteration":case"topAnimationStart":i=s;break;case"topTransitionEnd":i=m;break;case"topScroll":i=v;break;case"topWheel":i=g;break;case"topCopy":case"topCut":case"topPaste":i=u}i||r("86",e);var _=i.getPooled(y,t,n,o);return a.accumulateTwoPhaseDispatches(_),_},didPutListener:function(e,t,n){if("onClick"===t&&!S(e._tag)){var r=E(e),a=i.getNodeFromInstance(e);x[r]||(x[r]=o.listen(a,"click",y))}},willDeleteListener:function(e,t){if("onClick"===t&&!S(e._tag)){var n=E(e);x[n].remove(),delete x[n]}}};e.exports=C},function(e,t,n){"use strict";var r=n(90);function o(e,t,n,o){return r.call(this,e,t,n,o)}r.augmentClass(o,{animationName:null,elapsedTime:null,pseudoElement:null}),e.exports=o},function(e,t,n){"use strict";var r=n(90),o={clipboardData:function(e){return"clipboardData"in e?e.clipboardData:window.clipboardData}};function a(e,t,n,o){return r.call(this,e,t,n,o)}r.augmentClass(a,o),e.exports=a},function(e,t,n){"use strict";var r=n(168);function o(e,t,n,o){return r.call(this,e,t,n,o)}r.augmentClass(o,{relatedTarget:null}),e.exports=o},function(e,t,n){"use strict";var r=n(168),o=n(276),a={key:n(977),location:null,ctrlKey:null,shiftKey:null,altKey:null,metaKey:null,repeat:null,locale:null,getModifierState:n(265),charCode:function(e){return"keypress"===e.type?o(e):0},keyCode:function(e){return"keydown"===e.type||"keyup"===e.type?e.keyCode:0},which:function(e){return"keypress"===e.type?o(e):"keydown"===e.type||"keyup"===e.type?e.keyCode:0}};function i(e,t,n,o){return r.call(this,e,t,n,o)}r.augmentClass(i,a),e.exports=i},function(e,t,n){"use strict";var r=n(276),o={Esc:"Escape",Spacebar:" ",Left:"ArrowLeft",Up:"ArrowUp",Right:"ArrowRight",Down:"ArrowDown",Del:"Delete",Win:"OS",Menu:"ContextMenu",Apps:"ContextMenu",Scroll:"ScrollLock",MozPrintableKey:"Unidentified"},a={8:"Backspace",9:"Tab",12:"Clear",13:"Enter",16:"Shift",17:"Control",18:"Alt",19:"Pause",20:"CapsLock",27:"Escape",32:" ",33:"PageUp",34:"PageDown",35:"End",36:"Home",37:"ArrowLeft",38:"ArrowUp",39:"ArrowRight",40:"ArrowDown",45:"Insert",46:"Delete",112:"F1",113:"F2",114:"F3",115:"F4",116:"F5",117:"F6",118:"F7",119:"F8",120:"F9",121:"F10",122:"F11",123:"F12",144:"NumLock",145:"ScrollLock",224:"Meta"};e.exports=function(e){if(e.key){var t=o[e.key]||e.key;if("Unidentified"!==t)return t}if("keypress"===e.type){var n=r(e);return 13===n?"Enter":String.fromCharCode(n)}return"keydown"===e.type||"keyup"===e.type?a[e.keyCode]||"Unidentified":""}},function(e,t,n){"use strict";var r=n(204);function o(e,t,n,o){return r.call(this,e,t,n,o)}r.augmentClass(o,{dataTransfer:null}),e.exports=o},function(e,t,n){"use strict";var r=n(168),o={touches:null,targetTouches:null,changedTouches:null,altKey:null,metaKey:null,ctrlKey:null,shiftKey:null,getModifierState:n(265)};function a(e,t,n,o){return r.call(this,e,t,n,o)}r.augmentClass(a,o),e.exports=a},function(e,t,n){"use strict";var r=n(90);function o(e,t,n,o){return r.call(this,e,t,n,o)}r.augmentClass(o,{propertyName:null,elapsedTime:null,pseudoElement:null}),e.exports=o},function(e,t,n){"use strict";var r=n(204);function o(e,t,n,o){return r.call(this,e,t,n,o)}r.augmentClass(o,{deltaX:function(e){return"deltaX"in e?e.deltaX:"wheelDeltaX"in e?-e.wheelDeltaX:0},deltaY:function(e){return"deltaY"in e?e.deltaY:"wheelDeltaY"in e?-e.wheelDeltaY:"wheelDelta"in e?-e.wheelDelta:0},deltaZ:null,deltaMode:null}),e.exports=o},function(e,t,n){"use strict";n(275);e.exports=function(e,t){return{_topLevelWrapper:e,_idCounter:1,_ownerDocument:t?9===t.nodeType?t:t.ownerDocument:null,_node:t,_tag:t?t.nodeName.toLowerCase():null,_namespaceURI:t?t.namespaceURI:null}}},function(e,t,n){"use strict";e.exports={useCreateElement:!0,useFiber:!1}},function(e,t,n){"use strict";var r=n(985),o=/\/?>/,a=/^<\!\-\-/,i={CHECKSUM_ATTR_NAME:"data-react-checksum",addChecksumToMarkup:function(e){var t=r(e);return a.test(e)?e:e.replace(o," "+i.CHECKSUM_ATTR_NAME+'="'+t+'"$&')},canReuseMarkup:function(e,t){var n=t.getAttribute(i.CHECKSUM_ATTR_NAME);return n=n&&parseInt(n,10),r(e)===n}};e.exports=i},function(e,t,n){"use strict";var r=65521;e.exports=function(e){for(var t=1,n=0,o=0,a=e.length,i=-4&a;o3&&void 0!==arguments[3]?arguments[3]:{},w=Boolean(e),x=e||d,E=void 0;E="function"==typeof t?t:t?(0,s.default)(t):m;var S=n||v,C=l.pure,A=void 0===C||C,O=l.withRef,k=void 0!==O&&O,j=A&&S!==v,T=_++;return function(e){var t="Connect("+g(e)+")";var n=function(n){function a(e,r){p(this,a);var o=f(this,n.call(this,e,r));o.version=T,o.store=e.store||r.store,(0,c.default)(o.store,'Could not find "store" in either the context or props of "'+t+'". Either wrap the root component in a , or explicitly pass "store" as a prop to "'+t+'".');var i=o.store.getState();return o.state={storeState:i},o.clearCache(),o}return h(a,n),a.prototype.shouldComponentUpdate=function(){return!A||this.haveOwnPropsChanged||this.hasStoreStateChanged},a.prototype.computeStateProps=function(e,t){if(!this.finalMapStateToProps)return this.configureFinalMapState(e,t);var n=e.getState();return this.doStatePropsDependOnOwnProps?this.finalMapStateToProps(n,t):this.finalMapStateToProps(n)},a.prototype.configureFinalMapState=function(e,t){var n=x(e.getState(),t),r="function"==typeof n;return this.finalMapStateToProps=r?n:x,this.doStatePropsDependOnOwnProps=1!==this.finalMapStateToProps.length,r?this.computeStateProps(e,t):n},a.prototype.computeDispatchProps=function(e,t){if(!this.finalMapDispatchToProps)return this.configureFinalMapDispatch(e,t);var n=e.dispatch;return this.doDispatchPropsDependOnOwnProps?this.finalMapDispatchToProps(n,t):this.finalMapDispatchToProps(n)},a.prototype.configureFinalMapDispatch=function(e,t){var n=E(e.dispatch,t),r="function"==typeof n;return this.finalMapDispatchToProps=r?n:E,this.doDispatchPropsDependOnOwnProps=1!==this.finalMapDispatchToProps.length,r?this.computeDispatchProps(e,t):n},a.prototype.updateStatePropsIfNeeded=function(){var e=this.computeStateProps(this.store,this.props);return(!this.stateProps||!(0,i.default)(e,this.stateProps))&&(this.stateProps=e,!0)},a.prototype.updateDispatchPropsIfNeeded=function(){var e=this.computeDispatchProps(this.store,this.props);return(!this.dispatchProps||!(0,i.default)(e,this.dispatchProps))&&(this.dispatchProps=e,!0)},a.prototype.updateMergedPropsIfNeeded=function(){var e,t,n,r=(e=this.stateProps,t=this.dispatchProps,n=this.props,S(e,t,n));return!(this.mergedProps&&j&&(0,i.default)(r,this.mergedProps))&&(this.mergedProps=r,!0)},a.prototype.isSubscribed=function(){return"function"==typeof this.unsubscribe},a.prototype.trySubscribe=function(){w&&!this.unsubscribe&&(this.unsubscribe=this.store.subscribe(this.handleChange.bind(this)),this.handleChange())},a.prototype.tryUnsubscribe=function(){this.unsubscribe&&(this.unsubscribe(),this.unsubscribe=null)},a.prototype.componentDidMount=function(){this.trySubscribe()},a.prototype.componentWillReceiveProps=function(e){A&&(0,i.default)(e,this.props)||(this.haveOwnPropsChanged=!0)},a.prototype.componentWillUnmount=function(){this.tryUnsubscribe(),this.clearCache()},a.prototype.clearCache=function(){this.dispatchProps=null,this.stateProps=null,this.mergedProps=null,this.haveOwnPropsChanged=!0,this.hasStoreStateChanged=!0,this.haveStatePropsBeenPrecalculated=!1,this.statePropsPrecalculationError=null,this.renderedElement=null,this.finalMapDispatchToProps=null,this.finalMapStateToProps=null},a.prototype.handleChange=function(){if(this.unsubscribe){var e=this.store.getState(),t=this.state.storeState;if(!A||t!==e){if(A&&!this.doStatePropsDependOnOwnProps){var n=b(this.updateStatePropsIfNeeded,this);if(!n)return;n===y&&(this.statePropsPrecalculationError=y.value),this.haveStatePropsBeenPrecalculated=!0}this.hasStoreStateChanged=!0,this.setState({storeState:e})}}},a.prototype.getWrappedInstance=function(){return(0,c.default)(k,"To access the wrapped instance, you need to specify { withRef: true } as the fourth argument of the connect() call."),this.refs.wrappedInstance},a.prototype.render=function(){var t=this.haveOwnPropsChanged,n=this.hasStoreStateChanged,a=this.haveStatePropsBeenPrecalculated,i=this.statePropsPrecalculationError,s=this.renderedElement;if(this.haveOwnPropsChanged=!1,this.hasStoreStateChanged=!1,this.haveStatePropsBeenPrecalculated=!1,this.statePropsPrecalculationError=null,i)throw i;var u=!0,c=!0;A&&s&&(u=n||t&&this.doStatePropsDependOnOwnProps,c=t&&this.doDispatchPropsDependOnOwnProps);var l=!1,p=!1;a?l=!0:u&&(l=this.updateStatePropsIfNeeded()),c&&(p=this.updateDispatchPropsIfNeeded());return!(!!(l||p||t)&&this.updateMergedPropsIfNeeded())&&s?s:(this.renderedElement=k?(0,o.createElement)(e,r({},this.mergedProps,{ref:"wrappedInstance"})):(0,o.createElement)(e,this.mergedProps),this.renderedElement)},a}(o.Component);return n.displayName=t,n.WrappedComponent=e,n.contextTypes={store:a.default},n.propTypes={store:a.default},(0,u.default)(n,e)}};var o=n(0),a=l(n(487)),i=l(n(992)),s=l(n(993)),u=(l(n(488)),l(n(145)),l(n(994))),c=l(n(995));function l(e){return e&&e.__esModule?e:{default:e}}function p(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function f(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function h(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}var d=function(e){return{}},m=function(e){return{dispatch:e}},v=function(e,t,n){return r({},n,e,t)};function g(e){return e.displayName||e.name||"Component"}var y={value:null};function b(e,t){try{return e.apply(t)}catch(e){return y.value=e,y}}var _=0},function(e,t,n){"use strict";t.__esModule=!0,t.default=function(e,t){if(e===t)return!0;var n=Object.keys(e),r=Object.keys(t);if(n.length!==r.length)return!1;for(var o=Object.prototype.hasOwnProperty,a=0;a0&&a(l)?n>1?e(l,n-1,a,i,s):r(s,l):i||(s[s.length]=l)}return s}},function(e,t,n){var r=n(135),o=n(194),a=n(56),i=r?r.isConcatSpreadable:void 0;e.exports=function(e){return a(e)||o(e)||!!(i&&e&&e[i])}},function(e,t,n){var r=n(1026),o=Math.max;e.exports=function(e,t,n){return t=o(void 0===t?e.length-1:t,0),function(){for(var a=arguments,i=-1,s=o(a.length-t,0),u=Array(s);++i0){if(++t>=800)return arguments[0]}else t=0;return e.apply(void 0,arguments)}}},function(e,t,n){var r=n(1032);e.exports=r},function(e,t,n){var r=n(1033),o=String.prototype;e.exports=function(e){var t=e.repeat;return"string"==typeof e||e===o||e instanceof String&&t===o.repeat?r:t}},function(e,t,n){n(1034);var r=n(42);e.exports=r("String").repeat},function(e,t,n){n(22)({target:"String",proto:!0},{repeat:n(1035)})},function(e,t,n){"use strict";var r=n(128),o=n(108);e.exports=function(e){var t=String(o(this)),n="",a=r(e);if(a<0||a==1/0)throw RangeError("Wrong number of repetitions");for(;a>0;(a>>>=1)&&(t+=t))1&a&&(n+=t);return n}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.CopyToClipboard=void 0;var r=a(n(0)),o=a(n(1037));function a(e){return e&&e.__esModule?e:{default:e}}function i(e){return(i="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function s(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function u(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},a=Object.keys(e);for(r=0;r=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}function c(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function l(e,t){for(var n=0;n/g,">").replace(/"/g,""").replace(/'/g,"'")}function s(e,...t){const n=Object.create(null);for(const t in e)n[t]=e[t];return t.forEach((function(e){for(const t in e)n[t]=e[t]})),n}function u(e){return e.nodeName.toLowerCase()}var c=Object.freeze({__proto__:null,escapeHTML:i,inherit:s,nodeStream:function(e){const t=[];return function e(n,r){for(let o=n.firstChild;o;o=o.nextSibling)3===o.nodeType?r+=o.nodeValue.length:1===o.nodeType&&(t.push({event:"start",offset:r,node:o}),r=e(o,r),u(o).match(/br|hr|img|input/)||t.push({event:"stop",offset:r,node:o}));return r}(e,0),t},mergeStreams:function(e,t,n){let r=0,o="";const a=[];function s(){return e.length&&t.length?e[0].offset!==t[0].offset?e[0].offset"}function l(e){o+=""}function p(e){("start"===e.event?c:l)(e.node)}for(;e.length||t.length;){let t=s();if(o+=i(n.substring(r,t[0].offset)),r=t[0].offset,t===e){a.reverse().forEach(l);do{p(t.splice(0,1)[0]),t=s()}while(t===e&&t.length&&t[0].offset===r);a.reverse().forEach(c)}else"start"===t[0].event?a.push(t[0].node):a.pop(),p(t.splice(0,1)[0])}return o+i(n.substr(r))}});const l=e=>!!e.kind;class p{constructor(e,t){this.buffer="",this.classPrefix=t.classPrefix,e.walk(this)}addText(e){this.buffer+=i(e)}openNode(e){if(!l(e))return;let t=e.kind;e.sublanguage||(t=`${this.classPrefix}${t}`),this.span(t)}closeNode(e){l(e)&&(this.buffer+="")}value(){return this.buffer}span(e){this.buffer+=``}}class f{constructor(){this.rootNode={children:[]},this.stack=[this.rootNode]}get top(){return this.stack[this.stack.length-1]}get root(){return this.rootNode}add(e){this.top.children.push(e)}openNode(e){const t={kind:e,children:[]};this.add(t),this.stack.push(t)}closeNode(){if(this.stack.length>1)return this.stack.pop()}closeAllNodes(){for(;this.closeNode(););}toJSON(){return JSON.stringify(this.rootNode,null,4)}walk(e){return this.constructor._walk(e,this.rootNode)}static _walk(e,t){return"string"==typeof t?e.addText(t):t.children&&(e.openNode(t),t.children.forEach((t=>this._walk(e,t))),e.closeNode(t)),e}static _collapse(e){"string"!=typeof e&&e.children&&(e.children.every((e=>"string"==typeof e))?e.children=[e.children.join("")]:e.children.forEach((e=>{f._collapse(e)})))}}class h extends f{constructor(e){super(),this.options=e}addKeyword(e,t){""!==e&&(this.openNode(t),this.addText(e),this.closeNode())}addText(e){""!==e&&this.add(e)}addSublanguage(e,t){const n=e.root;n.kind=t,n.sublanguage=!0,this.add(n)}toHTML(){return new p(this,this.options).value()}finalize(){return!0}}function d(e){return e?"string"==typeof e?e:e.source:null}const m="[a-zA-Z]\\w*",v="[a-zA-Z_]\\w*",g="\\b\\d+(\\.\\d+)?",y="(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)",b="\\b(0b[01]+)",_={begin:"\\\\[\\s\\S]",relevance:0},w={className:"string",begin:"'",end:"'",illegal:"\\n",contains:[_]},x={className:"string",begin:'"',end:'"',illegal:"\\n",contains:[_]},E={begin:/\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\b/},S=function(e,t,n={}){const r=s({className:"comment",begin:e,end:t,contains:[]},n);return r.contains.push(E),r.contains.push({className:"doctag",begin:"(?:TODO|FIXME|NOTE|BUG|OPTIMIZE|HACK|XXX):",relevance:0}),r},C=S("//","$"),A=S("/\\*","\\*/"),O=S("#","$"),k={className:"number",begin:g,relevance:0},j={className:"number",begin:y,relevance:0},T={className:"number",begin:b,relevance:0},I={className:"number",begin:g+"(%|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc|px|deg|grad|rad|turn|s|ms|Hz|kHz|dpi|dpcm|dppx)?",relevance:0},P={begin:/(?=\/[^/\n]*\/)/,contains:[{className:"regexp",begin:/\//,end:/\/[gimuy]*/,illegal:/\n/,contains:[_,{begin:/\[/,end:/\]/,relevance:0,contains:[_]}]}]},N={className:"title",begin:m,relevance:0},M={className:"title",begin:v,relevance:0},R={begin:"\\.\\s*[a-zA-Z_]\\w*",relevance:0};var D=Object.freeze({__proto__:null,IDENT_RE:m,UNDERSCORE_IDENT_RE:v,NUMBER_RE:g,C_NUMBER_RE:y,BINARY_NUMBER_RE:b,RE_STARTERS_RE:"!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~",SHEBANG:(e={})=>{const t=/^#![ ]*\//;return e.binary&&(e.begin=function(...e){return e.map((e=>d(e))).join("")}(t,/.*\b/,e.binary,/\b.*/)),s({className:"meta",begin:t,end:/$/,relevance:0,"on:begin":(e,t)=>{0!==e.index&&t.ignoreMatch()}},e)},BACKSLASH_ESCAPE:_,APOS_STRING_MODE:w,QUOTE_STRING_MODE:x,PHRASAL_WORDS_MODE:E,COMMENT:S,C_LINE_COMMENT_MODE:C,C_BLOCK_COMMENT_MODE:A,HASH_COMMENT_MODE:O,NUMBER_MODE:k,C_NUMBER_MODE:j,BINARY_NUMBER_MODE:T,CSS_NUMBER_MODE:I,REGEXP_MODE:P,TITLE_MODE:N,UNDERSCORE_TITLE_MODE:M,METHOD_GUARD:R,END_SAME_AS_BEGIN:function(e){return Object.assign(e,{"on:begin":(e,t)=>{t.data._beginMatch=e[1]},"on:end":(e,t)=>{t.data._beginMatch!==e[1]&&t.ignoreMatch()}})}});const L=["of","and","for","in","not","or","if","then","parent","list","value"];function B(e){function t(t,n){return new RegExp(d(t),"m"+(e.case_insensitive?"i":"")+(n?"g":""))}class n{constructor(){this.matchIndexes={},this.regexes=[],this.matchAt=1,this.position=0}addRule(e,t){t.position=this.position++,this.matchIndexes[this.matchAt]=t,this.regexes.push([t,e]),this.matchAt+=function(e){return new RegExp(e.toString()+"|").exec("").length-1}(e)+1}compile(){0===this.regexes.length&&(this.exec=()=>null);const e=this.regexes.map((e=>e[1]));this.matcherRe=t(function(e,t="|"){const n=/\[(?:[^\\\]]|\\.)*\]|\(\??|\\([1-9][0-9]*)|\\./;let r=0,o="";for(let a=0;a0&&(o+=t),o+="(";s.length>0;){const e=n.exec(s);if(null==e){o+=s;break}o+=s.substring(0,e.index),s=s.substring(e.index+e[0].length),"\\"===e[0][0]&&e[1]?o+="\\"+String(Number(e[1])+i):(o+=e[0],"("===e[0]&&r++)}o+=")"}return o}(e),!0),this.lastIndex=0}exec(e){this.matcherRe.lastIndex=this.lastIndex;const t=this.matcherRe.exec(e);if(!t)return null;const n=t.findIndex(((e,t)=>t>0&&void 0!==e)),r=this.matchIndexes[n];return t.splice(0,n),Object.assign(t,r)}}class r{constructor(){this.rules=[],this.multiRegexes=[],this.count=0,this.lastIndex=0,this.regexIndex=0}getMatcher(e){if(this.multiRegexes[e])return this.multiRegexes[e];const t=new n;return this.rules.slice(e).forEach((([e,n])=>t.addRule(e,n))),t.compile(),this.multiRegexes[e]=t,t}resumingScanAtSamePosition(){return 0!==this.regexIndex}considerAll(){this.regexIndex=0}addRule(e,t){this.rules.push([e,t]),"begin"===t.type&&this.count++}exec(e){const t=this.getMatcher(this.regexIndex);t.lastIndex=this.lastIndex;let n=t.exec(e);if(this.resumingScanAtSamePosition())if(n&&n.index===this.lastIndex);else{const t=this.getMatcher(0);t.lastIndex=this.lastIndex+1,n=t.exec(e)}return n&&(this.regexIndex+=n.position+1,this.regexIndex===this.count&&this.considerAll()),n}}function o(e,t){"."===e.input[e.index-1]&&t.ignoreMatch()}if(e.contains&&e.contains.includes("self"))throw new Error("ERR: contains `self` is not supported at the top-level of a language. See documentation.");return e.classNameAliases=s(e.classNameAliases||{}),function n(a,i){const u=a;if(a.compiled)return u;a.compiled=!0,a.__beforeBegin=null,a.keywords=a.keywords||a.beginKeywords;let c=null;if("object"==typeof a.keywords&&(c=a.keywords.$pattern,delete a.keywords.$pattern),a.keywords&&(a.keywords=function(e,t){const n={};"string"==typeof e?r("keyword",e):Object.keys(e).forEach((function(t){r(t,e[t])}));return n;function r(e,r){t&&(r=r.toLowerCase()),r.split(" ").forEach((function(t){const r=t.split("|");n[r[0]]=[e,U(r[0],r[1])]}))}}(a.keywords,e.case_insensitive)),a.lexemes&&c)throw new Error("ERR: Prefer `keywords.$pattern` to `mode.lexemes`, BOTH are not allowed. (see mode reference) ");return u.keywordPatternRe=t(a.lexemes||c||/\w+/,!0),i&&(a.beginKeywords&&(a.begin="\\b("+a.beginKeywords.split(" ").join("|")+")(?!\\.)(?=\\b|\\s)",a.__beforeBegin=o),a.begin||(a.begin=/\B|\b/),u.beginRe=t(a.begin),a.endSameAsBegin&&(a.end=a.begin),a.end||a.endsWithParent||(a.end=/\B|\b/),a.end&&(u.endRe=t(a.end)),u.terminator_end=d(a.end)||"",a.endsWithParent&&i.terminator_end&&(u.terminator_end+=(a.end?"|":"")+i.terminator_end)),a.illegal&&(u.illegalRe=t(a.illegal)),void 0===a.relevance&&(a.relevance=1),a.contains||(a.contains=[]),a.contains=[].concat(...a.contains.map((function(e){return function(e){e.variants&&!e.cached_variants&&(e.cached_variants=e.variants.map((function(t){return s(e,{variants:null},t)})));if(e.cached_variants)return e.cached_variants;if(F(e))return s(e,{starts:e.starts?s(e.starts):null});if(Object.isFrozen(e))return s(e);return e}("self"===e?a:e)}))),a.contains.forEach((function(e){n(e,u)})),a.starts&&n(a.starts,i),u.matcher=function(e){const t=new r;return e.contains.forEach((e=>t.addRule(e.begin,{rule:e,type:"begin"}))),e.terminator_end&&t.addRule(e.terminator_end,{type:"end"}),e.illegal&&t.addRule(e.illegal,{type:"illegal"}),t}(u),u}(e)}function F(e){return!!e&&(e.endsWithParent||F(e.starts))}function U(e,t){return t?Number(t):function(e){return L.includes(e.toLowerCase())}(e)?0:1}function q(e){const t={props:["language","code","autodetect"],data:function(){return{detectedLanguage:"",unknownLanguage:!1}},computed:{className(){return this.unknownLanguage?"":"hljs "+this.detectedLanguage},highlighted(){if(!this.autoDetect&&!e.getLanguage(this.language))return console.warn(`The language "${this.language}" you specified could not be found.`),this.unknownLanguage=!0,i(this.code);let t;return this.autoDetect?(t=e.highlightAuto(this.code),this.detectedLanguage=t.language):(t=e.highlight(this.language,this.code,this.ignoreIllegals),this.detectedLanguage=this.language),t.value},autoDetect(){return!this.language||(e=this.autodetect,Boolean(e||""===e));var e},ignoreIllegals:()=>!0},render(e){return e("pre",{},[e("code",{class:this.className,domProps:{innerHTML:this.highlighted}})])}};return{Component:t,VuePlugin:{install(e){e.component("highlightjs",t)}}}}const z=i,V=s,{nodeStream:W,mergeStreams:H}=c,$=Symbol("nomatch");var J=function(e){const t=[],n=Object.create(null),o=Object.create(null),i=[];let s=!0;const u=/(^(<[^>]+>|\t|)+|\n)/gm,c="Could not find the language '{}', did you forget to load/include a language module?",l={disableAutodetect:!0,name:"Plain text",contains:[]};let p={noHighlightRe:/^(no-?highlight)$/i,languageDetectRe:/\blang(?:uage)?-([\w-]+)\b/i,classPrefix:"hljs-",tabReplace:null,useBR:!1,languages:null,__emitter:h};function f(e){return p.noHighlightRe.test(e)}function d(e,t,n,r){const o={code:t,language:e};E("before:highlight",o);const a=o.result?o.result:m(o.language,o.code,n,r);return a.code=o.code,E("after:highlight",a),a}function m(e,t,r,o){const i=t;function u(e,t){const n=x.case_insensitive?t[0].toLowerCase():t[0];return Object.prototype.hasOwnProperty.call(e.keywords,n)&&e.keywords[n]}function l(){null!=C.subLanguage?function(){if(""===k)return;let e=null;if("string"==typeof C.subLanguage){if(!n[C.subLanguage])return void O.addText(k);e=m(C.subLanguage,k,!0,A[C.subLanguage]),A[C.subLanguage]=e.top}else e=v(k,C.subLanguage.length?C.subLanguage:null);C.relevance>0&&(j+=e.relevance),O.addSublanguage(e.emitter,e.language)}():function(){if(!C.keywords)return void O.addText(k);let e=0;C.keywordPatternRe.lastIndex=0;let t=C.keywordPatternRe.exec(k),n="";for(;t;){n+=k.substring(e,t.index);const r=u(C,t);if(r){const[e,o]=r;O.addText(n),n="",j+=o;const a=x.classNameAliases[e]||e;O.addKeyword(t[0],a)}else n+=t[0];e=C.keywordPatternRe.lastIndex,t=C.keywordPatternRe.exec(k)}n+=k.substr(e),O.addText(n)}(),k=""}function f(e){return e.className&&O.openNode(x.classNameAliases[e.className]||e.className),C=Object.create(e,{parent:{value:C}}),C}function h(e,t,n){let r=function(e,t){const n=e&&e.exec(t);return n&&0===n.index}(e.endRe,n);if(r){if(e["on:end"]){const n=new a(e);e["on:end"](t,n),n.ignore&&(r=!1)}if(r){for(;e.endsParent&&e.parent;)e=e.parent;return e}}if(e.endsWithParent)return h(e.parent,t,n)}function d(e){return 0===C.matcher.regexIndex?(k+=e[0],1):(P=!0,0)}function g(e){const t=e[0],n=e.rule,r=new a(n),o=[n.__beforeBegin,n["on:begin"]];for(const n of o)if(n&&(n(e,r),r.ignore))return d(t);return n&&n.endSameAsBegin&&(n.endRe=new RegExp(t.replace(/[-/\\^$*+?.()|[\]{}]/g,"\\$&"),"m")),n.skip?k+=t:(n.excludeBegin&&(k+=t),l(),n.returnBegin||n.excludeBegin||(k=t)),f(n),n.returnBegin?0:t.length}function y(e){const t=e[0],n=i.substr(e.index),r=h(C,e,n);if(!r)return $;const o=C;o.skip?k+=t:(o.returnEnd||o.excludeEnd||(k+=t),l(),o.excludeEnd&&(k=t));do{C.className&&O.closeNode(),C.skip||C.subLanguage||(j+=C.relevance),C=C.parent}while(C!==r.parent);return r.starts&&(r.endSameAsBegin&&(r.starts.endRe=r.endRe),f(r.starts)),o.returnEnd?0:t.length}let b={};function w(t,n){const o=n&&n[0];if(k+=t,null==o)return l(),0;if("begin"===b.type&&"end"===n.type&&b.index===n.index&&""===o){if(k+=i.slice(n.index,n.index+1),!s){const t=new Error("0 width match regex");throw t.languageName=e,t.badRule=b.rule,t}return 1}if(b=n,"begin"===n.type)return g(n);if("illegal"===n.type&&!r){const e=new Error('Illegal lexeme "'+o+'" for mode "'+(C.className||"")+'"');throw e.mode=C,e}if("end"===n.type){const e=y(n);if(e!==$)return e}if("illegal"===n.type&&""===o)return 1;if(I>1e5&&I>3*n.index){throw new Error("potential infinite loop, way more iterations than matches")}return k+=o,o.length}const x=_(e);if(!x)throw console.error(c.replace("{}",e)),new Error('Unknown language: "'+e+'"');const E=B(x);let S="",C=o||E;const A={},O=new p.__emitter(p);!function(){const e=[];for(let t=C;t!==x;t=t.parent)t.className&&e.unshift(t.className);e.forEach((e=>O.openNode(e)))}();let k="",j=0,T=0,I=0,P=!1;try{for(C.matcher.considerAll();;){I++,P?P=!1:C.matcher.considerAll(),C.matcher.lastIndex=T;const e=C.matcher.exec(i);if(!e)break;const t=w(i.substring(T,e.index),e);T=e.index+t}return w(i.substr(T)),O.closeAllNodes(),O.finalize(),S=O.toHTML(),{relevance:j,value:S,language:e,illegal:!1,emitter:O,top:C}}catch(t){if(t.message&&t.message.includes("Illegal"))return{illegal:!0,illegalBy:{msg:t.message,context:i.slice(T-100,T+100),mode:t.mode},sofar:S,relevance:0,value:z(i),emitter:O};if(s)return{illegal:!1,relevance:0,value:z(i),emitter:O,language:e,top:C,errorRaised:t};throw t}}function v(e,t){t=t||p.languages||Object.keys(n);const r=function(e){const t={relevance:0,emitter:new p.__emitter(p),value:z(e),illegal:!1,top:l};return t.emitter.addText(e),t}(e),o=t.filter(_).filter(x).map((t=>m(t,e,!1)));o.unshift(r);const a=o.sort(((e,t)=>{if(e.relevance!==t.relevance)return t.relevance-e.relevance;if(e.language&&t.language){if(_(e.language).supersetOf===t.language)return 1;if(_(t.language).supersetOf===e.language)return-1}return 0})),[i,s]=a,u=i;return u.second_best=s,u}function g(e){return p.tabReplace||p.useBR?e.replace(u,(e=>"\n"===e?p.useBR?"
":e:p.tabReplace?e.replace(/\t/g,p.tabReplace):e)):e}function y(e){let t=null;const n=function(e){let t=e.className+" ";t+=e.parentNode?e.parentNode.className:"";const n=p.languageDetectRe.exec(t);if(n){const t=_(n[1]);return t||(console.warn(c.replace("{}",n[1])),console.warn("Falling back to no-highlight mode for this block.",e)),t?n[1]:"no-highlight"}return t.split(/\s+/).find((e=>f(e)||_(e)))}(e);if(f(n))return;E("before:highlightBlock",{block:e,language:n}),p.useBR?(t=document.createElement("div"),t.innerHTML=e.innerHTML.replace(/\n/g,"").replace(//g,"\n")):t=e;const r=t.textContent,a=n?d(n,r,!0):v(r),i=W(t);if(i.length){const e=document.createElement("div");e.innerHTML=a.value,a.value=H(i,W(e),r)}a.value=g(a.value),E("after:highlightBlock",{block:e,result:a}),e.innerHTML=a.value,e.className=function(e,t,n){const r=t?o[t]:n,a=[e.trim()];return e.match(/\bhljs\b/)||a.push("hljs"),e.includes(r)||a.push(r),a.join(" ").trim()}(e.className,n,a.language),e.result={language:a.language,re:a.relevance,relavance:a.relevance},a.second_best&&(e.second_best={language:a.second_best.language,re:a.second_best.relevance,relavance:a.second_best.relevance})}const b=()=>{if(b.called)return;b.called=!0;const e=document.querySelectorAll("pre code");t.forEach.call(e,y)};function _(e){return e=(e||"").toLowerCase(),n[e]||n[o[e]]}function w(e,{languageName:t}){"string"==typeof e&&(e=[e]),e.forEach((e=>{o[e]=t}))}function x(e){const t=_(e);return t&&!t.disableAutodetect}function E(e,t){const n=e;i.forEach((function(e){e[n]&&e[n](t)}))}Object.assign(e,{highlight:d,highlightAuto:v,fixMarkup:function(e){return console.warn("fixMarkup is deprecated and will be removed entirely in v11.0"),console.warn("Please see https://github.com/highlightjs/highlight.js/issues/2534"),g(e)},highlightBlock:y,configure:function(e){e.useBR&&(console.warn("'useBR' option is deprecated and will be removed entirely in v11.0"),console.warn("Please see https://github.com/highlightjs/highlight.js/issues/2559")),p=V(p,e)},initHighlighting:b,initHighlightingOnLoad:function(){window.addEventListener("DOMContentLoaded",b,!1)},registerLanguage:function(t,r){let o=null;try{o=r(e)}catch(e){if(console.error("Language definition for '{}' could not be registered.".replace("{}",t)),!s)throw e;console.error(e),o=l}o.name||(o.name=t),n[t]=o,o.rawDefinition=r.bind(null,e),o.aliases&&w(o.aliases,{languageName:t})},listLanguages:function(){return Object.keys(n)},getLanguage:_,registerAliases:w,requireLanguage:function(e){console.warn("requireLanguage is deprecated and will be removed entirely in the future."),console.warn("Please see https://github.com/highlightjs/highlight.js/pull/2844");const t=_(e);if(t)return t;throw new Error("The '{}' language is required, but not loaded.".replace("{}",e))},autoDetection:x,inherit:V,addPlugin:function(e){i.push(e)},vuePlugin:q(e).VuePlugin}),e.debugMode=function(){s=!1},e.safeMode=function(){s=!0},e.versionString="10.4.1";for(const e in D)"object"==typeof D[e]&&r(D[e]);return Object.assign(e,D),e}({});e.exports=J},function(e,t,n){"use strict";var r=n(1041),o=a(Error);function a(e){return t.displayName=e.displayName||e.name,t;function t(t){return t&&(t=r.apply(null,arguments)),new e(t)}}e.exports=o,o.eval=a(EvalError),o.range=a(RangeError),o.reference=a(ReferenceError),o.syntax=a(SyntaxError),o.type=a(TypeError),o.uri=a(URIError),o.create=a},function(e,t,n){!function(){var t;function n(e){for(var t,n,r,o,a=1,i=[].slice.call(arguments),s=0,u=e.length,c="",l=!1,p=!1,f=function(){return i[a++]},h=function(){for(var n="";/\d/.test(e[s]);)n+=e[s++],t=e[s];return n.length>0?parseInt(n):null};s=0||(o[n]=e[n]);return o}},function(e,t,n){var r=n(492);e.exports=function(e){if(Array.isArray(e))return r(e)}},function(e,t){e.exports=function(e){if("undefined"!=typeof Symbol&&Symbol.iterator in Object(e))return Array.from(e)}},function(e,t,n){var r=n(492);e.exports=function(e,t){if(e){if("string"==typeof e)return r(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);return"Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?r(e,t):void 0}}},function(e,t){e.exports=function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}},function(e,t){e.exports=function(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}},function(e,t,n){var r=n(393);e.exports=r},function(e,t,n){var r=n(1050);e.exports=r},function(e,t,n){n(1051);var r=n(33);e.exports=r.Object.entries},function(e,t,n){var r=n(22),o=n(457).entries;r({target:"Object",stat:!0},{entries:function(e){return o(e)}})},function(e,t,n){"use strict";var r=n(1053),o=n(494),a=n(282),i=Object.prototype.hasOwnProperty,s={brackets:function(e){return e+"[]"},comma:"comma",indices:function(e,t){return e+"["+t+"]"},repeat:function(e){return e}},u=Array.isArray,c=Array.prototype.push,l=function(e,t){c.apply(e,u(t)?t:[t])},p=Date.prototype.toISOString,f=a.default,h={addQueryPrefix:!1,allowDots:!1,charset:"utf-8",charsetSentinel:!1,delimiter:"&",encode:!0,encoder:o.encode,encodeValuesOnly:!1,format:f,formatter:a.formatters[f],indices:!1,serializeDate:function(e){return p.call(e)},skipNulls:!1,strictNullHandling:!1},d=function e(t,n,a,i,s,c,p,f,d,m,v,g,y,b,_){var w,x=t;if(_.has(t))throw new RangeError("Cyclic object value");if("function"==typeof p?x=p(n,x):x instanceof Date?x=m(x):"comma"===a&&u(x)&&(x=o.maybeMap(x,(function(e){return e instanceof Date?m(e):e}))),null===x){if(i)return c&&!y?c(n,h.encoder,b,"key",v):n;x=""}if("string"==typeof(w=x)||"number"==typeof w||"boolean"==typeof w||"symbol"==typeof w||"bigint"==typeof w||o.isBuffer(x))return c?[g(y?n:c(n,h.encoder,b,"key",v))+"="+g(c(x,h.encoder,b,"value",v))]:[g(n)+"="+g(String(x))];var E,S=[];if(void 0===x)return S;if("comma"===a&&u(x))E=[{value:x.length>0?x.join(",")||null:void 0}];else if(u(p))E=p;else{var C=Object.keys(x);E=f?C.sort(f):C}for(var A=0;A0?_+b:""}},function(e,t,n){"use strict";var r=n(280),o=n(1058),a=n(1060),i=r("%TypeError%"),s=r("%WeakMap%",!0),u=r("%Map%",!0),c=o("WeakMap.prototype.get",!0),l=o("WeakMap.prototype.set",!0),p=o("WeakMap.prototype.has",!0),f=o("Map.prototype.get",!0),h=o("Map.prototype.set",!0),d=o("Map.prototype.has",!0),m=function(e,t){for(var n,r=e;null!==(n=r.next);r=n)if(n.key===t)return r.next=n.next,n.next=e.next,e.next=n,n};e.exports=function(){var e,t,n,r={assert:function(e){if(!r.has(e))throw new i("Side channel does not contain "+a(e))},get:function(r){if(s&&r&&("object"==typeof r||"function"==typeof r)){if(e)return c(e,r)}else if(u){if(t)return f(t,r)}else if(n)return function(e,t){var n=m(e,t);return n&&n.value}(n,r)},has:function(r){if(s&&r&&("object"==typeof r||"function"==typeof r)){if(e)return p(e,r)}else if(u){if(t)return d(t,r)}else if(n)return function(e,t){return!!m(e,t)}(n,r);return!1},set:function(r,o){s&&r&&("object"==typeof r||"function"==typeof r)?(e||(e=new s),l(e,r,o)):u?(t||(t=new u),h(t,r,o)):(n||(n={key:{},next:null}),function(e,t,n){var r=m(e,t);r?r.value=n:e.next={key:t,next:e.next,value:n}}(n,r,o))}};return r}},function(e,t,n){"use strict";var r="undefined"!=typeof Symbol&&Symbol,o=n(1055);e.exports=function(){return"function"==typeof r&&("function"==typeof Symbol&&("symbol"==typeof r("foo")&&("symbol"==typeof Symbol("bar")&&o())))}},function(e,t,n){"use strict";e.exports=function(){if("function"!=typeof Symbol||"function"!=typeof Object.getOwnPropertySymbols)return!1;if("symbol"==typeof Symbol.iterator)return!0;var e={},t=Symbol("test"),n=Object(t);if("string"==typeof t)return!1;if("[object Symbol]"!==Object.prototype.toString.call(t))return!1;if("[object Symbol]"!==Object.prototype.toString.call(n))return!1;for(t in e[t]=42,e)return!1;if("function"==typeof Object.keys&&0!==Object.keys(e).length)return!1;if("function"==typeof Object.getOwnPropertyNames&&0!==Object.getOwnPropertyNames(e).length)return!1;var r=Object.getOwnPropertySymbols(e);if(1!==r.length||r[0]!==t)return!1;if(!Object.prototype.propertyIsEnumerable.call(e,t))return!1;if("function"==typeof Object.getOwnPropertyDescriptor){var o=Object.getOwnPropertyDescriptor(e,t);if(42!==o.value||!0!==o.enumerable)return!1}return!0}},function(e,t,n){"use strict";var r="Function.prototype.bind called on incompatible ",o=Array.prototype.slice,a=Object.prototype.toString,i="[object Function]";e.exports=function(e){var t=this;if("function"!=typeof t||a.call(t)!==i)throw new TypeError(r+t);for(var n,s=o.call(arguments,1),u=function(){if(this instanceof n){var r=t.apply(this,s.concat(o.call(arguments)));return Object(r)===r?r:this}return t.apply(e,s.concat(o.call(arguments)))},c=Math.max(0,t.length-s.length),l=[],p=0;p-1?o(n):n}},function(e,t,n){"use strict";var r=n(281),o=n(280),a=o("%Function.prototype.apply%"),i=o("%Function.prototype.call%"),s=o("%Reflect.apply%",!0)||r.call(i,a),u=o("%Object.getOwnPropertyDescriptor%",!0),c=o("%Object.defineProperty%",!0),l=o("%Math.max%");if(c)try{c({},"a",{value:1})}catch(e){c=null}e.exports=function(e){var t=s(r,i,arguments);if(u&&c){var n=u(t,"length");n.configurable&&c(t,"length",{value:1+l(0,e.length-(arguments.length-1))})}return t};var p=function(){return s(r,a,arguments)};c?c(e.exports,"apply",{value:p}):e.exports.apply=p},function(e,t,n){var r="function"==typeof Map&&Map.prototype,o=Object.getOwnPropertyDescriptor&&r?Object.getOwnPropertyDescriptor(Map.prototype,"size"):null,a=r&&o&&"function"==typeof o.get?o.get:null,i=r&&Map.prototype.forEach,s="function"==typeof Set&&Set.prototype,u=Object.getOwnPropertyDescriptor&&s?Object.getOwnPropertyDescriptor(Set.prototype,"size"):null,c=s&&u&&"function"==typeof u.get?u.get:null,l=s&&Set.prototype.forEach,p="function"==typeof WeakMap&&WeakMap.prototype?WeakMap.prototype.has:null,f="function"==typeof WeakSet&&WeakSet.prototype?WeakSet.prototype.has:null,h="function"==typeof WeakRef&&WeakRef.prototype?WeakRef.prototype.deref:null,d=Boolean.prototype.valueOf,m=Object.prototype.toString,v=Function.prototype.toString,g=String.prototype.match,y="function"==typeof BigInt?BigInt.prototype.valueOf:null,b=Object.getOwnPropertySymbols,_="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?Symbol.prototype.toString:null,w="function"==typeof Symbol&&"object"==typeof Symbol.iterator,x=Object.prototype.propertyIsEnumerable,E=("function"==typeof Reflect?Reflect.getPrototypeOf:Object.getPrototypeOf)||([].__proto__===Array.prototype?function(e){return e.__proto__}:null),S=n(1061).custom,C=S&&T(S)?S:null,A="function"==typeof Symbol&&void 0!==Symbol.toStringTag?Symbol.toStringTag:null;function O(e,t,n){var r="double"===(n.quoteStyle||t)?'"':"'";return r+e+r}function k(e){return String(e).replace(/"/g,""")}function j(e){return!("[object Array]"!==N(e)||A&&"object"==typeof e&&A in e)}function T(e){if(w)return e&&"object"==typeof e&&e instanceof Symbol;if("symbol"==typeof e)return!0;if(!e||"object"!=typeof e||!_)return!1;try{return _.call(e),!0}catch(e){}return!1}e.exports=function e(t,n,r,o){var s=n||{};if(P(s,"quoteStyle")&&"single"!==s.quoteStyle&&"double"!==s.quoteStyle)throw new TypeError('option "quoteStyle" must be "single" or "double"');if(P(s,"maxStringLength")&&("number"==typeof s.maxStringLength?s.maxStringLength<0&&s.maxStringLength!==1/0:null!==s.maxStringLength))throw new TypeError('option "maxStringLength", if provided, must be a positive integer, Infinity, or `null`');var u=!P(s,"customInspect")||s.customInspect;if("boolean"!=typeof u&&"symbol"!==u)throw new TypeError("option \"customInspect\", if provided, must be `true`, `false`, or `'symbol'`");if(P(s,"indent")&&null!==s.indent&&"\t"!==s.indent&&!(parseInt(s.indent,10)===s.indent&&s.indent>0))throw new TypeError('options "indent" must be "\\t", an integer > 0, or `null`');if(void 0===t)return"undefined";if(null===t)return"null";if("boolean"==typeof t)return t?"true":"false";if("string"==typeof t)return R(t,s);if("number"==typeof t)return 0===t?1/0/t>0?"0":"-0":String(t);if("bigint"==typeof t)return String(t)+"n";var m=void 0===s.depth?5:s.depth;if(void 0===r&&(r=0),r>=m&&m>0&&"object"==typeof t)return j(t)?"[Array]":"[Object]";var b=function(e,t){var n;if("\t"===e.indent)n="\t";else{if(!("number"==typeof e.indent&&e.indent>0))return null;n=Array(e.indent+1).join(" ")}return{base:n,prev:Array(t+1).join(n)}}(s,r);if(void 0===o)o=[];else if(M(o,t)>=0)return"[Circular]";function x(t,n,a){if(n&&(o=o.slice()).push(n),a){var i={depth:s.depth};return P(s,"quoteStyle")&&(i.quoteStyle=s.quoteStyle),e(t,i,r+1,o)}return e(t,s,r+1,o)}if("function"==typeof t){var S=function(e){if(e.name)return e.name;var t=g.call(v.call(e),/^function\s*([\w$]+)/);if(t)return t[1];return null}(t),I=q(t,x);return"[Function"+(S?": "+S:" (anonymous)")+"]"+(I.length>0?" { "+I.join(", ")+" }":"")}if(T(t)){var D=w?String(t).replace(/^(Symbol\(.*\))_[^)]*$/,"$1"):_.call(t);return"object"!=typeof t||w?D:L(D)}if(function(e){if(!e||"object"!=typeof e)return!1;if("undefined"!=typeof HTMLElement&&e instanceof HTMLElement)return!0;return"string"==typeof e.nodeName&&"function"==typeof e.getAttribute}(t)){for(var z="<"+String(t.nodeName).toLowerCase(),V=t.attributes||[],W=0;W"}if(j(t)){if(0===t.length)return"[]";var H=q(t,x);return b&&!function(e){for(var t=0;t=0)return!1;return!0}(H)?"["+U(H,b)+"]":"[ "+H.join(", ")+" ]"}if(function(e){return!("[object Error]"!==N(e)||A&&"object"==typeof e&&A in e)}(t)){var $=q(t,x);return 0===$.length?"["+String(t)+"]":"{ ["+String(t)+"] "+$.join(", ")+" }"}if("object"==typeof t&&u){if(C&&"function"==typeof t[C])return t[C]();if("symbol"!==u&&"function"==typeof t.inspect)return t.inspect()}if(function(e){if(!a||!e||"object"!=typeof e)return!1;try{a.call(e);try{c.call(e)}catch(e){return!0}return e instanceof Map}catch(e){}return!1}(t)){var J=[];return i.call(t,(function(e,n){J.push(x(n,t,!0)+" => "+x(e,t))})),F("Map",a.call(t),J,b)}if(function(e){if(!c||!e||"object"!=typeof e)return!1;try{c.call(e);try{a.call(e)}catch(e){return!0}return e instanceof Set}catch(e){}return!1}(t)){var K=[];return l.call(t,(function(e){K.push(x(e,t))})),F("Set",c.call(t),K,b)}if(function(e){if(!p||!e||"object"!=typeof e)return!1;try{p.call(e,p);try{f.call(e,f)}catch(e){return!0}return e instanceof WeakMap}catch(e){}return!1}(t))return B("WeakMap");if(function(e){if(!f||!e||"object"!=typeof e)return!1;try{f.call(e,f);try{p.call(e,p)}catch(e){return!0}return e instanceof WeakSet}catch(e){}return!1}(t))return B("WeakSet");if(function(e){if(!h||!e||"object"!=typeof e)return!1;try{return h.call(e),!0}catch(e){}return!1}(t))return B("WeakRef");if(function(e){return!("[object Number]"!==N(e)||A&&"object"==typeof e&&A in e)}(t))return L(x(Number(t)));if(function(e){if(!e||"object"!=typeof e||!y)return!1;try{return y.call(e),!0}catch(e){}return!1}(t))return L(x(y.call(t)));if(function(e){return!("[object Boolean]"!==N(e)||A&&"object"==typeof e&&A in e)}(t))return L(d.call(t));if(function(e){return!("[object String]"!==N(e)||A&&"object"==typeof e&&A in e)}(t))return L(x(String(t)));if(!function(e){return!("[object Date]"!==N(e)||A&&"object"==typeof e&&A in e)}(t)&&!function(e){return!("[object RegExp]"!==N(e)||A&&"object"==typeof e&&A in e)}(t)){var Y=q(t,x),G=E?E(t)===Object.prototype:t instanceof Object||t.constructor===Object,Z=t instanceof Object?"":"null prototype",X=!G&&A&&Object(t)===t&&A in t?N(t).slice(8,-1):Z?"Object":"",Q=(G||"function"!=typeof t.constructor?"":t.constructor.name?t.constructor.name+" ":"")+(X||Z?"["+[].concat(X||[],Z||[]).join(": ")+"] ":"");return 0===Y.length?Q+"{}":b?Q+"{"+U(Y,b)+"}":Q+"{ "+Y.join(", ")+" }"}return String(t)};var I=Object.prototype.hasOwnProperty||function(e){return e in this};function P(e,t){return I.call(e,t)}function N(e){return m.call(e)}function M(e,t){if(e.indexOf)return e.indexOf(t);for(var n=0,r=e.length;nt.maxStringLength){var n=e.length-t.maxStringLength,r="... "+n+" more character"+(n>1?"s":"");return R(e.slice(0,t.maxStringLength),t)+r}return O(e.replace(/(['\\])/g,"\\$1").replace(/[\x00-\x1f]/g,D),"single",t)}function D(e){var t=e.charCodeAt(0),n={8:"b",9:"t",10:"n",12:"f",13:"r"}[t];return n?"\\"+n:"\\x"+(t<16?"0":"")+t.toString(16).toUpperCase()}function L(e){return"Object("+e+")"}function B(e){return e+" { ? }"}function F(e,t,n,r){return e+" ("+t+") {"+(r?U(n,r):n.join(", "))+"}"}function U(e,t){if(0===e.length)return"";var n="\n"+t.prev+t.base;return n+e.join(","+n)+"\n"+t.prev}function q(e,t){var n=j(e),r=[];if(n){r.length=e.length;for(var o=0;o-1?e.split(","):e},c=function(e,t,n,r){if(e){var a=n.allowDots?e.replace(/\.([^.[]+)/g,"[$1]"):e,i=/(\[[^[\]]*])/g,s=n.depth>0&&/(\[[^[\]]*])/.exec(a),c=s?a.slice(0,s.index):a,l=[];if(c){if(!n.plainObjects&&o.call(Object.prototype,c)&&!n.allowPrototypes)return;l.push(c)}for(var p=0;n.depth>0&&null!==(s=i.exec(a))&&p=0;--a){var i,s=e[a];if("[]"===s&&n.parseArrays)i=[].concat(o);else{i=n.plainObjects?Object.create(null):{};var c="["===s.charAt(0)&&"]"===s.charAt(s.length-1)?s.slice(1,-1):s,l=parseInt(c,10);n.parseArrays||""!==c?!isNaN(l)&&s!==c&&String(l)===c&&l>=0&&n.parseArrays&&l<=n.arrayLimit?(i=[])[l]=o:i[c]=o:i={0:o}}o=i}return o}(l,t,n,r)}};e.exports=function(e,t){var n=function(e){if(!e)return i;if(null!==e.decoder&&void 0!==e.decoder&&"function"!=typeof e.decoder)throw new TypeError("Decoder has to be a function.");if(void 0!==e.charset&&"utf-8"!==e.charset&&"iso-8859-1"!==e.charset)throw new TypeError("The charset option must be either utf-8, iso-8859-1, or undefined");var t=void 0===e.charset?i.charset:e.charset;return{allowDots:void 0===e.allowDots?i.allowDots:!!e.allowDots,allowPrototypes:"boolean"==typeof e.allowPrototypes?e.allowPrototypes:i.allowPrototypes,allowSparse:"boolean"==typeof e.allowSparse?e.allowSparse:i.allowSparse,arrayLimit:"number"==typeof e.arrayLimit?e.arrayLimit:i.arrayLimit,charset:t,charsetSentinel:"boolean"==typeof e.charsetSentinel?e.charsetSentinel:i.charsetSentinel,comma:"boolean"==typeof e.comma?e.comma:i.comma,decoder:"function"==typeof e.decoder?e.decoder:i.decoder,delimiter:"string"==typeof e.delimiter||r.isRegExp(e.delimiter)?e.delimiter:i.delimiter,depth:"number"==typeof e.depth||!1===e.depth?+e.depth:i.depth,ignoreQueryPrefix:!0===e.ignoreQueryPrefix,interpretNumericEntities:"boolean"==typeof e.interpretNumericEntities?e.interpretNumericEntities:i.interpretNumericEntities,parameterLimit:"number"==typeof e.parameterLimit?e.parameterLimit:i.parameterLimit,parseArrays:!1!==e.parseArrays,plainObjects:"boolean"==typeof e.plainObjects?e.plainObjects:i.plainObjects,strictNullHandling:"boolean"==typeof e.strictNullHandling?e.strictNullHandling:i.strictNullHandling}}(t);if(""===e||null==e)return n.plainObjects?Object.create(null):{};for(var l="string"==typeof e?function(e,t){var n,c={},l=t.ignoreQueryPrefix?e.replace(/^\?/,""):e,p=t.parameterLimit===1/0?void 0:t.parameterLimit,f=l.split(t.delimiter,p),h=-1,d=t.charset;if(t.charsetSentinel)for(n=0;n-1&&(v=a(v)?[v]:v),o.call(c,m)?c[m]=r.combine(c[m],v):c[m]=v}return c}(e,n):e,p=n.plainObjects?Object.create(null):{},f=Object.keys(l),h=0;hh)throw TypeError(d);for(l=u(y,r),m=0;mb-r+n;m--)delete y[m-1]}else if(n>r)for(m=b-r;m>_;m--)g=m+n-1,(v=m+r-1)in y?y[g]=y[v]:delete y[g];for(m=0;m= 0x80 (not a basic code point)","invalid-input":"Invalid input"},d=Math.floor,m=String.fromCharCode;function v(e){throw RangeError(h[e])}function g(e,t){for(var n=e.length,r=[];n--;)r[n]=t(e[n]);return r}function y(e,t){var n=e.split("@"),r="";return n.length>1&&(r=n[0]+"@",e=n[1]),r+g((e=e.replace(f,".")).split("."),t).join(".")}function b(e){for(var t,n,r=[],o=0,a=e.length;o=55296&&t<=56319&&o65535&&(t+=m((e-=65536)>>>10&1023|55296),e=56320|1023&e),t+=m(e)})).join("")}function w(e,t){return e+22+75*(e<26)-((0!=t)<<5)}function x(e,t,n){var r=0;for(e=n?d(e/700):e>>1,e+=d(e/t);e>455;r+=c)e=d(e/35);return d(r+36*e/(e+38))}function E(e){var t,n,r,o,a,i,s,l,p,f,h,m=[],g=e.length,y=0,b=128,w=72;for((n=e.lastIndexOf("-"))<0&&(n=0),r=0;r=128&&v("not-basic"),m.push(e.charCodeAt(r));for(o=n>0?n+1:0;o=g&&v("invalid-input"),((l=(h=e.charCodeAt(o++))-48<10?h-22:h-65<26?h-65:h-97<26?h-97:c)>=c||l>d((u-y)/i))&&v("overflow"),y+=l*i,!(l<(p=s<=w?1:s>=w+26?26:s-w));s+=c)i>d(u/(f=c-p))&&v("overflow"),i*=f;w=x(y-a,t=m.length+1,0==a),d(y/t)>u-b&&v("overflow"),b+=d(y/t),y%=t,m.splice(y++,0,b)}return _(m)}function S(e){var t,n,r,o,a,i,s,l,p,f,h,g,y,_,E,S=[];for(g=(e=b(e)).length,t=128,n=0,a=72,i=0;i=t&&hd((u-n)/(y=r+1))&&v("overflow"),n+=(s-t)*y,t=s,i=0;iu&&v("overflow"),h==t){for(l=n,p=c;!(l<(f=p<=a?1:p>=a+26?26:p-a));p+=c)E=l-f,_=c-f,S.push(m(w(f+E%_,0))),l=d(E/_);S.push(m(w(l,0))),a=x(n,y,r==o),n=0,++r}++n,++t}return S.join("")}s={version:"1.3.2",ucs2:{decode:b,encode:_},decode:E,encode:S,toASCII:function(e){return y(e,(function(e){return p.test(e)?"xn--"+S(e):e}))},toUnicode:function(e){return y(e,(function(e){return l.test(e)?E(e.slice(4).toLowerCase()):e}))}},void 0===(o=function(){return s}.call(t,n,t,e))||(e.exports=o)}()}).call(this,n(196)(e),n(51))},function(e,t,n){"use strict";e.exports={isString:function(e){return"string"==typeof e},isObject:function(e){return"object"==typeof e&&null!==e},isNull:function(e){return null===e},isNullOrUndefined:function(e){return null==e}}},function(e,t,n){"use strict";t.decode=t.parse=n(1078),t.encode=t.stringify=n(1079)},function(e,t,n){"use strict";function r(e,t){return Object.prototype.hasOwnProperty.call(e,t)}e.exports=function(e,t,n,a){t=t||"&",n=n||"=";var i={};if("string"!=typeof e||0===e.length)return i;var s=/\+/g;e=e.split(t);var u=1e3;a&&"number"==typeof a.maxKeys&&(u=a.maxKeys);var c=e.length;u>0&&c>u&&(c=u);for(var l=0;l=0?(p=m.substr(0,v),f=m.substr(v+1)):(p=m,f=""),h=decodeURIComponent(p),d=decodeURIComponent(f),r(i,h)?o(i[h])?i[h].push(d):i[h]=[i[h],d]:i[h]=d}return i};var o=Array.isArray||function(e){return"[object Array]"===Object.prototype.toString.call(e)}},function(e,t,n){"use strict";var r=function(e){switch(typeof e){case"string":return e;case"boolean":return e?"true":"false";case"number":return isFinite(e)?e:"";default:return""}};e.exports=function(e,t,n,s){return t=t||"&",n=n||"=",null===e&&(e=void 0),"object"==typeof e?a(i(e),(function(i){var s=encodeURIComponent(r(i))+n;return o(e[i])?a(e[i],(function(e){return s+encodeURIComponent(r(e))})).join(t):s+encodeURIComponent(r(e[i]))})).join(t):s?encodeURIComponent(r(s))+n+encodeURIComponent(r(e)):""};var o=Array.isArray||function(e){return"[object Array]"===Object.prototype.toString.call(e)};function a(e,t){if(e.map)return e.map(t);for(var n=[],r=0;r?@[\\\]^|]/,L=/[\0\t\n\r #/:<>?@[\\\]^|]/,B=/^[\u0000-\u001F ]+|[\u0000-\u001F ]+$/g,F=/[\t\n\r]/g,U=function(e,t){var n,r,o;if("["==t.charAt(0)){if("]"!=t.charAt(t.length-1))return O;if(!(n=z(t.slice(1,-1))))return O;e.host=n}else if(G(e)){if(t=m(t),D.test(t))return O;if(null===(n=q(t)))return O;e.host=n}else{if(L.test(t))return O;for(n="",r=h(t),o=0;o4)return e;for(n=[],r=0;r1&&"0"==o.charAt(0)&&(a=P.test(o)?16:8,o=o.slice(8==a?1:2)),""===o)i=0;else{if(!(10==a?M:8==a?N:R).test(o))return e;i=parseInt(o,a)}n.push(i)}for(r=0;r=C(256,5-t))return null}else if(i>255)return null;for(s=n.pop(),r=0;r6)return;for(r=0;f();){if(o=null,r>0){if(!("."==f()&&r<4))return;p++}if(!I.test(f()))return;for(;I.test(f());){if(a=parseInt(f(),10),null===o)o=a;else{if(0==o)return;o=10*o+a}if(o>255)return;p++}u[c]=256*u[c]+o,2!=++r&&4!=r||c++}if(4!=r)return;break}if(":"==f()){if(p++,!f())return}else if(f())return;u[c++]=t}else{if(null!==l)return;p++,l=++c}}if(null!==l)for(i=c-l,c=7;0!=c&&i>0;)s=u[c],u[c--]=u[l+i-1],u[l+--i]=s;else if(8!=c)return;return u},V=function(e){var t,n,r,o;if("number"==typeof e){for(t=[],n=0;n<4;n++)t.unshift(e%256),e=S(e/256);return t.join(".")}if("object"==typeof e){for(t="",r=function(e){for(var t=null,n=1,r=null,o=0,a=0;a<8;a++)0!==e[a]?(o>n&&(t=r,n=o),r=null,o=0):(null===r&&(r=a),++o);return o>n&&(t=r,n=o),t}(e),n=0;n<8;n++)o&&0===e[n]||(o&&(o=!1),r===n?(t+=n?":":"::",o=!0):(t+=e[n].toString(16),n<7&&(t+=":")));return"["+t+"]"}return e},W={},H=f({},W,{" ":1,'"':1,"<":1,">":1,"`":1}),$=f({},H,{"#":1,"?":1,"{":1,"}":1}),J=f({},$,{"/":1,":":1,";":1,"=":1,"@":1,"[":1,"\\":1,"]":1,"^":1,"|":1}),K=function(e,t){var n=d(e,0);return n>32&&n<127&&!p(t,e)?e:encodeURIComponent(e)},Y={ftp:21,file:null,http:80,https:443,ws:80,wss:443},G=function(e){return p(Y,e.scheme)},Z=function(e){return""!=e.username||""!=e.password},X=function(e){return!e.host||e.cannotBeABaseURL||"file"==e.scheme},Q=function(e,t){var n;return 2==e.length&&j.test(e.charAt(0))&&(":"==(n=e.charAt(1))||!t&&"|"==n)},ee=function(e){var t;return e.length>1&&Q(e.slice(0,2))&&(2==e.length||"/"===(t=e.charAt(2))||"\\"===t||"?"===t||"#"===t)},te=function(e){var t=e.path,n=t.length;!n||"file"==e.scheme&&1==n&&Q(t[0],!0)||t.pop()},ne=function(e){return"."===e||"%2e"===e.toLowerCase()},re={},oe={},ae={},ie={},se={},ue={},ce={},le={},pe={},fe={},he={},de={},me={},ve={},ge={},ye={},be={},_e={},we={},xe={},Ee={},Se=function(e,t,n,o){var a,i,s,u,c,l=n||re,f=0,d="",m=!1,v=!1,g=!1;for(n||(e.scheme="",e.username="",e.password="",e.host=null,e.port=null,e.path=[],e.query=null,e.fragment=null,e.cannotBeABaseURL=!1,t=t.replace(B,"")),t=t.replace(F,""),a=h(t);f<=a.length;){switch(i=a[f],l){case re:if(!i||!j.test(i)){if(n)return A;l=ae;continue}d+=i.toLowerCase(),l=oe;break;case oe:if(i&&(T.test(i)||"+"==i||"-"==i||"."==i))d+=i.toLowerCase();else{if(":"!=i){if(n)return A;d="",l=ae,f=0;continue}if(n&&(G(e)!=p(Y,d)||"file"==d&&(Z(e)||null!==e.port)||"file"==e.scheme&&!e.host))return;if(e.scheme=d,n)return void(G(e)&&Y[e.scheme]==e.port&&(e.port=null));d="","file"==e.scheme?l=ve:G(e)&&o&&o.scheme==e.scheme?l=ie:G(e)?l=le:"/"==a[f+1]?(l=se,f++):(e.cannotBeABaseURL=!0,e.path.push(""),l=we)}break;case ae:if(!o||o.cannotBeABaseURL&&"#"!=i)return A;if(o.cannotBeABaseURL&&"#"==i){e.scheme=o.scheme,e.path=o.path.slice(),e.query=o.query,e.fragment="",e.cannotBeABaseURL=!0,l=Ee;break}l="file"==o.scheme?ve:ue;continue;case ie:if("/"!=i||"/"!=a[f+1]){l=ue;continue}l=pe,f++;break;case se:if("/"==i){l=fe;break}l=_e;continue;case ue:if(e.scheme=o.scheme,i==r)e.username=o.username,e.password=o.password,e.host=o.host,e.port=o.port,e.path=o.path.slice(),e.query=o.query;else if("/"==i||"\\"==i&&G(e))l=ce;else if("?"==i)e.username=o.username,e.password=o.password,e.host=o.host,e.port=o.port,e.path=o.path.slice(),e.query="",l=xe;else{if("#"!=i){e.username=o.username,e.password=o.password,e.host=o.host,e.port=o.port,e.path=o.path.slice(),e.path.pop(),l=_e;continue}e.username=o.username,e.password=o.password,e.host=o.host,e.port=o.port,e.path=o.path.slice(),e.query=o.query,e.fragment="",l=Ee}break;case ce:if(!G(e)||"/"!=i&&"\\"!=i){if("/"!=i){e.username=o.username,e.password=o.password,e.host=o.host,e.port=o.port,l=_e;continue}l=fe}else l=pe;break;case le:if(l=pe,"/"!=i||"/"!=d.charAt(f+1))continue;f++;break;case pe:if("/"!=i&&"\\"!=i){l=fe;continue}break;case fe:if("@"==i){m&&(d="%40"+d),m=!0,s=h(d);for(var y=0;y65535)return k;e.port=G(e)&&w===Y[e.scheme]?null:w,d=""}if(n)return;l=be;continue}return k}d+=i;break;case ve:if(e.scheme="file","/"==i||"\\"==i)l=ge;else{if(!o||"file"!=o.scheme){l=_e;continue}if(i==r)e.host=o.host,e.path=o.path.slice(),e.query=o.query;else if("?"==i)e.host=o.host,e.path=o.path.slice(),e.query="",l=xe;else{if("#"!=i){ee(a.slice(f).join(""))||(e.host=o.host,e.path=o.path.slice(),te(e)),l=_e;continue}e.host=o.host,e.path=o.path.slice(),e.query=o.query,e.fragment="",l=Ee}}break;case ge:if("/"==i||"\\"==i){l=ye;break}o&&"file"==o.scheme&&!ee(a.slice(f).join(""))&&(Q(o.path[0],!0)?e.path.push(o.path[0]):e.host=o.host),l=_e;continue;case ye:if(i==r||"/"==i||"\\"==i||"?"==i||"#"==i){if(!n&&Q(d))l=_e;else if(""==d){if(e.host="",n)return;l=be}else{if(u=U(e,d))return u;if("localhost"==e.host&&(e.host=""),n)return;d="",l=be}continue}d+=i;break;case be:if(G(e)){if(l=_e,"/"!=i&&"\\"!=i)continue}else if(n||"?"!=i)if(n||"#"!=i){if(i!=r&&(l=_e,"/"!=i))continue}else e.fragment="",l=Ee;else e.query="",l=xe;break;case _e:if(i==r||"/"==i||"\\"==i&&G(e)||!n&&("?"==i||"#"==i)){if(".."===(c=(c=d).toLowerCase())||"%2e."===c||".%2e"===c||"%2e%2e"===c?(te(e),"/"==i||"\\"==i&&G(e)||e.path.push("")):ne(d)?"/"==i||"\\"==i&&G(e)||e.path.push(""):("file"==e.scheme&&!e.path.length&&Q(d)&&(e.host&&(e.host=""),d=d.charAt(0)+":"),e.path.push(d)),d="","file"==e.scheme&&(i==r||"?"==i||"#"==i))for(;e.path.length>1&&""===e.path[0];)e.path.shift();"?"==i?(e.query="",l=xe):"#"==i&&(e.fragment="",l=Ee)}else d+=K(i,$);break;case we:"?"==i?(e.query="",l=xe):"#"==i?(e.fragment="",l=Ee):i!=r&&(e.path[0]+=K(i,W));break;case xe:n||"#"!=i?i!=r&&("'"==i&&G(e)?e.query+="%27":e.query+="#"==i?"%23":K(i,W)):(e.fragment="",l=Ee);break;case Ee:i!=r&&(e.fragment+=K(i,H))}f++}},Ce=function(e){var t,n,r=l(this,Ce,"URL"),o=arguments.length>1?arguments[1]:void 0,i=String(e),s=x(r,{type:"URL"});if(void 0!==o)if(o instanceof Ce)t=E(o);else if(n=Se(t={},String(o)))throw TypeError(n);if(n=Se(s,i,null,t))throw TypeError(n);var u=s.searchParams=new _,c=w(u);c.updateSearchParams(s.query),c.updateURL=function(){s.query=String(u)||null},a||(r.href=Oe.call(r),r.origin=ke.call(r),r.protocol=je.call(r),r.username=Te.call(r),r.password=Ie.call(r),r.host=Pe.call(r),r.hostname=Ne.call(r),r.port=Me.call(r),r.pathname=Re.call(r),r.search=De.call(r),r.searchParams=Le.call(r),r.hash=Be.call(r))},Ae=Ce.prototype,Oe=function(){var e=E(this),t=e.scheme,n=e.username,r=e.password,o=e.host,a=e.port,i=e.path,s=e.query,u=e.fragment,c=t+":";return null!==o?(c+="//",Z(e)&&(c+=n+(r?":"+r:"")+"@"),c+=V(o),null!==a&&(c+=":"+a)):"file"==t&&(c+="//"),c+=e.cannotBeABaseURL?i[0]:i.length?"/"+i.join("/"):"",null!==s&&(c+="?"+s),null!==u&&(c+="#"+u),c},ke=function(){var e=E(this),t=e.scheme,n=e.port;if("blob"==t)try{return new Ce(t.path[0]).origin}catch(e){return"null"}return"file"!=t&&G(e)?t+"://"+V(e.host)+(null!==n?":"+n:""):"null"},je=function(){return E(this).scheme+":"},Te=function(){return E(this).username},Ie=function(){return E(this).password},Pe=function(){var e=E(this),t=e.host,n=e.port;return null===t?"":null===n?V(t):V(t)+":"+n},Ne=function(){var e=E(this).host;return null===e?"":V(e)},Me=function(){var e=E(this).port;return null===e?"":String(e)},Re=function(){var e=E(this),t=e.path;return e.cannotBeABaseURL?t[0]:t.length?"/"+t.join("/"):""},De=function(){var e=E(this).query;return e?"?"+e:""},Le=function(){return E(this).searchParams},Be=function(){var e=E(this).fragment;return e?"#"+e:""},Fe=function(e,t){return{get:e,set:t,configurable:!0,enumerable:!0}};if(a&&u(Ae,{href:Fe(Oe,(function(e){var t=E(this),n=String(e),r=Se(t,n);if(r)throw TypeError(r);w(t.searchParams).updateSearchParams(t.query)})),origin:Fe(ke),protocol:Fe(je,(function(e){var t=E(this);Se(t,String(e)+":",re)})),username:Fe(Te,(function(e){var t=E(this),n=h(String(e));if(!X(t)){t.username="";for(var r=0;r>1,e+=s(e/t);e>455;r+=36)e=s(e/35);return s(r+36*e/(e+38))},p=function(e){var t,n,o=[],a=(e=function(e){for(var t=[],n=0,r=e.length;n=55296&&o<=56319&&n=p&&ns((r-f)/g))throw RangeError(i);for(f+=(v-p)*g,p=v,t=0;tr)throw RangeError(i);if(n==p){for(var y=f,b=36;;b+=36){var _=b<=h?1:b>=h+26?26:b-h;if(y<_)break;var w=y-_,x=36-_;o.push(u(c(_+w%x))),y=s(w/x)}o.push(u(c(y))),h=l(f,g,m==d),f=0,++m}}++f,++p}return o.join("")};e.exports=function(e){var t,n,r=[],i=e.toLowerCase().replace(a,".").split(".");for(t=0;t2,o=r?i.call(arguments,2):void 0;return e(r?function(){("function"==typeof t?t:Function(t)).apply(this,o)}:t,n)}};r({global:!0,bind:!0,forced:/MSIE .\./.test(a)},{setTimeout:s(o.setTimeout),setInterval:s(o.setInterval)})},function(e,t,n){var r=n(1088);e.exports=r},function(e,t,n){n(1089),n(182),n(130),n(86);var r=n(33);e.exports=r.Map},function(e,t,n){"use strict";var r=n(495),o=n(1090);e.exports=r("Map",(function(e){return function(){return e(this,arguments.length?arguments[0]:void 0)}}),o)},function(e,t,n){"use strict";var r=n(68).f,o=n(111),a=n(164),i=n(109),s=n(141),u=n(121),c=n(236),l=n(450),p=n(48),f=n(208).fastKey,h=n(77),d=h.set,m=h.getterFor;e.exports={getConstructor:function(e,t,n,c){var l=e((function(e,r){s(e,l,t),d(e,{type:t,index:o(null),first:void 0,last:void 0,size:0}),p||(e.size=0),null!=r&&u(r,e[c],{that:e,AS_ENTRIES:n})})),h=m(t),v=function(e,t,n){var r,o,a=h(e),i=g(e,t);return i?i.value=n:(a.last=i={index:o=f(t,!0),key:t,value:n,previous:r=a.last,next:void 0,removed:!1},a.first||(a.first=i),r&&(r.next=i),p?a.size++:e.size++,"F"!==o&&(a.index[o]=i)),e},g=function(e,t){var n,r=h(e),o=f(t);if("F"!==o)return r.index[o];for(n=r.first;n;n=n.next)if(n.key==t)return n};return a(l.prototype,{clear:function(){for(var e=h(this),t=e.index,n=e.first;n;)n.removed=!0,n.previous&&(n.previous=n.previous.next=void 0),delete t[n.index],n=n.next;e.first=e.last=void 0,p?e.size=0:this.size=0},delete:function(e){var t=this,n=h(t),r=g(t,e);if(r){var o=r.next,a=r.previous;delete n.index[r.index],r.removed=!0,a&&(a.next=o),o&&(o.previous=a),n.first==r&&(n.first=o),n.last==r&&(n.last=a),p?n.size--:t.size--}return!!r},forEach:function(e){for(var t,n=h(this),r=i(e,arguments.length>1?arguments[1]:void 0,3);t=t?t.next:n.first;)for(r(t.value,t.key,this);t&&t.removed;)t=t.previous},has:function(e){return!!g(this,e)}}),a(l.prototype,n?{get:function(e){var t=g(this,e);return t&&t.value},set:function(e,t){return v(this,0===e?0:e,t)}}:{add:function(e){return v(this,e=0===e?0:e,e)}}),p&&r(l.prototype,"size",{get:function(){return h(this).size}}),l},setStrong:function(e,t,n){var r=t+" Iterator",o=m(t),a=m(r);c(e,t,(function(e,t){d(this,{type:r,target:e,state:o(e),kind:t,last:void 0})}),(function(){for(var e=a(this),t=e.kind,n=e.last;n&&n.removed;)n=n.previous;return e.target&&(e.last=n=n?n.next:e.state.first)?"keys"==t?{value:n.key,done:!1}:"values"==t?{value:n.value,done:!1}:{value:[n.key,n.value],done:!1}:(e.target=void 0,{value:void 0,done:!0})}),n?"entries":"values",!n,!0),l(t)}}},function(e,t,n){n(86);var r=n(1092),o=n(98),a=Array.prototype,i={DOMTokenList:!0,NodeList:!0};e.exports=function(e){var t=e.keys;return e===a||e instanceof Array&&t===a.keys||i.hasOwnProperty(o(e))?r:t}},function(e,t,n){var r=n(1093);e.exports=r},function(e,t,n){n(158);var r=n(42);e.exports=r("Array").keys},function(e,t){e.exports=function(e,t){return t.get?t.get.call(e):t.value},e.exports.default=e.exports,e.exports.__esModule=!0},function(e,t){e.exports=function(e,t,n){if(t.set)t.set.call(e,n);else{if(!t.writable)throw new TypeError("attempted to set read only private field");t.value=n}},e.exports.default=e.exports,e.exports.__esModule=!0},function(e,t,n){n(86);var r=n(1097),o=n(98),a=Array.prototype,i={DOMTokenList:!0,NodeList:!0};e.exports=function(e){var t=e.values;return e===a||e instanceof Array&&t===a.values||i.hasOwnProperty(o(e))?r:t}},function(e,t,n){var r=n(1098);e.exports=r},function(e,t,n){n(158);var r=n(42);e.exports=r("Array").values},function(e,t,n){var r=n(1100);e.exports=r},function(e,t,n){var r=n(1101),o=Array.prototype;e.exports=function(e){var t=e.lastIndexOf;return e===o||e instanceof Array&&t===o.lastIndexOf?r:t}},function(e,t,n){n(1102);var r=n(42);e.exports=r("Array").lastIndexOf},function(e,t,n){var r=n(22),o=n(1103);r({target:"Array",proto:!0,forced:o!==[].lastIndexOf},{lastIndexOf:o})},function(e,t,n){"use strict";var r=n(66),o=n(128),a=n(69),i=n(113),s=Math.min,u=[].lastIndexOf,c=!!u&&1/[1].lastIndexOf(1,-0)<0,l=i("lastIndexOf"),p=c||!l;e.exports=p?function(e){if(c)return u.apply(this,arguments)||0;var t=r(this),n=a(t.length),i=n-1;for(arguments.length>1&&(i=s(i,o(arguments[1]))),i<0&&(i=n+i);i>=0;i--)if(i in t&&t[i]===e)return i||0;return-1}:u},function(e,t,n){"use strict";var r,o="";e.exports=function(e,t){if("string"!=typeof e)throw new TypeError("expected a string");if(1===t)return e;if(2===t)return e+e;var n=e.length*t;if(r!==e||void 0===r)r=e,o="";else if(o.length>=n)return o.substr(0,n);for(;n>o.length&&t>1;)1&t&&(o+=e),t>>=1,e+=e;return o=(o+=e).substr(0,n)}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.DebounceInput=void 0;var r=a(n(0)),o=a(n(1106));function a(e){return e&&e.__esModule?e:{default:e}}function i(e){return(i="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function s(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},a=Object.keys(e);for(r=0;r=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}function u(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function c(e){for(var t=1;t=r?t.notify(e):n.length>o.length&&t.notify(c(c({},e),{},{target:c(c({},e.target),{},{value:""})}))}))})),v(d(t),"onKeyDown",(function(e){"Enter"===e.key&&t.forceNotify(e);var n=t.props.onKeyDown;n&&(e.persist(),n(e))})),v(d(t),"onBlur",(function(e){t.forceNotify(e);var n=t.props.onBlur;n&&(e.persist(),n(e))})),v(d(t),"createNotifier",(function(e){if(e<0)t.notify=function(){return null};else if(0===e)t.notify=t.doNotify;else{var n=(0,o.default)((function(e){t.isDebouncing=!1,t.doNotify(e)}),e);t.notify=function(e){t.isDebouncing=!0,n(e)},t.flush=function(){return n.flush()},t.cancel=function(){t.isDebouncing=!1,n.cancel()}}})),v(d(t),"doNotify",(function(){var e=t.props.onChange;e.apply(void 0,arguments)})),v(d(t),"forceNotify",(function(e){var n=t.props.debounceTimeout;if(t.isDebouncing||!(n>0)){t.cancel&&t.cancel();var r=t.state.value,o=t.props.minLength;r.length>=o?t.doNotify(e):t.doNotify(c(c({},e),{},{target:c(c({},e.target),{},{value:r})}))}})),t.isDebouncing=!1,t.state={value:void 0===e.value||null===e.value?"":e.value};var n=t.props.debounceTimeout;return t.createNotifier(n),t}return t=u,(n=[{key:"componentDidUpdate",value:function(e){if(!this.isDebouncing){var t=this.props,n=t.value,r=t.debounceTimeout,o=e.debounceTimeout,a=e.value,i=this.state.value;void 0!==n&&a!==n&&i!==n&&this.setState({value:n}),r!==o&&this.createNotifier(r)}}},{key:"componentWillUnmount",value:function(){this.flush&&this.flush()}},{key:"render",value:function(){var e,t,n=this.props,o=n.element,a=(n.onChange,n.value,n.minLength,n.debounceTimeout,n.forceNotifyByEnter),i=n.forceNotifyOnBlur,u=n.onKeyDown,l=n.onBlur,p=n.inputRef,f=s(n,["element","onChange","value","minLength","debounceTimeout","forceNotifyByEnter","forceNotifyOnBlur","onKeyDown","onBlur","inputRef"]),h=this.state.value;e=a?{onKeyDown:this.onKeyDown}:u?{onKeyDown:u}:{},t=i?{onBlur:this.onBlur}:l?{onBlur:l}:{};var d=p?{ref:p}:{};return r.default.createElement(o,c(c(c(c({},f),{},{onChange:this.onChange,value:h},e),t),d))}}])&&l(t.prototype,n),a&&l(t,a),u}(r.default.PureComponent);t.DebounceInput=g,v(g,"defaultProps",{element:"input",type:"text",onKeyDown:void 0,onBlur:void 0,value:void 0,minLength:0,debounceTimeout:100,forceNotifyByEnter:!0,forceNotifyOnBlur:!0,inputRef:void 0})},function(e,t,n){(function(t){var n=/^\s+|\s+$/g,r=/^[-+]0x[0-9a-f]+$/i,o=/^0b[01]+$/i,a=/^0o[0-7]+$/i,i=parseInt,s="object"==typeof t&&t&&t.Object===Object&&t,u="object"==typeof self&&self&&self.Object===Object&&self,c=s||u||Function("return this")(),l=Object.prototype.toString,p=Math.max,f=Math.min,h=function(){return c.Date.now()};function d(e){var t=typeof e;return!!e&&("object"==t||"function"==t)}function m(e){if("number"==typeof e)return e;if(function(e){return"symbol"==typeof e||function(e){return!!e&&"object"==typeof e}(e)&&"[object Symbol]"==l.call(e)}(e))return NaN;if(d(e)){var t="function"==typeof e.valueOf?e.valueOf():e;e=d(t)?t+"":t}if("string"!=typeof e)return 0===e?e:+e;e=e.replace(n,"");var s=o.test(e);return s||a.test(e)?i(e.slice(2),s?2:8):r.test(e)?NaN:+e}e.exports=function(e,t,n){var r,o,a,i,s,u,c=0,l=!1,v=!1,g=!0;if("function"!=typeof e)throw new TypeError("Expected a function");function y(t){var n=r,a=o;return r=o=void 0,c=t,i=e.apply(a,n)}function b(e){return c=e,s=setTimeout(w,t),l?y(e):i}function _(e){var n=e-u;return void 0===u||n>=t||n<0||v&&e-c>=a}function w(){var e=h();if(_(e))return x(e);s=setTimeout(w,function(e){var n=t-(e-u);return v?f(n,a-(e-c)):n}(e))}function x(e){return s=void 0,g&&r?y(e):(r=o=void 0,i)}function E(){var e=h(),n=_(e);if(r=arguments,o=this,u=e,n){if(void 0===s)return b(u);if(v)return s=setTimeout(w,t),y(u)}return void 0===s&&(s=setTimeout(w,t)),i}return t=m(t)||0,d(n)&&(l=!!n.leading,a=(v="maxWait"in n)?p(m(n.maxWait)||0,t):a,g="trailing"in n?!!n.trailing:g),E.cancel=function(){void 0!==s&&clearTimeout(s),c=0,r=u=o=s=void 0},E.flush=function(){return void 0===s?i:x(h())},E}}).call(this,n(51))},function(e,t,n){var r={"./all.js":342,"./auth/actions.js":83,"./auth/index.js":305,"./auth/reducers.js":306,"./auth/selectors.js":307,"./auth/spec-wrap-actions.js":308,"./configs/actions.js":149,"./configs/helpers.js":173,"./configs/index.js":344,"./configs/reducers.js":313,"./configs/selectors.js":312,"./configs/spec-actions.js":311,"./deep-linking/helpers.js":176,"./deep-linking/index.js":314,"./deep-linking/layout.js":315,"./deep-linking/operation-tag-wrapper.jsx":317,"./deep-linking/operation-wrapper.jsx":316,"./download-url.js":310,"./err/actions.js":61,"./err/error-transformers/hook.js":126,"./err/error-transformers/transformers/not-of-type.js":288,"./err/error-transformers/transformers/parameter-oneof.js":289,"./err/index.js":286,"./err/reducers.js":287,"./err/selectors.js":290,"./filter/index.js":318,"./filter/opsFilter.js":319,"./layout/actions.js":105,"./layout/index.js":291,"./layout/reducers.js":292,"./layout/selectors.js":293,"./layout/spec-extensions/wrap-selector.js":294,"./logs/index.js":303,"./oas3/actions.js":54,"./oas3/auth-extensions/wrap-selectors.js":323,"./oas3/components/callbacks.jsx":326,"./oas3/components/http-auth.jsx":331,"./oas3/components/index.js":325,"./oas3/components/operation-link.jsx":327,"./oas3/components/operation-servers.jsx":332,"./oas3/components/request-body-editor.jsx":330,"./oas3/components/request-body.jsx":174,"./oas3/components/servers-container.jsx":329,"./oas3/components/servers.jsx":328,"./oas3/helpers.jsx":35,"./oas3/index.js":321,"./oas3/reducers.js":341,"./oas3/selectors.js":340,"./oas3/spec-extensions/selectors.js":324,"./oas3/spec-extensions/wrap-selectors.js":322,"./oas3/wrap-components/auth-item.jsx":335,"./oas3/wrap-components/index.js":333,"./oas3/wrap-components/json-schema-string.jsx":339,"./oas3/wrap-components/markdown.jsx":334,"./oas3/wrap-components/model.jsx":338,"./oas3/wrap-components/online-validator-badge.js":337,"./oas3/wrap-components/version-stamp.jsx":336,"./on-complete/index.js":320,"./request-snippets/fn.js":172,"./request-snippets/index.js":300,"./request-snippets/request-snippets.jsx":302,"./request-snippets/selectors.js":301,"./samples/fn.js":147,"./samples/index.js":299,"./spec/actions.js":46,"./spec/index.js":295,"./spec/reducers.js":296,"./spec/selectors.js":91,"./spec/wrap-actions.js":297,"./swagger-js/configs-wrap-actions.js":304,"./swagger-js/index.js":343,"./util/index.js":309,"./view/index.js":298,"./view/root-injects.jsx":175};function o(e){var t=a(e);return n(t)}function a(e){if(!n.o(r,e)){var t=new Error("Cannot find module '"+e+"'");throw t.code="MODULE_NOT_FOUND",t}return r[e]}o.keys=function(){return Object.keys(r)},o.resolve=a,e.exports=o,o.id=1107},function(e,t,n){"use strict";n.r(t);var r={};n.r(r),n.d(r,"Container",(function(){return Tn})),n.d(r,"Col",(function(){return Pn})),n.d(r,"Row",(function(){return Nn})),n.d(r,"Button",(function(){return Mn})),n.d(r,"TextArea",(function(){return Rn})),n.d(r,"Input",(function(){return Dn})),n.d(r,"Select",(function(){return Ln})),n.d(r,"Link",(function(){return Bn})),n.d(r,"Collapse",(function(){return Un}));var o={};n.r(o),n.d(o,"JsonSchemaForm",(function(){return Tr})),n.d(o,"JsonSchema_string",(function(){return Ir})),n.d(o,"JsonSchema_array",(function(){return Pr})),n.d(o,"JsonSchemaArrayItemText",(function(){return Nr})),n.d(o,"JsonSchemaArrayItemFile",(function(){return Mr})),n.d(o,"JsonSchema_boolean",(function(){return Rr})),n.d(o,"JsonSchema_object",(function(){return Lr}));var a=n(18),i=n.n(a),s=n(2),u=n.n(s),c=n(12),l=n.n(c),p=n(15),f=n.n(p),h=n(32),d=n.n(h),m=n(80),v=n.n(m),g=n(3),y=n.n(g),b=n(6),_=n.n(b),w=n(7),x=n.n(w),E=n(36),S=n.n(E),C=n(20),A=n.n(C),O=n(19),k=n.n(O),j=n(23),T=n.n(j),I=n(29),P=n.n(I),N=n(4),M=n.n(N),R=n(0),D=n.n(R),L=n(151),B=n(1),F=n.n(B),U=n(501),q=n(146),z=n(502),V=n.n(z),W=n(61),H=n(26),$=n(5),J=function(e){return e};var K=function(){function e(){var t,n=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};_()(this,e),v()(this,{state:{},plugins:[],pluginsOptions:{},system:{configs:{},fn:{},components:{},rootInjects:{},statePlugins:{}},boundSystem:{},toolbox:{}},n),this.getSystem=S()(t=this._getSystem).call(t,this),this.store=Q(J,Object(B.fromJS)(this.state),this.getSystem),this.buildSystem(!1),this.register(this.plugins)}return x()(e,[{key:"getStore",value:function(){return this.store}},{key:"register",value:function(e){var t=!(arguments.length>1&&void 0!==arguments[1])||arguments[1],n=Y(e,this.getSystem(),this.pluginsOptions);Z(this.system,n),t&&this.buildSystem();var r=G.call(this.system,e,this.getSystem());r&&this.buildSystem()}},{key:"buildSystem",value:function(){var e=!(arguments.length>0&&void 0!==arguments[0])||arguments[0],t=this.getStore().dispatch,n=this.getStore().getState;this.boundSystem=A()({},this.getRootInjects(),this.getWrappedAndBoundActions(t),this.getWrappedAndBoundSelectors(n,this.getSystem),this.getStateThunks(n),this.getFn(),this.getConfigs()),e&&this.rebuildReducer()}},{key:"_getSystem",value:function(){return this.boundSystem}},{key:"getRootInjects",value:function(){var e,t,n;return A()({getSystem:this.getSystem,getStore:S()(e=this.getStore).call(e,this),getComponents:S()(t=this.getComponents).call(t,this),getState:this.getStore().getState,getConfigs:S()(n=this._getConfigs).call(n,this),Im:F.a,React:D.a},this.system.rootInjects||{})}},{key:"_getConfigs",value:function(){return this.system.configs}},{key:"getConfigs",value:function(){return{configs:this.system.configs}}},{key:"setConfigs",value:function(e){this.system.configs=e}},{key:"rebuildReducer",value:function(){var e,t,n,r;this.store.replaceReducer((r=this.system.statePlugins,e=Object($.x)(r,(function(e){return e.reducers})),n=P()(t=f()(e)).call(t,(function(t,n){return t[n]=function(e){return function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:new B.Map,n=arguments.length>1?arguments[1]:void 0;if(!e)return t;var r=e[n.type];if(r){var o=X(r)(t,n);return null===o?t:o}return t}}(e[n]),t}),{}),f()(n).length?Object(U.combineReducers)(n):J))}},{key:"getType",value:function(e){var t=e[0].toUpperCase()+k()(e).call(e,1);return Object($.y)(this.system.statePlugins,(function(n,r){var o=n[e];if(o)return y()({},r+t,o)}))}},{key:"getSelectors",value:function(){return this.getType("selectors")}},{key:"getActions",value:function(){var e=this.getType("actions");return Object($.x)(e,(function(e){return Object($.y)(e,(function(e,t){if(Object($.r)(e))return y()({},t,e)}))}))}},{key:"getWrappedAndBoundActions",value:function(e){var t=this,n=this.getBoundActions(e);return Object($.x)(n,(function(e,n){var r=t.system.statePlugins[k()(n).call(n,0,-7)].wrapActions;return r?Object($.x)(e,(function(e,n){var o=r[n];return o?(T()(o)||(o=[o]),P()(o).call(o,(function(e,n){var r=function(){return n(e,t.getSystem()).apply(void 0,arguments)};if(!Object($.r)(r))throw new TypeError("wrapActions needs to return a function that returns a new function (ie the wrapped action)");return X(r)}),e||Function.prototype)):e})):e}))}},{key:"getWrappedAndBoundSelectors",value:function(e,t){var n=this,r=this.getBoundSelectors(e,t);return Object($.x)(r,(function(t,r){var o=[k()(r).call(r,0,-9)],a=n.system.statePlugins[o].wrapSelectors;return a?Object($.x)(t,(function(t,r){var i=a[r];return i?(T()(i)||(i=[i]),P()(i).call(i,(function(t,r){var a=function(){for(var a,i=arguments.length,s=new Array(i),c=0;c2&&void 0!==arguments[2]?arguments[2]:{},o=r.hasLoaded,a=o;return Object($.t)(e)&&!Object($.p)(e)&&"function"==typeof e.afterLoad&&(a=!0,X(e.afterLoad).call(this,t)),Object($.s)(e)?G.call(this,e(t),t,{hasLoaded:a}):Object($.p)(e)?M()(e).call(e,(function(e){return G.call(n,e,t,{hasLoaded:a})})):a}function Z(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};if(!Object($.t)(e))return{};if(!Object($.t)(t))return e;t.wrapComponents&&(Object($.x)(t.wrapComponents,(function(n,r){var o=e.components&&e.components[r];o&&T()(o)?(e.components[r]=u()(o).call(o,[n]),delete t.wrapComponents[r]):o&&(e.components[r]=[o,n],delete t.wrapComponents[r])})),f()(t.wrapComponents).length||delete t.wrapComponents);var n=e.statePlugins;if(Object($.t)(n))for(var r in n){var o=n[r];if(Object($.t)(o)){var a=o.wrapActions,i=o.wrapSelectors;if(Object($.t)(a))for(var s in a){var c,l=a[s];if(T()(l)||(l=[l],a[s]=l),t&&t.statePlugins&&t.statePlugins[r]&&t.statePlugins[r].wrapActions&&t.statePlugins[r].wrapActions[s])t.statePlugins[r].wrapActions[s]=u()(c=a[s]).call(c,t.statePlugins[r].wrapActions[s])}if(Object($.t)(i))for(var p in i){var h,d=i[p];if(T()(d)||(d=[d],i[p]=d),t&&t.statePlugins&&t.statePlugins[r]&&t.statePlugins[r].wrapSelectors&&t.statePlugins[r].wrapSelectors[p])t.statePlugins[r].wrapSelectors[p]=u()(h=i[p]).call(h,t.statePlugins[r].wrapSelectors[p])}}}return v()(e,t)}function X(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=t.logErrors,r=void 0===n||n;return"function"!=typeof e?e:function(){try{for(var t,n=arguments.length,o=new Array(n),a=0;a=0&&(void 0===t.allowTryItOut?t.specSelectors.allowTryItOutFor(t.path,t.method):t.allowTryItOut),g=r.getIn(["operation","security"])||t.specSelectors.security();return{operationId:h,isDeepLinkingEnabled:m,showSummary:f,displayOperationId:c,displayRequestDuration:l,allowTryItOut:v,security:g,isAuthorized:t.authSelectors.isAuthorized(g),isShown:o.isShown(d,"full"===i),jumpToKey:u()(n="paths.".concat(t.path,".")).call(n,t.method),response:t.specSelectors.responseFor(t.path,t.method),request:t.specSelectors.requestFor(t.path,t.method)}}},{key:"componentDidMount",value:function(){var e=this.props.isShown,t=this.getResolvedSubtree();e&&void 0===t&&this.requestResolvedSubtree()}},{key:"componentWillReceiveProps",value:function(e){var t=e.response,n=e.isShown,r=this.getResolvedSubtree();t!==this.props.response&&this.setState({executeInProgress:!1}),n&&void 0===r&&this.requestResolvedSubtree()}},{key:"render",value:function(){var e=this.props,t=e.op,n=e.tag,r=e.path,o=e.method,a=e.security,i=e.isAuthorized,s=e.operationId,u=e.showSummary,c=e.isShown,l=e.jumpToKey,p=e.allowTryItOut,f=e.response,h=e.request,d=e.displayOperationId,m=e.displayRequestDuration,v=e.isDeepLinkingEnabled,g=e.specPath,y=e.specSelectors,b=e.specActions,_=e.getComponent,w=e.getConfigs,x=e.layoutSelectors,E=e.layoutActions,S=e.authActions,C=e.authSelectors,A=e.oas3Actions,O=e.oas3Selectors,k=e.fn,j=_("operation"),T=this.getResolvedSubtree()||Object(B.Map)(),I=Object(B.fromJS)({op:T,tag:n,path:r,summary:t.getIn(["operation","summary"])||"",deprecated:T.get("deprecated")||t.getIn(["operation","deprecated"])||!1,method:o,security:a,isAuthorized:i,operationId:s,originalOperationId:T.getIn(["operation","__originalOperationId"]),showSummary:u,isShown:c,jumpToKey:l,allowTryItOut:p,request:h,displayOperationId:d,displayRequestDuration:m,isDeepLinkingEnabled:v,executeInProgress:this.state.executeInProgress,tryItOutEnabled:this.state.tryItOutEnabled});return D.a.createElement(j,{operation:I,response:f,request:h,isShown:c,toggleShown:this.toggleShown,onTryoutClick:this.onTryoutClick,onCancelClick:this.onCancelClick,onExecute:this.onExecute,specPath:g,specActions:b,specSelectors:y,oas3Actions:A,oas3Selectors:O,layoutActions:E,layoutSelectors:x,authActions:S,authSelectors:C,getComponent:_,getConfigs:w,fn:k})}}]),n}(R.PureComponent);y()(Se,"defaultProps",{showSummary:!0,response:null,allowTryItOut:!0,displayOperationId:!1,displayRequestDuration:!1});var Ce=function(e){ye()(n,e);var t=_e()(n);function n(){return _()(this,n),t.apply(this,arguments)}return x()(n,[{key:"getLayout",value:function(){var e=this.props,t=e.getComponent,n=e.layoutSelectors.current(),r=t(n,!0);return r||function(){return D.a.createElement("h1",null,' No layout defined for "',n,'" ')}}},{key:"render",value:function(){var e=this.getLayout();return D.a.createElement(e,null)}}]),n}(D.a.Component);Ce.defaultProps={};var Ae=function(e){ye()(n,e);var t=_e()(n);function n(){var e,r;_()(this,n);for(var o=arguments.length,a=new Array(o),i=0;i1&&void 0!==arguments[1]?arguments[1]:{},n=t.isSyntheticChange,o=void 0!==n&&n;"function"==typeof r.props.onSelect&&r.props.onSelect(e,{isSyntheticChange:o})})),y()(ve()(r),"_onDomSelect",(function(e){if("function"==typeof r.props.onSelect){var t=e.target.selectedOptions[0].getAttribute("value");r._onSelect(t,{isSyntheticChange:!1})}})),y()(ve()(r),"getCurrentExample",(function(){var e=r.props,t=e.examples,n=e.currentExampleKey,o=t.get(n),a=t.keySeq().first(),i=t.get(a);return o||i||Le()({})})),r}return x()(n,[{key:"componentDidMount",value:function(){var e=this.props,t=e.onSelect,n=e.examples;if("function"==typeof t){var r=n.first(),o=n.keyOf(r);this._onSelect(o,{isSyntheticChange:!0})}}},{key:"componentWillReceiveProps",value:function(e){var t=e.currentExampleKey,n=e.examples;if(n!==this.props.examples&&!n.has(t)){var r=n.first(),o=n.keyOf(r);this._onSelect(o,{isSyntheticChange:!0})}}},{key:"render",value:function(){var e=this.props,t=e.examples,n=e.currentExampleKey,r=e.isValueModified,o=e.isModifiedValueAvailable,a=e.showLabels;return D.a.createElement("div",{className:"examples-select"},a?D.a.createElement("span",{className:"examples-select__section-label"},"Examples: "):null,D.a.createElement("select",{className:"examples-select-element",onChange:this._onDomSelect,value:o&&r?"__MODIFIED__VALUE__":n||""},o?D.a.createElement("option",{value:"__MODIFIED__VALUE__"},"[Modified value]"):null,M()(t).call(t,(function(e,t){return D.a.createElement("option",{key:t,value:t},e.get("summary")||t)})).valueSeq()))}}]),n}(D.a.PureComponent);y()(Be,"defaultProps",{examples:F.a.Map({}),onSelect:function(){for(var e,t,n=arguments.length,r=new Array(n),o=0;o1&&void 0!==arguments[1]?arguments[1]:{},n=t.isSyntheticChange,o=r.props,a=o.onSelect,i=o.updateValue,s=o.currentUserInputValue,c=o.userHasEditedBody,l=r._getStateForCurrentNamespace(),p=l.lastUserEditedValue,f=r._getValueForExample(e);if("__MODIFIED__VALUE__"===e)return i(Fe(p)),r._setStateForCurrentNamespace({isModifiedValueSelected:!0});if("function"==typeof a){for(var h,d=arguments.length,m=new Array(d>2?d-2:0),v=2;v-1){var p;o.setState({scopes:l()(p=o.state.scopes).call(p,(function(e){return e!==i}))})}})),y()(ve()(o),"onInputChange",(function(e){var t=e.target,n=t.dataset.name,r=t.value,a=y()({},n,r);o.setState(a)})),y()(ve()(o),"selectScopes",(function(e){var t;e.target.dataset.all?o.setState({scopes:ze()(We()(t=o.props.schema.get("allowedScopes")||o.props.schema.get("scopes")).call(t))}):o.setState({scopes:[]})})),y()(ve()(o),"logout",(function(e){e.preventDefault();var t=o.props,n=t.authActions,r=t.errActions,a=t.name;r.clear({authId:a,type:"auth",source:"auth"}),n.logoutWithPersistOption([a])}));var a=o.props,i=a.name,s=a.schema,c=a.authorized,p=a.authSelectors,f=c&&c.get(i),h=p.getConfigs()||{},d=f&&f.get("username")||"",m=f&&f.get("clientId")||h.clientId||"",v=f&&f.get("clientSecret")||h.clientSecret||"",g=f&&f.get("passwordType")||"basic",b=f&&f.get("scopes")||h.scopes||[];return"string"==typeof b&&(b=b.split(h.scopeSeparator||" ")),o.state={appName:h.appName,name:i,schema:s,scopes:b,clientId:m,clientSecret:v,username:d,password:"",passwordType:g},o}return x()(n,[{key:"render",value:function(){var e,t,n=this,r=this.props,o=r.schema,a=r.getComponent,i=r.authSelectors,s=r.errSelectors,c=r.name,p=r.specSelectors,f=a("Input"),h=a("Row"),d=a("Col"),m=a("Button"),v=a("authError"),g=a("JumpToPath",!0),y=a("Markdown",!0),b=a("InitializedInput"),_=p.isOAS3,w=_()?o.get("openIdConnectUrl"):null,x="implicit",E="password",S=_()?w?"authorization_code":"authorizationCode":"accessCode",C=_()?w?"client_credentials":"clientCredentials":"application",A=o.get("flow"),O=o.get("allowedScopes")||o.get("scopes"),k=!!i.authorized().get(c),j=l()(e=s.allErrors()).call(e,(function(e){return e.get("authId")===c})),T=!l()(j).call(j,(function(e){return"validation"===e.get("source")})).size,I=o.get("description");return D.a.createElement("div",null,D.a.createElement("h4",null,c," (OAuth2, ",o.get("flow"),") ",D.a.createElement(g,{path:["securityDefinitions",c]})),this.state.appName?D.a.createElement("h5",null,"Application: ",this.state.appName," "):null,I&&D.a.createElement(y,{source:o.get("description")}),k&&D.a.createElement("h6",null,"Authorized"),w&&D.a.createElement("p",null,"OpenID Connect URL: ",D.a.createElement("code",null,w)),(A===x||A===S)&&D.a.createElement("p",null,"Authorization URL: ",D.a.createElement("code",null,o.get("authorizationUrl"))),(A===E||A===S||A===C)&&D.a.createElement("p",null,"Token URL:",D.a.createElement("code",null," ",o.get("tokenUrl"))),D.a.createElement("p",{className:"flow"},"Flow: ",D.a.createElement("code",null,o.get("flow"))),A!==E?null:D.a.createElement(h,null,D.a.createElement(h,null,D.a.createElement("label",{htmlFor:"oauth_username"},"username:"),k?D.a.createElement("code",null," ",this.state.username," "):D.a.createElement(d,{tablet:10,desktop:10},D.a.createElement("input",{id:"oauth_username",type:"text","data-name":"username",onChange:this.onInputChange,autoFocus:!0}))),D.a.createElement(h,null,D.a.createElement("label",{htmlFor:"oauth_password"},"password:"),k?D.a.createElement("code",null," ****** "):D.a.createElement(d,{tablet:10,desktop:10},D.a.createElement("input",{id:"oauth_password",type:"password","data-name":"password",onChange:this.onInputChange}))),D.a.createElement(h,null,D.a.createElement("label",{htmlFor:"password_type"},"Client credentials location:"),k?D.a.createElement("code",null," ",this.state.passwordType," "):D.a.createElement(d,{tablet:10,desktop:10},D.a.createElement("select",{id:"password_type","data-name":"passwordType",onChange:this.onInputChange},D.a.createElement("option",{value:"basic"},"Authorization header"),D.a.createElement("option",{value:"request-body"},"Request body"))))),(A===C||A===x||A===S||A===E)&&(!k||k&&this.state.clientId)&&D.a.createElement(h,null,D.a.createElement("label",{htmlFor:"client_id"},"client_id:"),k?D.a.createElement("code",null," ****** "):D.a.createElement(d,{tablet:10,desktop:10},D.a.createElement(b,{id:"client_id",type:"text",required:A===E,initialValue:this.state.clientId,"data-name":"clientId",onChange:this.onInputChange}))),(A===C||A===S||A===E)&&D.a.createElement(h,null,D.a.createElement("label",{htmlFor:"client_secret"},"client_secret:"),k?D.a.createElement("code",null," ****** "):D.a.createElement(d,{tablet:10,desktop:10},D.a.createElement(b,{id:"client_secret",initialValue:this.state.clientSecret,type:"password","data-name":"clientSecret",onChange:this.onInputChange}))),!k&&O&&O.size?D.a.createElement("div",{className:"scopes"},D.a.createElement("h2",null,"Scopes:",D.a.createElement("a",{onClick:this.selectScopes,"data-all":!0},"select all"),D.a.createElement("a",{onClick:this.selectScopes},"select none")),M()(O).call(O,(function(e,t){var r,o,a,i,s;return D.a.createElement(h,{key:t},D.a.createElement("div",{className:"checkbox"},D.a.createElement(f,{"data-value":t,id:u()(r=u()(o="".concat(t,"-")).call(o,A,"-checkbox-")).call(r,n.state.name),disabled:k,checked:$e()(a=n.state.scopes).call(a,t),type:"checkbox",onChange:n.onScopeChange}),D.a.createElement("label",{htmlFor:u()(i=u()(s="".concat(t,"-")).call(s,A,"-checkbox-")).call(i,n.state.name)},D.a.createElement("span",{className:"item"}),D.a.createElement("div",{className:"text"},D.a.createElement("p",{className:"name"},t),D.a.createElement("p",{className:"description"},e)))))})).toArray()):null,M()(t=j.valueSeq()).call(t,(function(e,t){return D.a.createElement(v,{error:e,key:t})})),D.a.createElement("div",{className:"auth-btn-wrapper"},T&&(k?D.a.createElement(m,{className:"btn modal-btn auth authorize",onClick:this.logout},"Logout"):D.a.createElement(m,{className:"btn modal-btn auth authorize",onClick:this.authorize},"Authorize")),D.a.createElement(m,{className:"btn modal-btn auth btn-done",onClick:this.close},"Close")))}}]),n}(D.a.Component),Ge=function(e){ye()(n,e);var t=_e()(n);function n(){var e,r;_()(this,n);for(var o=arguments.length,a=new Array(o),i=0;i2&&void 0!==arguments[2]?arguments[2]:{},r=n.selectedServer,o=void 0===r?"":r;if(e){if(it(e))return e;var a=st(o,t);return it(a)?new at.a(e,a).href:new at.a(e,window.location.href).href}}var ct=function(e){ye()(n,e);var t=_e()(n);function n(){return _()(this,n),t.apply(this,arguments)}return x()(n,[{key:"render",value:function(){var e,t=this.props,n=t.tagObj,r=t.tag,o=t.children,a=t.oas3Selectors,i=t.layoutSelectors,s=t.layoutActions,u=t.getConfigs,c=t.getComponent,l=t.specUrl,p=u(),f=p.docExpansion,h=p.deepLinking,d=h&&"false"!==h,m=c("Collapse"),v=c("Markdown",!0),g=c("DeepLink"),y=c("Link"),b=n.getIn(["tagDetails","description"],null),_=n.getIn(["tagDetails","externalDocs","description"]),w=n.getIn(["tagDetails","externalDocs","url"]);e=Object($.s)(a)&&Object($.s)(a.selectedServer)?ut(w,l,{selectedServer:a.selectedServer()}):w;var x=["operations-tag",r],E=i.isShown(x,"full"===f||"list"===f);return D.a.createElement("div",{className:E?"opblock-tag-section is-open":"opblock-tag-section"},D.a.createElement("h3",{onClick:function(){return s.show(x,!E)},className:b?"opblock-tag":"opblock-tag no-desc",id:M()(x).call(x,(function(e){return Object($.g)(e)})).join("-"),"data-tag":r,"data-is-open":E},D.a.createElement(g,{enabled:d,isShown:E,path:Object($.d)(r),text:r}),b?D.a.createElement("small",null,D.a.createElement(v,{source:b})):D.a.createElement("small",null),D.a.createElement("div",null,_?D.a.createElement("small",null,_,e?": ":null,e?D.a.createElement(y,{href:Object($.F)(e),onClick:function(e){return e.stopPropagation()},target:"_blank"},e):null):null),D.a.createElement("button",{"aria-expanded":E,className:"expand-operation",title:E?"Collapse operation":"Expand operation",onClick:function(){return s.show(x,!E)}},D.a.createElement("svg",{className:"arrow",width:"20",height:"20","aria-hidden":"true",focusable:"false"},D.a.createElement("use",{href:E?"#large-arrow-up":"#large-arrow-down",xlinkHref:E?"#large-arrow-up":"#large-arrow-down"})))),D.a.createElement(m,{isOpened:E},o))}}]),n}(D.a.Component);y()(ct,"defaultProps",{tagObj:F.a.fromJS({}),tag:""});var lt=function(e){ye()(r,e);var t=_e()(r);function r(){return _()(this,r),t.apply(this,arguments)}return x()(r,[{key:"render",value:function(){var e=this.props,t=e.specPath,r=e.response,o=e.request,a=e.toggleShown,i=e.onTryoutClick,s=e.onCancelClick,u=e.onExecute,c=e.fn,l=e.getComponent,p=e.getConfigs,f=e.specActions,h=e.specSelectors,d=e.authActions,m=e.authSelectors,v=e.oas3Actions,g=e.oas3Selectors,y=this.props.operation,b=y.toJS(),_=b.deprecated,w=b.isShown,x=b.path,E=b.method,S=b.op,C=b.tag,A=b.operationId,O=b.allowTryItOut,k=b.displayRequestDuration,j=b.tryItOutEnabled,T=b.executeInProgress,I=S.description,P=S.externalDocs,N=S.schemes,M=P?ut(P.url,h.url(),{selectedServer:g.selectedServer()}):"",R=y.getIn(["op"]),L=R.get("responses"),B=Object($.n)(R,["parameters"]),F=h.operationScheme(x,E),U=["operations",C,A],q=Object($.m)(R),z=l("responses"),V=l("parameters"),W=l("execute"),H=l("clear"),J=l("Collapse"),K=l("Markdown",!0),Y=l("schemes"),G=l("OperationServers"),Z=l("OperationExt"),X=l("OperationSummary"),Q=l("Link"),ee=p().showExtensions;if(L&&r&&r.size>0){var te=!L.get(String(r.get("status")))&&!L.get("default");r=r.set("notDocumented",te)}var ne=[x,E];return D.a.createElement("div",{className:_?"opblock opblock-deprecated":w?"opblock opblock-".concat(E," is-open"):"opblock opblock-".concat(E),id:Object($.g)(U.join("-"))},D.a.createElement(X,{operationProps:y,isShown:w,toggleShown:a,getComponent:l,authActions:d,authSelectors:m,specPath:t}),D.a.createElement(J,{isOpened:w},D.a.createElement("div",{className:"opblock-body"},R&&R.size||null===R?null:D.a.createElement("img",{height:"32px",width:"32px",src:n(497),className:"opblock-loading-animation"}),_&&D.a.createElement("h4",{className:"opblock-title_normal"}," Warning: Deprecated"),I&&D.a.createElement("div",{className:"opblock-description-wrapper"},D.a.createElement("div",{className:"opblock-description"},D.a.createElement(K,{source:I}))),M?D.a.createElement("div",{className:"opblock-external-docs-wrapper"},D.a.createElement("h4",{className:"opblock-title_normal"},"Find more details"),D.a.createElement("div",{className:"opblock-external-docs"},D.a.createElement("span",{className:"opblock-external-docs__description"},D.a.createElement(K,{source:P.description})),D.a.createElement(Q,{target:"_blank",className:"opblock-external-docs__link",href:Object($.F)(M)},M))):null,R&&R.size?D.a.createElement(V,{parameters:B,specPath:t.push("parameters"),operation:R,onChangeKey:ne,onTryoutClick:i,onCancelClick:s,tryItOutEnabled:j,allowTryItOut:O,fn:c,getComponent:l,specActions:f,specSelectors:h,pathMethod:[x,E],getConfigs:p,oas3Actions:v,oas3Selectors:g}):null,j?D.a.createElement(G,{getComponent:l,path:x,method:E,operationServers:R.get("servers"),pathServers:h.paths().getIn([x,"servers"]),getSelectedServer:g.selectedServer,setSelectedServer:v.setSelectedServer,setServerVariableValue:v.setServerVariableValue,getServerVariable:g.serverVariableValue,getEffectiveServerValue:g.serverEffectiveValue}):null,j&&O&&N&&N.size?D.a.createElement("div",{className:"opblock-schemes"},D.a.createElement(Y,{schemes:N,path:x,method:E,specActions:f,currentScheme:F})):null,D.a.createElement("div",{className:j&&r&&O?"btn-group":"execute-wrapper"},j&&O?D.a.createElement(W,{operation:R,specActions:f,specSelectors:h,oas3Selectors:g,oas3Actions:v,path:x,method:E,onExecute:u,disabled:T}):null,j&&r&&O?D.a.createElement(H,{specActions:f,path:x,method:E}):null),T?D.a.createElement("div",{className:"loading-container"},D.a.createElement("div",{className:"loading"})):null,L?D.a.createElement(z,{responses:L,request:o,tryItOutResponse:r,getComponent:l,getConfigs:p,specSelectors:h,oas3Actions:v,oas3Selectors:g,specActions:f,produces:h.producesOptionsFor([x,E]),producesValue:h.currentProducesFor([x,E]),specPath:t.push("responses"),path:x,method:E,displayRequestDuration:k,fn:c}):null,ee&&q.size?D.a.createElement(Z,{extensions:q,getComponent:l}):null)))}}]),r}(R.PureComponent);y()(lt,"defaultProps",{operation:null,response:null,request:null,specPath:Object(B.List)(),summary:""});var pt=n(100),ft=n.n(pt),ht=function(e){ye()(n,e);var t=_e()(n);function n(){return _()(this,n),t.apply(this,arguments)}return x()(n,[{key:"render",value:function(){var e,t=this.props,n=t.isShown,r=t.toggleShown,o=t.getComponent,a=t.authActions,i=t.authSelectors,s=t.operationProps,c=t.specPath,l=s.toJS(),p=l.summary,f=l.isAuthorized,h=l.method,d=l.op,m=l.showSummary,v=l.path,g=l.operationId,y=l.originalOperationId,b=l.displayOperationId,_=d.summary,w=s.get("security"),x=o("authorizeOperationBtn"),E=o("OperationSummaryMethod"),S=o("OperationSummaryPath"),C=o("JumpToPath",!0),A=w&&!!w.count(),O=A&&1===w.size&&w.first().isEmpty(),k=!A||O;return D.a.createElement("div",{className:"opblock-summary opblock-summary-".concat(h)},D.a.createElement("button",{"aria-label":u()(e="".concat(h," ")).call(e,v.replace(/\//g,"​/")),"aria-expanded":n,className:"opblock-summary-control",onClick:r},D.a.createElement(E,{method:h}),D.a.createElement(S,{getComponent:o,operationProps:s,specPath:c}),m?D.a.createElement("div",{className:"opblock-summary-description"},ft()(_||p)):null,b&&(y||g)?D.a.createElement("span",{className:"opblock-summary-operation-id"},y||g):null,D.a.createElement("svg",{className:"arrow",width:"20",height:"20","aria-hidden":"true",focusable:"false"},D.a.createElement("use",{href:n?"#large-arrow-up":"#large-arrow-down",xlinkHref:n?"#large-arrow-up":"#large-arrow-down"}))),k?null:D.a.createElement(x,{isAuthorized:f,onClick:function(){var e=i.definitionsForRequirements(w);a.showDefinitions(e)}}),D.a.createElement(C,{path:c}))}}]),n}(R.PureComponent);y()(ht,"defaultProps",{operationProps:null,specPath:Object(B.List)(),summary:""});var dt=function(e){ye()(n,e);var t=_e()(n);function n(){return _()(this,n),t.apply(this,arguments)}return x()(n,[{key:"render",value:function(){var e=this.props.method;return D.a.createElement("span",{className:"opblock-summary-method"},e.toUpperCase())}}]),n}(R.PureComponent);y()(dt,"defaultProps",{operationProps:null});var mt=n(213),vt=n.n(mt),gt=function(e){ye()(n,e);var t=_e()(n);function n(){return _()(this,n),t.apply(this,arguments)}return x()(n,[{key:"render",value:function(){for(var e,t=this.props,n=t.getComponent,r=t.operationProps.toJS(),o=r.deprecated,a=r.isShown,i=r.path,s=r.tag,c=r.operationId,l=r.isDeepLinkingEnabled,p=i.split(/(?=\/)/g),f=1;fo&&(0===a&&n<0||o+a>=r&&n>0)&&e.preventDefault()})),r}return x()(n,[{key:"componentDidMount",value:function(){var e,t=this;null===(e=Et()(this,Dt))||void 0===e||Ot()(e).call(e,(function(e){return e.addEventListener("mousewheel",t.preventYScrollingBeyondElement,{passive:!1})}))}},{key:"componentWillUnmount",value:function(){var e,t=this;null===(e=Et()(this,Dt))||void 0===e||Ot()(e).call(e,(function(e){return e.removeEventListener("mousewheel",t.preventYScrollingBeyondElement)}))}},{key:"render",value:function(){var e=this.props,t=e.value,n=e.className,r=e.downloadable,o=e.getConfigs,a=e.canCopy,i=e.language,s=o?o():{syntaxHighlight:{activated:!0,theme:"agate"}};n=n||"";var u=Pt()(s,"syntaxHighlight.activated")?D.a.createElement(Tt.a,{language:i,className:n+" microlight",style:Object(Tt.b)(Pt()(s,"syntaxHighlight.theme"))},t):D.a.createElement("pre",{className:n+" microlight"},t);return D.a.createElement("div",{className:"highlight-code",ref:this.handleRootRef},r?D.a.createElement("div",{className:"download-contents",onClick:this.downloadText},"Download"):null,a?D.a.createElement("div",{className:"copy-to-clipboard"},D.a.createElement(Rt.CopyToClipboard,{text:t},D.a.createElement("button",null))):null,u)}}]),n}(R.Component);var Bt=function(e){ye()(n,e);var t=_e()(n);function n(){var e,r;_()(this,n);for(var o=arguments.length,a=new Array(o),i=0;i1&&void 0!==arguments[1]?arguments[1]:"_";return e.replace(/[^\w-]/g,t)}(u()(e="".concat(v)).call(e,m,"_responses")),A="".concat(C,"_select");return D.a.createElement("div",{className:"responses-wrapper"},D.a.createElement("div",{className:"opblock-section-header"},D.a.createElement("h4",null,"Responses"),l.isOAS3()?null:D.a.createElement("label",{htmlFor:A},D.a.createElement("span",null,"Response content type"),D.a.createElement(_,{value:f,ariaControls:C,ariaLabel:"Response content type",className:"execute-content-type",contentTypes:E,controlId:A,onChange:this.onChangeProducesWrapper}))),D.a.createElement("div",{className:"responses-inner"},i?D.a.createElement("div",null,D.a.createElement(w,{response:i,getComponent:s,getConfigs:c,specSelectors:l,path:this.props.path,method:this.props.method,displayRequestDuration:h}),D.a.createElement("h4",null,"Responses")):null,D.a.createElement("table",{"aria-live":"polite",className:"responses-table",id:C,role:"region"},D.a.createElement("thead",null,D.a.createElement("tr",{className:"responses-header"},D.a.createElement("td",{className:"col_header response-col_status"},"Code"),D.a.createElement("td",{className:"col_header response-col_description"},"Description"),l.isOAS3()?D.a.createElement("td",{className:"col col_header response-col_links"},"Links"):null)),D.a.createElement("tbody",null,M()(t=a.entrySeq()).call(t,(function(e){var t=bt()(e,2),n=t[0],o=t[1],a=i&&i.get("status")==n?"response_current":"";return D.a.createElement(x,{key:n,path:m,method:v,specPath:d.push(n),isDefault:b===n,fn:p,className:a,code:n,response:o,specSelectors:l,controlsAcceptHeader:o===S,onContentTypeChange:r.onResponseContentTypeChange,contentType:f,getConfigs:c,activeExamplesKey:g.activeExamplesMember(m,v,"responses",n),oas3Actions:y,getComponent:s})})).toArray()))))}}]),n}(D.a.Component);y()(Bt,"defaultProps",{tryItOutResponse:null,produces:Object(B.fromJS)(["application/json"]),displayRequestDuration:!1});var Ft=n(24),Ut=n.n(Ft),qt=n(531),zt=n.n(qt),Vt=n(50),Wt=n.n(Vt),Ht=n(103),$t=function(e){ye()(n,e);var t=_e()(n);function n(e,r){var o;return _()(this,n),o=t.call(this,e,r),y()(ve()(o),"_onContentTypeChange",(function(e){var t=o.props,n=t.onContentTypeChange,r=t.controlsAcceptHeader;o.setState({responseContentType:e}),n({value:e,controlsAcceptHeader:r})})),y()(ve()(o),"getTargetExamplesKey",(function(){var e=o.props,t=e.response,n=e.contentType,r=e.activeExamplesKey,a=o.state.responseContentType||n,i=t.getIn(["content",a],Object(B.Map)({})).get("examples",null).keySeq().first();return r||i})),o.state={responseContentType:""},o}return x()(n,[{key:"render",value:function(){var e,t,n,r,o,a=this.props,i=a.path,s=a.method,c=a.code,l=a.response,p=a.className,f=a.specPath,h=a.fn,d=a.getComponent,m=a.getConfigs,v=a.specSelectors,g=a.contentType,y=a.controlsAcceptHeader,b=a.oas3Actions,_=h.inferSchema,w=v.isOAS3(),x=m().showExtensions,E=x?Object($.m)(l):null,S=l.get("headers"),C=l.get("links"),A=d("ResponseExtension"),O=d("headers"),k=d("highlightCode"),j=d("modelExample"),T=d("Markdown",!0),I=d("operationLink"),P=d("contentType"),N=d("ExamplesSelect"),R=d("Example"),L=this.state.responseContentType||g,F=l.getIn(["content",L],Object(B.Map)({})),U=F.get("examples",null);if(w){var q=F.get("schema");n=q?_(q.toJS()):null,r=q?Object(B.List)(["content",this.state.responseContentType,"schema"]):f}else n=l.get("schema"),r=l.has("schema")?f.push("schema"):f;var z,V=!1,W={includeReadOnly:!0};if(w){var H;if(z=null===(H=F.get("schema"))||void 0===H?void 0:H.toJS(),U){var J=this.getTargetExamplesKey(),K=function(e){return e.get("value")};void 0===(o=K(U.get(J,Object(B.Map)({}))))&&(o=K(zt()(U).call(U).next().value)),V=!0}else void 0!==F.get("example")&&(o=F.get("example"),V=!0)}else{z=n,W=Ut()(Ut()({},W),{},{includeWriteOnly:!0});var Y=l.getIn(["examples",L]);Y&&(o=Y,V=!0)}var G=function(e,t,n){if(null!=e){var r=null;return Object(Ht.a)(e)&&(r="json"),D.a.createElement("div",null,D.a.createElement(t,{className:"example",getConfigs:n,language:r,value:Object($.I)(e)}))}return null}(Object($.o)(z,L,W,V?o:void 0),k,m);return D.a.createElement("tr",{className:"response "+(p||""),"data-code":c},D.a.createElement("td",{className:"response-col_status"},c),D.a.createElement("td",{className:"response-col_description"},D.a.createElement("div",{className:"response-col_description__inner"},D.a.createElement(T,{source:l.get("description")})),x&&E.size?M()(e=E.entrySeq()).call(e,(function(e){var t,n=bt()(e,2),r=n[0],o=n[1];return D.a.createElement(A,{key:u()(t="".concat(r,"-")).call(t,o),xKey:r,xVal:o})})):null,w&&l.get("content")?D.a.createElement("section",{className:"response-controls"},D.a.createElement("div",{className:Wt()("response-control-media-type",{"response-control-media-type--accept-controller":y})},D.a.createElement("small",{className:"response-control-media-type__title"},"Media type"),D.a.createElement(P,{value:this.state.responseContentType,contentTypes:l.get("content")?l.get("content").keySeq():Object(B.Seq)(),onChange:this._onContentTypeChange,ariaLabel:"Media Type"}),y?D.a.createElement("small",{className:"response-control-media-type__accept-message"},"Controls ",D.a.createElement("code",null,"Accept")," header."):null),U?D.a.createElement("div",{className:"response-control-examples"},D.a.createElement("small",{className:"response-control-examples__title"},"Examples"),D.a.createElement(N,{examples:U,currentExampleKey:this.getTargetExamplesKey(),onSelect:function(e){return b.setActiveExamplesMember({name:e,pathMethod:[i,s],contextType:"responses",contextName:c})},showLabels:!1})):null):null,G||n?D.a.createElement(j,{specPath:r,getComponent:d,getConfigs:m,specSelectors:v,schema:Object($.i)(n),example:G,includeReadOnly:!0}):null,w&&U?D.a.createElement(R,{example:U.get(this.getTargetExamplesKey(),Object(B.Map)({})),getComponent:d,getConfigs:m,omitValue:!0}):null,S?D.a.createElement(O,{headers:S,getComponent:d}):null),w?D.a.createElement("td",{className:"response-col_links"},C?M()(t=C.toSeq().entrySeq()).call(t,(function(e){var t=bt()(e,2),n=t[0],r=t[1];return D.a.createElement(I,{key:n,name:n,link:r,getComponent:d})})):D.a.createElement("i",null,"No links")):null)}}]),n}(D.a.Component);y()($t,"defaultProps",{response:Object(B.fromJS)({}),onContentTypeChange:function(){}});var Jt=function(e){var t=e.xKey,n=e.xVal;return D.a.createElement("div",{className:"response__extension"},t,": ",String(n))},Kt=n(532),Yt=n.n(Kt),Gt=n(533),Zt=n.n(Gt),Xt=n(356),Qt=n.n(Xt),en=function(e){ye()(n,e);var t=_e()(n);function n(){var e,r;_()(this,n);for(var o=arguments.length,a=new Array(o),i=0;i0?l?D.a.createElement("div",null,D.a.createElement("p",{className:"i"},"Unrecognized response type; displaying content as text."),D.a.createElement(p,{downloadable:!0,fileName:"".concat(f,".txt"),value:l,getConfigs:u,canCopy:!0})):D.a.createElement("p",{className:"i"},"Unrecognized response type; unable to display."):null;return t?D.a.createElement("div",null,D.a.createElement("h5",null,"Response body"),t):null}}]),n}(D.a.PureComponent),tn=n(14),nn=n.n(tn),rn=n(211),on=n.n(rn),an=function(e){ye()(n,e);var t=_e()(n);function n(e){var r;return _()(this,n),r=t.call(this,e),y()(ve()(r),"onChange",(function(e,t,n){var o=r.props;(0,o.specActions.changeParamByIdentity)(o.onChangeKey,e,t,n)})),y()(ve()(r),"onChangeConsumesWrapper",(function(e){var t=r.props;(0,t.specActions.changeConsumesValue)(t.onChangeKey,e)})),y()(ve()(r),"toggleTab",(function(e){return"parameters"===e?r.setState({parametersVisible:!0,callbackVisible:!1}):"callbacks"===e?r.setState({callbackVisible:!0,parametersVisible:!1}):void 0})),y()(ve()(r),"onChangeMediaType",(function(e){var t=e.value,n=e.pathMethod,o=r.props,a=o.specActions,i=o.oas3Selectors,s=o.oas3Actions,u=i.hasUserEditedBody.apply(i,nn()(n)),c=i.shouldRetainRequestBodyValue.apply(i,nn()(n));s.setRequestContentType({value:t,pathMethod:n}),s.initRequestBodyValidateError({pathMethod:n}),u||(c||s.setRequestBodyValue({value:void 0,pathMethod:n}),a.clearResponse.apply(a,nn()(n)),a.clearRequest.apply(a,nn()(n)),a.clearValidateParams(n))})),r.state={callbackVisible:!1,parametersVisible:!0},r}return x()(n,[{key:"render",value:function(){var e,t,n=this,r=this.props,o=r.onTryoutClick,a=r.parameters,i=r.allowTryItOut,s=r.tryItOutEnabled,c=r.specPath,l=r.fn,p=r.getComponent,f=r.getConfigs,h=r.specSelectors,d=r.specActions,m=r.pathMethod,v=r.oas3Actions,g=r.oas3Selectors,y=r.operation,b=p("parameterRow"),_=p("TryItOutButton"),w=p("contentType"),x=p("Callbacks",!0),E=p("RequestBody",!0),S=s&&i,C=h.isOAS3(),A=y.get("requestBody"),O=P()(e=on()(P()(a).call(a,(function(e,t){var n,r=t.get("in");return null!==(n=e[r])&&void 0!==n||(e[r]=[]),e[r].push(t),e}),{}))).call(e,(function(e,t){return u()(e).call(e,t)}),[]);return D.a.createElement("div",{className:"opblock-section"},D.a.createElement("div",{className:"opblock-section-header"},C?D.a.createElement("div",{className:"tab-header"},D.a.createElement("div",{onClick:function(){return n.toggleTab("parameters")},className:"tab-item ".concat(this.state.parametersVisible&&"active")},D.a.createElement("h4",{className:"opblock-title"},D.a.createElement("span",null,"Parameters"))),y.get("callbacks")?D.a.createElement("div",{onClick:function(){return n.toggleTab("callbacks")},className:"tab-item ".concat(this.state.callbackVisible&&"active")},D.a.createElement("h4",{className:"opblock-title"},D.a.createElement("span",null,"Callbacks"))):null):D.a.createElement("div",{className:"tab-header"},D.a.createElement("h4",{className:"opblock-title"},"Parameters")),i?D.a.createElement(_,{isOAS3:h.isOAS3(),hasUserEditedBody:g.hasUserEditedBody.apply(g,nn()(m)),enabled:s,onCancelClick:this.props.onCancelClick,onTryoutClick:o,onResetClick:function(){return v.setRequestBodyValue({value:void 0,pathMethod:m})}}):null),this.state.parametersVisible?D.a.createElement("div",{className:"parameters-container"},O.length?D.a.createElement("div",{className:"table-container"},D.a.createElement("table",{className:"parameters"},D.a.createElement("thead",null,D.a.createElement("tr",null,D.a.createElement("th",{className:"col_header parameters-col_name"},"Name"),D.a.createElement("th",{className:"col_header parameters-col_description"},"Description"))),D.a.createElement("tbody",null,M()(O).call(O,(function(e,t){var r;return D.a.createElement(b,{fn:l,specPath:c.push(t.toString()),getComponent:p,getConfigs:f,rawParam:e,param:h.parameterWithMetaByIdentity(m,e),key:u()(r="".concat(e.get("in"),".")).call(r,e.get("name")),onChange:n.onChange,onChangeConsumes:n.onChangeConsumesWrapper,specSelectors:h,specActions:d,oas3Actions:v,oas3Selectors:g,pathMethod:m,isExecute:S})}))))):D.a.createElement("div",{className:"opblock-description-wrapper"},D.a.createElement("p",null,"No parameters"))):null,this.state.callbackVisible?D.a.createElement("div",{className:"callbacks-container opblock-description-wrapper"},D.a.createElement(x,{callbacks:Object(B.Map)(y.get("callbacks")),specPath:k()(c).call(c,0,-1).push("callbacks")})):null,C&&A&&this.state.parametersVisible&&D.a.createElement("div",{className:"opblock-section opblock-section-request-body"},D.a.createElement("div",{className:"opblock-section-header"},D.a.createElement("h4",{className:"opblock-title parameter__name ".concat(A.get("required")&&"required")},"Request body"),D.a.createElement("label",null,D.a.createElement(w,{value:g.requestContentType.apply(g,nn()(m)),contentTypes:A.get("content",Object(B.List)()).keySeq(),onChange:function(e){n.onChangeMediaType({value:e,pathMethod:m})},className:"body-param-content-type",ariaLabel:"Request content type"}))),D.a.createElement("div",{className:"opblock-description-wrapper"},D.a.createElement(E,{setRetainRequestBodyValueFlag:function(e){return v.setRetainRequestBodyValueFlag({value:e,pathMethod:m})},userHasEditedBody:g.hasUserEditedBody.apply(g,nn()(m)),specPath:k()(c).call(c,0,-1).push("requestBody"),requestBody:A,requestBodyValue:g.requestBodyValue.apply(g,nn()(m)),requestBodyInclusionSetting:g.requestBodyInclusionSetting.apply(g,nn()(m)),requestBodyErrors:g.requestBodyErrors.apply(g,nn()(m)),isExecute:S,getConfigs:f,activeExamplesKey:g.activeExamplesMember.apply(g,u()(t=nn()(m)).call(t,["requestBody","requestBody"])),updateActiveExamplesKey:function(e){n.props.oas3Actions.setActiveExamplesMember({name:e,pathMethod:n.props.pathMethod,contextType:"requestBody",contextName:"requestBody"})},onChange:function(e,t){if(t){var n=g.requestBodyValue.apply(g,nn()(m)),r=B.Map.isMap(n)?n:Object(B.Map)();return v.setRequestBodyValue({pathMethod:m,value:r.setIn(t,e)})}v.setRequestBodyValue({value:e,pathMethod:m})},onChangeIncludeEmpty:function(e,t){v.setRequestBodyInclusion({pathMethod:m,value:t,name:e})},contentType:g.requestContentType.apply(g,nn()(m))}))))}}]),n}(R.Component);y()(an,"defaultProps",{onTryoutClick:Function.prototype,onCancelClick:Function.prototype,tryItOutEnabled:!1,allowTryItOut:!0,onChangeKey:[],specPath:[]});var sn=function(e){var t=e.xKey,n=e.xVal;return D.a.createElement("div",{className:"parameter__extension"},t,": ",String(n))},un={onChange:function(){},isIncludedOptions:{}},cn=function(e){ye()(n,e);var t=_e()(n);function n(){var e,r;_()(this,n);for(var o=arguments.length,a=new Array(o),i=0;i1&&void 0!==arguments[1]&&arguments[1],n=o.props,r=n.onChange,a=n.rawParam;return r(a,""===e||e&&0===e.size?null:e,t)})),y()(ve()(o),"_onExampleSelect",(function(e){o.props.oas3Actions.setActiveExamplesMember({name:e,pathMethod:o.props.pathMethod,contextType:"parameters",contextName:o.getParamKey()})})),y()(ve()(o),"onChangeIncludeEmpty",(function(e){var t=o.props,n=t.specActions,r=t.param,a=t.pathMethod,i=r.get("name"),s=r.get("in");return n.updateEmptyParamInclusion(a,i,s,e)})),y()(ve()(o),"setDefaultValue",(function(){var e=o.props,t=e.specSelectors,n=e.pathMethod,r=e.rawParam,a=e.oas3Selectors,i=t.parameterWithMetaByIdentity(n,r)||Object(B.Map)(),s=Object(ln.a)(i,{isOAS3:t.isOAS3()}).schema,c=i.get("content",Object(B.Map)()).keySeq().first(),l=s?Object($.o)(s.toJS(),c,{includeWriteOnly:!0}):null;if(i&&void 0===i.get("value")&&"body"!==i.get("in")){var p;if(t.isSwagger2())p=void 0!==i.get("x-example")?i.get("x-example"):void 0!==i.getIn(["schema","example"])?i.getIn(["schema","example"]):s&&s.getIn(["default"]);else if(t.isOAS3()){var f,h=a.activeExamplesMember.apply(a,u()(f=nn()(n)).call(f,["parameters",o.getParamKey()]));p=void 0!==i.getIn(["examples",h,"value"])?i.getIn(["examples",h,"value"]):void 0!==i.getIn(["content",c,"example"])?i.getIn(["content",c,"example"]):void 0!==i.get("example")?i.get("example"):void 0!==(s&&s.get("example"))?s&&s.get("example"):void 0!==(s&&s.get("default"))?s&&s.get("default"):i.get("default")}void 0===p||B.List.isList(p)||(p=Object($.I)(p)),void 0!==p?o.onChangeWrapper(p):s&&"object"===s.get("type")&&l&&!i.get("examples")&&o.onChangeWrapper(B.List.isList(l)?l:Object($.I)(l))}})),o.setDefaultValue(),o}return x()(n,[{key:"componentWillReceiveProps",value:function(e){var t,n=e.specSelectors,r=e.pathMethod,o=e.rawParam,a=n.isOAS3(),i=n.parameterWithMetaByIdentity(r,o)||new B.Map;if(i=i.isEmpty()?o:i,a){var s=Object(ln.a)(i,{isOAS3:a}).schema;t=s?s.get("enum"):void 0}else t=i?i.get("enum"):void 0;var u,c=i?i.get("value"):void 0;void 0!==c?u=c:o.get("required")&&t&&t.size&&(u=t.first()),void 0!==u&&u!==c&&this.onChangeWrapper(Object($.w)(u)),this.setDefaultValue()}},{key:"getParamKey",value:function(){var e,t=this.props.param;return t?u()(e="".concat(t.get("name"),"-")).call(e,t.get("in")):null}},{key:"render",value:function(){var e,t,n,r,o=this.props,a=o.param,i=o.rawParam,s=o.getComponent,c=o.getConfigs,l=o.isExecute,p=o.fn,f=o.onChangeConsumes,h=o.specSelectors,d=o.pathMethod,m=o.specPath,v=o.oas3Selectors,g=h.isOAS3(),y=c(),b=y.showExtensions,_=y.showCommonExtensions;if(a||(a=i),!i)return null;var w,x,E,S,C=s("JsonSchemaForm"),A=s("ParamBody"),O=a.get("in"),k="body"!==O?null:D.a.createElement(A,{getComponent:s,getConfigs:c,fn:p,param:a,consumes:h.consumesOptionsFor(d),consumesValue:h.contentTypeValues(d).get("requestContentType"),onChange:this.onChangeWrapper,onChangeConsumes:f,isExecute:l,specSelectors:h,pathMethod:d}),j=s("modelExample"),T=s("Markdown",!0),I=s("ParameterExt"),P=s("ParameterIncludeEmpty"),N=s("ExamplesSelectValueRetainer"),R=s("Example"),L=Object(ln.a)(a,{isOAS3:g}).schema,F=h.parameterWithMetaByIdentity(d,i)||Object(B.Map)(),U=L?L.get("format"):null,q=L?L.get("type"):null,z=L?L.getIn(["items","type"]):null,V="formData"===O,W="FormData"in H.a,J=a.get("required"),K=F?F.get("value"):"",Y=_?Object($.l)(L):null,G=b?Object($.m)(a):null,Z=!1;return void 0!==a&&L&&(w=L.get("items")),void 0!==w?(x=w.get("enum"),E=w.get("default")):L&&(x=L.get("enum")),x&&x.size&&x.size>0&&(Z=!0),void 0!==a&&(L&&(E=L.get("default")),void 0===E&&(E=a.get("default")),void 0===(S=a.get("example"))&&(S=a.get("x-example"))),D.a.createElement("tr",{"data-param-name":a.get("name"),"data-param-in":a.get("in")},D.a.createElement("td",{className:"parameters-col_name"},D.a.createElement("div",{className:J?"parameter__name required":"parameter__name"},a.get("name"),J?D.a.createElement("span",null," *"):null),D.a.createElement("div",{className:"parameter__type"},q,z&&"[".concat(z,"]"),U&&D.a.createElement("span",{className:"prop-format"},"($",U,")")),D.a.createElement("div",{className:"parameter__deprecated"},g&&a.get("deprecated")?"deprecated":null),D.a.createElement("div",{className:"parameter__in"},"(",a.get("in"),")"),_&&Y.size?M()(e=Y.entrySeq()).call(e,(function(e){var t,n=bt()(e,2),r=n[0],o=n[1];return D.a.createElement(I,{key:u()(t="".concat(r,"-")).call(t,o),xKey:r,xVal:o})})):null,b&&G.size?M()(t=G.entrySeq()).call(t,(function(e){var t,n=bt()(e,2),r=n[0],o=n[1];return D.a.createElement(I,{key:u()(t="".concat(r,"-")).call(t,o),xKey:r,xVal:o})})):null),D.a.createElement("td",{className:"parameters-col_description"},a.get("description")?D.a.createElement(T,{source:a.get("description")}):null,!k&&l||!Z?null:D.a.createElement(T,{className:"parameter__enum",source:"Available values : "+M()(x).call(x,(function(e){return e})).toArray().join(", ")}),!k&&l||void 0===E?null:D.a.createElement(T,{className:"parameter__default",source:"Default value : "+E}),!k&&l||void 0===S?null:D.a.createElement(T,{source:"Example : "+S}),V&&!W&&D.a.createElement("div",null,"Error: your browser does not support FormData"),g&&a.get("examples")?D.a.createElement("section",{className:"parameter-controls"},D.a.createElement(N,{examples:a.get("examples"),onSelect:this._onExampleSelect,updateValue:this.onChangeWrapper,getComponent:s,defaultToFirstExample:!0,currentKey:v.activeExamplesMember.apply(v,u()(n=nn()(d)).call(n,["parameters",this.getParamKey()])),currentUserInputValue:K})):null,k?null:D.a.createElement(C,{fn:p,getComponent:s,value:K,required:J,disabled:!l,description:a.get("name"),onChange:this.onChangeWrapper,errors:F.get("errors"),schema:L}),k&&L?D.a.createElement(j,{getComponent:s,specPath:m.push("schema"),getConfigs:c,isExecute:l,specSelectors:h,schema:L,example:k,includeWriteOnly:!0}):null,!k&&l&&a.get("allowEmptyValue")?D.a.createElement(P,{onChange:this.onChangeIncludeEmpty,isIncluded:h.parameterInclusionSettingFor(d,a.get("name"),a.get("in")),isDisabled:!Object($.q)(K)}):null,g&&a.get("examples")?D.a.createElement(R,{example:a.getIn(["examples",v.activeExamplesMember.apply(v,u()(r=nn()(d)).call(r,["parameters",this.getParamKey()]))]),getComponent:s,getConfigs:c}):null))}}]),n}(R.Component),fn=n(216),hn=n.n(fn),dn=function(e){ye()(n,e);var t=_e()(n);function n(){var e,r;_()(this,n);for(var o=arguments.length,a=new Array(o),i=0;i0&&"none"!==p),m=r.isOAS3(),v=o("ModelWrapper"),g=o("Collapse"),y=o("ModelCollapse"),b=o("JumpToPath");return D.a.createElement("section",{className:d?"models is-open":"models",ref:this.onLoadModels},D.a.createElement("h4",null,D.a.createElement("button",{"aria-expanded":d,className:"models-control",onClick:function(){return i.show(h,!d)}},D.a.createElement("span",null,m?"Schemas":"Models"),D.a.createElement("svg",{width:"20",height:"20","aria-hidden":"true",focusable:"false"},D.a.createElement("use",{xlinkHref:d?"#large-arrow-up":"#large-arrow-down"})))),D.a.createElement(g,{isOpened:d},M()(e=c.entrySeq()).call(e,(function(e){var n,c=bt()(e,1)[0],l=u()(n=[]).call(n,nn()(h),[c]),p=F.a.List(l),d=r.specResolvedSubtree(l),m=r.specJson().getIn(l),g=B.Map.isMap(d)?d:F.a.Map(),_=B.Map.isMap(m)?m:F.a.Map(),w=g.get("title")||_.get("title")||c,x=a.isShown(l,!1);x&&0===g.size&&_.size>0&&t.props.specActions.requestResolvedSubtree(l);var E=D.a.createElement(v,{name:c,expandDepth:f,schema:g||F.a.Map(),displayName:w,fullPath:l,specPath:p,getComponent:o,specSelectors:r,getConfigs:s,layoutSelectors:a,layoutActions:i,includeReadOnly:!0,includeWriteOnly:!0}),S=D.a.createElement("span",{className:"model-box"},D.a.createElement("span",{className:"model model-title"},w));return D.a.createElement("div",{id:"model-".concat(c),className:"model-container",key:"models-section-".concat(c),"data-name":c,ref:t.onLoadModel},D.a.createElement("span",{className:"models-jump-to-path"},D.a.createElement(b,{specPath:p})),D.a.createElement(y,{classes:"model-box",collapsedContent:t.getCollapsedContent(c),onToggle:t.handleToggle,title:S,displayName:w,modelName:c,specPath:p,layoutSelectors:a,layoutActions:i,hideSelfOnExpand:!0,expanded:f>0&&x},E))})).toArray()))}}]),n}(R.Component),hr=function(e){var t=e.value,n=(0,e.getComponent)("ModelCollapse"),r=D.a.createElement("span",null,"Array [ ",t.count()," ]");return D.a.createElement("span",{className:"prop-enum"},"Enum:",D.a.createElement("br",null),D.a.createElement(n,{collapsedContent:r},"[ ",t.join(", ")," ]"))},dr=["schema","name","displayName","isRef","getComponent","getConfigs","depth","onToggle","expanded","specPath"],mr=function(e){ye()(n,e);var t=_e()(n);function n(){return _()(this,n),t.apply(this,arguments)}return x()(n,[{key:"render",value:function(){var e,t,n,r,o=this.props,a=o.schema,i=o.name,s=o.displayName,c=o.isRef,p=o.getComponent,f=o.getConfigs,h=o.depth,m=o.onToggle,v=o.expanded,g=o.specPath,y=Sn()(o,dr),b=y.specSelectors,_=y.expandDepth,w=y.includeReadOnly,x=y.includeWriteOnly,E=b.isOAS3;if(!a)return null;var S=f().showExtensions,C=a.get("description"),A=a.get("properties"),O=a.get("additionalProperties"),j=a.get("title")||s||i,T=a.get("required"),I=l()(a).call(a,(function(e,t){var n;return-1!==xe()(n=["maxProperties","minProperties","nullable","example"]).call(n,t)})),P=a.get("deprecated"),N=p("JumpToPath",!0),R=p("Markdown",!0),L=p("Model"),F=p("ModelCollapse"),U=p("Property"),q=function(){return D.a.createElement("span",{className:"model-jump-to-path"},D.a.createElement(N,{specPath:g}))},z=D.a.createElement("span",null,D.a.createElement("span",null,"{"),"...",D.a.createElement("span",null,"}"),c?D.a.createElement(q,null):""),V=b.isOAS3()?a.get("anyOf"):null,W=b.isOAS3()?a.get("oneOf"):null,H=b.isOAS3()?a.get("not"):null,$=j&&D.a.createElement("span",{className:"model-title"},c&&a.get("$$ref")&&D.a.createElement("span",{className:"model-hint"},a.get("$$ref")),D.a.createElement("span",{className:"model-title__text"},j));return D.a.createElement("span",{className:"model"},D.a.createElement(F,{modelName:i,title:$,onToggle:m,expanded:!!v||h<=_,collapsedContent:z},D.a.createElement("span",{className:"brace-open object"},"{"),c?D.a.createElement(q,null):null,D.a.createElement("span",{className:"inner-object"},D.a.createElement("table",{className:"model"},D.a.createElement("tbody",null,C?D.a.createElement("tr",{className:"description"},D.a.createElement("td",null,"description:"),D.a.createElement("td",null,D.a.createElement(R,{source:C}))):null,P?D.a.createElement("tr",{className:"property"},D.a.createElement("td",null,"deprecated:"),D.a.createElement("td",null,"true")):null,A&&A.size?M()(e=l()(t=A.entrySeq()).call(t,(function(e){var t=bt()(e,2)[1];return(!t.get("readOnly")||w)&&(!t.get("writeOnly")||x)}))).call(e,(function(e){var t,n,r=bt()(e,2),o=r[0],a=r[1],s=E()&&a.get("deprecated"),c=B.List.isList(T)&&T.contains(o),l=["property-row"];return s&&l.push("deprecated"),c&&l.push("required"),D.a.createElement("tr",{key:o,className:l.join(" ")},D.a.createElement("td",null,o,c&&D.a.createElement("span",{className:"star"},"*")),D.a.createElement("td",null,D.a.createElement(L,xn()({key:u()(t=u()(n="object-".concat(i,"-")).call(n,o,"_")).call(t,a)},y,{required:c,getComponent:p,specPath:g.push("properties",o),getConfigs:f,schema:a,depth:h+1}))))})).toArray():null,S?D.a.createElement("tr",null,D.a.createElement("td",null," ")):null,S?M()(n=a.entrySeq()).call(n,(function(e){var t=bt()(e,2),n=t[0],r=t[1];if("x-"===k()(n).call(n,0,2)){var o=r?r.toJS?r.toJS():r:null;return D.a.createElement("tr",{key:n,className:"extension"},D.a.createElement("td",null,n),D.a.createElement("td",null,d()(o)))}})).toArray():null,O&&O.size?D.a.createElement("tr",null,D.a.createElement("td",null,"< * >:"),D.a.createElement("td",null,D.a.createElement(L,xn()({},y,{required:!1,getComponent:p,specPath:g.push("additionalProperties"),getConfigs:f,schema:O,depth:h+1})))):null,V?D.a.createElement("tr",null,D.a.createElement("td",null,"anyOf ->"),D.a.createElement("td",null,M()(V).call(V,(function(e,t){return D.a.createElement("div",{key:t},D.a.createElement(L,xn()({},y,{required:!1,getComponent:p,specPath:g.push("anyOf",t),getConfigs:f,schema:e,depth:h+1})))})))):null,W?D.a.createElement("tr",null,D.a.createElement("td",null,"oneOf ->"),D.a.createElement("td",null,M()(W).call(W,(function(e,t){return D.a.createElement("div",{key:t},D.a.createElement(L,xn()({},y,{required:!1,getComponent:p,specPath:g.push("oneOf",t),getConfigs:f,schema:e,depth:h+1})))})))):null,H?D.a.createElement("tr",null,D.a.createElement("td",null,"not ->"),D.a.createElement("td",null,D.a.createElement("div",null,D.a.createElement(L,xn()({},y,{required:!1,getComponent:p,specPath:g.push("not"),getConfigs:f,schema:H,depth:h+1}))))):null))),D.a.createElement("span",{className:"brace-close"},"}")),I.size?M()(r=I.entrySeq()).call(r,(function(e){var t,n=bt()(e,2),r=n[0],o=n[1];return D.a.createElement(U,{key:u()(t="".concat(r,"-")).call(t,o),propKey:r,propVal:o,propClass:"property"})})):null)}}]),n}(R.Component),vr=function(e){ye()(n,e);var t=_e()(n);function n(){return _()(this,n),t.apply(this,arguments)}return x()(n,[{key:"render",value:function(){var e,t=this.props,n=t.getComponent,r=t.getConfigs,o=t.schema,a=t.depth,i=t.expandDepth,s=t.name,c=t.displayName,p=t.specPath,f=o.get("description"),h=o.get("items"),d=o.get("title")||c||s,m=l()(o).call(o,(function(e,t){var n;return-1===xe()(n=["type","items","description","$$ref"]).call(n,t)})),v=n("Markdown",!0),g=n("ModelCollapse"),y=n("Model"),b=n("Property"),_=d&&D.a.createElement("span",{className:"model-title"},D.a.createElement("span",{className:"model-title__text"},d));return D.a.createElement("span",{className:"model"},D.a.createElement(g,{title:_,expanded:a<=i,collapsedContent:"[...]"},"[",m.size?M()(e=m.entrySeq()).call(e,(function(e){var t,n=bt()(e,2),r=n[0],o=n[1];return D.a.createElement(b,{key:u()(t="".concat(r,"-")).call(t,o),propKey:r,propVal:o,propClass:"property"})})):null,f?D.a.createElement(v,{source:f}):m.size?D.a.createElement("div",{className:"markdown"}):null,D.a.createElement("span",null,D.a.createElement(y,xn()({},this.props,{getConfigs:r,specPath:p.push("items"),name:null,schema:h,required:!1,depth:a+1}))),"]"))}}]),n}(R.Component),gr="property primitive",yr=function(e){ye()(n,e);var t=_e()(n);function n(){return _()(this,n),t.apply(this,arguments)}return x()(n,[{key:"render",value:function(){var e,t,n,r=this.props,o=r.schema,a=r.getComponent,i=r.getConfigs,s=r.name,c=r.displayName,p=r.depth,f=i().showExtensions;if(!o||!o.get)return D.a.createElement("div",null);var h=o.get("type"),d=o.get("format"),m=o.get("xml"),v=o.get("enum"),g=o.get("title")||c||s,y=o.get("description"),b=Object($.m)(o),_=l()(o).call(o,(function(e,t){var n;return-1===xe()(n=["enum","type","format","description","$$ref"]).call(n,t)})).filterNot((function(e,t){return b.has(t)})),w=a("Markdown",!0),x=a("EnumModel"),E=a("Property");return D.a.createElement("span",{className:"model"},D.a.createElement("span",{className:"prop"},s&&D.a.createElement("span",{className:"".concat(1===p&&"model-title"," prop-name")},g),D.a.createElement("span",{className:"prop-type"},h),d&&D.a.createElement("span",{className:"prop-format"},"($",d,")"),_.size?M()(e=_.entrySeq()).call(e,(function(e){var t,n=bt()(e,2),r=n[0],o=n[1];return D.a.createElement(E,{key:u()(t="".concat(r,"-")).call(t,o),propKey:r,propVal:o,propClass:gr})})):null,f&&b.size?M()(t=b.entrySeq()).call(t,(function(e){var t,n=bt()(e,2),r=n[0],o=n[1];return D.a.createElement(E,{key:u()(t="".concat(r,"-")).call(t,o),propKey:r,propVal:o,propClass:gr})})):null,y?D.a.createElement(w,{source:y}):null,m&&m.size?D.a.createElement("span",null,D.a.createElement("br",null),D.a.createElement("span",{className:gr},"xml:"),M()(n=m.entrySeq()).call(n,(function(e){var t,n=bt()(e,2),r=n[0],o=n[1];return D.a.createElement("span",{key:u()(t="".concat(r,"-")).call(t,o),className:gr},D.a.createElement("br",null),"   ",r,": ",String(o))})).toArray()):null,v&&D.a.createElement(x,{value:v,getComponent:a})))}}]),n}(R.Component),br=function(e){var t=e.propKey,n=e.propVal,r=e.propClass;return D.a.createElement("span",{className:r},D.a.createElement("br",null),t,": ",String(n))},_r=function(e){ye()(n,e);var t=_e()(n);function n(){return _()(this,n),t.apply(this,arguments)}return x()(n,[{key:"render",value:function(){var e=this.props,t=e.onTryoutClick,n=e.onCancelClick,r=e.onResetClick,o=e.enabled,a=e.hasUserEditedBody,i=e.isOAS3&&a;return D.a.createElement("div",{className:i?"try-out btn-group":"try-out"},o?D.a.createElement("button",{className:"btn try-out__btn cancel",onClick:n},"Cancel"):D.a.createElement("button",{className:"btn try-out__btn",onClick:t},"Try it out "),i&&D.a.createElement("button",{className:"btn try-out__btn reset",onClick:r},"Reset"))}}]),n}(D.a.Component);y()(_r,"defaultProps",{onTryoutClick:Function.prototype,onCancelClick:Function.prototype,onResetClick:Function.prototype,enabled:!1,hasUserEditedBody:!1,isOAS3:!1});var wr=function(e){ye()(n,e);var t=_e()(n);function n(){return _()(this,n),t.apply(this,arguments)}return x()(n,[{key:"render",value:function(){var e=this.props,t=e.bypass,n=e.isSwagger2,r=e.isOAS3,o=e.alsoShow;return t?D.a.createElement("div",null,this.props.children):n&&r?D.a.createElement("div",{className:"version-pragma"},o,D.a.createElement("div",{className:"version-pragma__message version-pragma__message--ambiguous"},D.a.createElement("div",null,D.a.createElement("h3",null,"Unable to render this definition"),D.a.createElement("p",null,D.a.createElement("code",null,"swagger")," and ",D.a.createElement("code",null,"openapi")," fields cannot be present in the same Swagger or OpenAPI definition. Please remove one of the fields."),D.a.createElement("p",null,"Supported version fields are ",D.a.createElement("code",null,"swagger: ",'"2.0"')," and those that match ",D.a.createElement("code",null,"openapi: 3.0.n")," (for example, ",D.a.createElement("code",null,"openapi: 3.0.0"),").")))):n||r?D.a.createElement("div",null,this.props.children):D.a.createElement("div",{className:"version-pragma"},o,D.a.createElement("div",{className:"version-pragma__message version-pragma__message--missing"},D.a.createElement("div",null,D.a.createElement("h3",null,"Unable to render this definition"),D.a.createElement("p",null,"The provided definition does not specify a valid version field."),D.a.createElement("p",null,"Please indicate a valid Swagger or OpenAPI version field. Supported version fields are ",D.a.createElement("code",null,"swagger: ",'"2.0"')," and those that match ",D.a.createElement("code",null,"openapi: 3.0.n")," (for example, ",D.a.createElement("code",null,"openapi: 3.0.0"),")."))))}}]),n}(D.a.PureComponent);y()(wr,"defaultProps",{alsoShow:null,children:null,bypass:!1});var xr=function(e){var t=e.version;return D.a.createElement("small",null,D.a.createElement("pre",{className:"version"}," ",t," "))},Er=function(e){var t=e.enabled,n=e.path,r=e.text;return D.a.createElement("a",{className:"nostyle",onClick:t?function(e){return e.preventDefault()}:null,href:t?"#/".concat(n):null},D.a.createElement("span",null,r))},Sr=function(){return D.a.createElement("div",null,D.a.createElement("svg",{xmlns:"http://www.w3.org/2000/svg",xmlnsXlink:"http://www.w3.org/1999/xlink",className:"svg-assets"},D.a.createElement("defs",null,D.a.createElement("symbol",{viewBox:"0 0 20 20",id:"unlocked"},D.a.createElement("path",{d:"M15.8 8H14V5.6C14 2.703 12.665 1 10 1 7.334 1 6 2.703 6 5.6V6h2v-.801C8 3.754 8.797 3 10 3c1.203 0 2 .754 2 2.199V8H4c-.553 0-1 .646-1 1.199V17c0 .549.428 1.139.951 1.307l1.197.387C5.672 18.861 6.55 19 7.1 19h5.8c.549 0 1.428-.139 1.951-.307l1.196-.387c.524-.167.953-.757.953-1.306V9.199C17 8.646 16.352 8 15.8 8z"})),D.a.createElement("symbol",{viewBox:"0 0 20 20",id:"locked"},D.a.createElement("path",{d:"M15.8 8H14V5.6C14 2.703 12.665 1 10 1 7.334 1 6 2.703 6 5.6V8H4c-.553 0-1 .646-1 1.199V17c0 .549.428 1.139.951 1.307l1.197.387C5.672 18.861 6.55 19 7.1 19h5.8c.549 0 1.428-.139 1.951-.307l1.196-.387c.524-.167.953-.757.953-1.306V9.199C17 8.646 16.352 8 15.8 8zM12 8H8V5.199C8 3.754 8.797 3 10 3c1.203 0 2 .754 2 2.199V8z"})),D.a.createElement("symbol",{viewBox:"0 0 20 20",id:"close"},D.a.createElement("path",{d:"M14.348 14.849c-.469.469-1.229.469-1.697 0L10 11.819l-2.651 3.029c-.469.469-1.229.469-1.697 0-.469-.469-.469-1.229 0-1.697l2.758-3.15-2.759-3.152c-.469-.469-.469-1.228 0-1.697.469-.469 1.228-.469 1.697 0L10 8.183l2.651-3.031c.469-.469 1.228-.469 1.697 0 .469.469.469 1.229 0 1.697l-2.758 3.152 2.758 3.15c.469.469.469 1.229 0 1.698z"})),D.a.createElement("symbol",{viewBox:"0 0 20 20",id:"large-arrow"},D.a.createElement("path",{d:"M13.25 10L6.109 2.58c-.268-.27-.268-.707 0-.979.268-.27.701-.27.969 0l7.83 7.908c.268.271.268.709 0 .979l-7.83 7.908c-.268.271-.701.27-.969 0-.268-.269-.268-.707 0-.979L13.25 10z"})),D.a.createElement("symbol",{viewBox:"0 0 20 20",id:"large-arrow-down"},D.a.createElement("path",{d:"M17.418 6.109c.272-.268.709-.268.979 0s.271.701 0 .969l-7.908 7.83c-.27.268-.707.268-.979 0l-7.908-7.83c-.27-.268-.27-.701 0-.969.271-.268.709-.268.979 0L10 13.25l7.418-7.141z"})),D.a.createElement("symbol",{viewBox:"0 0 20 20",id:"large-arrow-up"},D.a.createElement("path",{d:"M 17.418 14.908 C 17.69 15.176 18.127 15.176 18.397 14.908 C 18.667 14.64 18.668 14.207 18.397 13.939 L 10.489 6.109 C 10.219 5.841 9.782 5.841 9.51 6.109 L 1.602 13.939 C 1.332 14.207 1.332 14.64 1.602 14.908 C 1.873 15.176 2.311 15.176 2.581 14.908 L 10 7.767 L 17.418 14.908 Z"})),D.a.createElement("symbol",{viewBox:"0 0 24 24",id:"jump-to"},D.a.createElement("path",{d:"M19 7v4H5.83l3.58-3.59L8 6l-6 6 6 6 1.41-1.41L5.83 13H21V7z"})),D.a.createElement("symbol",{viewBox:"0 0 24 24",id:"expand"},D.a.createElement("path",{d:"M10 18h4v-2h-4v2zM3 6v2h18V6H3zm3 7h12v-2H6v2z"})))))},Cr=n(219),Ar=function(e){ye()(n,e);var t=_e()(n);function n(){return _()(this,n),t.apply(this,arguments)}return x()(n,[{key:"render",value:function(){var e=this.props,t=e.errSelectors,n=e.specSelectors,r=e.getComponent,o=r("SvgAssets"),a=r("InfoContainer",!0),i=r("VersionPragmaFilter"),s=r("operations",!0),u=r("Models",!0),c=r("Row"),l=r("Col"),p=r("errors",!0),f=r("ServersContainer",!0),h=r("SchemesContainer",!0),d=r("AuthorizeBtnContainer",!0),m=r("FilterContainer",!0),v=n.isSwagger2(),g=n.isOAS3(),y=!n.specStr(),b=n.loadingStatus(),_=null;if("loading"===b&&(_=D.a.createElement("div",{className:"info"},D.a.createElement("div",{className:"loading-container"},D.a.createElement("div",{className:"loading"})))),"failed"===b&&(_=D.a.createElement("div",{className:"info"},D.a.createElement("div",{className:"loading-container"},D.a.createElement("h4",{className:"title"},"Failed to load API definition."),D.a.createElement(p,null)))),"failedConfig"===b){var w=t.lastError(),x=w?w.get("message"):"";_=D.a.createElement("div",{className:"info failed-config"},D.a.createElement("div",{className:"loading-container"},D.a.createElement("h4",{className:"title"},"Failed to load remote configuration."),D.a.createElement("p",null,x)))}if(!_&&y&&(_=D.a.createElement("h4",null,"No API definition provided.")),_)return D.a.createElement("div",{className:"swagger-ui"},D.a.createElement("div",{className:"loading-container"},_));var E=n.servers(),S=n.schemes(),C=E&&E.size,A=S&&S.size,O=!!n.securityDefinitions();return D.a.createElement("div",{className:"swagger-ui"},D.a.createElement(o,null),D.a.createElement(i,{isSwagger2:v,isOAS3:g,alsoShow:D.a.createElement(p,null)},D.a.createElement(p,null),D.a.createElement(c,{className:"information-container"},D.a.createElement(l,{mobile:12},D.a.createElement(a,null))),C||A||O?D.a.createElement("div",{className:"scheme-container"},D.a.createElement(l,{className:"schemes wrapper",mobile:12},C?D.a.createElement(f,null):null,A?D.a.createElement(h,null):null,O?D.a.createElement(d,null):null)):null,D.a.createElement(m,null),D.a.createElement(c,null,D.a.createElement(l,{mobile:12,desktop:12},D.a.createElement(s,null))),D.a.createElement(c,null,D.a.createElement(l,{mobile:12,desktop:12},D.a.createElement(u,null)))))}}]),n}(D.a.Component),Or=n(357),kr=n.n(Or),jr={value:"",onChange:function(){},schema:{},keyName:"",required:!1,errors:Object(B.List)()},Tr=function(e){ye()(n,e);var t=_e()(n);function n(){return _()(this,n),t.apply(this,arguments)}return x()(n,[{key:"componentDidMount",value:function(){var e=this.props,t=e.dispatchInitialValue,n=e.value,r=e.onChange;t?r(n):!1===t&&r("")}},{key:"render",value:function(){var e,t=this.props,n=t.schema,r=t.errors,o=t.value,a=t.onChange,i=t.getComponent,s=t.fn,c=t.disabled,l=n&&n.get?n.get("format"):null,p=n&&n.get?n.get("type"):null,f=function(e){return i(e,!1,{failSilently:!0})},h=p?f(l?u()(e="JsonSchema_".concat(p,"_")).call(e,l):"JsonSchema_".concat(p)):i("JsonSchema_string");return h||(h=i("JsonSchema_string")),D.a.createElement(h,xn()({},this.props,{errors:r,fn:s,getComponent:i,value:o,onChange:a,schema:n,disabled:c}))}}]),n}(R.Component);y()(Tr,"defaultProps",jr);var Ir=function(e){ye()(n,e);var t=_e()(n);function n(){var e,r;_()(this,n);for(var o=arguments.length,a=new Array(o),i=0;i0),g=a.getIn(["items","enum"]),y=a.getIn(["items","type"]),b=a.getIn(["items","format"]),_=a.get("items"),w=!1,x="file"===y||"string"===y&&"binary"===b;y&&b?p=r(u()(f="JsonSchema_".concat(y,"_")).call(f,b)):"boolean"!==y&&"array"!==y&&"object"!==y||(p=r("JsonSchema_".concat(y)));if(p||x||(w=!0),g){var E=r("Select");return D.a.createElement(E,{className:i.length?"invalid":"",title:i.length?i:"",multiple:!0,value:m,disabled:c,allowedValues:g,allowEmptyValue:!o,onChange:this.onEnumChange})}var S=r("Button");return D.a.createElement("div",{className:"json-schema-array"},v?M()(m).call(m,(function(e,n){var o,a=Object(B.fromJS)(nn()(M()(o=l()(i).call(i,(function(e){return e.index===n}))).call(o,(function(e){return e.error}))));return D.a.createElement("div",{key:n,className:"json-schema-form-item"},x?D.a.createElement(Mr,{value:e,onChange:function(e){return t.onItemChange(e,n)},disabled:c,errors:a,getComponent:r}):w?D.a.createElement(Nr,{value:e,onChange:function(e){return t.onItemChange(e,n)},disabled:c,errors:a}):D.a.createElement(p,xn()({},t.props,{value:e,onChange:function(e){return t.onItemChange(e,n)},disabled:c,errors:a,schema:_,getComponent:r,fn:s})),c?null:D.a.createElement(S,{className:"btn btn-sm json-schema-form-item-remove ".concat(d.length?"invalid":null),title:d.length?d:"",onClick:function(){return t.removeItem(n)}}," - "))})):null,c?null:D.a.createElement(S,{className:"btn btn-sm json-schema-form-item-add ".concat(h.length?"invalid":null),title:h.length?h:"",onClick:this.addItem},"Add ",y?"".concat(y," "):"","item"))}}]),n}(R.PureComponent);y()(Pr,"defaultProps",jr);var Nr=function(e){ye()(n,e);var t=_e()(n);function n(){var e,r;_()(this,n);for(var o=arguments.length,a=new Array(o),i=0;i>> 0; // N >>> 0 is shorthand for ToUint32\n if ('' + uint32Index !== index || uint32Index === 4294967295) {\n return NaN;\n }\n index = uint32Index;\n }\n return index < 0 ? ensureSize(iter) + index : index;\n }\n\n function returnTrue() {\n return true;\n }\n\n function wholeSlice(begin, end, size) {\n return (begin === 0 || (size !== undefined && begin <= -size)) &&\n (end === undefined || (size !== undefined && end >= size));\n }\n\n function resolveBegin(begin, size) {\n return resolveIndex(begin, size, 0);\n }\n\n function resolveEnd(end, size) {\n return resolveIndex(end, size, size);\n }\n\n function resolveIndex(index, size, defaultIndex) {\n return index === undefined ?\n defaultIndex :\n index < 0 ?\n Math.max(0, size + index) :\n size === undefined ?\n index :\n Math.min(size, index);\n }\n\n /* global Symbol */\n\n var ITERATE_KEYS = 0;\n var ITERATE_VALUES = 1;\n var ITERATE_ENTRIES = 2;\n\n var REAL_ITERATOR_SYMBOL = typeof Symbol === 'function' && Symbol.iterator;\n var FAUX_ITERATOR_SYMBOL = '@@iterator';\n\n var ITERATOR_SYMBOL = REAL_ITERATOR_SYMBOL || FAUX_ITERATOR_SYMBOL;\n\n\n function Iterator(next) {\n this.next = next;\n }\n\n Iterator.prototype.toString = function() {\n return '[Iterator]';\n };\n\n\n Iterator.KEYS = ITERATE_KEYS;\n Iterator.VALUES = ITERATE_VALUES;\n Iterator.ENTRIES = ITERATE_ENTRIES;\n\n Iterator.prototype.inspect =\n Iterator.prototype.toSource = function () { return this.toString(); }\n Iterator.prototype[ITERATOR_SYMBOL] = function () {\n return this;\n };\n\n\n function iteratorValue(type, k, v, iteratorResult) {\n var value = type === 0 ? k : type === 1 ? v : [k, v];\n iteratorResult ? (iteratorResult.value = value) : (iteratorResult = {\n value: value, done: false\n });\n return iteratorResult;\n }\n\n function iteratorDone() {\n return { value: undefined, done: true };\n }\n\n function hasIterator(maybeIterable) {\n return !!getIteratorFn(maybeIterable);\n }\n\n function isIterator(maybeIterator) {\n return maybeIterator && typeof maybeIterator.next === 'function';\n }\n\n function getIterator(iterable) {\n var iteratorFn = getIteratorFn(iterable);\n return iteratorFn && iteratorFn.call(iterable);\n }\n\n function getIteratorFn(iterable) {\n var iteratorFn = iterable && (\n (REAL_ITERATOR_SYMBOL && iterable[REAL_ITERATOR_SYMBOL]) ||\n iterable[FAUX_ITERATOR_SYMBOL]\n );\n if (typeof iteratorFn === 'function') {\n return iteratorFn;\n }\n }\n\n function isArrayLike(value) {\n return value && typeof value.length === 'number';\n }\n\n createClass(Seq, Iterable);\n function Seq(value) {\n return value === null || value === undefined ? emptySequence() :\n isIterable(value) ? value.toSeq() : seqFromValue(value);\n }\n\n Seq.of = function(/*...values*/) {\n return Seq(arguments);\n };\n\n Seq.prototype.toSeq = function() {\n return this;\n };\n\n Seq.prototype.toString = function() {\n return this.__toString('Seq {', '}');\n };\n\n Seq.prototype.cacheResult = function() {\n if (!this._cache && this.__iterateUncached) {\n this._cache = this.entrySeq().toArray();\n this.size = this._cache.length;\n }\n return this;\n };\n\n // abstract __iterateUncached(fn, reverse)\n\n Seq.prototype.__iterate = function(fn, reverse) {\n return seqIterate(this, fn, reverse, true);\n };\n\n // abstract __iteratorUncached(type, reverse)\n\n Seq.prototype.__iterator = function(type, reverse) {\n return seqIterator(this, type, reverse, true);\n };\n\n\n\n createClass(KeyedSeq, Seq);\n function KeyedSeq(value) {\n return value === null || value === undefined ?\n emptySequence().toKeyedSeq() :\n isIterable(value) ?\n (isKeyed(value) ? value.toSeq() : value.fromEntrySeq()) :\n keyedSeqFromValue(value);\n }\n\n KeyedSeq.prototype.toKeyedSeq = function() {\n return this;\n };\n\n\n\n createClass(IndexedSeq, Seq);\n function IndexedSeq(value) {\n return value === null || value === undefined ? emptySequence() :\n !isIterable(value) ? indexedSeqFromValue(value) :\n isKeyed(value) ? value.entrySeq() : value.toIndexedSeq();\n }\n\n IndexedSeq.of = function(/*...values*/) {\n return IndexedSeq(arguments);\n };\n\n IndexedSeq.prototype.toIndexedSeq = function() {\n return this;\n };\n\n IndexedSeq.prototype.toString = function() {\n return this.__toString('Seq [', ']');\n };\n\n IndexedSeq.prototype.__iterate = function(fn, reverse) {\n return seqIterate(this, fn, reverse, false);\n };\n\n IndexedSeq.prototype.__iterator = function(type, reverse) {\n return seqIterator(this, type, reverse, false);\n };\n\n\n\n createClass(SetSeq, Seq);\n function SetSeq(value) {\n return (\n value === null || value === undefined ? emptySequence() :\n !isIterable(value) ? indexedSeqFromValue(value) :\n isKeyed(value) ? value.entrySeq() : value\n ).toSetSeq();\n }\n\n SetSeq.of = function(/*...values*/) {\n return SetSeq(arguments);\n };\n\n SetSeq.prototype.toSetSeq = function() {\n return this;\n };\n\n\n\n Seq.isSeq = isSeq;\n Seq.Keyed = KeyedSeq;\n Seq.Set = SetSeq;\n Seq.Indexed = IndexedSeq;\n\n var IS_SEQ_SENTINEL = '@@__IMMUTABLE_SEQ__@@';\n\n Seq.prototype[IS_SEQ_SENTINEL] = true;\n\n\n\n createClass(ArraySeq, IndexedSeq);\n function ArraySeq(array) {\n this._array = array;\n this.size = array.length;\n }\n\n ArraySeq.prototype.get = function(index, notSetValue) {\n return this.has(index) ? this._array[wrapIndex(this, index)] : notSetValue;\n };\n\n ArraySeq.prototype.__iterate = function(fn, reverse) {\n var array = this._array;\n var maxIndex = array.length - 1;\n for (var ii = 0; ii <= maxIndex; ii++) {\n if (fn(array[reverse ? maxIndex - ii : ii], ii, this) === false) {\n return ii + 1;\n }\n }\n return ii;\n };\n\n ArraySeq.prototype.__iterator = function(type, reverse) {\n var array = this._array;\n var maxIndex = array.length - 1;\n var ii = 0;\n return new Iterator(function() \n {return ii > maxIndex ?\n iteratorDone() :\n iteratorValue(type, ii, array[reverse ? maxIndex - ii++ : ii++])}\n );\n };\n\n\n\n createClass(ObjectSeq, KeyedSeq);\n function ObjectSeq(object) {\n var keys = Object.keys(object);\n this._object = object;\n this._keys = keys;\n this.size = keys.length;\n }\n\n ObjectSeq.prototype.get = function(key, notSetValue) {\n if (notSetValue !== undefined && !this.has(key)) {\n return notSetValue;\n }\n return this._object[key];\n };\n\n ObjectSeq.prototype.has = function(key) {\n return this._object.hasOwnProperty(key);\n };\n\n ObjectSeq.prototype.__iterate = function(fn, reverse) {\n var object = this._object;\n var keys = this._keys;\n var maxIndex = keys.length - 1;\n for (var ii = 0; ii <= maxIndex; ii++) {\n var key = keys[reverse ? maxIndex - ii : ii];\n if (fn(object[key], key, this) === false) {\n return ii + 1;\n }\n }\n return ii;\n };\n\n ObjectSeq.prototype.__iterator = function(type, reverse) {\n var object = this._object;\n var keys = this._keys;\n var maxIndex = keys.length - 1;\n var ii = 0;\n return new Iterator(function() {\n var key = keys[reverse ? maxIndex - ii : ii];\n return ii++ > maxIndex ?\n iteratorDone() :\n iteratorValue(type, key, object[key]);\n });\n };\n\n ObjectSeq.prototype[IS_ORDERED_SENTINEL] = true;\n\n\n createClass(IterableSeq, IndexedSeq);\n function IterableSeq(iterable) {\n this._iterable = iterable;\n this.size = iterable.length || iterable.size;\n }\n\n IterableSeq.prototype.__iterateUncached = function(fn, reverse) {\n if (reverse) {\n return this.cacheResult().__iterate(fn, reverse);\n }\n var iterable = this._iterable;\n var iterator = getIterator(iterable);\n var iterations = 0;\n if (isIterator(iterator)) {\n var step;\n while (!(step = iterator.next()).done) {\n if (fn(step.value, iterations++, this) === false) {\n break;\n }\n }\n }\n return iterations;\n };\n\n IterableSeq.prototype.__iteratorUncached = function(type, reverse) {\n if (reverse) {\n return this.cacheResult().__iterator(type, reverse);\n }\n var iterable = this._iterable;\n var iterator = getIterator(iterable);\n if (!isIterator(iterator)) {\n return new Iterator(iteratorDone);\n }\n var iterations = 0;\n return new Iterator(function() {\n var step = iterator.next();\n return step.done ? step : iteratorValue(type, iterations++, step.value);\n });\n };\n\n\n\n createClass(IteratorSeq, IndexedSeq);\n function IteratorSeq(iterator) {\n this._iterator = iterator;\n this._iteratorCache = [];\n }\n\n IteratorSeq.prototype.__iterateUncached = function(fn, reverse) {\n if (reverse) {\n return this.cacheResult().__iterate(fn, reverse);\n }\n var iterator = this._iterator;\n var cache = this._iteratorCache;\n var iterations = 0;\n while (iterations < cache.length) {\n if (fn(cache[iterations], iterations++, this) === false) {\n return iterations;\n }\n }\n var step;\n while (!(step = iterator.next()).done) {\n var val = step.value;\n cache[iterations] = val;\n if (fn(val, iterations++, this) === false) {\n break;\n }\n }\n return iterations;\n };\n\n IteratorSeq.prototype.__iteratorUncached = function(type, reverse) {\n if (reverse) {\n return this.cacheResult().__iterator(type, reverse);\n }\n var iterator = this._iterator;\n var cache = this._iteratorCache;\n var iterations = 0;\n return new Iterator(function() {\n if (iterations >= cache.length) {\n var step = iterator.next();\n if (step.done) {\n return step;\n }\n cache[iterations] = step.value;\n }\n return iteratorValue(type, iterations, cache[iterations++]);\n });\n };\n\n\n\n\n // # pragma Helper functions\n\n function isSeq(maybeSeq) {\n return !!(maybeSeq && maybeSeq[IS_SEQ_SENTINEL]);\n }\n\n var EMPTY_SEQ;\n\n function emptySequence() {\n return EMPTY_SEQ || (EMPTY_SEQ = new ArraySeq([]));\n }\n\n function keyedSeqFromValue(value) {\n var seq =\n Array.isArray(value) ? new ArraySeq(value).fromEntrySeq() :\n isIterator(value) ? new IteratorSeq(value).fromEntrySeq() :\n hasIterator(value) ? new IterableSeq(value).fromEntrySeq() :\n typeof value === 'object' ? new ObjectSeq(value) :\n undefined;\n if (!seq) {\n throw new TypeError(\n 'Expected Array or iterable object of [k, v] entries, '+\n 'or keyed object: ' + value\n );\n }\n return seq;\n }\n\n function indexedSeqFromValue(value) {\n var seq = maybeIndexedSeqFromValue(value);\n if (!seq) {\n throw new TypeError(\n 'Expected Array or iterable object of values: ' + value\n );\n }\n return seq;\n }\n\n function seqFromValue(value) {\n var seq = maybeIndexedSeqFromValue(value) ||\n (typeof value === 'object' && new ObjectSeq(value));\n if (!seq) {\n throw new TypeError(\n 'Expected Array or iterable object of values, or keyed object: ' + value\n );\n }\n return seq;\n }\n\n function maybeIndexedSeqFromValue(value) {\n return (\n isArrayLike(value) ? new ArraySeq(value) :\n isIterator(value) ? new IteratorSeq(value) :\n hasIterator(value) ? new IterableSeq(value) :\n undefined\n );\n }\n\n function seqIterate(seq, fn, reverse, useKeys) {\n var cache = seq._cache;\n if (cache) {\n var maxIndex = cache.length - 1;\n for (var ii = 0; ii <= maxIndex; ii++) {\n var entry = cache[reverse ? maxIndex - ii : ii];\n if (fn(entry[1], useKeys ? entry[0] : ii, seq) === false) {\n return ii + 1;\n }\n }\n return ii;\n }\n return seq.__iterateUncached(fn, reverse);\n }\n\n function seqIterator(seq, type, reverse, useKeys) {\n var cache = seq._cache;\n if (cache) {\n var maxIndex = cache.length - 1;\n var ii = 0;\n return new Iterator(function() {\n var entry = cache[reverse ? maxIndex - ii : ii];\n return ii++ > maxIndex ?\n iteratorDone() :\n iteratorValue(type, useKeys ? entry[0] : ii - 1, entry[1]);\n });\n }\n return seq.__iteratorUncached(type, reverse);\n }\n\n function fromJS(json, converter) {\n return converter ?\n fromJSWith(converter, json, '', {'': json}) :\n fromJSDefault(json);\n }\n\n function fromJSWith(converter, json, key, parentJSON) {\n if (Array.isArray(json)) {\n return converter.call(parentJSON, key, IndexedSeq(json).map(function(v, k) {return fromJSWith(converter, v, k, json)}));\n }\n if (isPlainObj(json)) {\n return converter.call(parentJSON, key, KeyedSeq(json).map(function(v, k) {return fromJSWith(converter, v, k, json)}));\n }\n return json;\n }\n\n function fromJSDefault(json) {\n if (Array.isArray(json)) {\n return IndexedSeq(json).map(fromJSDefault).toList();\n }\n if (isPlainObj(json)) {\n return KeyedSeq(json).map(fromJSDefault).toMap();\n }\n return json;\n }\n\n function isPlainObj(value) {\n return value && (value.constructor === Object || value.constructor === undefined);\n }\n\n /**\n * An extension of the \"same-value\" algorithm as [described for use by ES6 Map\n * and Set](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map#Key_equality)\n *\n * NaN is considered the same as NaN, however -0 and 0 are considered the same\n * value, which is different from the algorithm described by\n * [`Object.is`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is).\n *\n * This is extended further to allow Objects to describe the values they\n * represent, by way of `valueOf` or `equals` (and `hashCode`).\n *\n * Note: because of this extension, the key equality of Immutable.Map and the\n * value equality of Immutable.Set will differ from ES6 Map and Set.\n *\n * ### Defining custom values\n *\n * The easiest way to describe the value an object represents is by implementing\n * `valueOf`. For example, `Date` represents a value by returning a unix\n * timestamp for `valueOf`:\n *\n * var date1 = new Date(1234567890000); // Fri Feb 13 2009 ...\n * var date2 = new Date(1234567890000);\n * date1.valueOf(); // 1234567890000\n * assert( date1 !== date2 );\n * assert( Immutable.is( date1, date2 ) );\n *\n * Note: overriding `valueOf` may have other implications if you use this object\n * where JavaScript expects a primitive, such as implicit string coercion.\n *\n * For more complex types, especially collections, implementing `valueOf` may\n * not be performant. An alternative is to implement `equals` and `hashCode`.\n *\n * `equals` takes another object, presumably of similar type, and returns true\n * if the it is equal. Equality is symmetrical, so the same result should be\n * returned if this and the argument are flipped.\n *\n * assert( a.equals(b) === b.equals(a) );\n *\n * `hashCode` returns a 32bit integer number representing the object which will\n * be used to determine how to store the value object in a Map or Set. You must\n * provide both or neither methods, one must not exist without the other.\n *\n * Also, an important relationship between these methods must be upheld: if two\n * values are equal, they *must* return the same hashCode. If the values are not\n * equal, they might have the same hashCode; this is called a hash collision,\n * and while undesirable for performance reasons, it is acceptable.\n *\n * if (a.equals(b)) {\n * assert( a.hashCode() === b.hashCode() );\n * }\n *\n * All Immutable collections implement `equals` and `hashCode`.\n *\n */\n function is(valueA, valueB) {\n if (valueA === valueB || (valueA !== valueA && valueB !== valueB)) {\n return true;\n }\n if (!valueA || !valueB) {\n return false;\n }\n if (typeof valueA.valueOf === 'function' &&\n typeof valueB.valueOf === 'function') {\n valueA = valueA.valueOf();\n valueB = valueB.valueOf();\n if (valueA === valueB || (valueA !== valueA && valueB !== valueB)) {\n return true;\n }\n if (!valueA || !valueB) {\n return false;\n }\n }\n if (typeof valueA.equals === 'function' &&\n typeof valueB.equals === 'function' &&\n valueA.equals(valueB)) {\n return true;\n }\n return false;\n }\n\n function deepEqual(a, b) {\n if (a === b) {\n return true;\n }\n\n if (\n !isIterable(b) ||\n a.size !== undefined && b.size !== undefined && a.size !== b.size ||\n a.__hash !== undefined && b.__hash !== undefined && a.__hash !== b.__hash ||\n isKeyed(a) !== isKeyed(b) ||\n isIndexed(a) !== isIndexed(b) ||\n isOrdered(a) !== isOrdered(b)\n ) {\n return false;\n }\n\n if (a.size === 0 && b.size === 0) {\n return true;\n }\n\n var notAssociative = !isAssociative(a);\n\n if (isOrdered(a)) {\n var entries = a.entries();\n return b.every(function(v, k) {\n var entry = entries.next().value;\n return entry && is(entry[1], v) && (notAssociative || is(entry[0], k));\n }) && entries.next().done;\n }\n\n var flipped = false;\n\n if (a.size === undefined) {\n if (b.size === undefined) {\n if (typeof a.cacheResult === 'function') {\n a.cacheResult();\n }\n } else {\n flipped = true;\n var _ = a;\n a = b;\n b = _;\n }\n }\n\n var allEqual = true;\n var bSize = b.__iterate(function(v, k) {\n if (notAssociative ? !a.has(v) :\n flipped ? !is(v, a.get(k, NOT_SET)) : !is(a.get(k, NOT_SET), v)) {\n allEqual = false;\n return false;\n }\n });\n\n return allEqual && a.size === bSize;\n }\n\n createClass(Repeat, IndexedSeq);\n\n function Repeat(value, times) {\n if (!(this instanceof Repeat)) {\n return new Repeat(value, times);\n }\n this._value = value;\n this.size = times === undefined ? Infinity : Math.max(0, times);\n if (this.size === 0) {\n if (EMPTY_REPEAT) {\n return EMPTY_REPEAT;\n }\n EMPTY_REPEAT = this;\n }\n }\n\n Repeat.prototype.toString = function() {\n if (this.size === 0) {\n return 'Repeat []';\n }\n return 'Repeat [ ' + this._value + ' ' + this.size + ' times ]';\n };\n\n Repeat.prototype.get = function(index, notSetValue) {\n return this.has(index) ? this._value : notSetValue;\n };\n\n Repeat.prototype.includes = function(searchValue) {\n return is(this._value, searchValue);\n };\n\n Repeat.prototype.slice = function(begin, end) {\n var size = this.size;\n return wholeSlice(begin, end, size) ? this :\n new Repeat(this._value, resolveEnd(end, size) - resolveBegin(begin, size));\n };\n\n Repeat.prototype.reverse = function() {\n return this;\n };\n\n Repeat.prototype.indexOf = function(searchValue) {\n if (is(this._value, searchValue)) {\n return 0;\n }\n return -1;\n };\n\n Repeat.prototype.lastIndexOf = function(searchValue) {\n if (is(this._value, searchValue)) {\n return this.size;\n }\n return -1;\n };\n\n Repeat.prototype.__iterate = function(fn, reverse) {\n for (var ii = 0; ii < this.size; ii++) {\n if (fn(this._value, ii, this) === false) {\n return ii + 1;\n }\n }\n return ii;\n };\n\n Repeat.prototype.__iterator = function(type, reverse) {var this$0 = this;\n var ii = 0;\n return new Iterator(function() \n {return ii < this$0.size ? iteratorValue(type, ii++, this$0._value) : iteratorDone()}\n );\n };\n\n Repeat.prototype.equals = function(other) {\n return other instanceof Repeat ?\n is(this._value, other._value) :\n deepEqual(other);\n };\n\n\n var EMPTY_REPEAT;\n\n function invariant(condition, error) {\n if (!condition) throw new Error(error);\n }\n\n createClass(Range, IndexedSeq);\n\n function Range(start, end, step) {\n if (!(this instanceof Range)) {\n return new Range(start, end, step);\n }\n invariant(step !== 0, 'Cannot step a Range by 0');\n start = start || 0;\n if (end === undefined) {\n end = Infinity;\n }\n step = step === undefined ? 1 : Math.abs(step);\n if (end < start) {\n step = -step;\n }\n this._start = start;\n this._end = end;\n this._step = step;\n this.size = Math.max(0, Math.ceil((end - start) / step - 1) + 1);\n if (this.size === 0) {\n if (EMPTY_RANGE) {\n return EMPTY_RANGE;\n }\n EMPTY_RANGE = this;\n }\n }\n\n Range.prototype.toString = function() {\n if (this.size === 0) {\n return 'Range []';\n }\n return 'Range [ ' +\n this._start + '...' + this._end +\n (this._step !== 1 ? ' by ' + this._step : '') +\n ' ]';\n };\n\n Range.prototype.get = function(index, notSetValue) {\n return this.has(index) ?\n this._start + wrapIndex(this, index) * this._step :\n notSetValue;\n };\n\n Range.prototype.includes = function(searchValue) {\n var possibleIndex = (searchValue - this._start) / this._step;\n return possibleIndex >= 0 &&\n possibleIndex < this.size &&\n possibleIndex === Math.floor(possibleIndex);\n };\n\n Range.prototype.slice = function(begin, end) {\n if (wholeSlice(begin, end, this.size)) {\n return this;\n }\n begin = resolveBegin(begin, this.size);\n end = resolveEnd(end, this.size);\n if (end <= begin) {\n return new Range(0, 0);\n }\n return new Range(this.get(begin, this._end), this.get(end, this._end), this._step);\n };\n\n Range.prototype.indexOf = function(searchValue) {\n var offsetValue = searchValue - this._start;\n if (offsetValue % this._step === 0) {\n var index = offsetValue / this._step;\n if (index >= 0 && index < this.size) {\n return index\n }\n }\n return -1;\n };\n\n Range.prototype.lastIndexOf = function(searchValue) {\n return this.indexOf(searchValue);\n };\n\n Range.prototype.__iterate = function(fn, reverse) {\n var maxIndex = this.size - 1;\n var step = this._step;\n var value = reverse ? this._start + maxIndex * step : this._start;\n for (var ii = 0; ii <= maxIndex; ii++) {\n if (fn(value, ii, this) === false) {\n return ii + 1;\n }\n value += reverse ? -step : step;\n }\n return ii;\n };\n\n Range.prototype.__iterator = function(type, reverse) {\n var maxIndex = this.size - 1;\n var step = this._step;\n var value = reverse ? this._start + maxIndex * step : this._start;\n var ii = 0;\n return new Iterator(function() {\n var v = value;\n value += reverse ? -step : step;\n return ii > maxIndex ? iteratorDone() : iteratorValue(type, ii++, v);\n });\n };\n\n Range.prototype.equals = function(other) {\n return other instanceof Range ?\n this._start === other._start &&\n this._end === other._end &&\n this._step === other._step :\n deepEqual(this, other);\n };\n\n\n var EMPTY_RANGE;\n\n createClass(Collection, Iterable);\n function Collection() {\n throw TypeError('Abstract');\n }\n\n\n createClass(KeyedCollection, Collection);function KeyedCollection() {}\n\n createClass(IndexedCollection, Collection);function IndexedCollection() {}\n\n createClass(SetCollection, Collection);function SetCollection() {}\n\n\n Collection.Keyed = KeyedCollection;\n Collection.Indexed = IndexedCollection;\n Collection.Set = SetCollection;\n\n var imul =\n typeof Math.imul === 'function' && Math.imul(0xffffffff, 2) === -2 ?\n Math.imul :\n function imul(a, b) {\n a = a | 0; // int\n b = b | 0; // int\n var c = a & 0xffff;\n var d = b & 0xffff;\n // Shift by 0 fixes the sign on the high part.\n return (c * d) + ((((a >>> 16) * d + c * (b >>> 16)) << 16) >>> 0) | 0; // int\n };\n\n // v8 has an optimization for storing 31-bit signed numbers.\n // Values which have either 00 or 11 as the high order bits qualify.\n // This function drops the highest order bit in a signed number, maintaining\n // the sign bit.\n function smi(i32) {\n return ((i32 >>> 1) & 0x40000000) | (i32 & 0xBFFFFFFF);\n }\n\n function hash(o) {\n if (o === false || o === null || o === undefined) {\n return 0;\n }\n if (typeof o.valueOf === 'function') {\n o = o.valueOf();\n if (o === false || o === null || o === undefined) {\n return 0;\n }\n }\n if (o === true) {\n return 1;\n }\n var type = typeof o;\n if (type === 'number') {\n if (o !== o || o === Infinity) {\n return 0;\n }\n var h = o | 0;\n if (h !== o) {\n h ^= o * 0xFFFFFFFF;\n }\n while (o > 0xFFFFFFFF) {\n o /= 0xFFFFFFFF;\n h ^= o;\n }\n return smi(h);\n }\n if (type === 'string') {\n return o.length > STRING_HASH_CACHE_MIN_STRLEN ? cachedHashString(o) : hashString(o);\n }\n if (typeof o.hashCode === 'function') {\n return o.hashCode();\n }\n if (type === 'object') {\n return hashJSObj(o);\n }\n if (typeof o.toString === 'function') {\n return hashString(o.toString());\n }\n throw new Error('Value type ' + type + ' cannot be hashed.');\n }\n\n function cachedHashString(string) {\n var hash = stringHashCache[string];\n if (hash === undefined) {\n hash = hashString(string);\n if (STRING_HASH_CACHE_SIZE === STRING_HASH_CACHE_MAX_SIZE) {\n STRING_HASH_CACHE_SIZE = 0;\n stringHashCache = {};\n }\n STRING_HASH_CACHE_SIZE++;\n stringHashCache[string] = hash;\n }\n return hash;\n }\n\n // http://jsperf.com/hashing-strings\n function hashString(string) {\n // This is the hash from JVM\n // The hash code for a string is computed as\n // s[0] * 31 ^ (n - 1) + s[1] * 31 ^ (n - 2) + ... + s[n - 1],\n // where s[i] is the ith character of the string and n is the length of\n // the string. We \"mod\" the result to make it between 0 (inclusive) and 2^31\n // (exclusive) by dropping high bits.\n var hash = 0;\n for (var ii = 0; ii < string.length; ii++) {\n hash = 31 * hash + string.charCodeAt(ii) | 0;\n }\n return smi(hash);\n }\n\n function hashJSObj(obj) {\n var hash;\n if (usingWeakMap) {\n hash = weakMap.get(obj);\n if (hash !== undefined) {\n return hash;\n }\n }\n\n hash = obj[UID_HASH_KEY];\n if (hash !== undefined) {\n return hash;\n }\n\n if (!canDefineProperty) {\n hash = obj.propertyIsEnumerable && obj.propertyIsEnumerable[UID_HASH_KEY];\n if (hash !== undefined) {\n return hash;\n }\n\n hash = getIENodeHash(obj);\n if (hash !== undefined) {\n return hash;\n }\n }\n\n hash = ++objHashUID;\n if (objHashUID & 0x40000000) {\n objHashUID = 0;\n }\n\n if (usingWeakMap) {\n weakMap.set(obj, hash);\n } else if (isExtensible !== undefined && isExtensible(obj) === false) {\n throw new Error('Non-extensible objects are not allowed as keys.');\n } else if (canDefineProperty) {\n Object.defineProperty(obj, UID_HASH_KEY, {\n 'enumerable': false,\n 'configurable': false,\n 'writable': false,\n 'value': hash\n });\n } else if (obj.propertyIsEnumerable !== undefined &&\n obj.propertyIsEnumerable === obj.constructor.prototype.propertyIsEnumerable) {\n // Since we can't define a non-enumerable property on the object\n // we'll hijack one of the less-used non-enumerable properties to\n // save our hash on it. Since this is a function it will not show up in\n // `JSON.stringify` which is what we want.\n obj.propertyIsEnumerable = function() {\n return this.constructor.prototype.propertyIsEnumerable.apply(this, arguments);\n };\n obj.propertyIsEnumerable[UID_HASH_KEY] = hash;\n } else if (obj.nodeType !== undefined) {\n // At this point we couldn't get the IE `uniqueID` to use as a hash\n // and we couldn't use a non-enumerable property to exploit the\n // dontEnum bug so we simply add the `UID_HASH_KEY` on the node\n // itself.\n obj[UID_HASH_KEY] = hash;\n } else {\n throw new Error('Unable to set a non-enumerable property on object.');\n }\n\n return hash;\n }\n\n // Get references to ES5 object methods.\n var isExtensible = Object.isExtensible;\n\n // True if Object.defineProperty works as expected. IE8 fails this test.\n var canDefineProperty = (function() {\n try {\n Object.defineProperty({}, '@', {});\n return true;\n } catch (e) {\n return false;\n }\n }());\n\n // IE has a `uniqueID` property on DOM nodes. We can construct the hash from it\n // and avoid memory leaks from the IE cloneNode bug.\n function getIENodeHash(node) {\n if (node && node.nodeType > 0) {\n switch (node.nodeType) {\n case 1: // Element\n return node.uniqueID;\n case 9: // Document\n return node.documentElement && node.documentElement.uniqueID;\n }\n }\n }\n\n // If possible, use a WeakMap.\n var usingWeakMap = typeof WeakMap === 'function';\n var weakMap;\n if (usingWeakMap) {\n weakMap = new WeakMap();\n }\n\n var objHashUID = 0;\n\n var UID_HASH_KEY = '__immutablehash__';\n if (typeof Symbol === 'function') {\n UID_HASH_KEY = Symbol(UID_HASH_KEY);\n }\n\n var STRING_HASH_CACHE_MIN_STRLEN = 16;\n var STRING_HASH_CACHE_MAX_SIZE = 255;\n var STRING_HASH_CACHE_SIZE = 0;\n var stringHashCache = {};\n\n function assertNotInfinite(size) {\n invariant(\n size !== Infinity,\n 'Cannot perform this action with an infinite size.'\n );\n }\n\n createClass(Map, KeyedCollection);\n\n // @pragma Construction\n\n function Map(value) {\n return value === null || value === undefined ? emptyMap() :\n isMap(value) && !isOrdered(value) ? value :\n emptyMap().withMutations(function(map ) {\n var iter = KeyedIterable(value);\n assertNotInfinite(iter.size);\n iter.forEach(function(v, k) {return map.set(k, v)});\n });\n }\n\n Map.of = function() {var keyValues = SLICE$0.call(arguments, 0);\n return emptyMap().withMutations(function(map ) {\n for (var i = 0; i < keyValues.length; i += 2) {\n if (i + 1 >= keyValues.length) {\n throw new Error('Missing value for key: ' + keyValues[i]);\n }\n map.set(keyValues[i], keyValues[i + 1]);\n }\n });\n };\n\n Map.prototype.toString = function() {\n return this.__toString('Map {', '}');\n };\n\n // @pragma Access\n\n Map.prototype.get = function(k, notSetValue) {\n return this._root ?\n this._root.get(0, undefined, k, notSetValue) :\n notSetValue;\n };\n\n // @pragma Modification\n\n Map.prototype.set = function(k, v) {\n return updateMap(this, k, v);\n };\n\n Map.prototype.setIn = function(keyPath, v) {\n return this.updateIn(keyPath, NOT_SET, function() {return v});\n };\n\n Map.prototype.remove = function(k) {\n return updateMap(this, k, NOT_SET);\n };\n\n Map.prototype.deleteIn = function(keyPath) {\n return this.updateIn(keyPath, function() {return NOT_SET});\n };\n\n Map.prototype.update = function(k, notSetValue, updater) {\n return arguments.length === 1 ?\n k(this) :\n this.updateIn([k], notSetValue, updater);\n };\n\n Map.prototype.updateIn = function(keyPath, notSetValue, updater) {\n if (!updater) {\n updater = notSetValue;\n notSetValue = undefined;\n }\n var updatedValue = updateInDeepMap(\n this,\n forceIterator(keyPath),\n notSetValue,\n updater\n );\n return updatedValue === NOT_SET ? undefined : updatedValue;\n };\n\n Map.prototype.clear = function() {\n if (this.size === 0) {\n return this;\n }\n if (this.__ownerID) {\n this.size = 0;\n this._root = null;\n this.__hash = undefined;\n this.__altered = true;\n return this;\n }\n return emptyMap();\n };\n\n // @pragma Composition\n\n Map.prototype.merge = function(/*...iters*/) {\n return mergeIntoMapWith(this, undefined, arguments);\n };\n\n Map.prototype.mergeWith = function(merger) {var iters = SLICE$0.call(arguments, 1);\n return mergeIntoMapWith(this, merger, iters);\n };\n\n Map.prototype.mergeIn = function(keyPath) {var iters = SLICE$0.call(arguments, 1);\n return this.updateIn(\n keyPath,\n emptyMap(),\n function(m ) {return typeof m.merge === 'function' ?\n m.merge.apply(m, iters) :\n iters[iters.length - 1]}\n );\n };\n\n Map.prototype.mergeDeep = function(/*...iters*/) {\n return mergeIntoMapWith(this, deepMerger, arguments);\n };\n\n Map.prototype.mergeDeepWith = function(merger) {var iters = SLICE$0.call(arguments, 1);\n return mergeIntoMapWith(this, deepMergerWith(merger), iters);\n };\n\n Map.prototype.mergeDeepIn = function(keyPath) {var iters = SLICE$0.call(arguments, 1);\n return this.updateIn(\n keyPath,\n emptyMap(),\n function(m ) {return typeof m.mergeDeep === 'function' ?\n m.mergeDeep.apply(m, iters) :\n iters[iters.length - 1]}\n );\n };\n\n Map.prototype.sort = function(comparator) {\n // Late binding\n return OrderedMap(sortFactory(this, comparator));\n };\n\n Map.prototype.sortBy = function(mapper, comparator) {\n // Late binding\n return OrderedMap(sortFactory(this, comparator, mapper));\n };\n\n // @pragma Mutability\n\n Map.prototype.withMutations = function(fn) {\n var mutable = this.asMutable();\n fn(mutable);\n return mutable.wasAltered() ? mutable.__ensureOwner(this.__ownerID) : this;\n };\n\n Map.prototype.asMutable = function() {\n return this.__ownerID ? this : this.__ensureOwner(new OwnerID());\n };\n\n Map.prototype.asImmutable = function() {\n return this.__ensureOwner();\n };\n\n Map.prototype.wasAltered = function() {\n return this.__altered;\n };\n\n Map.prototype.__iterator = function(type, reverse) {\n return new MapIterator(this, type, reverse);\n };\n\n Map.prototype.__iterate = function(fn, reverse) {var this$0 = this;\n var iterations = 0;\n this._root && this._root.iterate(function(entry ) {\n iterations++;\n return fn(entry[1], entry[0], this$0);\n }, reverse);\n return iterations;\n };\n\n Map.prototype.__ensureOwner = function(ownerID) {\n if (ownerID === this.__ownerID) {\n return this;\n }\n if (!ownerID) {\n this.__ownerID = ownerID;\n this.__altered = false;\n return this;\n }\n return makeMap(this.size, this._root, ownerID, this.__hash);\n };\n\n\n function isMap(maybeMap) {\n return !!(maybeMap && maybeMap[IS_MAP_SENTINEL]);\n }\n\n Map.isMap = isMap;\n\n var IS_MAP_SENTINEL = '@@__IMMUTABLE_MAP__@@';\n\n var MapPrototype = Map.prototype;\n MapPrototype[IS_MAP_SENTINEL] = true;\n MapPrototype[DELETE] = MapPrototype.remove;\n MapPrototype.removeIn = MapPrototype.deleteIn;\n\n\n // #pragma Trie Nodes\n\n\n\n function ArrayMapNode(ownerID, entries) {\n this.ownerID = ownerID;\n this.entries = entries;\n }\n\n ArrayMapNode.prototype.get = function(shift, keyHash, key, notSetValue) {\n var entries = this.entries;\n for (var ii = 0, len = entries.length; ii < len; ii++) {\n if (is(key, entries[ii][0])) {\n return entries[ii][1];\n }\n }\n return notSetValue;\n };\n\n ArrayMapNode.prototype.update = function(ownerID, shift, keyHash, key, value, didChangeSize, didAlter) {\n var removed = value === NOT_SET;\n\n var entries = this.entries;\n var idx = 0;\n for (var len = entries.length; idx < len; idx++) {\n if (is(key, entries[idx][0])) {\n break;\n }\n }\n var exists = idx < len;\n\n if (exists ? entries[idx][1] === value : removed) {\n return this;\n }\n\n SetRef(didAlter);\n (removed || !exists) && SetRef(didChangeSize);\n\n if (removed && entries.length === 1) {\n return; // undefined\n }\n\n if (!exists && !removed && entries.length >= MAX_ARRAY_MAP_SIZE) {\n return createNodes(ownerID, entries, key, value);\n }\n\n var isEditable = ownerID && ownerID === this.ownerID;\n var newEntries = isEditable ? entries : arrCopy(entries);\n\n if (exists) {\n if (removed) {\n idx === len - 1 ? newEntries.pop() : (newEntries[idx] = newEntries.pop());\n } else {\n newEntries[idx] = [key, value];\n }\n } else {\n newEntries.push([key, value]);\n }\n\n if (isEditable) {\n this.entries = newEntries;\n return this;\n }\n\n return new ArrayMapNode(ownerID, newEntries);\n };\n\n\n\n\n function BitmapIndexedNode(ownerID, bitmap, nodes) {\n this.ownerID = ownerID;\n this.bitmap = bitmap;\n this.nodes = nodes;\n }\n\n BitmapIndexedNode.prototype.get = function(shift, keyHash, key, notSetValue) {\n if (keyHash === undefined) {\n keyHash = hash(key);\n }\n var bit = (1 << ((shift === 0 ? keyHash : keyHash >>> shift) & MASK));\n var bitmap = this.bitmap;\n return (bitmap & bit) === 0 ? notSetValue :\n this.nodes[popCount(bitmap & (bit - 1))].get(shift + SHIFT, keyHash, key, notSetValue);\n };\n\n BitmapIndexedNode.prototype.update = function(ownerID, shift, keyHash, key, value, didChangeSize, didAlter) {\n if (keyHash === undefined) {\n keyHash = hash(key);\n }\n var keyHashFrag = (shift === 0 ? keyHash : keyHash >>> shift) & MASK;\n var bit = 1 << keyHashFrag;\n var bitmap = this.bitmap;\n var exists = (bitmap & bit) !== 0;\n\n if (!exists && value === NOT_SET) {\n return this;\n }\n\n var idx = popCount(bitmap & (bit - 1));\n var nodes = this.nodes;\n var node = exists ? nodes[idx] : undefined;\n var newNode = updateNode(node, ownerID, shift + SHIFT, keyHash, key, value, didChangeSize, didAlter);\n\n if (newNode === node) {\n return this;\n }\n\n if (!exists && newNode && nodes.length >= MAX_BITMAP_INDEXED_SIZE) {\n return expandNodes(ownerID, nodes, bitmap, keyHashFrag, newNode);\n }\n\n if (exists && !newNode && nodes.length === 2 && isLeafNode(nodes[idx ^ 1])) {\n return nodes[idx ^ 1];\n }\n\n if (exists && newNode && nodes.length === 1 && isLeafNode(newNode)) {\n return newNode;\n }\n\n var isEditable = ownerID && ownerID === this.ownerID;\n var newBitmap = exists ? newNode ? bitmap : bitmap ^ bit : bitmap | bit;\n var newNodes = exists ? newNode ?\n setIn(nodes, idx, newNode, isEditable) :\n spliceOut(nodes, idx, isEditable) :\n spliceIn(nodes, idx, newNode, isEditable);\n\n if (isEditable) {\n this.bitmap = newBitmap;\n this.nodes = newNodes;\n return this;\n }\n\n return new BitmapIndexedNode(ownerID, newBitmap, newNodes);\n };\n\n\n\n\n function HashArrayMapNode(ownerID, count, nodes) {\n this.ownerID = ownerID;\n this.count = count;\n this.nodes = nodes;\n }\n\n HashArrayMapNode.prototype.get = function(shift, keyHash, key, notSetValue) {\n if (keyHash === undefined) {\n keyHash = hash(key);\n }\n var idx = (shift === 0 ? keyHash : keyHash >>> shift) & MASK;\n var node = this.nodes[idx];\n return node ? node.get(shift + SHIFT, keyHash, key, notSetValue) : notSetValue;\n };\n\n HashArrayMapNode.prototype.update = function(ownerID, shift, keyHash, key, value, didChangeSize, didAlter) {\n if (keyHash === undefined) {\n keyHash = hash(key);\n }\n var idx = (shift === 0 ? keyHash : keyHash >>> shift) & MASK;\n var removed = value === NOT_SET;\n var nodes = this.nodes;\n var node = nodes[idx];\n\n if (removed && !node) {\n return this;\n }\n\n var newNode = updateNode(node, ownerID, shift + SHIFT, keyHash, key, value, didChangeSize, didAlter);\n if (newNode === node) {\n return this;\n }\n\n var newCount = this.count;\n if (!node) {\n newCount++;\n } else if (!newNode) {\n newCount--;\n if (newCount < MIN_HASH_ARRAY_MAP_SIZE) {\n return packNodes(ownerID, nodes, newCount, idx);\n }\n }\n\n var isEditable = ownerID && ownerID === this.ownerID;\n var newNodes = setIn(nodes, idx, newNode, isEditable);\n\n if (isEditable) {\n this.count = newCount;\n this.nodes = newNodes;\n return this;\n }\n\n return new HashArrayMapNode(ownerID, newCount, newNodes);\n };\n\n\n\n\n function HashCollisionNode(ownerID, keyHash, entries) {\n this.ownerID = ownerID;\n this.keyHash = keyHash;\n this.entries = entries;\n }\n\n HashCollisionNode.prototype.get = function(shift, keyHash, key, notSetValue) {\n var entries = this.entries;\n for (var ii = 0, len = entries.length; ii < len; ii++) {\n if (is(key, entries[ii][0])) {\n return entries[ii][1];\n }\n }\n return notSetValue;\n };\n\n HashCollisionNode.prototype.update = function(ownerID, shift, keyHash, key, value, didChangeSize, didAlter) {\n if (keyHash === undefined) {\n keyHash = hash(key);\n }\n\n var removed = value === NOT_SET;\n\n if (keyHash !== this.keyHash) {\n if (removed) {\n return this;\n }\n SetRef(didAlter);\n SetRef(didChangeSize);\n return mergeIntoNode(this, ownerID, shift, keyHash, [key, value]);\n }\n\n var entries = this.entries;\n var idx = 0;\n for (var len = entries.length; idx < len; idx++) {\n if (is(key, entries[idx][0])) {\n break;\n }\n }\n var exists = idx < len;\n\n if (exists ? entries[idx][1] === value : removed) {\n return this;\n }\n\n SetRef(didAlter);\n (removed || !exists) && SetRef(didChangeSize);\n\n if (removed && len === 2) {\n return new ValueNode(ownerID, this.keyHash, entries[idx ^ 1]);\n }\n\n var isEditable = ownerID && ownerID === this.ownerID;\n var newEntries = isEditable ? entries : arrCopy(entries);\n\n if (exists) {\n if (removed) {\n idx === len - 1 ? newEntries.pop() : (newEntries[idx] = newEntries.pop());\n } else {\n newEntries[idx] = [key, value];\n }\n } else {\n newEntries.push([key, value]);\n }\n\n if (isEditable) {\n this.entries = newEntries;\n return this;\n }\n\n return new HashCollisionNode(ownerID, this.keyHash, newEntries);\n };\n\n\n\n\n function ValueNode(ownerID, keyHash, entry) {\n this.ownerID = ownerID;\n this.keyHash = keyHash;\n this.entry = entry;\n }\n\n ValueNode.prototype.get = function(shift, keyHash, key, notSetValue) {\n return is(key, this.entry[0]) ? this.entry[1] : notSetValue;\n };\n\n ValueNode.prototype.update = function(ownerID, shift, keyHash, key, value, didChangeSize, didAlter) {\n var removed = value === NOT_SET;\n var keyMatch = is(key, this.entry[0]);\n if (keyMatch ? value === this.entry[1] : removed) {\n return this;\n }\n\n SetRef(didAlter);\n\n if (removed) {\n SetRef(didChangeSize);\n return; // undefined\n }\n\n if (keyMatch) {\n if (ownerID && ownerID === this.ownerID) {\n this.entry[1] = value;\n return this;\n }\n return new ValueNode(ownerID, this.keyHash, [key, value]);\n }\n\n SetRef(didChangeSize);\n return mergeIntoNode(this, ownerID, shift, hash(key), [key, value]);\n };\n\n\n\n // #pragma Iterators\n\n ArrayMapNode.prototype.iterate =\n HashCollisionNode.prototype.iterate = function (fn, reverse) {\n var entries = this.entries;\n for (var ii = 0, maxIndex = entries.length - 1; ii <= maxIndex; ii++) {\n if (fn(entries[reverse ? maxIndex - ii : ii]) === false) {\n return false;\n }\n }\n }\n\n BitmapIndexedNode.prototype.iterate =\n HashArrayMapNode.prototype.iterate = function (fn, reverse) {\n var nodes = this.nodes;\n for (var ii = 0, maxIndex = nodes.length - 1; ii <= maxIndex; ii++) {\n var node = nodes[reverse ? maxIndex - ii : ii];\n if (node && node.iterate(fn, reverse) === false) {\n return false;\n }\n }\n }\n\n ValueNode.prototype.iterate = function (fn, reverse) {\n return fn(this.entry);\n }\n\n createClass(MapIterator, Iterator);\n\n function MapIterator(map, type, reverse) {\n this._type = type;\n this._reverse = reverse;\n this._stack = map._root && mapIteratorFrame(map._root);\n }\n\n MapIterator.prototype.next = function() {\n var type = this._type;\n var stack = this._stack;\n while (stack) {\n var node = stack.node;\n var index = stack.index++;\n var maxIndex;\n if (node.entry) {\n if (index === 0) {\n return mapIteratorValue(type, node.entry);\n }\n } else if (node.entries) {\n maxIndex = node.entries.length - 1;\n if (index <= maxIndex) {\n return mapIteratorValue(type, node.entries[this._reverse ? maxIndex - index : index]);\n }\n } else {\n maxIndex = node.nodes.length - 1;\n if (index <= maxIndex) {\n var subNode = node.nodes[this._reverse ? maxIndex - index : index];\n if (subNode) {\n if (subNode.entry) {\n return mapIteratorValue(type, subNode.entry);\n }\n stack = this._stack = mapIteratorFrame(subNode, stack);\n }\n continue;\n }\n }\n stack = this._stack = this._stack.__prev;\n }\n return iteratorDone();\n };\n\n\n function mapIteratorValue(type, entry) {\n return iteratorValue(type, entry[0], entry[1]);\n }\n\n function mapIteratorFrame(node, prev) {\n return {\n node: node,\n index: 0,\n __prev: prev\n };\n }\n\n function makeMap(size, root, ownerID, hash) {\n var map = Object.create(MapPrototype);\n map.size = size;\n map._root = root;\n map.__ownerID = ownerID;\n map.__hash = hash;\n map.__altered = false;\n return map;\n }\n\n var EMPTY_MAP;\n function emptyMap() {\n return EMPTY_MAP || (EMPTY_MAP = makeMap(0));\n }\n\n function updateMap(map, k, v) {\n var newRoot;\n var newSize;\n if (!map._root) {\n if (v === NOT_SET) {\n return map;\n }\n newSize = 1;\n newRoot = new ArrayMapNode(map.__ownerID, [[k, v]]);\n } else {\n var didChangeSize = MakeRef(CHANGE_LENGTH);\n var didAlter = MakeRef(DID_ALTER);\n newRoot = updateNode(map._root, map.__ownerID, 0, undefined, k, v, didChangeSize, didAlter);\n if (!didAlter.value) {\n return map;\n }\n newSize = map.size + (didChangeSize.value ? v === NOT_SET ? -1 : 1 : 0);\n }\n if (map.__ownerID) {\n map.size = newSize;\n map._root = newRoot;\n map.__hash = undefined;\n map.__altered = true;\n return map;\n }\n return newRoot ? makeMap(newSize, newRoot) : emptyMap();\n }\n\n function updateNode(node, ownerID, shift, keyHash, key, value, didChangeSize, didAlter) {\n if (!node) {\n if (value === NOT_SET) {\n return node;\n }\n SetRef(didAlter);\n SetRef(didChangeSize);\n return new ValueNode(ownerID, keyHash, [key, value]);\n }\n return node.update(ownerID, shift, keyHash, key, value, didChangeSize, didAlter);\n }\n\n function isLeafNode(node) {\n return node.constructor === ValueNode || node.constructor === HashCollisionNode;\n }\n\n function mergeIntoNode(node, ownerID, shift, keyHash, entry) {\n if (node.keyHash === keyHash) {\n return new HashCollisionNode(ownerID, keyHash, [node.entry, entry]);\n }\n\n var idx1 = (shift === 0 ? node.keyHash : node.keyHash >>> shift) & MASK;\n var idx2 = (shift === 0 ? keyHash : keyHash >>> shift) & MASK;\n\n var newNode;\n var nodes = idx1 === idx2 ?\n [mergeIntoNode(node, ownerID, shift + SHIFT, keyHash, entry)] :\n ((newNode = new ValueNode(ownerID, keyHash, entry)), idx1 < idx2 ? [node, newNode] : [newNode, node]);\n\n return new BitmapIndexedNode(ownerID, (1 << idx1) | (1 << idx2), nodes);\n }\n\n function createNodes(ownerID, entries, key, value) {\n if (!ownerID) {\n ownerID = new OwnerID();\n }\n var node = new ValueNode(ownerID, hash(key), [key, value]);\n for (var ii = 0; ii < entries.length; ii++) {\n var entry = entries[ii];\n node = node.update(ownerID, 0, undefined, entry[0], entry[1]);\n }\n return node;\n }\n\n function packNodes(ownerID, nodes, count, excluding) {\n var bitmap = 0;\n var packedII = 0;\n var packedNodes = new Array(count);\n for (var ii = 0, bit = 1, len = nodes.length; ii < len; ii++, bit <<= 1) {\n var node = nodes[ii];\n if (node !== undefined && ii !== excluding) {\n bitmap |= bit;\n packedNodes[packedII++] = node;\n }\n }\n return new BitmapIndexedNode(ownerID, bitmap, packedNodes);\n }\n\n function expandNodes(ownerID, nodes, bitmap, including, node) {\n var count = 0;\n var expandedNodes = new Array(SIZE);\n for (var ii = 0; bitmap !== 0; ii++, bitmap >>>= 1) {\n expandedNodes[ii] = bitmap & 1 ? nodes[count++] : undefined;\n }\n expandedNodes[including] = node;\n return new HashArrayMapNode(ownerID, count + 1, expandedNodes);\n }\n\n function mergeIntoMapWith(map, merger, iterables) {\n var iters = [];\n for (var ii = 0; ii < iterables.length; ii++) {\n var value = iterables[ii];\n var iter = KeyedIterable(value);\n if (!isIterable(value)) {\n iter = iter.map(function(v ) {return fromJS(v)});\n }\n iters.push(iter);\n }\n return mergeIntoCollectionWith(map, merger, iters);\n }\n\n function deepMerger(existing, value, key) {\n return existing && existing.mergeDeep && isIterable(value) ?\n existing.mergeDeep(value) :\n is(existing, value) ? existing : value;\n }\n\n function deepMergerWith(merger) {\n return function(existing, value, key) {\n if (existing && existing.mergeDeepWith && isIterable(value)) {\n return existing.mergeDeepWith(merger, value);\n }\n var nextValue = merger(existing, value, key);\n return is(existing, nextValue) ? existing : nextValue;\n };\n }\n\n function mergeIntoCollectionWith(collection, merger, iters) {\n iters = iters.filter(function(x ) {return x.size !== 0});\n if (iters.length === 0) {\n return collection;\n }\n if (collection.size === 0 && !collection.__ownerID && iters.length === 1) {\n return collection.constructor(iters[0]);\n }\n return collection.withMutations(function(collection ) {\n var mergeIntoMap = merger ?\n function(value, key) {\n collection.update(key, NOT_SET, function(existing )\n {return existing === NOT_SET ? value : merger(existing, value, key)}\n );\n } :\n function(value, key) {\n collection.set(key, value);\n }\n for (var ii = 0; ii < iters.length; ii++) {\n iters[ii].forEach(mergeIntoMap);\n }\n });\n }\n\n function updateInDeepMap(existing, keyPathIter, notSetValue, updater) {\n var isNotSet = existing === NOT_SET;\n var step = keyPathIter.next();\n if (step.done) {\n var existingValue = isNotSet ? notSetValue : existing;\n var newValue = updater(existingValue);\n return newValue === existingValue ? existing : newValue;\n }\n invariant(\n isNotSet || (existing && existing.set),\n 'invalid keyPath'\n );\n var key = step.value;\n var nextExisting = isNotSet ? NOT_SET : existing.get(key, NOT_SET);\n var nextUpdated = updateInDeepMap(\n nextExisting,\n keyPathIter,\n notSetValue,\n updater\n );\n return nextUpdated === nextExisting ? existing :\n nextUpdated === NOT_SET ? existing.remove(key) :\n (isNotSet ? emptyMap() : existing).set(key, nextUpdated);\n }\n\n function popCount(x) {\n x = x - ((x >> 1) & 0x55555555);\n x = (x & 0x33333333) + ((x >> 2) & 0x33333333);\n x = (x + (x >> 4)) & 0x0f0f0f0f;\n x = x + (x >> 8);\n x = x + (x >> 16);\n return x & 0x7f;\n }\n\n function setIn(array, idx, val, canEdit) {\n var newArray = canEdit ? array : arrCopy(array);\n newArray[idx] = val;\n return newArray;\n }\n\n function spliceIn(array, idx, val, canEdit) {\n var newLen = array.length + 1;\n if (canEdit && idx + 1 === newLen) {\n array[idx] = val;\n return array;\n }\n var newArray = new Array(newLen);\n var after = 0;\n for (var ii = 0; ii < newLen; ii++) {\n if (ii === idx) {\n newArray[ii] = val;\n after = -1;\n } else {\n newArray[ii] = array[ii + after];\n }\n }\n return newArray;\n }\n\n function spliceOut(array, idx, canEdit) {\n var newLen = array.length - 1;\n if (canEdit && idx === newLen) {\n array.pop();\n return array;\n }\n var newArray = new Array(newLen);\n var after = 0;\n for (var ii = 0; ii < newLen; ii++) {\n if (ii === idx) {\n after = 1;\n }\n newArray[ii] = array[ii + after];\n }\n return newArray;\n }\n\n var MAX_ARRAY_MAP_SIZE = SIZE / 4;\n var MAX_BITMAP_INDEXED_SIZE = SIZE / 2;\n var MIN_HASH_ARRAY_MAP_SIZE = SIZE / 4;\n\n createClass(List, IndexedCollection);\n\n // @pragma Construction\n\n function List(value) {\n var empty = emptyList();\n if (value === null || value === undefined) {\n return empty;\n }\n if (isList(value)) {\n return value;\n }\n var iter = IndexedIterable(value);\n var size = iter.size;\n if (size === 0) {\n return empty;\n }\n assertNotInfinite(size);\n if (size > 0 && size < SIZE) {\n return makeList(0, size, SHIFT, null, new VNode(iter.toArray()));\n }\n return empty.withMutations(function(list ) {\n list.setSize(size);\n iter.forEach(function(v, i) {return list.set(i, v)});\n });\n }\n\n List.of = function(/*...values*/) {\n return this(arguments);\n };\n\n List.prototype.toString = function() {\n return this.__toString('List [', ']');\n };\n\n // @pragma Access\n\n List.prototype.get = function(index, notSetValue) {\n index = wrapIndex(this, index);\n if (index >= 0 && index < this.size) {\n index += this._origin;\n var node = listNodeFor(this, index);\n return node && node.array[index & MASK];\n }\n return notSetValue;\n };\n\n // @pragma Modification\n\n List.prototype.set = function(index, value) {\n return updateList(this, index, value);\n };\n\n List.prototype.remove = function(index) {\n return !this.has(index) ? this :\n index === 0 ? this.shift() :\n index === this.size - 1 ? this.pop() :\n this.splice(index, 1);\n };\n\n List.prototype.insert = function(index, value) {\n return this.splice(index, 0, value);\n };\n\n List.prototype.clear = function() {\n if (this.size === 0) {\n return this;\n }\n if (this.__ownerID) {\n this.size = this._origin = this._capacity = 0;\n this._level = SHIFT;\n this._root = this._tail = null;\n this.__hash = undefined;\n this.__altered = true;\n return this;\n }\n return emptyList();\n };\n\n List.prototype.push = function(/*...values*/) {\n var values = arguments;\n var oldSize = this.size;\n return this.withMutations(function(list ) {\n setListBounds(list, 0, oldSize + values.length);\n for (var ii = 0; ii < values.length; ii++) {\n list.set(oldSize + ii, values[ii]);\n }\n });\n };\n\n List.prototype.pop = function() {\n return setListBounds(this, 0, -1);\n };\n\n List.prototype.unshift = function(/*...values*/) {\n var values = arguments;\n return this.withMutations(function(list ) {\n setListBounds(list, -values.length);\n for (var ii = 0; ii < values.length; ii++) {\n list.set(ii, values[ii]);\n }\n });\n };\n\n List.prototype.shift = function() {\n return setListBounds(this, 1);\n };\n\n // @pragma Composition\n\n List.prototype.merge = function(/*...iters*/) {\n return mergeIntoListWith(this, undefined, arguments);\n };\n\n List.prototype.mergeWith = function(merger) {var iters = SLICE$0.call(arguments, 1);\n return mergeIntoListWith(this, merger, iters);\n };\n\n List.prototype.mergeDeep = function(/*...iters*/) {\n return mergeIntoListWith(this, deepMerger, arguments);\n };\n\n List.prototype.mergeDeepWith = function(merger) {var iters = SLICE$0.call(arguments, 1);\n return mergeIntoListWith(this, deepMergerWith(merger), iters);\n };\n\n List.prototype.setSize = function(size) {\n return setListBounds(this, 0, size);\n };\n\n // @pragma Iteration\n\n List.prototype.slice = function(begin, end) {\n var size = this.size;\n if (wholeSlice(begin, end, size)) {\n return this;\n }\n return setListBounds(\n this,\n resolveBegin(begin, size),\n resolveEnd(end, size)\n );\n };\n\n List.prototype.__iterator = function(type, reverse) {\n var index = 0;\n var values = iterateList(this, reverse);\n return new Iterator(function() {\n var value = values();\n return value === DONE ?\n iteratorDone() :\n iteratorValue(type, index++, value);\n });\n };\n\n List.prototype.__iterate = function(fn, reverse) {\n var index = 0;\n var values = iterateList(this, reverse);\n var value;\n while ((value = values()) !== DONE) {\n if (fn(value, index++, this) === false) {\n break;\n }\n }\n return index;\n };\n\n List.prototype.__ensureOwner = function(ownerID) {\n if (ownerID === this.__ownerID) {\n return this;\n }\n if (!ownerID) {\n this.__ownerID = ownerID;\n return this;\n }\n return makeList(this._origin, this._capacity, this._level, this._root, this._tail, ownerID, this.__hash);\n };\n\n\n function isList(maybeList) {\n return !!(maybeList && maybeList[IS_LIST_SENTINEL]);\n }\n\n List.isList = isList;\n\n var IS_LIST_SENTINEL = '@@__IMMUTABLE_LIST__@@';\n\n var ListPrototype = List.prototype;\n ListPrototype[IS_LIST_SENTINEL] = true;\n ListPrototype[DELETE] = ListPrototype.remove;\n ListPrototype.setIn = MapPrototype.setIn;\n ListPrototype.deleteIn =\n ListPrototype.removeIn = MapPrototype.removeIn;\n ListPrototype.update = MapPrototype.update;\n ListPrototype.updateIn = MapPrototype.updateIn;\n ListPrototype.mergeIn = MapPrototype.mergeIn;\n ListPrototype.mergeDeepIn = MapPrototype.mergeDeepIn;\n ListPrototype.withMutations = MapPrototype.withMutations;\n ListPrototype.asMutable = MapPrototype.asMutable;\n ListPrototype.asImmutable = MapPrototype.asImmutable;\n ListPrototype.wasAltered = MapPrototype.wasAltered;\n\n\n\n function VNode(array, ownerID) {\n this.array = array;\n this.ownerID = ownerID;\n }\n\n // TODO: seems like these methods are very similar\n\n VNode.prototype.removeBefore = function(ownerID, level, index) {\n if (index === level ? 1 << level : 0 || this.array.length === 0) {\n return this;\n }\n var originIndex = (index >>> level) & MASK;\n if (originIndex >= this.array.length) {\n return new VNode([], ownerID);\n }\n var removingFirst = originIndex === 0;\n var newChild;\n if (level > 0) {\n var oldChild = this.array[originIndex];\n newChild = oldChild && oldChild.removeBefore(ownerID, level - SHIFT, index);\n if (newChild === oldChild && removingFirst) {\n return this;\n }\n }\n if (removingFirst && !newChild) {\n return this;\n }\n var editable = editableVNode(this, ownerID);\n if (!removingFirst) {\n for (var ii = 0; ii < originIndex; ii++) {\n editable.array[ii] = undefined;\n }\n }\n if (newChild) {\n editable.array[originIndex] = newChild;\n }\n return editable;\n };\n\n VNode.prototype.removeAfter = function(ownerID, level, index) {\n if (index === (level ? 1 << level : 0) || this.array.length === 0) {\n return this;\n }\n var sizeIndex = ((index - 1) >>> level) & MASK;\n if (sizeIndex >= this.array.length) {\n return this;\n }\n\n var newChild;\n if (level > 0) {\n var oldChild = this.array[sizeIndex];\n newChild = oldChild && oldChild.removeAfter(ownerID, level - SHIFT, index);\n if (newChild === oldChild && sizeIndex === this.array.length - 1) {\n return this;\n }\n }\n\n var editable = editableVNode(this, ownerID);\n editable.array.splice(sizeIndex + 1);\n if (newChild) {\n editable.array[sizeIndex] = newChild;\n }\n return editable;\n };\n\n\n\n var DONE = {};\n\n function iterateList(list, reverse) {\n var left = list._origin;\n var right = list._capacity;\n var tailPos = getTailOffset(right);\n var tail = list._tail;\n\n return iterateNodeOrLeaf(list._root, list._level, 0);\n\n function iterateNodeOrLeaf(node, level, offset) {\n return level === 0 ?\n iterateLeaf(node, offset) :\n iterateNode(node, level, offset);\n }\n\n function iterateLeaf(node, offset) {\n var array = offset === tailPos ? tail && tail.array : node && node.array;\n var from = offset > left ? 0 : left - offset;\n var to = right - offset;\n if (to > SIZE) {\n to = SIZE;\n }\n return function() {\n if (from === to) {\n return DONE;\n }\n var idx = reverse ? --to : from++;\n return array && array[idx];\n };\n }\n\n function iterateNode(node, level, offset) {\n var values;\n var array = node && node.array;\n var from = offset > left ? 0 : (left - offset) >> level;\n var to = ((right - offset) >> level) + 1;\n if (to > SIZE) {\n to = SIZE;\n }\n return function() {\n do {\n if (values) {\n var value = values();\n if (value !== DONE) {\n return value;\n }\n values = null;\n }\n if (from === to) {\n return DONE;\n }\n var idx = reverse ? --to : from++;\n values = iterateNodeOrLeaf(\n array && array[idx], level - SHIFT, offset + (idx << level)\n );\n } while (true);\n };\n }\n }\n\n function makeList(origin, capacity, level, root, tail, ownerID, hash) {\n var list = Object.create(ListPrototype);\n list.size = capacity - origin;\n list._origin = origin;\n list._capacity = capacity;\n list._level = level;\n list._root = root;\n list._tail = tail;\n list.__ownerID = ownerID;\n list.__hash = hash;\n list.__altered = false;\n return list;\n }\n\n var EMPTY_LIST;\n function emptyList() {\n return EMPTY_LIST || (EMPTY_LIST = makeList(0, 0, SHIFT));\n }\n\n function updateList(list, index, value) {\n index = wrapIndex(list, index);\n\n if (index !== index) {\n return list;\n }\n\n if (index >= list.size || index < 0) {\n return list.withMutations(function(list ) {\n index < 0 ?\n setListBounds(list, index).set(0, value) :\n setListBounds(list, 0, index + 1).set(index, value)\n });\n }\n\n index += list._origin;\n\n var newTail = list._tail;\n var newRoot = list._root;\n var didAlter = MakeRef(DID_ALTER);\n if (index >= getTailOffset(list._capacity)) {\n newTail = updateVNode(newTail, list.__ownerID, 0, index, value, didAlter);\n } else {\n newRoot = updateVNode(newRoot, list.__ownerID, list._level, index, value, didAlter);\n }\n\n if (!didAlter.value) {\n return list;\n }\n\n if (list.__ownerID) {\n list._root = newRoot;\n list._tail = newTail;\n list.__hash = undefined;\n list.__altered = true;\n return list;\n }\n return makeList(list._origin, list._capacity, list._level, newRoot, newTail);\n }\n\n function updateVNode(node, ownerID, level, index, value, didAlter) {\n var idx = (index >>> level) & MASK;\n var nodeHas = node && idx < node.array.length;\n if (!nodeHas && value === undefined) {\n return node;\n }\n\n var newNode;\n\n if (level > 0) {\n var lowerNode = node && node.array[idx];\n var newLowerNode = updateVNode(lowerNode, ownerID, level - SHIFT, index, value, didAlter);\n if (newLowerNode === lowerNode) {\n return node;\n }\n newNode = editableVNode(node, ownerID);\n newNode.array[idx] = newLowerNode;\n return newNode;\n }\n\n if (nodeHas && node.array[idx] === value) {\n return node;\n }\n\n SetRef(didAlter);\n\n newNode = editableVNode(node, ownerID);\n if (value === undefined && idx === newNode.array.length - 1) {\n newNode.array.pop();\n } else {\n newNode.array[idx] = value;\n }\n return newNode;\n }\n\n function editableVNode(node, ownerID) {\n if (ownerID && node && ownerID === node.ownerID) {\n return node;\n }\n return new VNode(node ? node.array.slice() : [], ownerID);\n }\n\n function listNodeFor(list, rawIndex) {\n if (rawIndex >= getTailOffset(list._capacity)) {\n return list._tail;\n }\n if (rawIndex < 1 << (list._level + SHIFT)) {\n var node = list._root;\n var level = list._level;\n while (node && level > 0) {\n node = node.array[(rawIndex >>> level) & MASK];\n level -= SHIFT;\n }\n return node;\n }\n }\n\n function setListBounds(list, begin, end) {\n // Sanitize begin & end using this shorthand for ToInt32(argument)\n // http://www.ecma-international.org/ecma-262/6.0/#sec-toint32\n if (begin !== undefined) {\n begin = begin | 0;\n }\n if (end !== undefined) {\n end = end | 0;\n }\n var owner = list.__ownerID || new OwnerID();\n var oldOrigin = list._origin;\n var oldCapacity = list._capacity;\n var newOrigin = oldOrigin + begin;\n var newCapacity = end === undefined ? oldCapacity : end < 0 ? oldCapacity + end : oldOrigin + end;\n if (newOrigin === oldOrigin && newCapacity === oldCapacity) {\n return list;\n }\n\n // If it's going to end after it starts, it's empty.\n if (newOrigin >= newCapacity) {\n return list.clear();\n }\n\n var newLevel = list._level;\n var newRoot = list._root;\n\n // New origin might need creating a higher root.\n var offsetShift = 0;\n while (newOrigin + offsetShift < 0) {\n newRoot = new VNode(newRoot && newRoot.array.length ? [undefined, newRoot] : [], owner);\n newLevel += SHIFT;\n offsetShift += 1 << newLevel;\n }\n if (offsetShift) {\n newOrigin += offsetShift;\n oldOrigin += offsetShift;\n newCapacity += offsetShift;\n oldCapacity += offsetShift;\n }\n\n var oldTailOffset = getTailOffset(oldCapacity);\n var newTailOffset = getTailOffset(newCapacity);\n\n // New size might need creating a higher root.\n while (newTailOffset >= 1 << (newLevel + SHIFT)) {\n newRoot = new VNode(newRoot && newRoot.array.length ? [newRoot] : [], owner);\n newLevel += SHIFT;\n }\n\n // Locate or create the new tail.\n var oldTail = list._tail;\n var newTail = newTailOffset < oldTailOffset ?\n listNodeFor(list, newCapacity - 1) :\n newTailOffset > oldTailOffset ? new VNode([], owner) : oldTail;\n\n // Merge Tail into tree.\n if (oldTail && newTailOffset > oldTailOffset && newOrigin < oldCapacity && oldTail.array.length) {\n newRoot = editableVNode(newRoot, owner);\n var node = newRoot;\n for (var level = newLevel; level > SHIFT; level -= SHIFT) {\n var idx = (oldTailOffset >>> level) & MASK;\n node = node.array[idx] = editableVNode(node.array[idx], owner);\n }\n node.array[(oldTailOffset >>> SHIFT) & MASK] = oldTail;\n }\n\n // If the size has been reduced, there's a chance the tail needs to be trimmed.\n if (newCapacity < oldCapacity) {\n newTail = newTail && newTail.removeAfter(owner, 0, newCapacity);\n }\n\n // If the new origin is within the tail, then we do not need a root.\n if (newOrigin >= newTailOffset) {\n newOrigin -= newTailOffset;\n newCapacity -= newTailOffset;\n newLevel = SHIFT;\n newRoot = null;\n newTail = newTail && newTail.removeBefore(owner, 0, newOrigin);\n\n // Otherwise, if the root has been trimmed, garbage collect.\n } else if (newOrigin > oldOrigin || newTailOffset < oldTailOffset) {\n offsetShift = 0;\n\n // Identify the new top root node of the subtree of the old root.\n while (newRoot) {\n var beginIndex = (newOrigin >>> newLevel) & MASK;\n if (beginIndex !== (newTailOffset >>> newLevel) & MASK) {\n break;\n }\n if (beginIndex) {\n offsetShift += (1 << newLevel) * beginIndex;\n }\n newLevel -= SHIFT;\n newRoot = newRoot.array[beginIndex];\n }\n\n // Trim the new sides of the new root.\n if (newRoot && newOrigin > oldOrigin) {\n newRoot = newRoot.removeBefore(owner, newLevel, newOrigin - offsetShift);\n }\n if (newRoot && newTailOffset < oldTailOffset) {\n newRoot = newRoot.removeAfter(owner, newLevel, newTailOffset - offsetShift);\n }\n if (offsetShift) {\n newOrigin -= offsetShift;\n newCapacity -= offsetShift;\n }\n }\n\n if (list.__ownerID) {\n list.size = newCapacity - newOrigin;\n list._origin = newOrigin;\n list._capacity = newCapacity;\n list._level = newLevel;\n list._root = newRoot;\n list._tail = newTail;\n list.__hash = undefined;\n list.__altered = true;\n return list;\n }\n return makeList(newOrigin, newCapacity, newLevel, newRoot, newTail);\n }\n\n function mergeIntoListWith(list, merger, iterables) {\n var iters = [];\n var maxSize = 0;\n for (var ii = 0; ii < iterables.length; ii++) {\n var value = iterables[ii];\n var iter = IndexedIterable(value);\n if (iter.size > maxSize) {\n maxSize = iter.size;\n }\n if (!isIterable(value)) {\n iter = iter.map(function(v ) {return fromJS(v)});\n }\n iters.push(iter);\n }\n if (maxSize > list.size) {\n list = list.setSize(maxSize);\n }\n return mergeIntoCollectionWith(list, merger, iters);\n }\n\n function getTailOffset(size) {\n return size < SIZE ? 0 : (((size - 1) >>> SHIFT) << SHIFT);\n }\n\n createClass(OrderedMap, Map);\n\n // @pragma Construction\n\n function OrderedMap(value) {\n return value === null || value === undefined ? emptyOrderedMap() :\n isOrderedMap(value) ? value :\n emptyOrderedMap().withMutations(function(map ) {\n var iter = KeyedIterable(value);\n assertNotInfinite(iter.size);\n iter.forEach(function(v, k) {return map.set(k, v)});\n });\n }\n\n OrderedMap.of = function(/*...values*/) {\n return this(arguments);\n };\n\n OrderedMap.prototype.toString = function() {\n return this.__toString('OrderedMap {', '}');\n };\n\n // @pragma Access\n\n OrderedMap.prototype.get = function(k, notSetValue) {\n var index = this._map.get(k);\n return index !== undefined ? this._list.get(index)[1] : notSetValue;\n };\n\n // @pragma Modification\n\n OrderedMap.prototype.clear = function() {\n if (this.size === 0) {\n return this;\n }\n if (this.__ownerID) {\n this.size = 0;\n this._map.clear();\n this._list.clear();\n return this;\n }\n return emptyOrderedMap();\n };\n\n OrderedMap.prototype.set = function(k, v) {\n return updateOrderedMap(this, k, v);\n };\n\n OrderedMap.prototype.remove = function(k) {\n return updateOrderedMap(this, k, NOT_SET);\n };\n\n OrderedMap.prototype.wasAltered = function() {\n return this._map.wasAltered() || this._list.wasAltered();\n };\n\n OrderedMap.prototype.__iterate = function(fn, reverse) {var this$0 = this;\n return this._list.__iterate(\n function(entry ) {return entry && fn(entry[1], entry[0], this$0)},\n reverse\n );\n };\n\n OrderedMap.prototype.__iterator = function(type, reverse) {\n return this._list.fromEntrySeq().__iterator(type, reverse);\n };\n\n OrderedMap.prototype.__ensureOwner = function(ownerID) {\n if (ownerID === this.__ownerID) {\n return this;\n }\n var newMap = this._map.__ensureOwner(ownerID);\n var newList = this._list.__ensureOwner(ownerID);\n if (!ownerID) {\n this.__ownerID = ownerID;\n this._map = newMap;\n this._list = newList;\n return this;\n }\n return makeOrderedMap(newMap, newList, ownerID, this.__hash);\n };\n\n\n function isOrderedMap(maybeOrderedMap) {\n return isMap(maybeOrderedMap) && isOrdered(maybeOrderedMap);\n }\n\n OrderedMap.isOrderedMap = isOrderedMap;\n\n OrderedMap.prototype[IS_ORDERED_SENTINEL] = true;\n OrderedMap.prototype[DELETE] = OrderedMap.prototype.remove;\n\n\n\n function makeOrderedMap(map, list, ownerID, hash) {\n var omap = Object.create(OrderedMap.prototype);\n omap.size = map ? map.size : 0;\n omap._map = map;\n omap._list = list;\n omap.__ownerID = ownerID;\n omap.__hash = hash;\n return omap;\n }\n\n var EMPTY_ORDERED_MAP;\n function emptyOrderedMap() {\n return EMPTY_ORDERED_MAP || (EMPTY_ORDERED_MAP = makeOrderedMap(emptyMap(), emptyList()));\n }\n\n function updateOrderedMap(omap, k, v) {\n var map = omap._map;\n var list = omap._list;\n var i = map.get(k);\n var has = i !== undefined;\n var newMap;\n var newList;\n if (v === NOT_SET) { // removed\n if (!has) {\n return omap;\n }\n if (list.size >= SIZE && list.size >= map.size * 2) {\n newList = list.filter(function(entry, idx) {return entry !== undefined && i !== idx});\n newMap = newList.toKeyedSeq().map(function(entry ) {return entry[0]}).flip().toMap();\n if (omap.__ownerID) {\n newMap.__ownerID = newList.__ownerID = omap.__ownerID;\n }\n } else {\n newMap = map.remove(k);\n newList = i === list.size - 1 ? list.pop() : list.set(i, undefined);\n }\n } else {\n if (has) {\n if (v === list.get(i)[1]) {\n return omap;\n }\n newMap = map;\n newList = list.set(i, [k, v]);\n } else {\n newMap = map.set(k, list.size);\n newList = list.set(list.size, [k, v]);\n }\n }\n if (omap.__ownerID) {\n omap.size = newMap.size;\n omap._map = newMap;\n omap._list = newList;\n omap.__hash = undefined;\n return omap;\n }\n return makeOrderedMap(newMap, newList);\n }\n\n createClass(ToKeyedSequence, KeyedSeq);\n function ToKeyedSequence(indexed, useKeys) {\n this._iter = indexed;\n this._useKeys = useKeys;\n this.size = indexed.size;\n }\n\n ToKeyedSequence.prototype.get = function(key, notSetValue) {\n return this._iter.get(key, notSetValue);\n };\n\n ToKeyedSequence.prototype.has = function(key) {\n return this._iter.has(key);\n };\n\n ToKeyedSequence.prototype.valueSeq = function() {\n return this._iter.valueSeq();\n };\n\n ToKeyedSequence.prototype.reverse = function() {var this$0 = this;\n var reversedSequence = reverseFactory(this, true);\n if (!this._useKeys) {\n reversedSequence.valueSeq = function() {return this$0._iter.toSeq().reverse()};\n }\n return reversedSequence;\n };\n\n ToKeyedSequence.prototype.map = function(mapper, context) {var this$0 = this;\n var mappedSequence = mapFactory(this, mapper, context);\n if (!this._useKeys) {\n mappedSequence.valueSeq = function() {return this$0._iter.toSeq().map(mapper, context)};\n }\n return mappedSequence;\n };\n\n ToKeyedSequence.prototype.__iterate = function(fn, reverse) {var this$0 = this;\n var ii;\n return this._iter.__iterate(\n this._useKeys ?\n function(v, k) {return fn(v, k, this$0)} :\n ((ii = reverse ? resolveSize(this) : 0),\n function(v ) {return fn(v, reverse ? --ii : ii++, this$0)}),\n reverse\n );\n };\n\n ToKeyedSequence.prototype.__iterator = function(type, reverse) {\n if (this._useKeys) {\n return this._iter.__iterator(type, reverse);\n }\n var iterator = this._iter.__iterator(ITERATE_VALUES, reverse);\n var ii = reverse ? resolveSize(this) : 0;\n return new Iterator(function() {\n var step = iterator.next();\n return step.done ? step :\n iteratorValue(type, reverse ? --ii : ii++, step.value, step);\n });\n };\n\n ToKeyedSequence.prototype[IS_ORDERED_SENTINEL] = true;\n\n\n createClass(ToIndexedSequence, IndexedSeq);\n function ToIndexedSequence(iter) {\n this._iter = iter;\n this.size = iter.size;\n }\n\n ToIndexedSequence.prototype.includes = function(value) {\n return this._iter.includes(value);\n };\n\n ToIndexedSequence.prototype.__iterate = function(fn, reverse) {var this$0 = this;\n var iterations = 0;\n return this._iter.__iterate(function(v ) {return fn(v, iterations++, this$0)}, reverse);\n };\n\n ToIndexedSequence.prototype.__iterator = function(type, reverse) {\n var iterator = this._iter.__iterator(ITERATE_VALUES, reverse);\n var iterations = 0;\n return new Iterator(function() {\n var step = iterator.next();\n return step.done ? step :\n iteratorValue(type, iterations++, step.value, step)\n });\n };\n\n\n\n createClass(ToSetSequence, SetSeq);\n function ToSetSequence(iter) {\n this._iter = iter;\n this.size = iter.size;\n }\n\n ToSetSequence.prototype.has = function(key) {\n return this._iter.includes(key);\n };\n\n ToSetSequence.prototype.__iterate = function(fn, reverse) {var this$0 = this;\n return this._iter.__iterate(function(v ) {return fn(v, v, this$0)}, reverse);\n };\n\n ToSetSequence.prototype.__iterator = function(type, reverse) {\n var iterator = this._iter.__iterator(ITERATE_VALUES, reverse);\n return new Iterator(function() {\n var step = iterator.next();\n return step.done ? step :\n iteratorValue(type, step.value, step.value, step);\n });\n };\n\n\n\n createClass(FromEntriesSequence, KeyedSeq);\n function FromEntriesSequence(entries) {\n this._iter = entries;\n this.size = entries.size;\n }\n\n FromEntriesSequence.prototype.entrySeq = function() {\n return this._iter.toSeq();\n };\n\n FromEntriesSequence.prototype.__iterate = function(fn, reverse) {var this$0 = this;\n return this._iter.__iterate(function(entry ) {\n // Check if entry exists first so array access doesn't throw for holes\n // in the parent iteration.\n if (entry) {\n validateEntry(entry);\n var indexedIterable = isIterable(entry);\n return fn(\n indexedIterable ? entry.get(1) : entry[1],\n indexedIterable ? entry.get(0) : entry[0],\n this$0\n );\n }\n }, reverse);\n };\n\n FromEntriesSequence.prototype.__iterator = function(type, reverse) {\n var iterator = this._iter.__iterator(ITERATE_VALUES, reverse);\n return new Iterator(function() {\n while (true) {\n var step = iterator.next();\n if (step.done) {\n return step;\n }\n var entry = step.value;\n // Check if entry exists first so array access doesn't throw for holes\n // in the parent iteration.\n if (entry) {\n validateEntry(entry);\n var indexedIterable = isIterable(entry);\n return iteratorValue(\n type,\n indexedIterable ? entry.get(0) : entry[0],\n indexedIterable ? entry.get(1) : entry[1],\n step\n );\n }\n }\n });\n };\n\n\n ToIndexedSequence.prototype.cacheResult =\n ToKeyedSequence.prototype.cacheResult =\n ToSetSequence.prototype.cacheResult =\n FromEntriesSequence.prototype.cacheResult =\n cacheResultThrough;\n\n\n function flipFactory(iterable) {\n var flipSequence = makeSequence(iterable);\n flipSequence._iter = iterable;\n flipSequence.size = iterable.size;\n flipSequence.flip = function() {return iterable};\n flipSequence.reverse = function () {\n var reversedSequence = iterable.reverse.apply(this); // super.reverse()\n reversedSequence.flip = function() {return iterable.reverse()};\n return reversedSequence;\n };\n flipSequence.has = function(key ) {return iterable.includes(key)};\n flipSequence.includes = function(key ) {return iterable.has(key)};\n flipSequence.cacheResult = cacheResultThrough;\n flipSequence.__iterateUncached = function (fn, reverse) {var this$0 = this;\n return iterable.__iterate(function(v, k) {return fn(k, v, this$0) !== false}, reverse);\n }\n flipSequence.__iteratorUncached = function(type, reverse) {\n if (type === ITERATE_ENTRIES) {\n var iterator = iterable.__iterator(type, reverse);\n return new Iterator(function() {\n var step = iterator.next();\n if (!step.done) {\n var k = step.value[0];\n step.value[0] = step.value[1];\n step.value[1] = k;\n }\n return step;\n });\n }\n return iterable.__iterator(\n type === ITERATE_VALUES ? ITERATE_KEYS : ITERATE_VALUES,\n reverse\n );\n }\n return flipSequence;\n }\n\n\n function mapFactory(iterable, mapper, context) {\n var mappedSequence = makeSequence(iterable);\n mappedSequence.size = iterable.size;\n mappedSequence.has = function(key ) {return iterable.has(key)};\n mappedSequence.get = function(key, notSetValue) {\n var v = iterable.get(key, NOT_SET);\n return v === NOT_SET ?\n notSetValue :\n mapper.call(context, v, key, iterable);\n };\n mappedSequence.__iterateUncached = function (fn, reverse) {var this$0 = this;\n return iterable.__iterate(\n function(v, k, c) {return fn(mapper.call(context, v, k, c), k, this$0) !== false},\n reverse\n );\n }\n mappedSequence.__iteratorUncached = function (type, reverse) {\n var iterator = iterable.__iterator(ITERATE_ENTRIES, reverse);\n return new Iterator(function() {\n var step = iterator.next();\n if (step.done) {\n return step;\n }\n var entry = step.value;\n var key = entry[0];\n return iteratorValue(\n type,\n key,\n mapper.call(context, entry[1], key, iterable),\n step\n );\n });\n }\n return mappedSequence;\n }\n\n\n function reverseFactory(iterable, useKeys) {\n var reversedSequence = makeSequence(iterable);\n reversedSequence._iter = iterable;\n reversedSequence.size = iterable.size;\n reversedSequence.reverse = function() {return iterable};\n if (iterable.flip) {\n reversedSequence.flip = function () {\n var flipSequence = flipFactory(iterable);\n flipSequence.reverse = function() {return iterable.flip()};\n return flipSequence;\n };\n }\n reversedSequence.get = function(key, notSetValue) \n {return iterable.get(useKeys ? key : -1 - key, notSetValue)};\n reversedSequence.has = function(key )\n {return iterable.has(useKeys ? key : -1 - key)};\n reversedSequence.includes = function(value ) {return iterable.includes(value)};\n reversedSequence.cacheResult = cacheResultThrough;\n reversedSequence.__iterate = function (fn, reverse) {var this$0 = this;\n return iterable.__iterate(function(v, k) {return fn(v, k, this$0)}, !reverse);\n };\n reversedSequence.__iterator =\n function(type, reverse) {return iterable.__iterator(type, !reverse)};\n return reversedSequence;\n }\n\n\n function filterFactory(iterable, predicate, context, useKeys) {\n var filterSequence = makeSequence(iterable);\n if (useKeys) {\n filterSequence.has = function(key ) {\n var v = iterable.get(key, NOT_SET);\n return v !== NOT_SET && !!predicate.call(context, v, key, iterable);\n };\n filterSequence.get = function(key, notSetValue) {\n var v = iterable.get(key, NOT_SET);\n return v !== NOT_SET && predicate.call(context, v, key, iterable) ?\n v : notSetValue;\n };\n }\n filterSequence.__iterateUncached = function (fn, reverse) {var this$0 = this;\n var iterations = 0;\n iterable.__iterate(function(v, k, c) {\n if (predicate.call(context, v, k, c)) {\n iterations++;\n return fn(v, useKeys ? k : iterations - 1, this$0);\n }\n }, reverse);\n return iterations;\n };\n filterSequence.__iteratorUncached = function (type, reverse) {\n var iterator = iterable.__iterator(ITERATE_ENTRIES, reverse);\n var iterations = 0;\n return new Iterator(function() {\n while (true) {\n var step = iterator.next();\n if (step.done) {\n return step;\n }\n var entry = step.value;\n var key = entry[0];\n var value = entry[1];\n if (predicate.call(context, value, key, iterable)) {\n return iteratorValue(type, useKeys ? key : iterations++, value, step);\n }\n }\n });\n }\n return filterSequence;\n }\n\n\n function countByFactory(iterable, grouper, context) {\n var groups = Map().asMutable();\n iterable.__iterate(function(v, k) {\n groups.update(\n grouper.call(context, v, k, iterable),\n 0,\n function(a ) {return a + 1}\n );\n });\n return groups.asImmutable();\n }\n\n\n function groupByFactory(iterable, grouper, context) {\n var isKeyedIter = isKeyed(iterable);\n var groups = (isOrdered(iterable) ? OrderedMap() : Map()).asMutable();\n iterable.__iterate(function(v, k) {\n groups.update(\n grouper.call(context, v, k, iterable),\n function(a ) {return (a = a || [], a.push(isKeyedIter ? [k, v] : v), a)}\n );\n });\n var coerce = iterableClass(iterable);\n return groups.map(function(arr ) {return reify(iterable, coerce(arr))});\n }\n\n\n function sliceFactory(iterable, begin, end, useKeys) {\n var originalSize = iterable.size;\n\n // Sanitize begin & end using this shorthand for ToInt32(argument)\n // http://www.ecma-international.org/ecma-262/6.0/#sec-toint32\n if (begin !== undefined) {\n begin = begin | 0;\n }\n if (end !== undefined) {\n if (end === Infinity) {\n end = originalSize;\n } else {\n end = end | 0;\n }\n }\n\n if (wholeSlice(begin, end, originalSize)) {\n return iterable;\n }\n\n var resolvedBegin = resolveBegin(begin, originalSize);\n var resolvedEnd = resolveEnd(end, originalSize);\n\n // begin or end will be NaN if they were provided as negative numbers and\n // this iterable's size is unknown. In that case, cache first so there is\n // a known size and these do not resolve to NaN.\n if (resolvedBegin !== resolvedBegin || resolvedEnd !== resolvedEnd) {\n return sliceFactory(iterable.toSeq().cacheResult(), begin, end, useKeys);\n }\n\n // Note: resolvedEnd is undefined when the original sequence's length is\n // unknown and this slice did not supply an end and should contain all\n // elements after resolvedBegin.\n // In that case, resolvedSize will be NaN and sliceSize will remain undefined.\n var resolvedSize = resolvedEnd - resolvedBegin;\n var sliceSize;\n if (resolvedSize === resolvedSize) {\n sliceSize = resolvedSize < 0 ? 0 : resolvedSize;\n }\n\n var sliceSeq = makeSequence(iterable);\n\n // If iterable.size is undefined, the size of the realized sliceSeq is\n // unknown at this point unless the number of items to slice is 0\n sliceSeq.size = sliceSize === 0 ? sliceSize : iterable.size && sliceSize || undefined;\n\n if (!useKeys && isSeq(iterable) && sliceSize >= 0) {\n sliceSeq.get = function (index, notSetValue) {\n index = wrapIndex(this, index);\n return index >= 0 && index < sliceSize ?\n iterable.get(index + resolvedBegin, notSetValue) :\n notSetValue;\n }\n }\n\n sliceSeq.__iterateUncached = function(fn, reverse) {var this$0 = this;\n if (sliceSize === 0) {\n return 0;\n }\n if (reverse) {\n return this.cacheResult().__iterate(fn, reverse);\n }\n var skipped = 0;\n var isSkipping = true;\n var iterations = 0;\n iterable.__iterate(function(v, k) {\n if (!(isSkipping && (isSkipping = skipped++ < resolvedBegin))) {\n iterations++;\n return fn(v, useKeys ? k : iterations - 1, this$0) !== false &&\n iterations !== sliceSize;\n }\n });\n return iterations;\n };\n\n sliceSeq.__iteratorUncached = function(type, reverse) {\n if (sliceSize !== 0 && reverse) {\n return this.cacheResult().__iterator(type, reverse);\n }\n // Don't bother instantiating parent iterator if taking 0.\n var iterator = sliceSize !== 0 && iterable.__iterator(type, reverse);\n var skipped = 0;\n var iterations = 0;\n return new Iterator(function() {\n while (skipped++ < resolvedBegin) {\n iterator.next();\n }\n if (++iterations > sliceSize) {\n return iteratorDone();\n }\n var step = iterator.next();\n if (useKeys || type === ITERATE_VALUES) {\n return step;\n } else if (type === ITERATE_KEYS) {\n return iteratorValue(type, iterations - 1, undefined, step);\n } else {\n return iteratorValue(type, iterations - 1, step.value[1], step);\n }\n });\n }\n\n return sliceSeq;\n }\n\n\n function takeWhileFactory(iterable, predicate, context) {\n var takeSequence = makeSequence(iterable);\n takeSequence.__iterateUncached = function(fn, reverse) {var this$0 = this;\n if (reverse) {\n return this.cacheResult().__iterate(fn, reverse);\n }\n var iterations = 0;\n iterable.__iterate(function(v, k, c) \n {return predicate.call(context, v, k, c) && ++iterations && fn(v, k, this$0)}\n );\n return iterations;\n };\n takeSequence.__iteratorUncached = function(type, reverse) {var this$0 = this;\n if (reverse) {\n return this.cacheResult().__iterator(type, reverse);\n }\n var iterator = iterable.__iterator(ITERATE_ENTRIES, reverse);\n var iterating = true;\n return new Iterator(function() {\n if (!iterating) {\n return iteratorDone();\n }\n var step = iterator.next();\n if (step.done) {\n return step;\n }\n var entry = step.value;\n var k = entry[0];\n var v = entry[1];\n if (!predicate.call(context, v, k, this$0)) {\n iterating = false;\n return iteratorDone();\n }\n return type === ITERATE_ENTRIES ? step :\n iteratorValue(type, k, v, step);\n });\n };\n return takeSequence;\n }\n\n\n function skipWhileFactory(iterable, predicate, context, useKeys) {\n var skipSequence = makeSequence(iterable);\n skipSequence.__iterateUncached = function (fn, reverse) {var this$0 = this;\n if (reverse) {\n return this.cacheResult().__iterate(fn, reverse);\n }\n var isSkipping = true;\n var iterations = 0;\n iterable.__iterate(function(v, k, c) {\n if (!(isSkipping && (isSkipping = predicate.call(context, v, k, c)))) {\n iterations++;\n return fn(v, useKeys ? k : iterations - 1, this$0);\n }\n });\n return iterations;\n };\n skipSequence.__iteratorUncached = function(type, reverse) {var this$0 = this;\n if (reverse) {\n return this.cacheResult().__iterator(type, reverse);\n }\n var iterator = iterable.__iterator(ITERATE_ENTRIES, reverse);\n var skipping = true;\n var iterations = 0;\n return new Iterator(function() {\n var step, k, v;\n do {\n step = iterator.next();\n if (step.done) {\n if (useKeys || type === ITERATE_VALUES) {\n return step;\n } else if (type === ITERATE_KEYS) {\n return iteratorValue(type, iterations++, undefined, step);\n } else {\n return iteratorValue(type, iterations++, step.value[1], step);\n }\n }\n var entry = step.value;\n k = entry[0];\n v = entry[1];\n skipping && (skipping = predicate.call(context, v, k, this$0));\n } while (skipping);\n return type === ITERATE_ENTRIES ? step :\n iteratorValue(type, k, v, step);\n });\n };\n return skipSequence;\n }\n\n\n function concatFactory(iterable, values) {\n var isKeyedIterable = isKeyed(iterable);\n var iters = [iterable].concat(values).map(function(v ) {\n if (!isIterable(v)) {\n v = isKeyedIterable ?\n keyedSeqFromValue(v) :\n indexedSeqFromValue(Array.isArray(v) ? v : [v]);\n } else if (isKeyedIterable) {\n v = KeyedIterable(v);\n }\n return v;\n }).filter(function(v ) {return v.size !== 0});\n\n if (iters.length === 0) {\n return iterable;\n }\n\n if (iters.length === 1) {\n var singleton = iters[0];\n if (singleton === iterable ||\n isKeyedIterable && isKeyed(singleton) ||\n isIndexed(iterable) && isIndexed(singleton)) {\n return singleton;\n }\n }\n\n var concatSeq = new ArraySeq(iters);\n if (isKeyedIterable) {\n concatSeq = concatSeq.toKeyedSeq();\n } else if (!isIndexed(iterable)) {\n concatSeq = concatSeq.toSetSeq();\n }\n concatSeq = concatSeq.flatten(true);\n concatSeq.size = iters.reduce(\n function(sum, seq) {\n if (sum !== undefined) {\n var size = seq.size;\n if (size !== undefined) {\n return sum + size;\n }\n }\n },\n 0\n );\n return concatSeq;\n }\n\n\n function flattenFactory(iterable, depth, useKeys) {\n var flatSequence = makeSequence(iterable);\n flatSequence.__iterateUncached = function(fn, reverse) {\n var iterations = 0;\n var stopped = false;\n function flatDeep(iter, currentDepth) {var this$0 = this;\n iter.__iterate(function(v, k) {\n if ((!depth || currentDepth < depth) && isIterable(v)) {\n flatDeep(v, currentDepth + 1);\n } else if (fn(v, useKeys ? k : iterations++, this$0) === false) {\n stopped = true;\n }\n return !stopped;\n }, reverse);\n }\n flatDeep(iterable, 0);\n return iterations;\n }\n flatSequence.__iteratorUncached = function(type, reverse) {\n var iterator = iterable.__iterator(type, reverse);\n var stack = [];\n var iterations = 0;\n return new Iterator(function() {\n while (iterator) {\n var step = iterator.next();\n if (step.done !== false) {\n iterator = stack.pop();\n continue;\n }\n var v = step.value;\n if (type === ITERATE_ENTRIES) {\n v = v[1];\n }\n if ((!depth || stack.length < depth) && isIterable(v)) {\n stack.push(iterator);\n iterator = v.__iterator(type, reverse);\n } else {\n return useKeys ? step : iteratorValue(type, iterations++, v, step);\n }\n }\n return iteratorDone();\n });\n }\n return flatSequence;\n }\n\n\n function flatMapFactory(iterable, mapper, context) {\n var coerce = iterableClass(iterable);\n return iterable.toSeq().map(\n function(v, k) {return coerce(mapper.call(context, v, k, iterable))}\n ).flatten(true);\n }\n\n\n function interposeFactory(iterable, separator) {\n var interposedSequence = makeSequence(iterable);\n interposedSequence.size = iterable.size && iterable.size * 2 -1;\n interposedSequence.__iterateUncached = function(fn, reverse) {var this$0 = this;\n var iterations = 0;\n iterable.__iterate(function(v, k) \n {return (!iterations || fn(separator, iterations++, this$0) !== false) &&\n fn(v, iterations++, this$0) !== false},\n reverse\n );\n return iterations;\n };\n interposedSequence.__iteratorUncached = function(type, reverse) {\n var iterator = iterable.__iterator(ITERATE_VALUES, reverse);\n var iterations = 0;\n var step;\n return new Iterator(function() {\n if (!step || iterations % 2) {\n step = iterator.next();\n if (step.done) {\n return step;\n }\n }\n return iterations % 2 ?\n iteratorValue(type, iterations++, separator) :\n iteratorValue(type, iterations++, step.value, step);\n });\n };\n return interposedSequence;\n }\n\n\n function sortFactory(iterable, comparator, mapper) {\n if (!comparator) {\n comparator = defaultComparator;\n }\n var isKeyedIterable = isKeyed(iterable);\n var index = 0;\n var entries = iterable.toSeq().map(\n function(v, k) {return [k, v, index++, mapper ? mapper(v, k, iterable) : v]}\n ).toArray();\n entries.sort(function(a, b) {return comparator(a[3], b[3]) || a[2] - b[2]}).forEach(\n isKeyedIterable ?\n function(v, i) { entries[i].length = 2; } :\n function(v, i) { entries[i] = v[1]; }\n );\n return isKeyedIterable ? KeyedSeq(entries) :\n isIndexed(iterable) ? IndexedSeq(entries) :\n SetSeq(entries);\n }\n\n\n function maxFactory(iterable, comparator, mapper) {\n if (!comparator) {\n comparator = defaultComparator;\n }\n if (mapper) {\n var entry = iterable.toSeq()\n .map(function(v, k) {return [v, mapper(v, k, iterable)]})\n .reduce(function(a, b) {return maxCompare(comparator, a[1], b[1]) ? b : a});\n return entry && entry[0];\n } else {\n return iterable.reduce(function(a, b) {return maxCompare(comparator, a, b) ? b : a});\n }\n }\n\n function maxCompare(comparator, a, b) {\n var comp = comparator(b, a);\n // b is considered the new max if the comparator declares them equal, but\n // they are not equal and b is in fact a nullish value.\n return (comp === 0 && b !== a && (b === undefined || b === null || b !== b)) || comp > 0;\n }\n\n\n function zipWithFactory(keyIter, zipper, iters) {\n var zipSequence = makeSequence(keyIter);\n zipSequence.size = new ArraySeq(iters).map(function(i ) {return i.size}).min();\n // Note: this a generic base implementation of __iterate in terms of\n // __iterator which may be more generically useful in the future.\n zipSequence.__iterate = function(fn, reverse) {\n /* generic:\n var iterator = this.__iterator(ITERATE_ENTRIES, reverse);\n var step;\n var iterations = 0;\n while (!(step = iterator.next()).done) {\n iterations++;\n if (fn(step.value[1], step.value[0], this) === false) {\n break;\n }\n }\n return iterations;\n */\n // indexed:\n var iterator = this.__iterator(ITERATE_VALUES, reverse);\n var step;\n var iterations = 0;\n while (!(step = iterator.next()).done) {\n if (fn(step.value, iterations++, this) === false) {\n break;\n }\n }\n return iterations;\n };\n zipSequence.__iteratorUncached = function(type, reverse) {\n var iterators = iters.map(function(i )\n {return (i = Iterable(i), getIterator(reverse ? i.reverse() : i))}\n );\n var iterations = 0;\n var isDone = false;\n return new Iterator(function() {\n var steps;\n if (!isDone) {\n steps = iterators.map(function(i ) {return i.next()});\n isDone = steps.some(function(s ) {return s.done});\n }\n if (isDone) {\n return iteratorDone();\n }\n return iteratorValue(\n type,\n iterations++,\n zipper.apply(null, steps.map(function(s ) {return s.value}))\n );\n });\n };\n return zipSequence\n }\n\n\n // #pragma Helper Functions\n\n function reify(iter, seq) {\n return isSeq(iter) ? seq : iter.constructor(seq);\n }\n\n function validateEntry(entry) {\n if (entry !== Object(entry)) {\n throw new TypeError('Expected [K, V] tuple: ' + entry);\n }\n }\n\n function resolveSize(iter) {\n assertNotInfinite(iter.size);\n return ensureSize(iter);\n }\n\n function iterableClass(iterable) {\n return isKeyed(iterable) ? KeyedIterable :\n isIndexed(iterable) ? IndexedIterable :\n SetIterable;\n }\n\n function makeSequence(iterable) {\n return Object.create(\n (\n isKeyed(iterable) ? KeyedSeq :\n isIndexed(iterable) ? IndexedSeq :\n SetSeq\n ).prototype\n );\n }\n\n function cacheResultThrough() {\n if (this._iter.cacheResult) {\n this._iter.cacheResult();\n this.size = this._iter.size;\n return this;\n } else {\n return Seq.prototype.cacheResult.call(this);\n }\n }\n\n function defaultComparator(a, b) {\n return a > b ? 1 : a < b ? -1 : 0;\n }\n\n function forceIterator(keyPath) {\n var iter = getIterator(keyPath);\n if (!iter) {\n // Array might not be iterable in this environment, so we need a fallback\n // to our wrapped type.\n if (!isArrayLike(keyPath)) {\n throw new TypeError('Expected iterable or array-like: ' + keyPath);\n }\n iter = getIterator(Iterable(keyPath));\n }\n return iter;\n }\n\n createClass(Record, KeyedCollection);\n\n function Record(defaultValues, name) {\n var hasInitialized;\n\n var RecordType = function Record(values) {\n if (values instanceof RecordType) {\n return values;\n }\n if (!(this instanceof RecordType)) {\n return new RecordType(values);\n }\n if (!hasInitialized) {\n hasInitialized = true;\n var keys = Object.keys(defaultValues);\n setProps(RecordTypePrototype, keys);\n RecordTypePrototype.size = keys.length;\n RecordTypePrototype._name = name;\n RecordTypePrototype._keys = keys;\n RecordTypePrototype._defaultValues = defaultValues;\n }\n this._map = Map(values);\n };\n\n var RecordTypePrototype = RecordType.prototype = Object.create(RecordPrototype);\n RecordTypePrototype.constructor = RecordType;\n\n return RecordType;\n }\n\n Record.prototype.toString = function() {\n return this.__toString(recordName(this) + ' {', '}');\n };\n\n // @pragma Access\n\n Record.prototype.has = function(k) {\n return this._defaultValues.hasOwnProperty(k);\n };\n\n Record.prototype.get = function(k, notSetValue) {\n if (!this.has(k)) {\n return notSetValue;\n }\n var defaultVal = this._defaultValues[k];\n return this._map ? this._map.get(k, defaultVal) : defaultVal;\n };\n\n // @pragma Modification\n\n Record.prototype.clear = function() {\n if (this.__ownerID) {\n this._map && this._map.clear();\n return this;\n }\n var RecordType = this.constructor;\n return RecordType._empty || (RecordType._empty = makeRecord(this, emptyMap()));\n };\n\n Record.prototype.set = function(k, v) {\n if (!this.has(k)) {\n throw new Error('Cannot set unknown key \"' + k + '\" on ' + recordName(this));\n }\n if (this._map && !this._map.has(k)) {\n var defaultVal = this._defaultValues[k];\n if (v === defaultVal) {\n return this;\n }\n }\n var newMap = this._map && this._map.set(k, v);\n if (this.__ownerID || newMap === this._map) {\n return this;\n }\n return makeRecord(this, newMap);\n };\n\n Record.prototype.remove = function(k) {\n if (!this.has(k)) {\n return this;\n }\n var newMap = this._map && this._map.remove(k);\n if (this.__ownerID || newMap === this._map) {\n return this;\n }\n return makeRecord(this, newMap);\n };\n\n Record.prototype.wasAltered = function() {\n return this._map.wasAltered();\n };\n\n Record.prototype.__iterator = function(type, reverse) {var this$0 = this;\n return KeyedIterable(this._defaultValues).map(function(_, k) {return this$0.get(k)}).__iterator(type, reverse);\n };\n\n Record.prototype.__iterate = function(fn, reverse) {var this$0 = this;\n return KeyedIterable(this._defaultValues).map(function(_, k) {return this$0.get(k)}).__iterate(fn, reverse);\n };\n\n Record.prototype.__ensureOwner = function(ownerID) {\n if (ownerID === this.__ownerID) {\n return this;\n }\n var newMap = this._map && this._map.__ensureOwner(ownerID);\n if (!ownerID) {\n this.__ownerID = ownerID;\n this._map = newMap;\n return this;\n }\n return makeRecord(this, newMap, ownerID);\n };\n\n\n var RecordPrototype = Record.prototype;\n RecordPrototype[DELETE] = RecordPrototype.remove;\n RecordPrototype.deleteIn =\n RecordPrototype.removeIn = MapPrototype.removeIn;\n RecordPrototype.merge = MapPrototype.merge;\n RecordPrototype.mergeWith = MapPrototype.mergeWith;\n RecordPrototype.mergeIn = MapPrototype.mergeIn;\n RecordPrototype.mergeDeep = MapPrototype.mergeDeep;\n RecordPrototype.mergeDeepWith = MapPrototype.mergeDeepWith;\n RecordPrototype.mergeDeepIn = MapPrototype.mergeDeepIn;\n RecordPrototype.setIn = MapPrototype.setIn;\n RecordPrototype.update = MapPrototype.update;\n RecordPrototype.updateIn = MapPrototype.updateIn;\n RecordPrototype.withMutations = MapPrototype.withMutations;\n RecordPrototype.asMutable = MapPrototype.asMutable;\n RecordPrototype.asImmutable = MapPrototype.asImmutable;\n\n\n function makeRecord(likeRecord, map, ownerID) {\n var record = Object.create(Object.getPrototypeOf(likeRecord));\n record._map = map;\n record.__ownerID = ownerID;\n return record;\n }\n\n function recordName(record) {\n return record._name || record.constructor.name || 'Record';\n }\n\n function setProps(prototype, names) {\n try {\n names.forEach(setProp.bind(undefined, prototype));\n } catch (error) {\n // Object.defineProperty failed. Probably IE8.\n }\n }\n\n function setProp(prototype, name) {\n Object.defineProperty(prototype, name, {\n get: function() {\n return this.get(name);\n },\n set: function(value) {\n invariant(this.__ownerID, 'Cannot set on an immutable record.');\n this.set(name, value);\n }\n });\n }\n\n createClass(Set, SetCollection);\n\n // @pragma Construction\n\n function Set(value) {\n return value === null || value === undefined ? emptySet() :\n isSet(value) && !isOrdered(value) ? value :\n emptySet().withMutations(function(set ) {\n var iter = SetIterable(value);\n assertNotInfinite(iter.size);\n iter.forEach(function(v ) {return set.add(v)});\n });\n }\n\n Set.of = function(/*...values*/) {\n return this(arguments);\n };\n\n Set.fromKeys = function(value) {\n return this(KeyedIterable(value).keySeq());\n };\n\n Set.prototype.toString = function() {\n return this.__toString('Set {', '}');\n };\n\n // @pragma Access\n\n Set.prototype.has = function(value) {\n return this._map.has(value);\n };\n\n // @pragma Modification\n\n Set.prototype.add = function(value) {\n return updateSet(this, this._map.set(value, true));\n };\n\n Set.prototype.remove = function(value) {\n return updateSet(this, this._map.remove(value));\n };\n\n Set.prototype.clear = function() {\n return updateSet(this, this._map.clear());\n };\n\n // @pragma Composition\n\n Set.prototype.union = function() {var iters = SLICE$0.call(arguments, 0);\n iters = iters.filter(function(x ) {return x.size !== 0});\n if (iters.length === 0) {\n return this;\n }\n if (this.size === 0 && !this.__ownerID && iters.length === 1) {\n return this.constructor(iters[0]);\n }\n return this.withMutations(function(set ) {\n for (var ii = 0; ii < iters.length; ii++) {\n SetIterable(iters[ii]).forEach(function(value ) {return set.add(value)});\n }\n });\n };\n\n Set.prototype.intersect = function() {var iters = SLICE$0.call(arguments, 0);\n if (iters.length === 0) {\n return this;\n }\n iters = iters.map(function(iter ) {return SetIterable(iter)});\n var originalSet = this;\n return this.withMutations(function(set ) {\n originalSet.forEach(function(value ) {\n if (!iters.every(function(iter ) {return iter.includes(value)})) {\n set.remove(value);\n }\n });\n });\n };\n\n Set.prototype.subtract = function() {var iters = SLICE$0.call(arguments, 0);\n if (iters.length === 0) {\n return this;\n }\n iters = iters.map(function(iter ) {return SetIterable(iter)});\n var originalSet = this;\n return this.withMutations(function(set ) {\n originalSet.forEach(function(value ) {\n if (iters.some(function(iter ) {return iter.includes(value)})) {\n set.remove(value);\n }\n });\n });\n };\n\n Set.prototype.merge = function() {\n return this.union.apply(this, arguments);\n };\n\n Set.prototype.mergeWith = function(merger) {var iters = SLICE$0.call(arguments, 1);\n return this.union.apply(this, iters);\n };\n\n Set.prototype.sort = function(comparator) {\n // Late binding\n return OrderedSet(sortFactory(this, comparator));\n };\n\n Set.prototype.sortBy = function(mapper, comparator) {\n // Late binding\n return OrderedSet(sortFactory(this, comparator, mapper));\n };\n\n Set.prototype.wasAltered = function() {\n return this._map.wasAltered();\n };\n\n Set.prototype.__iterate = function(fn, reverse) {var this$0 = this;\n return this._map.__iterate(function(_, k) {return fn(k, k, this$0)}, reverse);\n };\n\n Set.prototype.__iterator = function(type, reverse) {\n return this._map.map(function(_, k) {return k}).__iterator(type, reverse);\n };\n\n Set.prototype.__ensureOwner = function(ownerID) {\n if (ownerID === this.__ownerID) {\n return this;\n }\n var newMap = this._map.__ensureOwner(ownerID);\n if (!ownerID) {\n this.__ownerID = ownerID;\n this._map = newMap;\n return this;\n }\n return this.__make(newMap, ownerID);\n };\n\n\n function isSet(maybeSet) {\n return !!(maybeSet && maybeSet[IS_SET_SENTINEL]);\n }\n\n Set.isSet = isSet;\n\n var IS_SET_SENTINEL = '@@__IMMUTABLE_SET__@@';\n\n var SetPrototype = Set.prototype;\n SetPrototype[IS_SET_SENTINEL] = true;\n SetPrototype[DELETE] = SetPrototype.remove;\n SetPrototype.mergeDeep = SetPrototype.merge;\n SetPrototype.mergeDeepWith = SetPrototype.mergeWith;\n SetPrototype.withMutations = MapPrototype.withMutations;\n SetPrototype.asMutable = MapPrototype.asMutable;\n SetPrototype.asImmutable = MapPrototype.asImmutable;\n\n SetPrototype.__empty = emptySet;\n SetPrototype.__make = makeSet;\n\n function updateSet(set, newMap) {\n if (set.__ownerID) {\n set.size = newMap.size;\n set._map = newMap;\n return set;\n }\n return newMap === set._map ? set :\n newMap.size === 0 ? set.__empty() :\n set.__make(newMap);\n }\n\n function makeSet(map, ownerID) {\n var set = Object.create(SetPrototype);\n set.size = map ? map.size : 0;\n set._map = map;\n set.__ownerID = ownerID;\n return set;\n }\n\n var EMPTY_SET;\n function emptySet() {\n return EMPTY_SET || (EMPTY_SET = makeSet(emptyMap()));\n }\n\n createClass(OrderedSet, Set);\n\n // @pragma Construction\n\n function OrderedSet(value) {\n return value === null || value === undefined ? emptyOrderedSet() :\n isOrderedSet(value) ? value :\n emptyOrderedSet().withMutations(function(set ) {\n var iter = SetIterable(value);\n assertNotInfinite(iter.size);\n iter.forEach(function(v ) {return set.add(v)});\n });\n }\n\n OrderedSet.of = function(/*...values*/) {\n return this(arguments);\n };\n\n OrderedSet.fromKeys = function(value) {\n return this(KeyedIterable(value).keySeq());\n };\n\n OrderedSet.prototype.toString = function() {\n return this.__toString('OrderedSet {', '}');\n };\n\n\n function isOrderedSet(maybeOrderedSet) {\n return isSet(maybeOrderedSet) && isOrdered(maybeOrderedSet);\n }\n\n OrderedSet.isOrderedSet = isOrderedSet;\n\n var OrderedSetPrototype = OrderedSet.prototype;\n OrderedSetPrototype[IS_ORDERED_SENTINEL] = true;\n\n OrderedSetPrototype.__empty = emptyOrderedSet;\n OrderedSetPrototype.__make = makeOrderedSet;\n\n function makeOrderedSet(map, ownerID) {\n var set = Object.create(OrderedSetPrototype);\n set.size = map ? map.size : 0;\n set._map = map;\n set.__ownerID = ownerID;\n return set;\n }\n\n var EMPTY_ORDERED_SET;\n function emptyOrderedSet() {\n return EMPTY_ORDERED_SET || (EMPTY_ORDERED_SET = makeOrderedSet(emptyOrderedMap()));\n }\n\n createClass(Stack, IndexedCollection);\n\n // @pragma Construction\n\n function Stack(value) {\n return value === null || value === undefined ? emptyStack() :\n isStack(value) ? value :\n emptyStack().unshiftAll(value);\n }\n\n Stack.of = function(/*...values*/) {\n return this(arguments);\n };\n\n Stack.prototype.toString = function() {\n return this.__toString('Stack [', ']');\n };\n\n // @pragma Access\n\n Stack.prototype.get = function(index, notSetValue) {\n var head = this._head;\n index = wrapIndex(this, index);\n while (head && index--) {\n head = head.next;\n }\n return head ? head.value : notSetValue;\n };\n\n Stack.prototype.peek = function() {\n return this._head && this._head.value;\n };\n\n // @pragma Modification\n\n Stack.prototype.push = function(/*...values*/) {\n if (arguments.length === 0) {\n return this;\n }\n var newSize = this.size + arguments.length;\n var head = this._head;\n for (var ii = arguments.length - 1; ii >= 0; ii--) {\n head = {\n value: arguments[ii],\n next: head\n };\n }\n if (this.__ownerID) {\n this.size = newSize;\n this._head = head;\n this.__hash = undefined;\n this.__altered = true;\n return this;\n }\n return makeStack(newSize, head);\n };\n\n Stack.prototype.pushAll = function(iter) {\n iter = IndexedIterable(iter);\n if (iter.size === 0) {\n return this;\n }\n assertNotInfinite(iter.size);\n var newSize = this.size;\n var head = this._head;\n iter.reverse().forEach(function(value ) {\n newSize++;\n head = {\n value: value,\n next: head\n };\n });\n if (this.__ownerID) {\n this.size = newSize;\n this._head = head;\n this.__hash = undefined;\n this.__altered = true;\n return this;\n }\n return makeStack(newSize, head);\n };\n\n Stack.prototype.pop = function() {\n return this.slice(1);\n };\n\n Stack.prototype.unshift = function(/*...values*/) {\n return this.push.apply(this, arguments);\n };\n\n Stack.prototype.unshiftAll = function(iter) {\n return this.pushAll(iter);\n };\n\n Stack.prototype.shift = function() {\n return this.pop.apply(this, arguments);\n };\n\n Stack.prototype.clear = function() {\n if (this.size === 0) {\n return this;\n }\n if (this.__ownerID) {\n this.size = 0;\n this._head = undefined;\n this.__hash = undefined;\n this.__altered = true;\n return this;\n }\n return emptyStack();\n };\n\n Stack.prototype.slice = function(begin, end) {\n if (wholeSlice(begin, end, this.size)) {\n return this;\n }\n var resolvedBegin = resolveBegin(begin, this.size);\n var resolvedEnd = resolveEnd(end, this.size);\n if (resolvedEnd !== this.size) {\n // super.slice(begin, end);\n return IndexedCollection.prototype.slice.call(this, begin, end);\n }\n var newSize = this.size - resolvedBegin;\n var head = this._head;\n while (resolvedBegin--) {\n head = head.next;\n }\n if (this.__ownerID) {\n this.size = newSize;\n this._head = head;\n this.__hash = undefined;\n this.__altered = true;\n return this;\n }\n return makeStack(newSize, head);\n };\n\n // @pragma Mutability\n\n Stack.prototype.__ensureOwner = function(ownerID) {\n if (ownerID === this.__ownerID) {\n return this;\n }\n if (!ownerID) {\n this.__ownerID = ownerID;\n this.__altered = false;\n return this;\n }\n return makeStack(this.size, this._head, ownerID, this.__hash);\n };\n\n // @pragma Iteration\n\n Stack.prototype.__iterate = function(fn, reverse) {\n if (reverse) {\n return this.reverse().__iterate(fn);\n }\n var iterations = 0;\n var node = this._head;\n while (node) {\n if (fn(node.value, iterations++, this) === false) {\n break;\n }\n node = node.next;\n }\n return iterations;\n };\n\n Stack.prototype.__iterator = function(type, reverse) {\n if (reverse) {\n return this.reverse().__iterator(type);\n }\n var iterations = 0;\n var node = this._head;\n return new Iterator(function() {\n if (node) {\n var value = node.value;\n node = node.next;\n return iteratorValue(type, iterations++, value);\n }\n return iteratorDone();\n });\n };\n\n\n function isStack(maybeStack) {\n return !!(maybeStack && maybeStack[IS_STACK_SENTINEL]);\n }\n\n Stack.isStack = isStack;\n\n var IS_STACK_SENTINEL = '@@__IMMUTABLE_STACK__@@';\n\n var StackPrototype = Stack.prototype;\n StackPrototype[IS_STACK_SENTINEL] = true;\n StackPrototype.withMutations = MapPrototype.withMutations;\n StackPrototype.asMutable = MapPrototype.asMutable;\n StackPrototype.asImmutable = MapPrototype.asImmutable;\n StackPrototype.wasAltered = MapPrototype.wasAltered;\n\n\n function makeStack(size, head, ownerID, hash) {\n var map = Object.create(StackPrototype);\n map.size = size;\n map._head = head;\n map.__ownerID = ownerID;\n map.__hash = hash;\n map.__altered = false;\n return map;\n }\n\n var EMPTY_STACK;\n function emptyStack() {\n return EMPTY_STACK || (EMPTY_STACK = makeStack(0));\n }\n\n /**\n * Contributes additional methods to a constructor\n */\n function mixin(ctor, methods) {\n var keyCopier = function(key ) { ctor.prototype[key] = methods[key]; };\n Object.keys(methods).forEach(keyCopier);\n Object.getOwnPropertySymbols &&\n Object.getOwnPropertySymbols(methods).forEach(keyCopier);\n return ctor;\n }\n\n Iterable.Iterator = Iterator;\n\n mixin(Iterable, {\n\n // ### Conversion to other types\n\n toArray: function() {\n assertNotInfinite(this.size);\n var array = new Array(this.size || 0);\n this.valueSeq().__iterate(function(v, i) { array[i] = v; });\n return array;\n },\n\n toIndexedSeq: function() {\n return new ToIndexedSequence(this);\n },\n\n toJS: function() {\n return this.toSeq().map(\n function(value ) {return value && typeof value.toJS === 'function' ? value.toJS() : value}\n ).__toJS();\n },\n\n toJSON: function() {\n return this.toSeq().map(\n function(value ) {return value && typeof value.toJSON === 'function' ? value.toJSON() : value}\n ).__toJS();\n },\n\n toKeyedSeq: function() {\n return new ToKeyedSequence(this, true);\n },\n\n toMap: function() {\n // Use Late Binding here to solve the circular dependency.\n return Map(this.toKeyedSeq());\n },\n\n toObject: function() {\n assertNotInfinite(this.size);\n var object = {};\n this.__iterate(function(v, k) { object[k] = v; });\n return object;\n },\n\n toOrderedMap: function() {\n // Use Late Binding here to solve the circular dependency.\n return OrderedMap(this.toKeyedSeq());\n },\n\n toOrderedSet: function() {\n // Use Late Binding here to solve the circular dependency.\n return OrderedSet(isKeyed(this) ? this.valueSeq() : this);\n },\n\n toSet: function() {\n // Use Late Binding here to solve the circular dependency.\n return Set(isKeyed(this) ? this.valueSeq() : this);\n },\n\n toSetSeq: function() {\n return new ToSetSequence(this);\n },\n\n toSeq: function() {\n return isIndexed(this) ? this.toIndexedSeq() :\n isKeyed(this) ? this.toKeyedSeq() :\n this.toSetSeq();\n },\n\n toStack: function() {\n // Use Late Binding here to solve the circular dependency.\n return Stack(isKeyed(this) ? this.valueSeq() : this);\n },\n\n toList: function() {\n // Use Late Binding here to solve the circular dependency.\n return List(isKeyed(this) ? this.valueSeq() : this);\n },\n\n\n // ### Common JavaScript methods and properties\n\n toString: function() {\n return '[Iterable]';\n },\n\n __toString: function(head, tail) {\n if (this.size === 0) {\n return head + tail;\n }\n return head + ' ' + this.toSeq().map(this.__toStringMapper).join(', ') + ' ' + tail;\n },\n\n\n // ### ES6 Collection methods (ES6 Array and Map)\n\n concat: function() {var values = SLICE$0.call(arguments, 0);\n return reify(this, concatFactory(this, values));\n },\n\n includes: function(searchValue) {\n return this.some(function(value ) {return is(value, searchValue)});\n },\n\n entries: function() {\n return this.__iterator(ITERATE_ENTRIES);\n },\n\n every: function(predicate, context) {\n assertNotInfinite(this.size);\n var returnValue = true;\n this.__iterate(function(v, k, c) {\n if (!predicate.call(context, v, k, c)) {\n returnValue = false;\n return false;\n }\n });\n return returnValue;\n },\n\n filter: function(predicate, context) {\n return reify(this, filterFactory(this, predicate, context, true));\n },\n\n find: function(predicate, context, notSetValue) {\n var entry = this.findEntry(predicate, context);\n return entry ? entry[1] : notSetValue;\n },\n\n forEach: function(sideEffect, context) {\n assertNotInfinite(this.size);\n return this.__iterate(context ? sideEffect.bind(context) : sideEffect);\n },\n\n join: function(separator) {\n assertNotInfinite(this.size);\n separator = separator !== undefined ? '' + separator : ',';\n var joined = '';\n var isFirst = true;\n this.__iterate(function(v ) {\n isFirst ? (isFirst = false) : (joined += separator);\n joined += v !== null && v !== undefined ? v.toString() : '';\n });\n return joined;\n },\n\n keys: function() {\n return this.__iterator(ITERATE_KEYS);\n },\n\n map: function(mapper, context) {\n return reify(this, mapFactory(this, mapper, context));\n },\n\n reduce: function(reducer, initialReduction, context) {\n assertNotInfinite(this.size);\n var reduction;\n var useFirst;\n if (arguments.length < 2) {\n useFirst = true;\n } else {\n reduction = initialReduction;\n }\n this.__iterate(function(v, k, c) {\n if (useFirst) {\n useFirst = false;\n reduction = v;\n } else {\n reduction = reducer.call(context, reduction, v, k, c);\n }\n });\n return reduction;\n },\n\n reduceRight: function(reducer, initialReduction, context) {\n var reversed = this.toKeyedSeq().reverse();\n return reversed.reduce.apply(reversed, arguments);\n },\n\n reverse: function() {\n return reify(this, reverseFactory(this, true));\n },\n\n slice: function(begin, end) {\n return reify(this, sliceFactory(this, begin, end, true));\n },\n\n some: function(predicate, context) {\n return !this.every(not(predicate), context);\n },\n\n sort: function(comparator) {\n return reify(this, sortFactory(this, comparator));\n },\n\n values: function() {\n return this.__iterator(ITERATE_VALUES);\n },\n\n\n // ### More sequential methods\n\n butLast: function() {\n return this.slice(0, -1);\n },\n\n isEmpty: function() {\n return this.size !== undefined ? this.size === 0 : !this.some(function() {return true});\n },\n\n count: function(predicate, context) {\n return ensureSize(\n predicate ? this.toSeq().filter(predicate, context) : this\n );\n },\n\n countBy: function(grouper, context) {\n return countByFactory(this, grouper, context);\n },\n\n equals: function(other) {\n return deepEqual(this, other);\n },\n\n entrySeq: function() {\n var iterable = this;\n if (iterable._cache) {\n // We cache as an entries array, so we can just return the cache!\n return new ArraySeq(iterable._cache);\n }\n var entriesSequence = iterable.toSeq().map(entryMapper).toIndexedSeq();\n entriesSequence.fromEntrySeq = function() {return iterable.toSeq()};\n return entriesSequence;\n },\n\n filterNot: function(predicate, context) {\n return this.filter(not(predicate), context);\n },\n\n findEntry: function(predicate, context, notSetValue) {\n var found = notSetValue;\n this.__iterate(function(v, k, c) {\n if (predicate.call(context, v, k, c)) {\n found = [k, v];\n return false;\n }\n });\n return found;\n },\n\n findKey: function(predicate, context) {\n var entry = this.findEntry(predicate, context);\n return entry && entry[0];\n },\n\n findLast: function(predicate, context, notSetValue) {\n return this.toKeyedSeq().reverse().find(predicate, context, notSetValue);\n },\n\n findLastEntry: function(predicate, context, notSetValue) {\n return this.toKeyedSeq().reverse().findEntry(predicate, context, notSetValue);\n },\n\n findLastKey: function(predicate, context) {\n return this.toKeyedSeq().reverse().findKey(predicate, context);\n },\n\n first: function() {\n return this.find(returnTrue);\n },\n\n flatMap: function(mapper, context) {\n return reify(this, flatMapFactory(this, mapper, context));\n },\n\n flatten: function(depth) {\n return reify(this, flattenFactory(this, depth, true));\n },\n\n fromEntrySeq: function() {\n return new FromEntriesSequence(this);\n },\n\n get: function(searchKey, notSetValue) {\n return this.find(function(_, key) {return is(key, searchKey)}, undefined, notSetValue);\n },\n\n getIn: function(searchKeyPath, notSetValue) {\n var nested = this;\n // Note: in an ES6 environment, we would prefer:\n // for (var key of searchKeyPath) {\n var iter = forceIterator(searchKeyPath);\n var step;\n while (!(step = iter.next()).done) {\n var key = step.value;\n nested = nested && nested.get ? nested.get(key, NOT_SET) : NOT_SET;\n if (nested === NOT_SET) {\n return notSetValue;\n }\n }\n return nested;\n },\n\n groupBy: function(grouper, context) {\n return groupByFactory(this, grouper, context);\n },\n\n has: function(searchKey) {\n return this.get(searchKey, NOT_SET) !== NOT_SET;\n },\n\n hasIn: function(searchKeyPath) {\n return this.getIn(searchKeyPath, NOT_SET) !== NOT_SET;\n },\n\n isSubset: function(iter) {\n iter = typeof iter.includes === 'function' ? iter : Iterable(iter);\n return this.every(function(value ) {return iter.includes(value)});\n },\n\n isSuperset: function(iter) {\n iter = typeof iter.isSubset === 'function' ? iter : Iterable(iter);\n return iter.isSubset(this);\n },\n\n keyOf: function(searchValue) {\n return this.findKey(function(value ) {return is(value, searchValue)});\n },\n\n keySeq: function() {\n return this.toSeq().map(keyMapper).toIndexedSeq();\n },\n\n last: function() {\n return this.toSeq().reverse().first();\n },\n\n lastKeyOf: function(searchValue) {\n return this.toKeyedSeq().reverse().keyOf(searchValue);\n },\n\n max: function(comparator) {\n return maxFactory(this, comparator);\n },\n\n maxBy: function(mapper, comparator) {\n return maxFactory(this, comparator, mapper);\n },\n\n min: function(comparator) {\n return maxFactory(this, comparator ? neg(comparator) : defaultNegComparator);\n },\n\n minBy: function(mapper, comparator) {\n return maxFactory(this, comparator ? neg(comparator) : defaultNegComparator, mapper);\n },\n\n rest: function() {\n return this.slice(1);\n },\n\n skip: function(amount) {\n return this.slice(Math.max(0, amount));\n },\n\n skipLast: function(amount) {\n return reify(this, this.toSeq().reverse().skip(amount).reverse());\n },\n\n skipWhile: function(predicate, context) {\n return reify(this, skipWhileFactory(this, predicate, context, true));\n },\n\n skipUntil: function(predicate, context) {\n return this.skipWhile(not(predicate), context);\n },\n\n sortBy: function(mapper, comparator) {\n return reify(this, sortFactory(this, comparator, mapper));\n },\n\n take: function(amount) {\n return this.slice(0, Math.max(0, amount));\n },\n\n takeLast: function(amount) {\n return reify(this, this.toSeq().reverse().take(amount).reverse());\n },\n\n takeWhile: function(predicate, context) {\n return reify(this, takeWhileFactory(this, predicate, context));\n },\n\n takeUntil: function(predicate, context) {\n return this.takeWhile(not(predicate), context);\n },\n\n valueSeq: function() {\n return this.toIndexedSeq();\n },\n\n\n // ### Hashable Object\n\n hashCode: function() {\n return this.__hash || (this.__hash = hashIterable(this));\n }\n\n\n // ### Internal\n\n // abstract __iterate(fn, reverse)\n\n // abstract __iterator(type, reverse)\n });\n\n // var IS_ITERABLE_SENTINEL = '@@__IMMUTABLE_ITERABLE__@@';\n // var IS_KEYED_SENTINEL = '@@__IMMUTABLE_KEYED__@@';\n // var IS_INDEXED_SENTINEL = '@@__IMMUTABLE_INDEXED__@@';\n // var IS_ORDERED_SENTINEL = '@@__IMMUTABLE_ORDERED__@@';\n\n var IterablePrototype = Iterable.prototype;\n IterablePrototype[IS_ITERABLE_SENTINEL] = true;\n IterablePrototype[ITERATOR_SYMBOL] = IterablePrototype.values;\n IterablePrototype.__toJS = IterablePrototype.toArray;\n IterablePrototype.__toStringMapper = quoteString;\n IterablePrototype.inspect =\n IterablePrototype.toSource = function() { return this.toString(); };\n IterablePrototype.chain = IterablePrototype.flatMap;\n IterablePrototype.contains = IterablePrototype.includes;\n\n mixin(KeyedIterable, {\n\n // ### More sequential methods\n\n flip: function() {\n return reify(this, flipFactory(this));\n },\n\n mapEntries: function(mapper, context) {var this$0 = this;\n var iterations = 0;\n return reify(this,\n this.toSeq().map(\n function(v, k) {return mapper.call(context, [k, v], iterations++, this$0)}\n ).fromEntrySeq()\n );\n },\n\n mapKeys: function(mapper, context) {var this$0 = this;\n return reify(this,\n this.toSeq().flip().map(\n function(k, v) {return mapper.call(context, k, v, this$0)}\n ).flip()\n );\n }\n\n });\n\n var KeyedIterablePrototype = KeyedIterable.prototype;\n KeyedIterablePrototype[IS_KEYED_SENTINEL] = true;\n KeyedIterablePrototype[ITERATOR_SYMBOL] = IterablePrototype.entries;\n KeyedIterablePrototype.__toJS = IterablePrototype.toObject;\n KeyedIterablePrototype.__toStringMapper = function(v, k) {return JSON.stringify(k) + ': ' + quoteString(v)};\n\n\n\n mixin(IndexedIterable, {\n\n // ### Conversion to other types\n\n toKeyedSeq: function() {\n return new ToKeyedSequence(this, false);\n },\n\n\n // ### ES6 Collection methods (ES6 Array and Map)\n\n filter: function(predicate, context) {\n return reify(this, filterFactory(this, predicate, context, false));\n },\n\n findIndex: function(predicate, context) {\n var entry = this.findEntry(predicate, context);\n return entry ? entry[0] : -1;\n },\n\n indexOf: function(searchValue) {\n var key = this.keyOf(searchValue);\n return key === undefined ? -1 : key;\n },\n\n lastIndexOf: function(searchValue) {\n var key = this.lastKeyOf(searchValue);\n return key === undefined ? -1 : key;\n },\n\n reverse: function() {\n return reify(this, reverseFactory(this, false));\n },\n\n slice: function(begin, end) {\n return reify(this, sliceFactory(this, begin, end, false));\n },\n\n splice: function(index, removeNum /*, ...values*/) {\n var numArgs = arguments.length;\n removeNum = Math.max(removeNum | 0, 0);\n if (numArgs === 0 || (numArgs === 2 && !removeNum)) {\n return this;\n }\n // If index is negative, it should resolve relative to the size of the\n // collection. However size may be expensive to compute if not cached, so\n // only call count() if the number is in fact negative.\n index = resolveBegin(index, index < 0 ? this.count() : this.size);\n var spliced = this.slice(0, index);\n return reify(\n this,\n numArgs === 1 ?\n spliced :\n spliced.concat(arrCopy(arguments, 2), this.slice(index + removeNum))\n );\n },\n\n\n // ### More collection methods\n\n findLastIndex: function(predicate, context) {\n var entry = this.findLastEntry(predicate, context);\n return entry ? entry[0] : -1;\n },\n\n first: function() {\n return this.get(0);\n },\n\n flatten: function(depth) {\n return reify(this, flattenFactory(this, depth, false));\n },\n\n get: function(index, notSetValue) {\n index = wrapIndex(this, index);\n return (index < 0 || (this.size === Infinity ||\n (this.size !== undefined && index > this.size))) ?\n notSetValue :\n this.find(function(_, key) {return key === index}, undefined, notSetValue);\n },\n\n has: function(index) {\n index = wrapIndex(this, index);\n return index >= 0 && (this.size !== undefined ?\n this.size === Infinity || index < this.size :\n this.indexOf(index) !== -1\n );\n },\n\n interpose: function(separator) {\n return reify(this, interposeFactory(this, separator));\n },\n\n interleave: function(/*...iterables*/) {\n var iterables = [this].concat(arrCopy(arguments));\n var zipped = zipWithFactory(this.toSeq(), IndexedSeq.of, iterables);\n var interleaved = zipped.flatten(true);\n if (zipped.size) {\n interleaved.size = zipped.size * iterables.length;\n }\n return reify(this, interleaved);\n },\n\n keySeq: function() {\n return Range(0, this.size);\n },\n\n last: function() {\n return this.get(-1);\n },\n\n skipWhile: function(predicate, context) {\n return reify(this, skipWhileFactory(this, predicate, context, false));\n },\n\n zip: function(/*, ...iterables */) {\n var iterables = [this].concat(arrCopy(arguments));\n return reify(this, zipWithFactory(this, defaultZipper, iterables));\n },\n\n zipWith: function(zipper/*, ...iterables */) {\n var iterables = arrCopy(arguments);\n iterables[0] = this;\n return reify(this, zipWithFactory(this, zipper, iterables));\n }\n\n });\n\n IndexedIterable.prototype[IS_INDEXED_SENTINEL] = true;\n IndexedIterable.prototype[IS_ORDERED_SENTINEL] = true;\n\n\n\n mixin(SetIterable, {\n\n // ### ES6 Collection methods (ES6 Array and Map)\n\n get: function(value, notSetValue) {\n return this.has(value) ? value : notSetValue;\n },\n\n includes: function(value) {\n return this.has(value);\n },\n\n\n // ### More sequential methods\n\n keySeq: function() {\n return this.valueSeq();\n }\n\n });\n\n SetIterable.prototype.has = IterablePrototype.includes;\n SetIterable.prototype.contains = SetIterable.prototype.includes;\n\n\n // Mixin subclasses\n\n mixin(KeyedSeq, KeyedIterable.prototype);\n mixin(IndexedSeq, IndexedIterable.prototype);\n mixin(SetSeq, SetIterable.prototype);\n\n mixin(KeyedCollection, KeyedIterable.prototype);\n mixin(IndexedCollection, IndexedIterable.prototype);\n mixin(SetCollection, SetIterable.prototype);\n\n\n // #pragma Helper functions\n\n function keyMapper(v, k) {\n return k;\n }\n\n function entryMapper(v, k) {\n return [k, v];\n }\n\n function not(predicate) {\n return function() {\n return !predicate.apply(this, arguments);\n }\n }\n\n function neg(predicate) {\n return function() {\n return -predicate.apply(this, arguments);\n }\n }\n\n function quoteString(value) {\n return typeof value === 'string' ? JSON.stringify(value) : String(value);\n }\n\n function defaultZipper() {\n return arrCopy(arguments);\n }\n\n function defaultNegComparator(a, b) {\n return a < b ? 1 : a > b ? -1 : 0;\n }\n\n function hashIterable(iterable) {\n if (iterable.size === Infinity) {\n return 0;\n }\n var ordered = isOrdered(iterable);\n var keyed = isKeyed(iterable);\n var h = ordered ? 1 : 0;\n var size = iterable.__iterate(\n keyed ?\n ordered ?\n function(v, k) { h = 31 * h + hashMerge(hash(v), hash(k)) | 0; } :\n function(v, k) { h = h + hashMerge(hash(v), hash(k)) | 0; } :\n ordered ?\n function(v ) { h = 31 * h + hash(v) | 0; } :\n function(v ) { h = h + hash(v) | 0; }\n );\n return murmurHashOfSize(size, h);\n }\n\n function murmurHashOfSize(size, h) {\n h = imul(h, 0xCC9E2D51);\n h = imul(h << 15 | h >>> -15, 0x1B873593);\n h = imul(h << 13 | h >>> -13, 5);\n h = (h + 0xE6546B64 | 0) ^ size;\n h = imul(h ^ h >>> 16, 0x85EBCA6B);\n h = imul(h ^ h >>> 13, 0xC2B2AE35);\n h = smi(h ^ h >>> 16);\n return h;\n }\n\n function hashMerge(a, b) {\n return a ^ b + 0x9E3779B9 + (a << 6) + (a >> 2) | 0; // int\n }\n\n var Immutable = {\n\n Iterable: Iterable,\n\n Seq: Seq,\n Collection: Collection,\n Map: Map,\n OrderedMap: OrderedMap,\n List: List,\n Stack: Stack,\n Set: Set,\n OrderedSet: OrderedSet,\n\n Record: Record,\n Range: Range,\n Repeat: Repeat,\n\n is: is,\n fromJS: fromJS\n\n };\n\n return Immutable;\n\n}));","var _Object$defineProperty = require(\"../core-js/object/define-property\");\n\nfunction _defineProperty(obj, key, value) {\n if (key in obj) {\n _Object$defineProperty(obj, key, {\n value: value,\n enumerable: true,\n configurable: true,\n writable: true\n });\n } else {\n obj[key] = value;\n }\n\n return obj;\n}\n\nmodule.exports = _defineProperty;","var _Object$getPrototypeOf = require(\"../core-js/object/get-prototype-of\");\n\nvar _Object$setPrototypeOf = require(\"../core-js/object/set-prototype-of\");\n\nfunction _getPrototypeOf(o) {\n module.exports = _getPrototypeOf = _Object$setPrototypeOf ? _Object$getPrototypeOf : function _getPrototypeOf(o) {\n return o.__proto__ || _Object$getPrototypeOf(o);\n };\n return _getPrototypeOf(o);\n}\n\nmodule.exports = _getPrototypeOf;","/* \n ATTENTION! This file (but not the functions within) is deprecated.\n\n You should probably add a new file to `./helpers/` instead of adding a new\n function here.\n\n One-function-per-file is a better pattern than what we have here.\n\n If you're refactoring something in here, feel free to break it out to a file\n in `./helpers` if you have the time.\n*/\n\nimport Im from \"immutable\"\nimport { sanitizeUrl as braintreeSanitizeUrl } from \"@braintree/sanitize-url\"\nimport camelCase from \"lodash/camelCase\"\nimport upperFirst from \"lodash/upperFirst\"\nimport _memoize from \"lodash/memoize\"\nimport find from \"lodash/find\"\nimport some from \"lodash/some\"\nimport eq from \"lodash/eq\"\nimport isFunction from \"lodash/isFunction\"\nimport { memoizedSampleFromSchema, memoizedCreateXMLExample } from \"core/plugins/samples/fn\"\nimport win from \"./window\"\nimport cssEscape from \"css.escape\"\nimport getParameterSchema from \"../helpers/get-parameter-schema\"\nimport randomBytes from \"randombytes\"\nimport shaJs from \"sha.js\"\n\n\nconst DEFAULT_RESPONSE_KEY = \"default\"\n\nexport const isImmutable = (maybe) => Im.Iterable.isIterable(maybe)\n\nexport function isJSONObject (str) {\n try {\n var o = JSON.parse(str)\n\n // Handle non-exception-throwing cases:\n // Neither JSON.parse(false) or JSON.parse(1234) throw errors, hence the type-checking,\n // but... JSON.parse(null) returns null, and typeof null === \"object\",\n // so we must check for that, too. Thankfully, null is falsey, so this suffices:\n if (o && typeof o === \"object\") {\n return o\n }\n }\n catch (e) {\n // do nothing\n }\n\n return false\n}\n\nexport function objectify (thing) {\n if(!isObject(thing))\n return {}\n if(isImmutable(thing))\n return thing.toJS()\n return thing\n}\n\nexport function arrayify (thing) {\n if(!thing)\n return []\n\n if(thing.toArray)\n return thing.toArray()\n\n return normalizeArray(thing)\n}\n\nexport function fromJSOrdered(js) {\n if (isImmutable(js)) {\n return js // Can't do much here\n }\n if (js instanceof win.File) {\n return js\n }\n if (!isObject(js)) {\n return js\n }\n if (Array.isArray(js)) {\n return Im.Seq(js).map(fromJSOrdered).toList()\n }\n if (isFunction(js.entries)) {\n // handle multipart/form-data\n const objWithHashedKeys = createObjWithHashedKeys(js)\n return Im.OrderedMap(objWithHashedKeys).map(fromJSOrdered)\n }\n return Im.OrderedMap(js).map(fromJSOrdered)\n}\n\n/**\n * Convert a FormData object into plain object\n * Append a hashIdx and counter to the key name, if multiple exists\n * if single, key name = \n * if multiple, key name = \n * @example single entry for vegetable\n * fdObj.entries.vegtables: \"carrot\"\n * // returns newObj.vegetables : \"carrot\"\n * @example multiple entries for fruits[]\n * fdObj.entries.fruits[]: \"apple\"\n * // returns newObj.fruits[]_**[]1 : \"apple\"\n * fdObj.entries.fruits[]: \"banana\"\n * // returns newObj.fruits[]_**[]2 : \"banana\"\n * fdObj.entries.fruits[]: \"grape\"\n * // returns newObj.fruits[]_**[]3 : \"grape\"\n * @param {FormData} fdObj - a FormData object\n * @return {Object} - a plain object\n */\nexport function createObjWithHashedKeys (fdObj) {\n if (!isFunction(fdObj.entries)) {\n return fdObj // not a FormData object with iterable\n }\n const newObj = {}\n const hashIdx = \"_**[]\" // our internal identifier\n const trackKeys = {}\n for (let pair of fdObj.entries()) {\n if (!newObj[pair[0]] && !(trackKeys[pair[0]] && trackKeys[pair[0]].containsMultiple)) {\n newObj[pair[0]] = pair[1] // first key name: no hash required\n } else {\n if (!trackKeys[pair[0]]) {\n // initiate tracking key for multiple\n trackKeys[pair[0]] = {\n containsMultiple: true,\n length: 1\n }\n // \"reassign\" first pair to matching hashed format for multiple\n let hashedKeyFirst = `${pair[0]}${hashIdx}${trackKeys[pair[0]].length}`\n newObj[hashedKeyFirst] = newObj[pair[0]]\n // remove non-hashed key of multiple\n delete newObj[pair[0]] // first\n }\n trackKeys[pair[0]].length += 1\n let hashedKeyCurrent = `${pair[0]}${hashIdx}${trackKeys[pair[0]].length}`\n newObj[hashedKeyCurrent] = pair[1]\n } \n }\n return newObj\n}\n\nexport function bindToState(obj, state) {\n\tvar newObj = {}\n\tObject.keys(obj)\n .filter(key => typeof obj[key] === \"function\")\n .forEach(key => newObj[key] = obj[key].bind(null, state))\n\treturn newObj\n}\n\nexport function normalizeArray(arr) {\n if(Array.isArray(arr))\n return arr\n return [arr]\n}\n\nexport function isFn(fn) {\n return typeof fn === \"function\"\n}\n\nexport function isObject(obj) {\n return !!obj && typeof obj === \"object\"\n}\n\nexport function isFunc(thing) {\n return typeof(thing) === \"function\"\n}\n\nexport function isArray(thing) {\n return Array.isArray(thing)\n}\n\n// I've changed memoize libs more than once, so I'm using this a way to make that simpler\nexport const memoize = _memoize\n\nexport function objMap(obj, fn) {\n return Object.keys(obj).reduce((newObj, key) => {\n newObj[key] = fn(obj[key], key)\n return newObj\n }, {})\n}\n\nexport function objReduce(obj, fn) {\n return Object.keys(obj).reduce((newObj, key) => {\n let res = fn(obj[key], key)\n if(res && typeof res === \"object\")\n Object.assign(newObj, res)\n return newObj\n }, {})\n}\n\n// Redux middleware that exposes the system to async actions (like redux-thunk, but with out system instead of (dispatch, getState)\nexport function systemThunkMiddleware(getSystem) {\n return ({ dispatch, getState }) => { // eslint-disable-line no-unused-vars\n return next => action => {\n if (typeof action === \"function\") {\n return action(getSystem())\n }\n\n return next(action)\n }\n }\n}\n\nexport function defaultStatusCode ( responses ) {\n let codes = responses.keySeq()\n return codes.contains(DEFAULT_RESPONSE_KEY) ? DEFAULT_RESPONSE_KEY : codes.filter( key => (key+\"\")[0] === \"2\").sort().first()\n}\n\n\n/**\n * Returns an Immutable List, safely\n * @param {Immutable.Iterable} iterable the iterable to get the key from\n * @param {String|[String]} key either an array of keys, or a single key\n * @returns {Immutable.List} either iterable.get(keys) or an empty Immutable.List\n */\nexport function getList(iterable, keys) {\n if(!Im.Iterable.isIterable(iterable)) {\n return Im.List()\n }\n let val = iterable.getIn(Array.isArray(keys) ? keys : [keys])\n return Im.List.isList(val) ? val : Im.List()\n}\n\n/**\n * Adapted from http://github.com/asvd/microlight\n * @copyright 2016 asvd \n */\nexport function highlight (el) {\n const MAX_LENGTH = 5000\n var\n _document = document,\n appendChild = \"appendChild\",\n test = \"test\"\n\n if (!el) return \"\"\n if (el.textContent.length > MAX_LENGTH) { return el.textContent }\n\n var reset = function(el) {\n var text = el.textContent,\n pos = 0, // current position\n next1 = text[0], // next character\n chr = 1, // current character\n prev1, // previous character\n prev2, // the one before the previous\n token = // current token content\n el.innerHTML = \"\", // (and cleaning the node)\n\n // current token type:\n // 0: anything else (whitespaces / newlines)\n // 1: operator or brace\n // 2: closing braces (after which '/' is division not regex)\n // 3: (key)word\n // 4: regex\n // 5: string starting with \"\n // 6: string starting with '\n // 7: xml comment \n // 8: multiline comment /* */\n // 9: single-line comment starting with two slashes //\n // 10: single-line comment starting with hash #\n tokenType = 0,\n\n // kept to determine between regex and division\n lastTokenType,\n // flag determining if token is multi-character\n multichar,\n node\n\n // running through characters and highlighting\n while (prev2 = prev1,\n // escaping if needed (with except for comments)\n // previous character will not be therefore\n // recognized as a token finalize condition\n prev1 = tokenType < 7 && prev1 == \"\\\\\" ? 1 : chr\n ) {\n chr = next1\n next1=text[++pos]\n multichar = token.length > 1\n\n // checking if current token should be finalized\n if (!chr || // end of content\n // types 9-10 (single-line comments) end with a\n // newline\n (tokenType > 8 && chr == \"\\n\") ||\n [ // finalize conditions for other token types\n // 0: whitespaces\n /\\S/[test](chr), // merged together\n // 1: operators\n 1, // consist of a single character\n // 2: braces\n 1, // consist of a single character\n // 3: (key)word\n !/[$\\w]/[test](chr),\n // 4: regex\n (prev1 == \"/\" || prev1 == \"\\n\") && multichar,\n // 5: string with \"\n prev1 == \"\\\"\" && multichar,\n // 6: string with '\n prev1 == \"'\" && multichar,\n // 7: xml comment\n text[pos-4]+prev2+prev1 == \"-->\",\n // 8: multiline comment\n prev2+prev1 == \"*/\"\n ][tokenType]\n ) {\n // appending the token to the result\n if (token) {\n // remapping token type into style\n // (some types are highlighted similarly)\n el[appendChild](\n node = _document.createElement(\"span\")\n ).setAttribute(\"style\", [\n // 0: not formatted\n \"color: #555; font-weight: bold;\",\n // 1: keywords\n \"\",\n // 2: punctuation\n \"\",\n // 3: strings and regexps\n \"color: #555;\",\n // 4: comments\n \"\"\n ][\n // not formatted\n !tokenType ? 0 :\n // punctuation\n tokenType < 3 ? 2 :\n // comments\n tokenType > 6 ? 4 :\n // regex and strings\n tokenType > 3 ? 3 :\n // otherwise tokenType == 3, (key)word\n // (1 if regexp matches, 0 otherwise)\n + /^(a(bstract|lias|nd|rguments|rray|s(m|sert)?|uto)|b(ase|egin|ool(ean)?|reak|yte)|c(ase|atch|har|hecked|lass|lone|ompl|onst|ontinue)|de(bugger|cimal|clare|f(ault|er)?|init|l(egate|ete)?)|do|double|e(cho|ls?if|lse(if)?|nd|nsure|num|vent|x(cept|ec|p(licit|ort)|te(nds|nsion|rn)))|f(allthrough|alse|inal(ly)?|ixed|loat|or(each)?|riend|rom|unc(tion)?)|global|goto|guard|i(f|mp(lements|licit|ort)|n(it|clude(_once)?|line|out|stanceof|t(erface|ernal)?)?|s)|l(ambda|et|ock|ong)|m(icrolight|odule|utable)|NaN|n(amespace|ative|ext|ew|il|ot|ull)|o(bject|perator|r|ut|verride)|p(ackage|arams|rivate|rotected|rotocol|ublic)|r(aise|e(adonly|do|f|gister|peat|quire(_once)?|scue|strict|try|turn))|s(byte|ealed|elf|hort|igned|izeof|tatic|tring|truct|ubscript|uper|ynchronized|witch)|t(emplate|hen|his|hrows?|ransient|rue|ry|ype(alias|def|id|name|of))|u(n(checked|def(ined)?|ion|less|signed|til)|se|sing)|v(ar|irtual|oid|olatile)|w(char_t|hen|here|hile|ith)|xor|yield)$/[test](token)\n ])\n\n node[appendChild](_document.createTextNode(token))\n }\n\n // saving the previous token type\n // (skipping whitespaces and comments)\n lastTokenType =\n (tokenType && tokenType < 7) ?\n tokenType : lastTokenType\n\n // initializing a new token\n token = \"\"\n\n // determining the new token type (going up the\n // list until matching a token type start\n // condition)\n tokenType = 11\n while (![\n 1, // 0: whitespace\n // 1: operator or braces\n /[\\/{}[(\\-+*=<>:;|\\\\.,?!&@~]/[test](chr), // eslint-disable-line no-useless-escape\n /[\\])]/[test](chr), // 2: closing brace\n /[$\\w]/[test](chr), // 3: (key)word\n chr == \"/\" && // 4: regex\n // previous token was an\n // opening brace or an\n // operator (otherwise\n // division, not a regex)\n (lastTokenType < 2) &&\n // workaround for xml\n // closing tags\n prev1 != \"<\",\n chr == \"\\\"\", // 5: string with \"\n chr == \"'\", // 6: string with '\n // 7: xml comment\n chr+next1+text[pos+1]+text[pos+2] == \"\"\n } else {\n return null\n }\n }\n return memoizedCreateXMLExample(schema, config)\n }\n\n const res = memoizedSampleFromSchema(schema, config)\n\n return typeof res === \"object\" ? JSON.stringify(res, null, 2) : res\n}\n\nexport const parseSearch = () => {\n let map = {}\n let search = win.location.search\n\n if(!search)\n return {}\n\n if ( search != \"\" ) {\n let params = search.substr(1).split(\"&\")\n\n for (let i in params) {\n if (!params.hasOwnProperty(i)) {\n continue\n }\n i = params[i].split(\"=\")\n map[decodeURIComponent(i[0])] = (i[1] && decodeURIComponent(i[1])) || \"\"\n }\n }\n\n return map\n}\n\nexport const serializeSearch = (searchMap) => {\n return Object.keys(searchMap).map(k => {\n return encodeURIComponent(k) + \"=\" + encodeURIComponent(searchMap[k])\n }).join(\"&\")\n}\n\nexport const btoa = (str) => {\n let buffer\n\n if (str instanceof Buffer) {\n buffer = str\n } else {\n buffer = new Buffer(str.toString(), \"utf-8\")\n }\n\n return buffer.toString(\"base64\")\n}\n\nexport const sorters = {\n operationsSorter: {\n alpha: (a, b) => a.get(\"path\").localeCompare(b.get(\"path\")),\n method: (a, b) => a.get(\"method\").localeCompare(b.get(\"method\"))\n },\n tagsSorter: {\n alpha: (a, b) => a.localeCompare(b)\n }\n}\n\nexport const buildFormData = (data) => {\n let formArr = []\n\n for (let name in data) {\n let val = data[name]\n if (val !== undefined && val !== \"\") {\n formArr.push([name, \"=\", encodeURIComponent(val).replace(/%20/g,\"+\")].join(\"\"))\n }\n }\n return formArr.join(\"&\")\n}\n\n// Is this really required as a helper? Perhaps. TODO: expose the system of presets.apis in docs, so we know what is supported\nexport const shallowEqualKeys = (a,b, keys) => {\n return !!find(keys, (key) => {\n return eq(a[key], b[key])\n })\n}\n\nexport function sanitizeUrl(url) {\n if(typeof url !== \"string\" || url === \"\") {\n return \"\"\n }\n\n return braintreeSanitizeUrl(url)\n}\n\nexport function getAcceptControllingResponse(responses) {\n if(!Im.OrderedMap.isOrderedMap(responses)) {\n // wrong type!\n return null\n }\n\n if(!responses.size) {\n // responses is empty\n return null\n }\n\n const suitable2xxResponse = responses.find((res, k) => {\n return k.startsWith(\"2\") && Object.keys(res.get(\"content\") || {}).length > 0\n })\n\n // try to find a suitable `default` responses\n const defaultResponse = responses.get(\"default\") || Im.OrderedMap()\n const defaultResponseMediaTypes = (defaultResponse.get(\"content\") || Im.OrderedMap()).keySeq().toJS()\n const suitableDefaultResponse = defaultResponseMediaTypes.length ? defaultResponse : null\n\n return suitable2xxResponse || suitableDefaultResponse\n}\n\n// suitable for use in URL fragments\nexport const createDeepLinkPath = (str) => typeof str == \"string\" || str instanceof String ? str.trim().replace(/\\s/g, \"%20\") : \"\"\n// suitable for use in CSS classes and ids\nexport const escapeDeepLinkPath = (str) => cssEscape( createDeepLinkPath(str).replace(/%20/g, \"_\") )\n\nexport const getExtensions = (defObj) => defObj.filter((v, k) => /^x-/.test(k))\nexport const getCommonExtensions = (defObj) => defObj.filter((v, k) => /^pattern|maxLength|minLength|maximum|minimum/.test(k))\n\n// Deeply strips a specific key from an object.\n//\n// `predicate` can be used to discriminate the stripping further,\n// by preserving the key's place in the object based on its value.\nexport function deeplyStripKey(input, keyToStrip, predicate = () => true) {\n if(typeof input !== \"object\" || Array.isArray(input) || input === null || !keyToStrip) {\n return input\n }\n\n const obj = Object.assign({}, input)\n\n Object.keys(obj).forEach(k => {\n if(k === keyToStrip && predicate(obj[k], k)) {\n delete obj[k]\n return\n }\n obj[k] = deeplyStripKey(obj[k], keyToStrip, predicate)\n })\n\n return obj\n}\n\nexport function stringify(thing) {\n if (typeof thing === \"string\") {\n return thing\n }\n\n if (thing && thing.toJS) {\n thing = thing.toJS()\n }\n\n if (typeof thing === \"object\" && thing !== null) {\n try {\n return JSON.stringify(thing, null, 2)\n }\n catch (e) {\n return String(thing)\n }\n }\n\n if(thing === null || thing === undefined) {\n return \"\"\n }\n\n return thing.toString()\n}\n\nexport function numberToString(thing) {\n if(typeof thing === \"number\") {\n return thing.toString()\n }\n\n return thing\n}\n\nexport function paramToIdentifier(param, { returnAll = false, allowHashes = true } = {}) {\n if(!Im.Map.isMap(param)) {\n throw new Error(\"paramToIdentifier: received a non-Im.Map parameter as input\")\n }\n const paramName = param.get(\"name\")\n const paramIn = param.get(\"in\")\n \n let generatedIdentifiers = []\n\n // Generate identifiers in order of most to least specificity\n\n if (param && param.hashCode && paramIn && paramName && allowHashes) {\n generatedIdentifiers.push(`${paramIn}.${paramName}.hash-${param.hashCode()}`)\n }\n \n if(paramIn && paramName) {\n generatedIdentifiers.push(`${paramIn}.${paramName}`)\n }\n\n generatedIdentifiers.push(paramName)\n\n // Return the most preferred identifier, or all if requested\n\n return returnAll ? generatedIdentifiers : (generatedIdentifiers[0] || \"\")\n}\n\nexport function paramToValue(param, paramValues) {\n const allIdentifiers = paramToIdentifier(param, { returnAll: true })\n\n // Map identifiers to values in the provided value hash, filter undefined values,\n // and return the first value found\n const values = allIdentifiers\n .map(id => {\n return paramValues[id]\n })\n .filter(value => value !== undefined)\n\n return values[0]\n}\n\n// adapted from https://auth0.com/docs/flows/guides/auth-code-pkce/includes/create-code-verifier\nexport function generateCodeVerifier() {\n return b64toB64UrlEncoded(\n randomBytes(32).toString(\"base64\")\n )\n}\n\nexport function createCodeChallenge(codeVerifier) {\n return b64toB64UrlEncoded(\n shaJs(\"sha256\")\n .update(codeVerifier)\n .digest(\"base64\")\n )\n}\n\nfunction b64toB64UrlEncoded(str) {\n return str\n .replace(/\\+/g, \"-\")\n .replace(/\\//g, \"_\")\n .replace(/=/g, \"\")\n}\n\nexport const isEmptyValue = (value) => {\n if (!value) {\n return true\n }\n\n if (isImmutable(value) && value.isEmpty()) {\n return true\n }\n\n return false\n}\n","function _classCallCheck(instance, Constructor) {\n if (!(instance instanceof Constructor)) {\n throw new TypeError(\"Cannot call a class as a function\");\n }\n}\n\nmodule.exports = _classCallCheck;","var _Object$defineProperty = require(\"../core-js/object/define-property\");\n\nfunction _defineProperties(target, props) {\n for (var i = 0; i < props.length; i++) {\n var descriptor = props[i];\n descriptor.enumerable = descriptor.enumerable || false;\n descriptor.configurable = true;\n if (\"value\" in descriptor) descriptor.writable = true;\n\n _Object$defineProperty(target, descriptor.key, descriptor);\n }\n}\n\nfunction _createClass(Constructor, protoProps, staticProps) {\n if (protoProps) _defineProperties(Constructor.prototype, protoProps);\n if (staticProps) _defineProperties(Constructor, staticProps);\n return Constructor;\n}\n\nmodule.exports = _createClass;","var _Object$create = require(\"../core-js/object/create\");\n\nvar setPrototypeOf = require(\"./setPrototypeOf\");\n\nfunction _inherits(subClass, superClass) {\n if (typeof superClass !== \"function\" && superClass !== null) {\n throw new TypeError(\"Super expression must either be null or a function\");\n }\n\n subClass.prototype = _Object$create(superClass && superClass.prototype, {\n constructor: {\n value: subClass,\n writable: true,\n configurable: true\n }\n });\n if (superClass) setPrototypeOf(subClass, superClass);\n}\n\nmodule.exports = _inherits;","var _typeof = require(\"../helpers/typeof\");\n\nvar assertThisInitialized = require(\"./assertThisInitialized\");\n\nfunction _possibleConstructorReturn(self, call) {\n if (call && (_typeof(call) === \"object\" || typeof call === \"function\")) {\n return call;\n }\n\n return assertThisInitialized(self);\n}\n\nmodule.exports = _possibleConstructorReturn;","function _assertThisInitialized(self) {\n if (self === void 0) {\n throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\");\n }\n\n return self;\n}\n\nmodule.exports = _assertThisInitialized;","/**\n * Copyright (c) 2013-present, Facebook, Inc.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\nif (process.env.NODE_ENV !== 'production') {\n var ReactIs = require('react-is');\n\n // By explicitly using `prop-types` you are opting into new development behavior.\n // http://fb.me/prop-types-in-prod\n var throwOnDirectAccess = true;\n module.exports = require('./factoryWithTypeCheckers')(ReactIs.isElement, throwOnDirectAccess);\n} else {\n // By explicitly using `prop-types` you are opting into new production behavior.\n // http://fb.me/prop-types-in-prod\n module.exports = require('./factoryWithThrowingShims')();\n}\n","function defaultEqualityCheck(a, b) {\n return a === b;\n}\n\nfunction areArgumentsShallowlyEqual(equalityCheck, prev, next) {\n if (prev === null || next === null || prev.length !== next.length) {\n return false;\n }\n\n // Do this in a for loop (and not a `forEach` or an `every`) so we can determine equality as fast as possible.\n var length = prev.length;\n for (var i = 0; i < length; i++) {\n if (!equalityCheck(prev[i], next[i])) {\n return false;\n }\n }\n\n return true;\n}\n\nexport function defaultMemoize(func) {\n var equalityCheck = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : defaultEqualityCheck;\n\n var lastArgs = null;\n var lastResult = null;\n // we reference arguments instead of spreading them for performance reasons\n return function () {\n if (!areArgumentsShallowlyEqual(equalityCheck, lastArgs, arguments)) {\n // apply arguments instead of spreading for performance.\n lastResult = func.apply(null, arguments);\n }\n\n lastArgs = arguments;\n return lastResult;\n };\n}\n\nfunction getDependencies(funcs) {\n var dependencies = Array.isArray(funcs[0]) ? funcs[0] : funcs;\n\n if (!dependencies.every(function (dep) {\n return typeof dep === 'function';\n })) {\n var dependencyTypes = dependencies.map(function (dep) {\n return typeof dep;\n }).join(', ');\n throw new Error('Selector creators expect all input-selectors to be functions, ' + ('instead received the following types: [' + dependencyTypes + ']'));\n }\n\n return dependencies;\n}\n\nexport function createSelectorCreator(memoize) {\n for (var _len = arguments.length, memoizeOptions = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {\n memoizeOptions[_key - 1] = arguments[_key];\n }\n\n return function () {\n for (var _len2 = arguments.length, funcs = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {\n funcs[_key2] = arguments[_key2];\n }\n\n var recomputations = 0;\n var resultFunc = funcs.pop();\n var dependencies = getDependencies(funcs);\n\n var memoizedResultFunc = memoize.apply(undefined, [function () {\n recomputations++;\n // apply arguments instead of spreading for performance.\n return resultFunc.apply(null, arguments);\n }].concat(memoizeOptions));\n\n // If a selector is called with the exact same arguments we don't need to traverse our dependencies again.\n var selector = memoize(function () {\n var params = [];\n var length = dependencies.length;\n\n for (var i = 0; i < length; i++) {\n // apply arguments instead of spreading and mutate a local list of params for performance.\n params.push(dependencies[i].apply(null, arguments));\n }\n\n // apply arguments instead of spreading for performance.\n return memoizedResultFunc.apply(null, params);\n });\n\n selector.resultFunc = resultFunc;\n selector.dependencies = dependencies;\n selector.recomputations = function () {\n return recomputations;\n };\n selector.resetRecomputations = function () {\n return recomputations = 0;\n };\n return selector;\n };\n}\n\nexport var createSelector = createSelectorCreator(defaultMemoize);\n\nexport function createStructuredSelector(selectors) {\n var selectorCreator = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : createSelector;\n\n if (typeof selectors !== 'object') {\n throw new Error('createStructuredSelector expects first argument to be an object ' + ('where each property is a selector, instead received a ' + typeof selectors));\n }\n var objectKeys = Object.keys(selectors);\n return selectorCreator(objectKeys.map(function (key) {\n return selectors[key];\n }), function () {\n for (var _len3 = arguments.length, values = Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {\n values[_key3] = arguments[_key3];\n }\n\n return values.reduce(function (composition, value, index) {\n composition[objectKeys[index]] = value;\n return composition;\n }, {});\n });\n}","var arrayWithoutHoles = require(\"./arrayWithoutHoles\");\n\nvar iterableToArray = require(\"./iterableToArray\");\n\nvar nonIterableSpread = require(\"./nonIterableSpread\");\n\nfunction _toConsumableArray(arr) {\n return arrayWithoutHoles(arr) || iterableToArray(arr) || nonIterableSpread();\n}\n\nmodule.exports = _toConsumableArray;","var arrayWithHoles = require(\"./arrayWithHoles\");\n\nvar iterableToArrayLimit = require(\"./iterableToArrayLimit\");\n\nvar nonIterableRest = require(\"./nonIterableRest\");\n\nfunction _slicedToArray(arr, i) {\n return arrayWithHoles(arr) || iterableToArrayLimit(arr, i) || nonIterableRest();\n}\n\nmodule.exports = _slicedToArray;","module.exports = require(\"core-js/library/fn/array/is-array\");","/**\n * Copyright (c) 2013-present, Facebook, Inc.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n *\n */\n\n'use strict';\n\n/**\n * Use invariant() to assert state which your program assumes to be true.\n *\n * Provide sprintf-style format (only %s is supported) and arguments\n * to provide information about what broke and what you were\n * expecting.\n *\n * The invariant message will be stripped in production, but the invariant\n * will remain to ensure logic does not differ in production.\n */\n\nvar validateFormat = function validateFormat(format) {};\n\nif (process.env.NODE_ENV !== 'production') {\n validateFormat = function validateFormat(format) {\n if (format === undefined) {\n throw new Error('invariant requires an error message argument');\n }\n };\n}\n\nfunction invariant(condition, format, a, b, c, d, e, f) {\n validateFormat(format);\n\n if (!condition) {\n var error;\n if (format === undefined) {\n error = new Error('Minified exception occurred; use the non-minified dev environment ' + 'for the full error message and additional helpful warnings.');\n } else {\n var args = [a, b, c, d, e, f];\n var argIndex = 0;\n error = new Error(format.replace(/%s/g, function () {\n return args[argIndex++];\n }));\n error.name = 'Invariant Violation';\n }\n\n error.framesToPop = 1; // we don't care about invariant's own frame\n throw error;\n }\n}\n\nmodule.exports = invariant;","module.exports = require(\"core-js/library/fn/object/keys\");","module.exports = require(\"core-js/library/fn/object/assign\");","function makeWindow() {\n var win = {\n location: {},\n history: {},\n open: () => {},\n close: () => {},\n File: function() {}\n }\n\n if(typeof window === \"undefined\") {\n return win\n }\n\n try {\n win = window\n var props = [\"File\", \"Blob\", \"FormData\"]\n for (var prop of props) {\n if (prop in window) {\n win[prop] = window[prop]\n }\n }\n } catch( e ) {\n console.error(e)\n }\n\n return win\n}\n\nmodule.exports = makeWindow()\n","var _Object$assign = require(\"../core-js/object/assign\");\n\nfunction _extends() {\n module.exports = _extends = _Object$assign || function (target) {\n for (var i = 1; i < arguments.length; i++) {\n var source = arguments[i];\n\n for (var key in source) {\n if (Object.prototype.hasOwnProperty.call(source, key)) {\n target[key] = source[key];\n }\n }\n }\n\n return target;\n };\n\n return _extends.apply(this, arguments);\n}\n\nmodule.exports = _extends;","/**\n * This is a straight rip-off of the React.js ReactPropTypes.js proptype validators,\n * modified to make it possible to validate Immutable.js data.\n * ImmutableTypes.listOf is patterned after React.PropTypes.arrayOf, but for Immutable.List\n * ImmutableTypes.shape is based on React.PropTypes.shape, but for any Immutable.Iterable\n */\n\"use strict\";\n\nvar Immutable = require(\"immutable\");\n\nvar ANONYMOUS = \"<>\";\n\nvar ImmutablePropTypes = {\n listOf: createListOfTypeChecker,\n mapOf: createMapOfTypeChecker,\n orderedMapOf: createOrderedMapOfTypeChecker,\n setOf: createSetOfTypeChecker,\n orderedSetOf: createOrderedSetOfTypeChecker,\n stackOf: createStackOfTypeChecker,\n iterableOf: createIterableOfTypeChecker,\n recordOf: createRecordOfTypeChecker,\n shape: createShapeChecker,\n contains: createShapeChecker,\n mapContains: createMapContainsChecker,\n // Primitive Types\n list: createImmutableTypeChecker(\"List\", Immutable.List.isList),\n map: createImmutableTypeChecker(\"Map\", Immutable.Map.isMap),\n orderedMap: createImmutableTypeChecker(\"OrderedMap\", Immutable.OrderedMap.isOrderedMap),\n set: createImmutableTypeChecker(\"Set\", Immutable.Set.isSet),\n orderedSet: createImmutableTypeChecker(\"OrderedSet\", Immutable.OrderedSet.isOrderedSet),\n stack: createImmutableTypeChecker(\"Stack\", Immutable.Stack.isStack),\n seq: createImmutableTypeChecker(\"Seq\", Immutable.Seq.isSeq),\n record: createImmutableTypeChecker(\"Record\", function (isRecord) {\n return isRecord instanceof Immutable.Record;\n }),\n iterable: createImmutableTypeChecker(\"Iterable\", Immutable.Iterable.isIterable)\n};\n\nfunction getPropType(propValue) {\n var propType = typeof propValue;\n if (Array.isArray(propValue)) {\n return \"array\";\n }\n if (propValue instanceof RegExp) {\n // Old webkits (at least until Android 4.0) return 'function' rather than\n // 'object' for typeof a RegExp. We'll normalize this here so that /bla/\n // passes PropTypes.object.\n return \"object\";\n }\n if (propValue instanceof Immutable.Iterable) {\n return \"Immutable.\" + propValue.toSource().split(\" \")[0];\n }\n return propType;\n}\n\nfunction createChainableTypeChecker(validate) {\n function checkType(isRequired, props, propName, componentName, location, propFullName) {\n for (var _len = arguments.length, rest = Array(_len > 6 ? _len - 6 : 0), _key = 6; _key < _len; _key++) {\n rest[_key - 6] = arguments[_key];\n }\n\n propFullName = propFullName || propName;\n componentName = componentName || ANONYMOUS;\n if (props[propName] == null) {\n var locationName = location;\n if (isRequired) {\n return new Error(\"Required \" + locationName + \" `\" + propFullName + \"` was not specified in \" + (\"`\" + componentName + \"`.\"));\n }\n } else {\n return validate.apply(undefined, [props, propName, componentName, location, propFullName].concat(rest));\n }\n }\n\n var chainedCheckType = checkType.bind(null, false);\n chainedCheckType.isRequired = checkType.bind(null, true);\n\n return chainedCheckType;\n}\n\nfunction createImmutableTypeChecker(immutableClassName, immutableClassTypeValidator) {\n function validate(props, propName, componentName, location, propFullName) {\n var propValue = props[propName];\n if (!immutableClassTypeValidator(propValue)) {\n var propType = getPropType(propValue);\n return new Error(\"Invalid \" + location + \" `\" + propFullName + \"` of type `\" + propType + \"` \" + (\"supplied to `\" + componentName + \"`, expected `\" + immutableClassName + \"`.\"));\n }\n return null;\n }\n return createChainableTypeChecker(validate);\n}\n\nfunction createIterableTypeChecker(typeChecker, immutableClassName, immutableClassTypeValidator) {\n\n function validate(props, propName, componentName, location, propFullName) {\n for (var _len = arguments.length, rest = Array(_len > 5 ? _len - 5 : 0), _key = 5; _key < _len; _key++) {\n rest[_key - 5] = arguments[_key];\n }\n\n var propValue = props[propName];\n if (!immutableClassTypeValidator(propValue)) {\n var locationName = location;\n var propType = getPropType(propValue);\n return new Error(\"Invalid \" + locationName + \" `\" + propFullName + \"` of type \" + (\"`\" + propType + \"` supplied to `\" + componentName + \"`, expected an Immutable.js \" + immutableClassName + \".\"));\n }\n\n if (typeof typeChecker !== \"function\") {\n return new Error(\"Invalid typeChecker supplied to `\" + componentName + \"` \" + (\"for propType `\" + propFullName + \"`, expected a function.\"));\n }\n\n var propValues = propValue.toArray();\n for (var i = 0, len = propValues.length; i < len; i++) {\n var error = typeChecker.apply(undefined, [propValues, i, componentName, location, \"\" + propFullName + \"[\" + i + \"]\"].concat(rest));\n if (error instanceof Error) {\n return error;\n }\n }\n }\n return createChainableTypeChecker(validate);\n}\n\nfunction createKeysTypeChecker(typeChecker) {\n\n function validate(props, propName, componentName, location, propFullName) {\n for (var _len = arguments.length, rest = Array(_len > 5 ? _len - 5 : 0), _key = 5; _key < _len; _key++) {\n rest[_key - 5] = arguments[_key];\n }\n\n var propValue = props[propName];\n if (typeof typeChecker !== \"function\") {\n return new Error(\"Invalid keysTypeChecker (optional second argument) supplied to `\" + componentName + \"` \" + (\"for propType `\" + propFullName + \"`, expected a function.\"));\n }\n\n var keys = propValue.keySeq().toArray();\n for (var i = 0, len = keys.length; i < len; i++) {\n var error = typeChecker.apply(undefined, [keys, i, componentName, location, \"\" + propFullName + \" -> key(\" + keys[i] + \")\"].concat(rest));\n if (error instanceof Error) {\n return error;\n }\n }\n }\n return createChainableTypeChecker(validate);\n}\n\nfunction createListOfTypeChecker(typeChecker) {\n return createIterableTypeChecker(typeChecker, \"List\", Immutable.List.isList);\n}\n\nfunction createMapOfTypeCheckerFactory(valuesTypeChecker, keysTypeChecker, immutableClassName, immutableClassTypeValidator) {\n function validate() {\n for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {\n args[_key] = arguments[_key];\n }\n\n return createIterableTypeChecker(valuesTypeChecker, immutableClassName, immutableClassTypeValidator).apply(undefined, args) || keysTypeChecker && createKeysTypeChecker(keysTypeChecker).apply(undefined, args);\n }\n\n return createChainableTypeChecker(validate);\n}\n\nfunction createMapOfTypeChecker(valuesTypeChecker, keysTypeChecker) {\n return createMapOfTypeCheckerFactory(valuesTypeChecker, keysTypeChecker, \"Map\", Immutable.Map.isMap);\n}\n\nfunction createOrderedMapOfTypeChecker(valuesTypeChecker, keysTypeChecker) {\n return createMapOfTypeCheckerFactory(valuesTypeChecker, keysTypeChecker, \"OrderedMap\", Immutable.OrderedMap.isOrderedMap);\n}\n\nfunction createSetOfTypeChecker(typeChecker) {\n return createIterableTypeChecker(typeChecker, \"Set\", Immutable.Set.isSet);\n}\n\nfunction createOrderedSetOfTypeChecker(typeChecker) {\n return createIterableTypeChecker(typeChecker, \"OrderedSet\", Immutable.OrderedSet.isOrderedSet);\n}\n\nfunction createStackOfTypeChecker(typeChecker) {\n return createIterableTypeChecker(typeChecker, \"Stack\", Immutable.Stack.isStack);\n}\n\nfunction createIterableOfTypeChecker(typeChecker) {\n return createIterableTypeChecker(typeChecker, \"Iterable\", Immutable.Iterable.isIterable);\n}\n\nfunction createRecordOfTypeChecker(recordKeys) {\n function validate(props, propName, componentName, location, propFullName) {\n for (var _len = arguments.length, rest = Array(_len > 5 ? _len - 5 : 0), _key = 5; _key < _len; _key++) {\n rest[_key - 5] = arguments[_key];\n }\n\n var propValue = props[propName];\n if (!(propValue instanceof Immutable.Record)) {\n var propType = getPropType(propValue);\n var locationName = location;\n return new Error(\"Invalid \" + locationName + \" `\" + propFullName + \"` of type `\" + propType + \"` \" + (\"supplied to `\" + componentName + \"`, expected an Immutable.js Record.\"));\n }\n for (var key in recordKeys) {\n var checker = recordKeys[key];\n if (!checker) {\n continue;\n }\n var mutablePropValue = propValue.toObject();\n var error = checker.apply(undefined, [mutablePropValue, key, componentName, location, \"\" + propFullName + \".\" + key].concat(rest));\n if (error) {\n return error;\n }\n }\n }\n return createChainableTypeChecker(validate);\n}\n\n// there is some irony in the fact that shapeTypes is a standard hash and not an immutable collection\nfunction createShapeTypeChecker(shapeTypes) {\n var immutableClassName = arguments[1] === undefined ? \"Iterable\" : arguments[1];\n var immutableClassTypeValidator = arguments[2] === undefined ? Immutable.Iterable.isIterable : arguments[2];\n\n function validate(props, propName, componentName, location, propFullName) {\n for (var _len = arguments.length, rest = Array(_len > 5 ? _len - 5 : 0), _key = 5; _key < _len; _key++) {\n rest[_key - 5] = arguments[_key];\n }\n\n var propValue = props[propName];\n if (!immutableClassTypeValidator(propValue)) {\n var propType = getPropType(propValue);\n var locationName = location;\n return new Error(\"Invalid \" + locationName + \" `\" + propFullName + \"` of type `\" + propType + \"` \" + (\"supplied to `\" + componentName + \"`, expected an Immutable.js \" + immutableClassName + \".\"));\n }\n var mutablePropValue = propValue.toObject();\n for (var key in shapeTypes) {\n var checker = shapeTypes[key];\n if (!checker) {\n continue;\n }\n var error = checker.apply(undefined, [mutablePropValue, key, componentName, location, \"\" + propFullName + \".\" + key].concat(rest));\n if (error) {\n return error;\n }\n }\n }\n return createChainableTypeChecker(validate);\n}\n\nfunction createShapeChecker(shapeTypes) {\n return createShapeTypeChecker(shapeTypes);\n}\n\nfunction createMapContainsChecker(shapeTypes) {\n return createShapeTypeChecker(shapeTypes, \"Map\", Immutable.Map.isMap);\n}\n\nmodule.exports = ImmutablePropTypes;","var core = module.exports = { version: '2.6.5' };\nif (typeof __e == 'number') __e = core; // eslint-disable-line no-undef\n","/**\n * Copyright (c) 2013-present, Facebook, Inc.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n *\n * \n */\n'use strict';\n\n/**\n * WARNING: DO NOT manually require this module.\n * This is a replacement for `invariant(...)` used by the error code system\n * and will _only_ be required by the corresponding babel pass.\n * It always throws.\n */\n\nfunction reactProdInvariant(code) {\n var argCount = arguments.length - 1;\n\n var message = 'Minified React error #' + code + '; visit ' + 'http://facebook.github.io/react/docs/error-decoder.html?invariant=' + code;\n\n for (var argIdx = 0; argIdx < argCount; argIdx++) {\n message += '&args[]=' + encodeURIComponent(arguments[argIdx + 1]);\n }\n\n message += ' for the full message or use the non-minified dev environment' + ' for full errors and additional helpful warnings.';\n\n var error = new Error(message);\n error.name = 'Invariant Violation';\n error.framesToPop = 1; // we don't care about reactProdInvariant's own frame\n\n throw error;\n}\n\nmodule.exports = reactProdInvariant;","/**\n * Copyright (c) 2014-present, Facebook, Inc.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n *\n */\n\n'use strict';\n\nvar emptyFunction = require('./emptyFunction');\n\n/**\n * Similar to invariant but only logs a warning if the condition is not met.\n * This can be used to log issues in development environments in critical\n * paths. Removing the logging code for production environments will keep the\n * same logic and follow the same code paths.\n */\n\nvar warning = emptyFunction;\n\nif (process.env.NODE_ENV !== 'production') {\n var printWarning = function printWarning(format) {\n for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {\n args[_key - 1] = arguments[_key];\n }\n\n var argIndex = 0;\n var message = 'Warning: ' + format.replace(/%s/g, function () {\n return args[argIndex++];\n });\n if (typeof console !== 'undefined') {\n console.error(message);\n }\n try {\n // --- Welcome to debugging React ---\n // This error was thrown as a convenience so that you can use this stack\n // to find the callsite that caused this warning to fire.\n throw new Error(message);\n } catch (x) {}\n };\n\n warning = function warning(condition, format) {\n if (format === undefined) {\n throw new Error('`warning(condition, format, ...args)` requires a warning ' + 'message argument');\n }\n\n if (format.indexOf('Failed Composite propType: ') === 0) {\n return; // Ignore CompositeComponent proptype check.\n }\n\n if (!condition) {\n for (var _len2 = arguments.length, args = Array(_len2 > 2 ? _len2 - 2 : 0), _key2 = 2; _key2 < _len2; _key2++) {\n args[_key2 - 2] = arguments[_key2];\n }\n\n printWarning.apply(undefined, [format].concat(args));\n }\n };\n}\n\nmodule.exports = warning;","import React from \"react\"\n\nexport function isOAS3(jsSpec) {\n const oasVersion = jsSpec.get(\"openapi\")\n if(typeof oasVersion !== \"string\") {\n return false\n }\n\n // we gate against `3.1` becasue we want to explicitly opt into supporting it\n // at some point in the future -- KS, 7/2018\n\n // starts with, but is not `3.0.` exactly\n return oasVersion.startsWith(\"3.0.\") && oasVersion.length > 4\n}\n\nexport function isSwagger2(jsSpec) {\n const swaggerVersion = jsSpec.get(\"swagger\")\n if(typeof swaggerVersion !== \"string\") {\n return false\n }\n\n return swaggerVersion.startsWith(\"2.0\")\n}\n\nexport function OAS3ComponentWrapFactory(Component) {\n return (Ori, system) => (props) => {\n if(system && system.specSelectors && system.specSelectors.specJson) {\n const spec = system.specSelectors.specJson()\n\n if(isOAS3(spec)) {\n return \n } else {\n return \n }\n } else {\n console.warn(\"OAS3 wrapper: couldn't get spec\")\n return null\n }\n }\n}\n","/*\nobject-assign\n(c) Sindre Sorhus\n@license MIT\n*/\n\n'use strict';\n/* eslint-disable no-unused-vars */\nvar getOwnPropertySymbols = Object.getOwnPropertySymbols;\nvar hasOwnProperty = Object.prototype.hasOwnProperty;\nvar propIsEnumerable = Object.prototype.propertyIsEnumerable;\n\nfunction toObject(val) {\n\tif (val === null || val === undefined) {\n\t\tthrow new TypeError('Object.assign cannot be called with null or undefined');\n\t}\n\n\treturn Object(val);\n}\n\nfunction shouldUseNative() {\n\ttry {\n\t\tif (!Object.assign) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// Detect buggy property enumeration order in older V8 versions.\n\n\t\t// https://bugs.chromium.org/p/v8/issues/detail?id=4118\n\t\tvar test1 = new String('abc'); // eslint-disable-line no-new-wrappers\n\t\ttest1[5] = 'de';\n\t\tif (Object.getOwnPropertyNames(test1)[0] === '5') {\n\t\t\treturn false;\n\t\t}\n\n\t\t// https://bugs.chromium.org/p/v8/issues/detail?id=3056\n\t\tvar test2 = {};\n\t\tfor (var i = 0; i < 10; i++) {\n\t\t\ttest2['_' + String.fromCharCode(i)] = i;\n\t\t}\n\t\tvar order2 = Object.getOwnPropertyNames(test2).map(function (n) {\n\t\t\treturn test2[n];\n\t\t});\n\t\tif (order2.join('') !== '0123456789') {\n\t\t\treturn false;\n\t\t}\n\n\t\t// https://bugs.chromium.org/p/v8/issues/detail?id=3056\n\t\tvar test3 = {};\n\t\t'abcdefghijklmnopqrst'.split('').forEach(function (letter) {\n\t\t\ttest3[letter] = letter;\n\t\t});\n\t\tif (Object.keys(Object.assign({}, test3)).join('') !==\n\t\t\t\t'abcdefghijklmnopqrst') {\n\t\t\treturn false;\n\t\t}\n\n\t\treturn true;\n\t} catch (err) {\n\t\t// We don't expect any of the above to throw, but better to be safe.\n\t\treturn false;\n\t}\n}\n\nmodule.exports = shouldUseNative() ? Object.assign : function (target, source) {\n\tvar from;\n\tvar to = toObject(target);\n\tvar symbols;\n\n\tfor (var s = 1; s < arguments.length; s++) {\n\t\tfrom = Object(arguments[s]);\n\n\t\tfor (var key in from) {\n\t\t\tif (hasOwnProperty.call(from, key)) {\n\t\t\t\tto[key] = from[key];\n\t\t\t}\n\t\t}\n\n\t\tif (getOwnPropertySymbols) {\n\t\t\tsymbols = getOwnPropertySymbols(from);\n\t\t\tfor (var i = 0; i < symbols.length; i++) {\n\t\t\t\tif (propIsEnumerable.call(from, symbols[i])) {\n\t\t\t\t\tto[symbols[i]] = from[symbols[i]];\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn to;\n};\n","var global = require('./_global');\nvar core = require('./_core');\nvar ctx = require('./_ctx');\nvar hide = require('./_hide');\nvar has = require('./_has');\nvar PROTOTYPE = 'prototype';\n\nvar $export = function (type, name, source) {\n var IS_FORCED = type & $export.F;\n var IS_GLOBAL = type & $export.G;\n var IS_STATIC = type & $export.S;\n var IS_PROTO = type & $export.P;\n var IS_BIND = type & $export.B;\n var IS_WRAP = type & $export.W;\n var exports = IS_GLOBAL ? core : core[name] || (core[name] = {});\n var expProto = exports[PROTOTYPE];\n var target = IS_GLOBAL ? global : IS_STATIC ? global[name] : (global[name] || {})[PROTOTYPE];\n var key, own, out;\n if (IS_GLOBAL) source = name;\n for (key in source) {\n // contains in native\n own = !IS_FORCED && target && target[key] !== undefined;\n if (own && has(exports, key)) continue;\n // export native or passed\n out = own ? target[key] : source[key];\n // prevent global pollution for namespaces\n exports[key] = IS_GLOBAL && typeof target[key] != 'function' ? source[key]\n // bind timers to global for call from export context\n : IS_BIND && own ? ctx(out, global)\n // wrap global constructors for prevent change them in library\n : IS_WRAP && target[key] == out ? (function (C) {\n var F = function (a, b, c) {\n if (this instanceof C) {\n switch (arguments.length) {\n case 0: return new C();\n case 1: return new C(a);\n case 2: return new C(a, b);\n } return new C(a, b, c);\n } return C.apply(this, arguments);\n };\n F[PROTOTYPE] = C[PROTOTYPE];\n return F;\n // make static versions for prototype methods\n })(out) : IS_PROTO && typeof out == 'function' ? ctx(Function.call, out) : out;\n // export proto methods to core.%CONSTRUCTOR%.methods.%NAME%\n if (IS_PROTO) {\n (exports.virtual || (exports.virtual = {}))[key] = out;\n // export proto methods to core.%CONSTRUCTOR%.prototype.%NAME%\n if (type & $export.R && expProto && !expProto[key]) hide(expProto, key, out);\n }\n }\n};\n// type bitmap\n$export.F = 1; // forced\n$export.G = 2; // global\n$export.S = 4; // static\n$export.P = 8; // proto\n$export.B = 16; // bind\n$export.W = 32; // wrap\n$export.U = 64; // safe\n$export.R = 128; // real proto method for `library`\nmodule.exports = $export;\n","var _Symbol$iterator = require(\"../core-js/symbol/iterator\");\n\nvar _Symbol = require(\"../core-js/symbol\");\n\nfunction _typeof2(obj) { if (typeof _Symbol === \"function\" && typeof _Symbol$iterator === \"symbol\") { _typeof2 = function _typeof2(obj) { return typeof obj; }; } else { _typeof2 = function _typeof2(obj) { return obj && typeof _Symbol === \"function\" && obj.constructor === _Symbol && obj !== _Symbol.prototype ? \"symbol\" : typeof obj; }; } return _typeof2(obj); }\n\nfunction _typeof(obj) {\n if (typeof _Symbol === \"function\" && _typeof2(_Symbol$iterator) === \"symbol\") {\n module.exports = _typeof = function _typeof(obj) {\n return _typeof2(obj);\n };\n } else {\n module.exports = _typeof = function _typeof(obj) {\n return obj && typeof _Symbol === \"function\" && obj.constructor === _Symbol && obj !== _Symbol.prototype ? \"symbol\" : _typeof2(obj);\n };\n }\n\n return _typeof(obj);\n}\n\nmodule.exports = _typeof;","/**\n * Copyright (c) 2013-present, Facebook, Inc.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n *\n */\n\n'use strict';\n\nvar _prodInvariant = require('./reactProdInvariant');\n\nvar DOMProperty = require('./DOMProperty');\nvar ReactDOMComponentFlags = require('./ReactDOMComponentFlags');\n\nvar invariant = require('fbjs/lib/invariant');\n\nvar ATTR_NAME = DOMProperty.ID_ATTRIBUTE_NAME;\nvar Flags = ReactDOMComponentFlags;\n\nvar internalInstanceKey = '__reactInternalInstance$' + Math.random().toString(36).slice(2);\n\n/**\n * Check if a given node should be cached.\n */\nfunction shouldPrecacheNode(node, nodeID) {\n return node.nodeType === 1 && node.getAttribute(ATTR_NAME) === String(nodeID) || node.nodeType === 8 && node.nodeValue === ' react-text: ' + nodeID + ' ' || node.nodeType === 8 && node.nodeValue === ' react-empty: ' + nodeID + ' ';\n}\n\n/**\n * Drill down (through composites and empty components) until we get a host or\n * host text component.\n *\n * This is pretty polymorphic but unavoidable with the current structure we have\n * for `_renderedChildren`.\n */\nfunction getRenderedHostOrTextFromComponent(component) {\n var rendered;\n while (rendered = component._renderedComponent) {\n component = rendered;\n }\n return component;\n}\n\n/**\n * Populate `_hostNode` on the rendered host/text component with the given\n * DOM node. The passed `inst` can be a composite.\n */\nfunction precacheNode(inst, node) {\n var hostInst = getRenderedHostOrTextFromComponent(inst);\n hostInst._hostNode = node;\n node[internalInstanceKey] = hostInst;\n}\n\nfunction uncacheNode(inst) {\n var node = inst._hostNode;\n if (node) {\n delete node[internalInstanceKey];\n inst._hostNode = null;\n }\n}\n\n/**\n * Populate `_hostNode` on each child of `inst`, assuming that the children\n * match up with the DOM (element) children of `node`.\n *\n * We cache entire levels at once to avoid an n^2 problem where we access the\n * children of a node sequentially and have to walk from the start to our target\n * node every time.\n *\n * Since we update `_renderedChildren` and the actual DOM at (slightly)\n * different times, we could race here and see a newer `_renderedChildren` than\n * the DOM nodes we see. To avoid this, ReactMultiChild calls\n * `prepareToManageChildren` before we change `_renderedChildren`, at which\n * time the container's child nodes are always cached (until it unmounts).\n */\nfunction precacheChildNodes(inst, node) {\n if (inst._flags & Flags.hasCachedChildNodes) {\n return;\n }\n var children = inst._renderedChildren;\n var childNode = node.firstChild;\n outer: for (var name in children) {\n if (!children.hasOwnProperty(name)) {\n continue;\n }\n var childInst = children[name];\n var childID = getRenderedHostOrTextFromComponent(childInst)._domID;\n if (childID === 0) {\n // We're currently unmounting this child in ReactMultiChild; skip it.\n continue;\n }\n // We assume the child nodes are in the same order as the child instances.\n for (; childNode !== null; childNode = childNode.nextSibling) {\n if (shouldPrecacheNode(childNode, childID)) {\n precacheNode(childInst, childNode);\n continue outer;\n }\n }\n // We reached the end of the DOM children without finding an ID match.\n !false ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Unable to find element with ID %s.', childID) : _prodInvariant('32', childID) : void 0;\n }\n inst._flags |= Flags.hasCachedChildNodes;\n}\n\n/**\n * Given a DOM node, return the closest ReactDOMComponent or\n * ReactDOMTextComponent instance ancestor.\n */\nfunction getClosestInstanceFromNode(node) {\n if (node[internalInstanceKey]) {\n return node[internalInstanceKey];\n }\n\n // Walk up the tree until we find an ancestor whose instance we have cached.\n var parents = [];\n while (!node[internalInstanceKey]) {\n parents.push(node);\n if (node.parentNode) {\n node = node.parentNode;\n } else {\n // Top of the tree. This node must not be part of a React tree (or is\n // unmounted, potentially).\n return null;\n }\n }\n\n var closest;\n var inst;\n for (; node && (inst = node[internalInstanceKey]); node = parents.pop()) {\n closest = inst;\n if (parents.length) {\n precacheChildNodes(inst, node);\n }\n }\n\n return closest;\n}\n\n/**\n * Given a DOM node, return the ReactDOMComponent or ReactDOMTextComponent\n * instance, or null if the node was not rendered by this React.\n */\nfunction getInstanceFromNode(node) {\n var inst = getClosestInstanceFromNode(node);\n if (inst != null && inst._hostNode === node) {\n return inst;\n } else {\n return null;\n }\n}\n\n/**\n * Given a ReactDOMComponent or ReactDOMTextComponent, return the corresponding\n * DOM node.\n */\nfunction getNodeFromInstance(inst) {\n // Without this first invariant, passing a non-DOM-component triggers the next\n // invariant for a missing parent, which is super confusing.\n !(inst._hostNode !== undefined) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'getNodeFromInstance: Invalid argument.') : _prodInvariant('33') : void 0;\n\n if (inst._hostNode) {\n return inst._hostNode;\n }\n\n // Walk up the tree until we find an ancestor whose DOM node we have cached.\n var parents = [];\n while (!inst._hostNode) {\n parents.push(inst);\n !inst._hostParent ? process.env.NODE_ENV !== 'production' ? invariant(false, 'React DOM tree root should always have a node reference.') : _prodInvariant('34') : void 0;\n inst = inst._hostParent;\n }\n\n // Now parents contains each ancestor that does *not* have a cached native\n // node, and `inst` is the deepest ancestor that does.\n for (; parents.length; inst = parents.pop()) {\n precacheChildNodes(inst, inst._hostNode);\n }\n\n return inst._hostNode;\n}\n\nvar ReactDOMComponentTree = {\n getClosestInstanceFromNode: getClosestInstanceFromNode,\n getInstanceFromNode: getInstanceFromNode,\n getNodeFromInstance: getNodeFromInstance,\n precacheChildNodes: precacheChildNodes,\n precacheNode: precacheNode,\n uncacheNode: uncacheNode\n};\n\nmodule.exports = ReactDOMComponentTree;","module.exports = require(\"core-js/library/fn/json/stringify\");","import YAML from \"js-yaml\"\nimport { Map } from \"immutable\"\nimport parseUrl from \"url-parse\"\nimport serializeError from \"serialize-error\"\nimport isString from \"lodash/isString\"\nimport debounce from \"lodash/debounce\"\nimport set from \"lodash/set\"\nimport { isJSONObject, paramToValue, isEmptyValue } from \"core/utils\"\n\n// Actions conform to FSA (flux-standard-actions)\n// {type: string,payload: Any|Error, meta: obj, error: bool}\n\nexport const UPDATE_SPEC = \"spec_update_spec\"\nexport const UPDATE_URL = \"spec_update_url\"\nexport const UPDATE_JSON = \"spec_update_json\"\nexport const UPDATE_PARAM = \"spec_update_param\"\nexport const UPDATE_EMPTY_PARAM_INCLUSION = \"spec_update_empty_param_inclusion\"\nexport const VALIDATE_PARAMS = \"spec_validate_param\"\nexport const SET_RESPONSE = \"spec_set_response\"\nexport const SET_REQUEST = \"spec_set_request\"\nexport const SET_MUTATED_REQUEST = \"spec_set_mutated_request\"\nexport const LOG_REQUEST = \"spec_log_request\"\nexport const CLEAR_RESPONSE = \"spec_clear_response\"\nexport const CLEAR_REQUEST = \"spec_clear_request\"\nexport const CLEAR_VALIDATE_PARAMS = \"spec_clear_validate_param\"\nexport const UPDATE_OPERATION_META_VALUE = \"spec_update_operation_meta_value\"\nexport const UPDATE_RESOLVED = \"spec_update_resolved\"\nexport const UPDATE_RESOLVED_SUBTREE = \"spec_update_resolved_subtree\"\nexport const SET_SCHEME = \"set_scheme\"\n\nconst toStr = (str) => isString(str) ? str : \"\"\n\nexport function updateSpec(spec) {\n const cleanSpec = (toStr(spec)).replace(/\\t/g, \" \")\n if(typeof spec === \"string\") {\n return {\n type: UPDATE_SPEC,\n payload: cleanSpec\n }\n }\n}\n\nexport function updateResolved(spec) {\n return {\n type: UPDATE_RESOLVED,\n payload: spec\n }\n}\n\nexport function updateUrl(url) {\n return {type: UPDATE_URL, payload: url}\n}\n\nexport function updateJsonSpec(json) {\n return {type: UPDATE_JSON, payload: json}\n}\n\nexport const parseToJson = (str) => ({specActions, specSelectors, errActions}) => {\n let { specStr } = specSelectors\n\n let json = null\n try {\n str = str || specStr()\n errActions.clear({ source: \"parser\" })\n json = YAML.safeLoad(str)\n } catch(e) {\n // TODO: push error to state\n console.error(e)\n return errActions.newSpecErr({\n source: \"parser\",\n level: \"error\",\n message: e.reason,\n line: e.mark && e.mark.line ? e.mark.line + 1 : undefined\n })\n }\n if(json && typeof json === \"object\") {\n return specActions.updateJsonSpec(json)\n }\n return {}\n}\n\nlet hasWarnedAboutResolveSpecDeprecation = false\n\nexport const resolveSpec = (json, url) => ({specActions, specSelectors, errActions, fn: { fetch, resolve, AST = {} }, getConfigs}) => {\n if(!hasWarnedAboutResolveSpecDeprecation) {\n console.warn(`specActions.resolveSpec is deprecated since v3.10.0 and will be removed in v4.0.0; use requestResolvedSubtree instead!`)\n hasWarnedAboutResolveSpecDeprecation = true\n }\n\n const {\n modelPropertyMacro,\n parameterMacro,\n requestInterceptor,\n responseInterceptor\n } = getConfigs()\n\n if(typeof(json) === \"undefined\") {\n json = specSelectors.specJson()\n }\n if(typeof(url) === \"undefined\") {\n url = specSelectors.url()\n }\n\n let getLineNumberForPath = AST.getLineNumberForPath ? AST.getLineNumberForPath : () => undefined\n\n let specStr = specSelectors.specStr()\n\n return resolve({\n fetch,\n spec: json,\n baseDoc: url,\n modelPropertyMacro,\n parameterMacro,\n requestInterceptor,\n responseInterceptor\n }).then( ({spec, errors}) => {\n errActions.clear({\n type: \"thrown\"\n })\n if(Array.isArray(errors) && errors.length > 0) {\n let preparedErrors = errors\n .map(err => {\n console.error(err)\n err.line = err.fullPath ? getLineNumberForPath(specStr, err.fullPath) : null\n err.path = err.fullPath ? err.fullPath.join(\".\") : null\n err.level = \"error\"\n err.type = \"thrown\"\n err.source = \"resolver\"\n Object.defineProperty(err, \"message\", { enumerable: true, value: err.message })\n return err\n })\n errActions.newThrownErrBatch(preparedErrors)\n }\n\n return specActions.updateResolved(spec)\n })\n}\n\nlet requestBatch = []\n\nconst debResolveSubtrees = debounce(async () => {\n const system = requestBatch.system // Just a reference to the \"latest\" system\n\n if(!system) {\n console.error(\"debResolveSubtrees: don't have a system to operate on, aborting.\")\n return\n }\n const {\n errActions,\n errSelectors,\n fn: {\n resolveSubtree,\n AST = {}\n },\n specSelectors,\n specActions,\n } = system\n\n if(!resolveSubtree) {\n console.error(\"Error: Swagger-Client did not provide a `resolveSubtree` method, doing nothing.\")\n return\n }\n\n let getLineNumberForPath = AST.getLineNumberForPath ? AST.getLineNumberForPath : () => undefined\n\n const specStr = specSelectors.specStr()\n\n const {\n modelPropertyMacro,\n parameterMacro,\n requestInterceptor,\n responseInterceptor\n } = system.getConfigs()\n\n try {\n var batchResult = await requestBatch.reduce(async (prev, path) => {\n const { resultMap, specWithCurrentSubtrees } = await prev\n const { errors, spec } = await resolveSubtree(specWithCurrentSubtrees, path, {\n baseDoc: specSelectors.url(),\n modelPropertyMacro,\n parameterMacro,\n requestInterceptor,\n responseInterceptor\n })\n\n if(errSelectors.allErrors().size) {\n errActions.clearBy(err => {\n // keep if...\n return err.get(\"type\") !== \"thrown\" // it's not a thrown error\n || err.get(\"source\") !== \"resolver\" // it's not a resolver error\n || !err.get(\"fullPath\").every((key, i) => key === path[i] || path[i] === undefined) // it's not within the path we're resolving\n })\n }\n\n if(Array.isArray(errors) && errors.length > 0) {\n let preparedErrors = errors\n .map(err => {\n err.line = err.fullPath ? getLineNumberForPath(specStr, err.fullPath) : null\n err.path = err.fullPath ? err.fullPath.join(\".\") : null\n err.level = \"error\"\n err.type = \"thrown\"\n err.source = \"resolver\"\n Object.defineProperty(err, \"message\", { enumerable: true, value: err.message })\n return err\n })\n errActions.newThrownErrBatch(preparedErrors)\n }\n\n set(resultMap, path, spec)\n set(specWithCurrentSubtrees, path, spec)\n\n return {\n resultMap,\n specWithCurrentSubtrees\n }\n }, Promise.resolve({\n resultMap: (specSelectors.specResolvedSubtree([]) || Map()).toJS(),\n specWithCurrentSubtrees: specSelectors.specJson().toJS()\n }))\n\n delete requestBatch.system\n requestBatch = [] // Clear stack\n } catch(e) {\n console.error(e)\n }\n\n specActions.updateResolvedSubtree([], batchResult.resultMap)\n}, 35)\n\nexport const requestResolvedSubtree = path => system => {\n // poor-man's array comparison\n // if this ever inadequate, this should be rewritten to use Im.List\n const isPathAlreadyBatched = requestBatch\n .map(arr => arr.join(\"@@\"))\n .indexOf(path.join(\"@@\")) > -1\n \n if(isPathAlreadyBatched) {\n return\n }\n\n requestBatch.push(path)\n requestBatch.system = system\n debResolveSubtrees()\n}\n\nexport function changeParam( path, paramName, paramIn, value, isXml ){\n return {\n type: UPDATE_PARAM,\n payload:{ path, value, paramName, paramIn, isXml }\n }\n}\n\nexport function changeParamByIdentity( pathMethod, param, value, isXml ){\n return {\n type: UPDATE_PARAM,\n payload:{ path: pathMethod, param, value, isXml }\n }\n}\n\nexport const updateResolvedSubtree = (path, value) => {\n return {\n type: UPDATE_RESOLVED_SUBTREE,\n payload: { path, value }\n }\n}\n\nexport const invalidateResolvedSubtreeCache = () => {\n return {\n type: UPDATE_RESOLVED_SUBTREE,\n payload: {\n path: [],\n value: Map()\n }\n }\n}\n\nexport const validateParams = ( payload, isOAS3 ) =>{\n return {\n type: VALIDATE_PARAMS,\n payload:{\n pathMethod: payload,\n isOAS3\n }\n }\n}\n\nexport const updateEmptyParamInclusion = ( pathMethod, paramName, paramIn, includeEmptyValue ) =>{\n return {\n type: UPDATE_EMPTY_PARAM_INCLUSION,\n payload:{\n pathMethod,\n paramName,\n paramIn,\n includeEmptyValue\n }\n }\n}\n\nexport function clearValidateParams( payload ){\n return {\n type: CLEAR_VALIDATE_PARAMS,\n payload:{ pathMethod: payload }\n }\n}\n\nexport function changeConsumesValue(path, value) {\n return {\n type: UPDATE_OPERATION_META_VALUE,\n payload:{ path, value, key: \"consumes_value\" }\n }\n}\n\nexport function changeProducesValue(path, value) {\n return {\n type: UPDATE_OPERATION_META_VALUE,\n payload:{ path, value, key: \"produces_value\" }\n }\n}\n\nexport const setResponse = ( path, method, res ) => {\n return {\n payload: { path, method, res },\n type: SET_RESPONSE\n }\n}\n\nexport const setRequest = ( path, method, req ) => {\n return {\n payload: { path, method, req },\n type: SET_REQUEST\n }\n}\n\nexport const setMutatedRequest = ( path, method, req ) => {\n return {\n payload: { path, method, req },\n type: SET_MUTATED_REQUEST\n }\n}\n\n// This is for debugging, remove this comment if you depend on this action\nexport const logRequest = (req) => {\n return {\n payload: req,\n type: LOG_REQUEST\n }\n}\n\n// Actually fire the request via fn.execute\n// (For debugging) and ease of testing\nexport const executeRequest = (req) =>\n ({fn, specActions, specSelectors, getConfigs, oas3Selectors}) => {\n let { pathName, method, operation } = req\n let { requestInterceptor, responseInterceptor } = getConfigs()\n\n \n let op = operation.toJS()\n \n // ensure that explicitly-included params are in the request\n\n if (operation && operation.get(\"parameters\")) {\n operation.get(\"parameters\")\n .filter(param => param && param.get(\"allowEmptyValue\") === true)\n .forEach(param => {\n if (specSelectors.parameterInclusionSettingFor([pathName, method], param.get(\"name\"), param.get(\"in\"))) {\n req.parameters = req.parameters || {}\n const paramValue = paramToValue(param, req.parameters)\n\n // if the value is falsy or an empty Immutable iterable...\n if(!paramValue || (paramValue && paramValue.size === 0)) {\n // set it to empty string, so Swagger Client will treat it as\n // present but empty.\n req.parameters[param.get(\"name\")] = \"\"\n }\n }\n })\n }\n\n // if url is relative, parseUrl makes it absolute by inferring from `window.location`\n req.contextUrl = parseUrl(specSelectors.url()).toString()\n\n if(op && op.operationId) {\n req.operationId = op.operationId\n } else if(op && pathName && method) {\n req.operationId = fn.opId(op, pathName, method)\n }\n\n if(specSelectors.isOAS3()) {\n const namespace = `${pathName}:${method}`\n\n req.server = oas3Selectors.selectedServer(namespace) || oas3Selectors.selectedServer()\n\n const namespaceVariables = oas3Selectors.serverVariables({\n server: req.server,\n namespace\n }).toJS()\n const globalVariables = oas3Selectors.serverVariables({ server: req.server }).toJS()\n\n req.serverVariables = Object.keys(namespaceVariables).length ? namespaceVariables : globalVariables\n\n req.requestContentType = oas3Selectors.requestContentType(pathName, method)\n req.responseContentType = oas3Selectors.responseContentType(pathName, method) || \"*/*\"\n const requestBody = oas3Selectors.requestBodyValue(pathName, method)\n const requestBodyInclusionSetting = oas3Selectors.requestBodyInclusionSetting(pathName, method)\n\n if(isJSONObject(requestBody)) {\n req.requestBody = JSON.parse(requestBody)\n } else if(requestBody && requestBody.toJS) {\n req.requestBody = requestBody.filter((value, key) => !isEmptyValue(value) || requestBodyInclusionSetting.get(key)).toJS()\n } else{\n req.requestBody = requestBody\n }\n }\n\n let parsedRequest = Object.assign({}, req)\n parsedRequest = fn.buildRequest(parsedRequest)\n\n specActions.setRequest(req.pathName, req.method, parsedRequest)\n\n let requestInterceptorWrapper = function(r) {\n let mutatedRequest = requestInterceptor.apply(this, [r])\n let parsedMutatedRequest = Object.assign({}, mutatedRequest)\n specActions.setMutatedRequest(req.pathName, req.method, parsedMutatedRequest)\n return mutatedRequest\n }\n\n req.requestInterceptor = requestInterceptorWrapper\n req.responseInterceptor = responseInterceptor\n\n // track duration of request\n const startTime = Date.now()\n\n\n return fn.execute(req)\n .then( res => {\n res.duration = Date.now() - startTime\n specActions.setResponse(req.pathName, req.method, res)\n } )\n .catch(\n err => {\n console.error(err)\n specActions.setResponse(req.pathName, req.method, {\n error: true, err: serializeError(err)\n })\n }\n )\n }\n\n\n// I'm using extras as a way to inject properties into the final, `execute` method - It's not great. Anyone have a better idea? @ponelat\nexport const execute = ( { path, method, ...extras }={} ) => (system) => {\n let { fn:{fetch}, specSelectors, specActions } = system\n let spec = specSelectors.specJsonWithResolvedSubtrees().toJS()\n let scheme = specSelectors.operationScheme(path, method)\n let { requestContentType, responseContentType } = specSelectors.contentTypeValues([path, method]).toJS()\n let isXml = /xml/i.test(requestContentType)\n let parameters = specSelectors.parameterValues([path, method], isXml).toJS()\n\n return specActions.executeRequest({\n ...extras,\n fetch,\n spec,\n pathName: path,\n method, parameters,\n requestContentType,\n scheme,\n responseContentType\n })\n}\n\nexport function clearResponse (path, method) {\n return {\n type: CLEAR_RESPONSE,\n payload:{ path, method }\n }\n}\n\nexport function clearRequest (path, method) {\n return {\n type: CLEAR_REQUEST,\n payload:{ path, method }\n }\n}\n\nexport function setScheme (scheme, path, method) {\n return {\n type: SET_SCHEME,\n payload: { scheme, path, method }\n }\n}\n","// https://github.com/zloirock/core-js/issues/86#issuecomment-115759028\nvar global = module.exports = typeof window != 'undefined' && window.Math == Math\n ? window : typeof self != 'undefined' && self.Math == Math ? self\n // eslint-disable-next-line no-new-func\n : Function('return this')();\nif (typeof __g == 'number') __g = global; // eslint-disable-line no-undef\n","'use strict';\n\nvar YAMLException = require('./exception');\n\nvar TYPE_CONSTRUCTOR_OPTIONS = [\n 'kind',\n 'resolve',\n 'construct',\n 'instanceOf',\n 'predicate',\n 'represent',\n 'defaultStyle',\n 'styleAliases'\n];\n\nvar YAML_NODE_KINDS = [\n 'scalar',\n 'sequence',\n 'mapping'\n];\n\nfunction compileStyleAliases(map) {\n var result = {};\n\n if (map !== null) {\n Object.keys(map).forEach(function (style) {\n map[style].forEach(function (alias) {\n result[String(alias)] = style;\n });\n });\n }\n\n return result;\n}\n\nfunction Type(tag, options) {\n options = options || {};\n\n Object.keys(options).forEach(function (name) {\n if (TYPE_CONSTRUCTOR_OPTIONS.indexOf(name) === -1) {\n throw new YAMLException('Unknown option \"' + name + '\" is met in definition of \"' + tag + '\" YAML type.');\n }\n });\n\n // TODO: Add tag format check.\n this.tag = tag;\n this.kind = options['kind'] || null;\n this.resolve = options['resolve'] || function () { return true; };\n this.construct = options['construct'] || function (data) { return data; };\n this.instanceOf = options['instanceOf'] || null;\n this.predicate = options['predicate'] || null;\n this.represent = options['represent'] || null;\n this.defaultStyle = options['defaultStyle'] || null;\n this.styleAliases = compileStyleAliases(options['styleAliases'] || null);\n\n if (YAML_NODE_KINDS.indexOf(this.kind) === -1) {\n throw new YAMLException('Unknown kind \"' + this.kind + '\" is specified for \"' + tag + '\" YAML type.');\n }\n}\n\nmodule.exports = Type;\n","var store = require('./_shared')('wks');\nvar uid = require('./_uid');\nvar Symbol = require('./_global').Symbol;\nvar USE_SYMBOL = typeof Symbol == 'function';\n\nvar $exports = module.exports = function (name) {\n return store[name] || (store[name] =\n USE_SYMBOL && Symbol[name] || (USE_SYMBOL ? Symbol : uid)('Symbol.' + name));\n};\n\n$exports.store = store;\n","module.exports = function (it) {\n return typeof it === 'object' ? it !== null : typeof it === 'function';\n};\n","var store = require('./_shared')('wks');\nvar uid = require('./_uid');\nvar Symbol = require('./_global').Symbol;\nvar USE_SYMBOL = typeof Symbol == 'function';\n\nvar $exports = module.exports = function (name) {\n return store[name] || (store[name] =\n USE_SYMBOL && Symbol[name] || (USE_SYMBOL ? Symbol : uid)('Symbol.' + name));\n};\n\n$exports.store = store;\n","var global = require('./_global');\nvar core = require('./_core');\nvar hide = require('./_hide');\nvar redefine = require('./_redefine');\nvar ctx = require('./_ctx');\nvar PROTOTYPE = 'prototype';\n\nvar $export = function (type, name, source) {\n var IS_FORCED = type & $export.F;\n var IS_GLOBAL = type & $export.G;\n var IS_STATIC = type & $export.S;\n var IS_PROTO = type & $export.P;\n var IS_BIND = type & $export.B;\n var target = IS_GLOBAL ? global : IS_STATIC ? global[name] || (global[name] = {}) : (global[name] || {})[PROTOTYPE];\n var exports = IS_GLOBAL ? core : core[name] || (core[name] = {});\n var expProto = exports[PROTOTYPE] || (exports[PROTOTYPE] = {});\n var key, own, out, exp;\n if (IS_GLOBAL) source = name;\n for (key in source) {\n // contains in native\n own = !IS_FORCED && target && target[key] !== undefined;\n // export native or passed\n out = (own ? target : source)[key];\n // bind timers to global for call from export context\n exp = IS_BIND && own ? ctx(out, global) : IS_PROTO && typeof out == 'function' ? ctx(Function.call, out) : out;\n // extend global\n if (target) redefine(target, key, out, type & $export.U);\n // export\n if (exports[key] != out) hide(exports, key, exp);\n if (IS_PROTO && expProto[key] != out) expProto[key] = out;\n }\n};\nglobal.core = core;\n// type bitmap\n$export.F = 1; // forced\n$export.G = 2; // global\n$export.S = 4; // static\n$export.P = 8; // proto\n$export.B = 16; // bind\n$export.W = 32; // wrap\n$export.U = 64; // safe\n$export.R = 128; // real proto method for `library`\nmodule.exports = $export;\n","var isObject = require('./_is-object');\nmodule.exports = function (it) {\n if (!isObject(it)) throw TypeError(it + ' is not an object!');\n return it;\n};\n","var g;\n\n// This works in non-strict mode\ng = (function() {\n\treturn this;\n})();\n\ntry {\n\t// This works if eval is allowed (see CSP)\n\tg = g || new Function(\"return this\")();\n} catch (e) {\n\t// This works if the window reference is available\n\tif (typeof window === \"object\") g = window;\n}\n\n// g can still be undefined, but nothing to do about it...\n// We return undefined, instead of nothing here, so it's\n// easier to handle this case. if(!global) { ...}\n\nmodule.exports = g;\n","/**\n * Checks if `value` is classified as an `Array` object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an array, else `false`.\n * @example\n *\n * _.isArray([1, 2, 3]);\n * // => true\n *\n * _.isArray(document.body.children);\n * // => false\n *\n * _.isArray('abc');\n * // => false\n *\n * _.isArray(_.noop);\n * // => false\n */\nvar isArray = Array.isArray;\n\nmodule.exports = isArray;\n","/**\n * Copyright (c) 2013-present, Facebook, Inc.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n *\n */\n\n'use strict';\n\nvar canUseDOM = !!(typeof window !== 'undefined' && window.document && window.document.createElement);\n\n/**\n * Simple, lightweight module assisting with the detection and context of\n * Worker. Helps avoid circular dependencies and allows code to reason about\n * whether or not they are in a Worker, even if they never include the main\n * `ReactWorker` dependency.\n */\nvar ExecutionEnvironment = {\n\n canUseDOM: canUseDOM,\n\n canUseWorkers: typeof Worker !== 'undefined',\n\n canUseEventListeners: canUseDOM && !!(window.addEventListener || window.attachEvent),\n\n canUseViewport: canUseDOM && !!window.screen,\n\n isInWorker: !canUseDOM // For now, this is true - might change in the future.\n\n};\n\nmodule.exports = ExecutionEnvironment;","var _Object$getOwnPropertySymbols = require(\"../core-js/object/get-own-property-symbols\");\n\nvar objectWithoutPropertiesLoose = require(\"./objectWithoutPropertiesLoose\");\n\nfunction _objectWithoutProperties(source, excluded) {\n if (source == null) return {};\n var target = objectWithoutPropertiesLoose(source, excluded);\n var key, i;\n\n if (_Object$getOwnPropertySymbols) {\n var sourceSymbolKeys = _Object$getOwnPropertySymbols(source);\n\n for (i = 0; i < sourceSymbolKeys.length; i++) {\n key = sourceSymbolKeys[i];\n if (excluded.indexOf(key) >= 0) continue;\n if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue;\n target[key] = source[key];\n }\n }\n\n return target;\n}\n\nmodule.exports = _objectWithoutProperties;","// https://github.com/zloirock/core-js/issues/86#issuecomment-115759028\nvar global = module.exports = typeof window != 'undefined' && window.Math == Math\n ? window : typeof self != 'undefined' && self.Math == Math ? self\n // eslint-disable-next-line no-new-func\n : Function('return this')();\nif (typeof __g == 'number') __g = global; // eslint-disable-line no-undef\n","var $export = require('./_export');\nvar fails = require('./_fails');\nvar defined = require('./_defined');\nvar quot = /\"/g;\n// B.2.3.2.1 CreateHTML(string, tag, attribute, value)\nvar createHTML = function (string, tag, attribute, value) {\n var S = String(defined(string));\n var p1 = '<' + tag;\n if (attribute !== '') p1 += ' ' + attribute + '=\"' + String(value).replace(quot, '"') + '\"';\n return p1 + '>' + S + '';\n};\nmodule.exports = function (NAME, exec) {\n var O = {};\n O[NAME] = exec(createHTML);\n $export($export.P + $export.F * fails(function () {\n var test = ''[NAME]('\"');\n return test !== test.toLowerCase() || test.split('\"').length > 3;\n }), 'String', O);\n};\n","import serializeError from \"serialize-error\"\n\nexport const NEW_THROWN_ERR = \"err_new_thrown_err\"\nexport const NEW_THROWN_ERR_BATCH = \"err_new_thrown_err_batch\"\nexport const NEW_SPEC_ERR = \"err_new_spec_err\"\nexport const NEW_SPEC_ERR_BATCH = \"err_new_spec_err_batch\"\nexport const NEW_AUTH_ERR = \"err_new_auth_err\"\nexport const CLEAR = \"err_clear\"\nexport const CLEAR_BY = \"err_clear_by\"\n\nexport function newThrownErr(err) {\n return {\n type: NEW_THROWN_ERR,\n payload: serializeError(err)\n }\n}\n\nexport function newThrownErrBatch(errors) {\n return {\n type: NEW_THROWN_ERR_BATCH,\n payload: errors\n }\n}\n\nexport function newSpecErr(err) {\n return {\n type: NEW_SPEC_ERR,\n payload: err\n }\n}\n\nexport function newSpecErrBatch(errArray) {\n return {\n type: NEW_SPEC_ERR_BATCH,\n payload: errArray\n }\n}\n\nexport function newAuthErr(err) {\n return {\n type: NEW_AUTH_ERR,\n payload: err\n }\n}\n\nexport function clear(filter = {}) {\n // filter looks like: {type: 'spec'}, {source: 'parser'}\n return {\n type: CLEAR,\n payload: filter\n }\n}\n\nexport function clearBy(filter = () => true) {\n // filter is a function\n return {\n type: CLEAR_BY,\n payload: filter\n }\n}\n","var isObject = require('./_is-object');\nmodule.exports = function (it) {\n if (!isObject(it)) throw TypeError(it + ' is not an object!');\n return it;\n};\n","if (typeof Object.create === 'function') {\n // implementation from standard node.js 'util' module\n module.exports = function inherits(ctor, superCtor) {\n ctor.super_ = superCtor\n ctor.prototype = Object.create(superCtor.prototype, {\n constructor: {\n value: ctor,\n enumerable: false,\n writable: true,\n configurable: true\n }\n });\n };\n} else {\n // old school shim for old browsers\n module.exports = function inherits(ctor, superCtor) {\n ctor.super_ = superCtor\n var TempCtor = function () {}\n TempCtor.prototype = superCtor.prototype\n ctor.prototype = new TempCtor()\n ctor.prototype.constructor = ctor\n }\n}\n","/* eslint-disable node/no-deprecated-api */\nvar buffer = require('buffer')\nvar Buffer = buffer.Buffer\n\n// alternative to using Object.keys for old browsers\nfunction copyProps (src, dst) {\n for (var key in src) {\n dst[key] = src[key]\n }\n}\nif (Buffer.from && Buffer.alloc && Buffer.allocUnsafe && Buffer.allocUnsafeSlow) {\n module.exports = buffer\n} else {\n // Copy properties from require('buffer')\n copyProps(buffer, exports)\n exports.Buffer = SafeBuffer\n}\n\nfunction SafeBuffer (arg, encodingOrOffset, length) {\n return Buffer(arg, encodingOrOffset, length)\n}\n\n// Copy static methods from Buffer\ncopyProps(Buffer, SafeBuffer)\n\nSafeBuffer.from = function (arg, encodingOrOffset, length) {\n if (typeof arg === 'number') {\n throw new TypeError('Argument must not be a number')\n }\n return Buffer(arg, encodingOrOffset, length)\n}\n\nSafeBuffer.alloc = function (size, fill, encoding) {\n if (typeof size !== 'number') {\n throw new TypeError('Argument must be a number')\n }\n var buf = Buffer(size)\n if (fill !== undefined) {\n if (typeof encoding === 'string') {\n buf.fill(fill, encoding)\n } else {\n buf.fill(fill)\n }\n } else {\n buf.fill(0)\n }\n return buf\n}\n\nSafeBuffer.allocUnsafe = function (size) {\n if (typeof size !== 'number') {\n throw new TypeError('Argument must be a number')\n }\n return Buffer(size)\n}\n\nSafeBuffer.allocUnsafeSlow = function (size) {\n if (typeof size !== 'number') {\n throw new TypeError('Argument must be a number')\n }\n return buffer.SlowBuffer(size)\n}\n","var anObject = require('./_an-object');\nvar IE8_DOM_DEFINE = require('./_ie8-dom-define');\nvar toPrimitive = require('./_to-primitive');\nvar dP = Object.defineProperty;\n\nexports.f = require('./_descriptors') ? Object.defineProperty : function defineProperty(O, P, Attributes) {\n anObject(O);\n P = toPrimitive(P, true);\n anObject(Attributes);\n if (IE8_DOM_DEFINE) try {\n return dP(O, P, Attributes);\n } catch (e) { /* empty */ }\n if ('get' in Attributes || 'set' in Attributes) throw TypeError('Accessors not supported!');\n if ('value' in Attributes) O[P] = Attributes.value;\n return O;\n};\n","// Thank's IE8 for his funny defineProperty\nmodule.exports = !require('./_fails')(function () {\n return Object.defineProperty({}, 'a', { get: function () { return 7; } }).a != 7;\n});\n","var freeGlobal = require('./_freeGlobal');\n\n/** Detect free variable `self`. */\nvar freeSelf = typeof self == 'object' && self && self.Object === Object && self;\n\n/** Used as a reference to the global object. */\nvar root = freeGlobal || freeSelf || Function('return this')();\n\nmodule.exports = root;\n","/**\n * Checks if `value` is the\n * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)\n * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an object, else `false`.\n * @example\n *\n * _.isObject({});\n * // => true\n *\n * _.isObject([1, 2, 3]);\n * // => true\n *\n * _.isObject(_.noop);\n * // => true\n *\n * _.isObject(null);\n * // => false\n */\nfunction isObject(value) {\n var type = typeof value;\n return value != null && (type == 'object' || type == 'function');\n}\n\nmodule.exports = isObject;\n","/**\n * Copyright (c) 2016-present, Facebook, Inc.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n *\n * \n */\n\n'use strict';\n\n// Trust the developer to only use ReactInstrumentation with a __DEV__ check\n\nvar debugTool = null;\n\nif (process.env.NODE_ENV !== 'production') {\n var ReactDebugTool = require('./ReactDebugTool');\n debugTool = ReactDebugTool;\n}\n\nmodule.exports = { debugTool: debugTool };","module.exports = require(\"core-js/library/fn/object/define-property\");","module.exports = require(\"core-js/library/fn/object/get-own-property-descriptor\");","module.exports = require(\"core-js/library/fn/object/get-own-property-symbols\");","// Actions conform to FSA (flux-standard-actions)\n// {type: string,payload: Any|Error, meta: obj, error: bool}\n\nexport const UPDATE_SELECTED_SERVER = \"oas3_set_servers\"\nexport const UPDATE_REQUEST_BODY_VALUE = \"oas3_set_request_body_value\"\nexport const UPDATE_REQUEST_BODY_INCLUSION = \"oas3_set_request_body_inclusion\"\nexport const UPDATE_ACTIVE_EXAMPLES_MEMBER = \"oas3_set_active_examples_member\"\nexport const UPDATE_REQUEST_CONTENT_TYPE = \"oas3_set_request_content_type\"\nexport const UPDATE_RESPONSE_CONTENT_TYPE = \"oas3_set_response_content_type\"\nexport const UPDATE_SERVER_VARIABLE_VALUE = \"oas3_set_server_variable_value\"\n\nexport function setSelectedServer (selectedServerUrl, namespace) {\n return {\n type: UPDATE_SELECTED_SERVER,\n payload: {selectedServerUrl, namespace}\n }\n}\n\nexport function setRequestBodyValue ({ value, pathMethod }) {\n return {\n type: UPDATE_REQUEST_BODY_VALUE,\n payload: { value, pathMethod }\n }\n}\n\nexport function setRequestBodyInclusion ({ value, pathMethod, name }) {\n return {\n type: UPDATE_REQUEST_BODY_INCLUSION,\n payload: { value, pathMethod, name }\n }\n}\n\nexport function setActiveExamplesMember ({ name, pathMethod, contextType, contextName }) {\n return {\n type: UPDATE_ACTIVE_EXAMPLES_MEMBER,\n payload: { name, pathMethod, contextType, contextName }\n }\n}\n\nexport function setRequestContentType ({ value, pathMethod }) {\n return {\n type: UPDATE_REQUEST_CONTENT_TYPE,\n payload: { value, pathMethod }\n }\n}\n\nexport function setResponseContentType ({ value, path, method }) {\n return {\n type: UPDATE_RESPONSE_CONTENT_TYPE,\n payload: { value, path, method }\n }\n}\n\nexport function setServerVariableValue ({ server, namespace, key, val }) {\n return {\n type: UPDATE_SERVER_VARIABLE_VALUE,\n payload: { server, namespace, key, val }\n }\n}\n","module.exports =\n/******/ (function(modules) { // webpackBootstrap\n/******/ \t// The module cache\n/******/ \tvar installedModules = {};\n/******/\n/******/ \t// The require function\n/******/ \tfunction __webpack_require__(moduleId) {\n/******/\n/******/ \t\t// Check if module is in cache\n/******/ \t\tif(installedModules[moduleId]) {\n/******/ \t\t\treturn installedModules[moduleId].exports;\n/******/ \t\t}\n/******/ \t\t// Create a new module (and put it into the cache)\n/******/ \t\tvar module = installedModules[moduleId] = {\n/******/ \t\t\ti: moduleId,\n/******/ \t\t\tl: false,\n/******/ \t\t\texports: {}\n/******/ \t\t};\n/******/\n/******/ \t\t// Execute the module function\n/******/ \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n/******/\n/******/ \t\t// Flag the module as loaded\n/******/ \t\tmodule.l = true;\n/******/\n/******/ \t\t// Return the exports of the module\n/******/ \t\treturn module.exports;\n/******/ \t}\n/******/\n/******/\n/******/ \t// expose the modules object (__webpack_modules__)\n/******/ \t__webpack_require__.m = modules;\n/******/\n/******/ \t// expose the module cache\n/******/ \t__webpack_require__.c = installedModules;\n/******/\n/******/ \t// define getter function for harmony exports\n/******/ \t__webpack_require__.d = function(exports, name, getter) {\n/******/ \t\tif(!__webpack_require__.o(exports, name)) {\n/******/ \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n/******/ \t\t}\n/******/ \t};\n/******/\n/******/ \t// define __esModule on exports\n/******/ \t__webpack_require__.r = function(exports) {\n/******/ \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n/******/ \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n/******/ \t\t}\n/******/ \t\tObject.defineProperty(exports, '__esModule', { value: true });\n/******/ \t};\n/******/\n/******/ \t// create a fake namespace object\n/******/ \t// mode & 1: value is a module id, require it\n/******/ \t// mode & 2: merge all properties of value into the ns\n/******/ \t// mode & 4: return value when already ns object\n/******/ \t// mode & 8|1: behave like require\n/******/ \t__webpack_require__.t = function(value, mode) {\n/******/ \t\tif(mode & 1) value = __webpack_require__(value);\n/******/ \t\tif(mode & 8) return value;\n/******/ \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n/******/ \t\tvar ns = Object.create(null);\n/******/ \t\t__webpack_require__.r(ns);\n/******/ \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n/******/ \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n/******/ \t\treturn ns;\n/******/ \t};\n/******/\n/******/ \t// getDefaultExport function for compatibility with non-harmony modules\n/******/ \t__webpack_require__.n = function(module) {\n/******/ \t\tvar getter = module && module.__esModule ?\n/******/ \t\t\tfunction getDefault() { return module['default']; } :\n/******/ \t\t\tfunction getModuleExports() { return module; };\n/******/ \t\t__webpack_require__.d(getter, 'a', getter);\n/******/ \t\treturn getter;\n/******/ \t};\n/******/\n/******/ \t// Object.prototype.hasOwnProperty.call\n/******/ \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n/******/\n/******/ \t// __webpack_public_path__\n/******/ \t__webpack_require__.p = \"\";\n/******/\n/******/\n/******/ \t// Load entry module and return exports\n/******/ \treturn __webpack_require__(__webpack_require__.s = 58);\n/******/ })\n/************************************************************************/\n/******/ ([\n/* 0 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"@babel/runtime-corejs2/core-js/object/keys\");\n\n/***/ }),\n/* 1 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"@babel/runtime-corejs2/core-js/array/is-array\");\n\n/***/ }),\n/* 2 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"@babel/runtime-corejs2/helpers/typeof\");\n\n/***/ }),\n/* 3 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"@babel/runtime-corejs2/core-js/object/assign\");\n\n/***/ }),\n/* 4 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"@babel/runtime-corejs2/regenerator\");\n\n/***/ }),\n/* 5 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"@babel/runtime-corejs2/core-js/object/get-own-property-descriptors\");\n\n/***/ }),\n/* 6 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"@babel/runtime-corejs2/core-js/object/get-own-property-descriptor\");\n\n/***/ }),\n/* 7 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"@babel/runtime-corejs2/core-js/object/get-own-property-symbols\");\n\n/***/ }),\n/* 8 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"@babel/runtime-corejs2/helpers/defineProperty\");\n\n/***/ }),\n/* 9 */\n/***/ (function(module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\n/* WEBPACK VAR INJECTION */(function(Buffer) {/* unused harmony export self */\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"a\", function() { return http; });\n/* unused harmony export shouldDownloadAsText */\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"e\", function() { return serializeRes; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"d\", function() { return serializeHeaders; });\n/* unused harmony export isFile */\n/* unused harmony export encodeFormOrQuery */\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"c\", function() { return mergeInQueryOrForm; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"b\", function() { return makeHttp; });\n/* harmony import */ var _babel_runtime_corejs2_core_js_get_iterator__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(22);\n/* harmony import */ var _babel_runtime_corejs2_core_js_get_iterator__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_corejs2_core_js_get_iterator__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _babel_runtime_corejs2_core_js_symbol_iterator__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(23);\n/* harmony import */ var _babel_runtime_corejs2_core_js_symbol_iterator__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_corejs2_core_js_symbol_iterator__WEBPACK_IMPORTED_MODULE_1__);\n/* harmony import */ var _babel_runtime_corejs2_core_js_symbol__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(24);\n/* harmony import */ var _babel_runtime_corejs2_core_js_symbol__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_corejs2_core_js_symbol__WEBPACK_IMPORTED_MODULE_2__);\n/* harmony import */ var _babel_runtime_corejs2_regenerator__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(4);\n/* harmony import */ var _babel_runtime_corejs2_regenerator__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_corejs2_regenerator__WEBPACK_IMPORTED_MODULE_3__);\n/* harmony import */ var _babel_runtime_corejs2_core_js_object_entries__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(40);\n/* harmony import */ var _babel_runtime_corejs2_core_js_object_entries__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_corejs2_core_js_object_entries__WEBPACK_IMPORTED_MODULE_4__);\n/* harmony import */ var _babel_runtime_corejs2_core_js_object_keys__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(0);\n/* harmony import */ var _babel_runtime_corejs2_core_js_object_keys__WEBPACK_IMPORTED_MODULE_5___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_corejs2_core_js_object_keys__WEBPACK_IMPORTED_MODULE_5__);\n/* harmony import */ var _babel_runtime_corejs2_core_js_json_stringify__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(13);\n/* harmony import */ var _babel_runtime_corejs2_core_js_json_stringify__WEBPACK_IMPORTED_MODULE_6___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_corejs2_core_js_json_stringify__WEBPACK_IMPORTED_MODULE_6__);\n/* harmony import */ var _babel_runtime_corejs2_core_js_array_is_array__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(1);\n/* harmony import */ var _babel_runtime_corejs2_core_js_array_is_array__WEBPACK_IMPORTED_MODULE_7___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_corejs2_core_js_array_is_array__WEBPACK_IMPORTED_MODULE_7__);\n/* harmony import */ var _babel_runtime_corejs2_helpers_typeof__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(2);\n/* harmony import */ var _babel_runtime_corejs2_helpers_typeof__WEBPACK_IMPORTED_MODULE_8___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_corejs2_helpers_typeof__WEBPACK_IMPORTED_MODULE_8__);\n/* harmony import */ var _babel_runtime_corejs2_helpers_slicedToArray__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(18);\n/* harmony import */ var _babel_runtime_corejs2_helpers_slicedToArray__WEBPACK_IMPORTED_MODULE_9___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_corejs2_helpers_slicedToArray__WEBPACK_IMPORTED_MODULE_9__);\n/* harmony import */ var _babel_runtime_corejs2_core_js_array_from__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(20);\n/* harmony import */ var _babel_runtime_corejs2_core_js_array_from__WEBPACK_IMPORTED_MODULE_10___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_corejs2_core_js_array_from__WEBPACK_IMPORTED_MODULE_10__);\n/* harmony import */ var _babel_runtime_corejs2_helpers_asyncToGenerator__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(25);\n/* harmony import */ var _babel_runtime_corejs2_helpers_asyncToGenerator__WEBPACK_IMPORTED_MODULE_11___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_corejs2_helpers_asyncToGenerator__WEBPACK_IMPORTED_MODULE_11__);\n/* harmony import */ var cross_fetch_polyfill__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(65);\n/* harmony import */ var cross_fetch_polyfill__WEBPACK_IMPORTED_MODULE_12___default = /*#__PURE__*/__webpack_require__.n(cross_fetch_polyfill__WEBPACK_IMPORTED_MODULE_12__);\n/* harmony import */ var qs__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(34);\n/* harmony import */ var qs__WEBPACK_IMPORTED_MODULE_13___default = /*#__PURE__*/__webpack_require__.n(qs__WEBPACK_IMPORTED_MODULE_13__);\n/* harmony import */ var js_yaml__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(33);\n/* harmony import */ var js_yaml__WEBPACK_IMPORTED_MODULE_14___default = /*#__PURE__*/__webpack_require__.n(js_yaml__WEBPACK_IMPORTED_MODULE_14__);\n/* harmony import */ var lodash_pick__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(26);\n/* harmony import */ var lodash_pick__WEBPACK_IMPORTED_MODULE_15___default = /*#__PURE__*/__webpack_require__.n(lodash_pick__WEBPACK_IMPORTED_MODULE_15__);\n/* harmony import */ var lodash_isFunction__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(21);\n/* harmony import */ var lodash_isFunction__WEBPACK_IMPORTED_MODULE_16___default = /*#__PURE__*/__webpack_require__.n(lodash_isFunction__WEBPACK_IMPORTED_MODULE_16__);\n/* harmony import */ var _internal_form_data_monkey_patch__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(41);\n/* harmony import */ var _execute_oas3_style_serializer__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(19);\nfunction _createForOfIteratorHelper(o) {if (typeof _babel_runtime_corejs2_core_js_symbol__WEBPACK_IMPORTED_MODULE_2___default.a === \"undefined\" || o[_babel_runtime_corejs2_core_js_symbol_iterator__WEBPACK_IMPORTED_MODULE_1___default.a] == null) {if (_babel_runtime_corejs2_core_js_array_is_array__WEBPACK_IMPORTED_MODULE_7___default()(o) || (o = _unsupportedIterableToArray(o))) {var i = 0;var F = function F() {};return { s: F, n: function n() {if (i >= o.length) return { done: true };return { done: false, value: o[i++] };}, e: function e(_e) {throw _e;}, f: F };}throw new TypeError(\"Invalid attempt to iterate non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.\");}var it,normalCompletion = true,didErr = false,err;return { s: function s() {it = _babel_runtime_corejs2_core_js_get_iterator__WEBPACK_IMPORTED_MODULE_0___default()(o);}, n: function n() {var step = it.next();normalCompletion = step.done;return step;}, e: function e(_e2) {didErr = true;err = _e2;}, f: function f() {try {if (!normalCompletion && it.return != null) it.return();} finally {if (didErr) throw err;}} };}function _unsupportedIterableToArray(o, minLen) {if (!o) return;if (typeof o === \"string\") return _arrayLikeToArray(o, minLen);var n = Object.prototype.toString.call(o).slice(8, -1);if (n === \"Object\" && o.constructor) n = o.constructor.name;if (n === \"Map\" || n === \"Set\") return _babel_runtime_corejs2_core_js_array_from__WEBPACK_IMPORTED_MODULE_10___default()(n);if (n === \"Arguments\" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);}function _arrayLikeToArray(arr, len) {if (len == null || len > arr.length) len = arr.length;for (var i = 0, arr2 = new Array(len); i < len; i++) {arr2[i] = arr[i];}return arr2;} /* global fetch */\n\n\n\n\n\n\n\n\n// For testing\nvar self = {\n serializeRes: serializeRes,\n mergeInQueryOrForm: mergeInQueryOrForm };\n\n\n// Handles fetch-like syntax and the case where there is only one object passed-in\n// (which will have the URL as a property). Also serilizes the response.\nfunction http(_x) {return _http.apply(this, arguments);}\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n// exported for testing\nfunction _http() {_http = _babel_runtime_corejs2_helpers_asyncToGenerator__WEBPACK_IMPORTED_MODULE_11___default()( /*#__PURE__*/_babel_runtime_corejs2_regenerator__WEBPACK_IMPORTED_MODULE_3___default.a.mark(function _callee(url) {var request,contentType,res,error,_error,_args = arguments;return _babel_runtime_corejs2_regenerator__WEBPACK_IMPORTED_MODULE_3___default.a.wrap(function _callee$(_context) {while (1) {switch (_context.prev = _context.next) {case 0:request = _args.length > 1 && _args[1] !== undefined ? _args[1] : {};if (_babel_runtime_corejs2_helpers_typeof__WEBPACK_IMPORTED_MODULE_8___default()(url) === 'object') {request = url;url = request.url;}request.headers = request.headers || {}; // Serializes query, for convenience\n // Should be the last thing we do, as its hard to mutate the URL with\n // the search string, but much easier to manipulate the req.query object\n self.mergeInQueryOrForm(request); // Newlines in header values cause weird error messages from `window.fetch`,\n // so let's massage them out.\n // Context: https://stackoverflow.com/a/50709178\n if (request.headers) {_babel_runtime_corejs2_core_js_object_keys__WEBPACK_IMPORTED_MODULE_5___default()(request.headers).forEach(function (headerName) {var value = request.headers[headerName];if (typeof value === 'string') {request.headers[headerName] = value.replace(/\\n+/g, ' ');}});} // Wait for the request interceptor, if it was provided\n // WARNING: don't put anything between this and the request firing unless\n // you have a good reason!\n if (!request.requestInterceptor) {_context.next = 12;break;}_context.next = 8;return request.requestInterceptor(request);case 8:_context.t0 = _context.sent;if (_context.t0) {_context.next = 11;break;}_context.t0 = request;case 11:request = _context.t0;case 12: // for content-type=multipart\\/form-data remove content-type from request before fetch\n // so that correct one with `boundary` is set\n contentType = request.headers['content-type'] || request.headers['Content-Type'];if (/multipart\\/form-data/i.test(contentType)) {delete request.headers['content-type'];delete request.headers['Content-Type'];} // eslint-disable-next-line no-undef\n _context.prev = 14;_context.next = 17;return (request.userFetch || fetch)(request.url, request);case 17:res = _context.sent;_context.next = 20;return self.serializeRes(res, url, request);case 20:res = _context.sent;if (!request.responseInterceptor) {_context.next = 28;break;}_context.next = 24;return request.responseInterceptor(res);case 24:_context.t1 = _context.sent;if (_context.t1) {_context.next = 27;break;}_context.t1 = res;case 27:res = _context.t1;case 28:_context.next = 38;break;case 30:_context.prev = 30;_context.t2 = _context[\"catch\"](14);if (res) {_context.next = 34;break;}throw _context.t2;case 34:error = new Error(res.statusText);error.statusCode = error.status = res.status;error.responseError = _context.t2;throw error;case 38:if (res.ok) {_context.next = 43;break;}_error = new Error(res.statusText);_error.statusCode = _error.status = res.status;_error.response = res;throw _error;case 43:return _context.abrupt(\"return\", res);case 44:case \"end\":return _context.stop();}}}, _callee, null, [[14, 30]]);}));return _http.apply(this, arguments);}var shouldDownloadAsText = function shouldDownloadAsText() {var contentType = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';return /(json|xml|yaml|text)\\b/.test(contentType);};function parseBody(body, contentType) {if (contentType && (contentType.indexOf('application/json') === 0 || contentType.indexOf('+json') > 0)) {return JSON.parse(body);}return js_yaml__WEBPACK_IMPORTED_MODULE_14___default.a.safeLoad(body);} // Serialize the response, returns a promise with headers and the body part of the hash\nfunction serializeRes(oriRes, url) {var _ref = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {},_ref$loadSpec = _ref.loadSpec,loadSpec = _ref$loadSpec === void 0 ? false : _ref$loadSpec;var res = { ok: oriRes.ok, url: oriRes.url || url,\n status: oriRes.status,\n statusText: oriRes.statusText,\n headers: serializeHeaders(oriRes.headers) };\n\n var contentType = res.headers['content-type'];\n var useText = loadSpec || shouldDownloadAsText(contentType);\n var getBody = useText ? oriRes.text : oriRes.blob || oriRes.buffer;\n return getBody.call(oriRes).then(function (body) {\n res.text = body;\n res.data = body;\n if (useText) {\n try {\n var obj = parseBody(body, contentType);\n res.body = obj;\n res.obj = obj;\n }\n catch (e) {\n res.parseError = e;\n }\n }\n return res;\n });\n}\n\nfunction serializeHeaderValue(value) {\n var isMulti = value.includes(', ');\n\n return isMulti ? value.split(', ') : value;\n}\n\n// Serialize headers into a hash, where mutliple-headers result in an array.\n//\n// eg: Cookie: one\n// Cookie: two\n// = { Cookie: [ \"one\", \"two\" ]\nfunction serializeHeaders() {var headers = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n if (!lodash_isFunction__WEBPACK_IMPORTED_MODULE_16___default()(headers.entries)) return {};\n\n return _babel_runtime_corejs2_core_js_array_from__WEBPACK_IMPORTED_MODULE_10___default()(\n headers.entries()).\n reduce(function (acc, _ref2) {var _ref3 = _babel_runtime_corejs2_helpers_slicedToArray__WEBPACK_IMPORTED_MODULE_9___default()(_ref2, 2),header = _ref3[0],value = _ref3[1];\n acc[header] = serializeHeaderValue(value);\n return acc;\n }, {});\n}\n\nfunction isFile(obj, navigatorObj) {\n if (!navigatorObj && typeof navigator !== 'undefined') {\n // eslint-disable-next-line no-undef\n navigatorObj = navigator;\n }\n if (navigatorObj && navigatorObj.product === 'ReactNative') {\n if (obj && _babel_runtime_corejs2_helpers_typeof__WEBPACK_IMPORTED_MODULE_8___default()(obj) === 'object' && typeof obj.uri === 'string') {\n return true;\n }\n return false;\n }\n\n if (typeof File !== 'undefined' && obj instanceof File) {// eslint-disable-line no-undef\n return true;\n }\n if (typeof Blob !== 'undefined' && obj instanceof Blob) {// eslint-disable-line no-undef\n return true;\n }\n if (typeof Buffer !== 'undefined' && obj instanceof Buffer) {\n return true;\n }\n\n return obj !== null && _babel_runtime_corejs2_helpers_typeof__WEBPACK_IMPORTED_MODULE_8___default()(obj) === 'object' && typeof obj.pipe === 'function';\n}\n\nfunction isArrayOfFile(obj, navigatorObj) {\n return _babel_runtime_corejs2_core_js_array_is_array__WEBPACK_IMPORTED_MODULE_7___default()(obj) && obj.some(function (v) {return isFile(v, navigatorObj);});\n}\n\nvar STYLE_SEPARATORS = {\n form: ',',\n spaceDelimited: '%20',\n pipeDelimited: '|' };\n\n\nvar SEPARATORS = {\n csv: ',',\n ssv: '%20',\n tsv: '%09',\n pipes: '|' };\n\n\n// Formats a key-value and returns an array of key-value pairs.\n//\n// Return value example 1: [['color', 'blue']]\n// Return value example 2: [['color', 'blue,black,brown']]\n// Return value example 3: [['color', ['blue', 'black', 'brown']]]\n// Return value example 4: [['color', 'R,100,G,200,B,150']]\n// Return value example 5: [['R', '100'], ['G', '200'], ['B', '150']]\n// Return value example 6: [['color[R]', '100'], ['color[G]', '200'], ['color[B]', '150']]\nfunction formatKeyValue(key, input) {var skipEncoding = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;var\n collectionFormat = input.collectionFormat,allowEmptyValue = input.allowEmptyValue,serializationOption = input.serializationOption,encoding = input.encoding;\n // `input` can be string\n var value = _babel_runtime_corejs2_helpers_typeof__WEBPACK_IMPORTED_MODULE_8___default()(input) === 'object' && !_babel_runtime_corejs2_core_js_array_is_array__WEBPACK_IMPORTED_MODULE_7___default()(input) ? input.value : input;\n var encodeFn = skipEncoding ? function (k) {return k.toString();} : function (k) {return encodeURIComponent(k);};\n var encodedKey = encodeFn(key);\n\n if (typeof value === 'undefined' && allowEmptyValue) {\n return [[encodedKey, '']];\n }\n\n // file\n if (isFile(value) || isArrayOfFile(value)) {\n return [[encodedKey, value]];\n }\n\n // for OAS 3 Parameter Object for serialization\n if (serializationOption) {\n return formatKeyValueBySerializationOption(key, value, skipEncoding, serializationOption);\n }\n\n // for OAS 3 Encoding Object\n if (encoding) {\n if ([_babel_runtime_corejs2_helpers_typeof__WEBPACK_IMPORTED_MODULE_8___default()(encoding.style), _babel_runtime_corejs2_helpers_typeof__WEBPACK_IMPORTED_MODULE_8___default()(encoding.explode), _babel_runtime_corejs2_helpers_typeof__WEBPACK_IMPORTED_MODULE_8___default()(encoding.allowReserved)].some(function (type) {return type !== 'undefined';})) {\n return formatKeyValueBySerializationOption(key, value, skipEncoding, lodash_pick__WEBPACK_IMPORTED_MODULE_15___default()(encoding, ['style', 'explode', 'allowReserved']));\n }\n\n if (encoding.contentType) {\n if (encoding.contentType === 'application/json') {\n // If value is a string, assume value is already a JSON string\n var json = typeof value === 'string' ? value : _babel_runtime_corejs2_core_js_json_stringify__WEBPACK_IMPORTED_MODULE_6___default()(value);\n return [[encodedKey, encodeFn(json)]];\n }\n return [[encodedKey, encodeFn(value.toString())]];\n }\n\n // Primitive\n if (_babel_runtime_corejs2_helpers_typeof__WEBPACK_IMPORTED_MODULE_8___default()(value) !== 'object') {\n return [[encodedKey, encodeFn(value)]];\n }\n\n // Array of primitives\n if (_babel_runtime_corejs2_core_js_array_is_array__WEBPACK_IMPORTED_MODULE_7___default()(value) && value.every(function (v) {return _babel_runtime_corejs2_helpers_typeof__WEBPACK_IMPORTED_MODULE_8___default()(v) !== 'object';})) {\n return [[encodedKey, value.map(encodeFn).join(',')]];\n }\n\n // Array or object\n return [[encodedKey, encodeFn(_babel_runtime_corejs2_core_js_json_stringify__WEBPACK_IMPORTED_MODULE_6___default()(value))]];\n }\n\n // for OAS 2 Parameter Object\n // Primitive\n if (_babel_runtime_corejs2_helpers_typeof__WEBPACK_IMPORTED_MODULE_8___default()(value) !== 'object') {\n return [[encodedKey, encodeFn(value)]];\n }\n\n // Array\n if (_babel_runtime_corejs2_core_js_array_is_array__WEBPACK_IMPORTED_MODULE_7___default()(value)) {\n if (collectionFormat === 'multi') {\n // In case of multipart/formdata, it is used as array.\n // Otherwise, the caller will convert it to a query by qs.stringify.\n return [[encodedKey, value.map(encodeFn)]];\n }\n\n return [[encodedKey, value.map(encodeFn).join(SEPARATORS[collectionFormat || 'csv'])]];\n }\n\n // Object\n return [[encodedKey, '']];\n}\n\nfunction formatKeyValueBySerializationOption(key, value, skipEncoding, serializationOption) {\n var style = serializationOption.style || 'form';\n var explode = typeof serializationOption.explode === 'undefined' ? style === 'form' : serializationOption.explode;\n // eslint-disable-next-line no-nested-ternary\n var escape = skipEncoding ? false : serializationOption && serializationOption.allowReserved ? 'unsafe' : 'reserved';\n var encodeFn = function encodeFn(v) {return Object(_execute_oas3_style_serializer__WEBPACK_IMPORTED_MODULE_18__[/* encodeDisallowedCharacters */ \"b\"])(v, { escape: escape });};\n var encodeKeyFn = skipEncoding ? function (k) {return k;} : function (k) {return Object(_execute_oas3_style_serializer__WEBPACK_IMPORTED_MODULE_18__[/* encodeDisallowedCharacters */ \"b\"])(k, { escape: escape });};\n\n // Primitive\n if (_babel_runtime_corejs2_helpers_typeof__WEBPACK_IMPORTED_MODULE_8___default()(value) !== 'object') {\n return [[encodeKeyFn(key), encodeFn(value)]];\n }\n\n // Array\n if (_babel_runtime_corejs2_core_js_array_is_array__WEBPACK_IMPORTED_MODULE_7___default()(value)) {\n if (explode) {\n // In case of multipart/formdata, it is used as array.\n // Otherwise, the caller will convert it to a query by qs.stringify.\n return [[encodeKeyFn(key), value.map(encodeFn)]];\n }\n return [[encodeKeyFn(key), value.map(encodeFn).join(STYLE_SEPARATORS[style])]];\n }\n\n // Object\n if (style === 'deepObject') {\n return _babel_runtime_corejs2_core_js_object_keys__WEBPACK_IMPORTED_MODULE_5___default()(value).map(function (valueKey) {return [encodeKeyFn(\"\".concat(key, \"[\").concat(valueKey, \"]\")), encodeFn(value[valueKey])];});\n }\n\n if (explode) {\n return _babel_runtime_corejs2_core_js_object_keys__WEBPACK_IMPORTED_MODULE_5___default()(value).map(function (valueKey) {return [encodeKeyFn(valueKey), encodeFn(value[valueKey])];});\n }\n\n return [[encodeKeyFn(key), _babel_runtime_corejs2_core_js_object_keys__WEBPACK_IMPORTED_MODULE_5___default()(value).map(function (valueKey) {return [\"\".concat(encodeKeyFn(valueKey), \",\").concat(encodeFn(value[valueKey]))];}).join(',')]];\n}\n\nfunction buildFormData(reqForm) {\n /**\n * Build a new FormData instance, support array as field value\n * OAS2.0 - when collectionFormat is multi\n * OAS3.0 - when explode of Encoding Object is true\n * @param {Object} reqForm - ori req.form\n * @return {FormData} - new FormData instance\n */\n return _babel_runtime_corejs2_core_js_object_entries__WEBPACK_IMPORTED_MODULE_4___default()(reqForm).reduce(function (formData, _ref4) {var _ref5 = _babel_runtime_corejs2_helpers_slicedToArray__WEBPACK_IMPORTED_MODULE_9___default()(_ref4, 2),name = _ref5[0],input = _ref5[1];var _iterator = _createForOfIteratorHelper(\n formatKeyValue(name, input, true)),_step;try {for (_iterator.s(); !(_step = _iterator.n()).done;) {var _ref8 = _step.value;var _ref7 = _babel_runtime_corejs2_helpers_slicedToArray__WEBPACK_IMPORTED_MODULE_9___default()(_ref8, 2);var key = _ref7[0];var value = _ref7[1];\n if (_babel_runtime_corejs2_core_js_array_is_array__WEBPACK_IMPORTED_MODULE_7___default()(value)) {var _iterator2 = _createForOfIteratorHelper(\n value),_step2;try {for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {var v = _step2.value;\n formData.append(key, v);\n }} catch (err) {_iterator2.e(err);} finally {_iterator2.f();}\n } else\n {\n formData.append(key, value);\n }\n }} catch (err) {_iterator.e(err);} finally {_iterator.f();}\n return formData;\n }, new _internal_form_data_monkey_patch__WEBPACK_IMPORTED_MODULE_17__[/* default */ \"a\"]());\n}\n\n// Encodes an object using appropriate serializer.\nfunction encodeFormOrQuery(data) {\n /**\n * Encode parameter names and values\n * @param {Object} result - parameter names and values\n * @param {string} parameterName - Parameter name\n * @return {object} encoded parameter names and values\n */\n var encodedQuery = _babel_runtime_corejs2_core_js_object_keys__WEBPACK_IMPORTED_MODULE_5___default()(data).reduce(function (result, parameterName) {var _iterator3 = _createForOfIteratorHelper(\n formatKeyValue(parameterName, data[parameterName])),_step3;try {for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {var _ref11 = _step3.value;var _ref10 = _babel_runtime_corejs2_helpers_slicedToArray__WEBPACK_IMPORTED_MODULE_9___default()(_ref11, 2);var key = _ref10[0];var value = _ref10[1];\n result[key] = value;\n }} catch (err) {_iterator3.e(err);} finally {_iterator3.f();}\n return result;\n }, {});\n return qs__WEBPACK_IMPORTED_MODULE_13___default.a.stringify(encodedQuery, { encode: false, indices: false }) || '';\n}\n\n// If the request has a `query` object, merge it into the request.url, and delete the object\n// If file and/or multipart, also create FormData instance\nfunction mergeInQueryOrForm() {var req = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};var _req$url =\n req.url,url = _req$url === void 0 ? '' : _req$url,query = req.query,form = req.form;\n var joinSearch = function joinSearch() {for (var _len = arguments.length, strs = new Array(_len), _key = 0; _key < _len; _key++) {strs[_key] = arguments[_key];}\n var search = strs.filter(function (a) {return a;}).join('&'); // Only truthy value\n return search ? \"?\".concat(search) : ''; // Only add '?' if there is a str\n };\n\n if (form) {\n var hasFile = _babel_runtime_corejs2_core_js_object_keys__WEBPACK_IMPORTED_MODULE_5___default()(form).some(function (key) {\n var value = form[key].value;\n return isFile(value) || isArrayOfFile(value);\n });\n\n var contentType = req.headers['content-type'] || req.headers['Content-Type'];\n\n if (hasFile || /multipart\\/form-data/i.test(contentType)) {\n req.body = buildFormData(req.form);\n } else\n {\n req.body = encodeFormOrQuery(form);\n }\n\n delete req.form;\n }\n\n if (query) {var _url$split =\n url.split('?'),_url$split2 = _babel_runtime_corejs2_helpers_slicedToArray__WEBPACK_IMPORTED_MODULE_9___default()(_url$split, 2),baseUrl = _url$split2[0],oriSearch = _url$split2[1];\n var newStr = '';\n\n if (oriSearch) {\n var oriQuery = qs__WEBPACK_IMPORTED_MODULE_13___default.a.parse(oriSearch);\n var keysToRemove = _babel_runtime_corejs2_core_js_object_keys__WEBPACK_IMPORTED_MODULE_5___default()(query);\n keysToRemove.forEach(function (key) {return delete oriQuery[key];});\n newStr = qs__WEBPACK_IMPORTED_MODULE_13___default.a.stringify(oriQuery, { encode: true });\n }\n\n var finalStr = joinSearch(newStr, encodeFormOrQuery(query));\n req.url = baseUrl + finalStr;\n delete req.query;\n }\n return req;\n}\n\n// Wrap a http function ( there are otherways to do this, consider this deprecated )\nfunction makeHttp(httpFn, preFetch, postFetch) {\n postFetch = postFetch || function (a) {return a;};\n preFetch = preFetch || function (a) {return a;};\n return function (req) {\n if (typeof req === 'string') {\n req = { url: req };\n }\n self.mergeInQueryOrForm(req);\n req = preFetch(req);\n return postFetch(httpFn(req));\n };\n}\n/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(60).Buffer))\n\n/***/ }),\n/* 10 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"@babel/runtime-corejs2/core-js/object/define-property\");\n\n/***/ }),\n/* 11 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"@babel/runtime-corejs2/core-js/object/define-properties\");\n\n/***/ }),\n/* 12 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"url\");\n\n/***/ }),\n/* 13 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"@babel/runtime-corejs2/core-js/json/stringify\");\n\n/***/ }),\n/* 14 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"@babel/runtime-corejs2/helpers/toConsumableArray\");\n\n/***/ }),\n/* 15 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"@babel/runtime-corejs2/core-js/promise\");\n\n/***/ }),\n/* 16 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"lodash/assign\");\n\n/***/ }),\n/* 17 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"lodash/get\");\n\n/***/ }),\n/* 18 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"@babel/runtime-corejs2/helpers/slicedToArray\");\n\n/***/ }),\n/* 19 */\n/***/ (function(module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"b\", function() { return encodeDisallowedCharacters; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"a\", function() { return stylize; });\n/* harmony import */ var _babel_runtime_corejs2_core_js_object_keys__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(0);\n/* harmony import */ var _babel_runtime_corejs2_core_js_object_keys__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_corejs2_core_js_object_keys__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _babel_runtime_corejs2_helpers_typeof__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(2);\n/* harmony import */ var _babel_runtime_corejs2_helpers_typeof__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_corejs2_helpers_typeof__WEBPACK_IMPORTED_MODULE_1__);\n/* harmony import */ var _babel_runtime_corejs2_core_js_array_is_array__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(1);\n/* harmony import */ var _babel_runtime_corejs2_core_js_array_is_array__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_corejs2_core_js_array_is_array__WEBPACK_IMPORTED_MODULE_2__);\n/* harmony import */ var encode_3986__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(66);\n/* harmony import */ var encode_3986__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(encode_3986__WEBPACK_IMPORTED_MODULE_3__);\n/* harmony import */ var utf8_bytes__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(46);\n/* harmony import */ var utf8_bytes__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(utf8_bytes__WEBPACK_IMPORTED_MODULE_4__);\n/* harmony import */ var utfstring__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(47);\n/* harmony import */ var utfstring__WEBPACK_IMPORTED_MODULE_5___default = /*#__PURE__*/__webpack_require__.n(utfstring__WEBPACK_IMPORTED_MODULE_5__);\n\n\n\n\nvar isRfc3986Reserved = function isRfc3986Reserved(char) {return ':/?#[]@!$&\\'()*+,;='.indexOf(char) > -1;};\nvar isRrc3986Unreserved = function isRrc3986Unreserved(char) {\n return /^[a-z0-9\\-._~]+$/i.test(char);\n};\n\nfunction encodeDisallowedCharacters(str) {var _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},escape = _ref.escape;var parse = arguments.length > 2 ? arguments[2] : undefined;\n if (typeof str === 'number') {\n str = str.toString();\n }\n if (typeof str !== 'string' || !str.length) {\n return str;\n }\n\n if (!escape) {\n return str;\n }\n\n if (parse) {\n return JSON.parse(str);\n }\n\n return Object(utfstring__WEBPACK_IMPORTED_MODULE_5__[\"stringToCharArray\"])(str).map(function (char) {\n if (isRrc3986Unreserved(char)) {\n return char;\n }\n\n if (isRfc3986Reserved(char) && escape === 'unsafe') {\n return char;\n }\n\n var encoded = (utf8_bytes__WEBPACK_IMPORTED_MODULE_4___default()(char) || []).\n map(function (byte) {return \"0\".concat(byte.toString(16).toUpperCase()).slice(-2);}).\n map(function (encodedByte) {return \"%\".concat(encodedByte);}).\n join('');\n\n return encoded;\n }).join('');\n}\n\nfunction stylize(config) {var\n value = config.value;\n\n if (_babel_runtime_corejs2_core_js_array_is_array__WEBPACK_IMPORTED_MODULE_2___default()(value)) {\n return encodeArray(config);\n } else\n if (_babel_runtime_corejs2_helpers_typeof__WEBPACK_IMPORTED_MODULE_1___default()(value) === 'object') {\n return encodeObject(config);\n }\n return encodePrimitive(config);\n}\n\nfunction encodeArray(_ref2) {var key = _ref2.key,value = _ref2.value,style = _ref2.style,explode = _ref2.explode,escape = _ref2.escape;\n var valueEncoder = function valueEncoder(str) {return encodeDisallowedCharacters(str, {\n escape: escape });};\n\n\n if (style === 'simple') {\n return value.map(function (val) {return valueEncoder(val);}).join(',');\n }\n\n if (style === 'label') {\n return \".\".concat(value.map(function (val) {return valueEncoder(val);}).join('.'));\n }\n\n if (style === 'matrix') {\n return value.map(function (val) {return valueEncoder(val);}).reduce(function (prev, curr) {\n if (!prev || explode) {\n return \"\".concat(prev || '', \";\").concat(key, \"=\").concat(curr);\n }\n return \"\".concat(prev, \",\").concat(curr);\n }, '');\n }\n\n if (style === 'form') {\n var after = explode ? \"&\".concat(key, \"=\") : ',';\n return value.map(function (val) {return valueEncoder(val);}).join(after);\n }\n\n if (style === 'spaceDelimited') {\n var _after = explode ? \"\".concat(key, \"=\") : '';\n return value.map(function (val) {return valueEncoder(val);}).join(\" \".concat(_after));\n }\n\n if (style === 'pipeDelimited') {\n var _after2 = explode ? \"\".concat(key, \"=\") : '';\n return value.map(function (val) {return valueEncoder(val);}).join(\"|\".concat(_after2));\n }\n}\n\nfunction encodeObject(_ref3) {var key = _ref3.key,value = _ref3.value,style = _ref3.style,explode = _ref3.explode,escape = _ref3.escape;\n var valueEncoder = function valueEncoder(str) {return encodeDisallowedCharacters(str, {\n escape: escape });};\n\n\n var valueKeys = _babel_runtime_corejs2_core_js_object_keys__WEBPACK_IMPORTED_MODULE_0___default()(value);\n\n if (style === 'simple') {\n return valueKeys.reduce(function (prev, curr) {\n var val = valueEncoder(value[curr]);\n var middleChar = explode ? '=' : ',';\n var prefix = prev ? \"\".concat(prev, \",\") : '';\n\n return \"\".concat(prefix).concat(curr).concat(middleChar).concat(val);\n }, '');\n }\n\n if (style === 'label') {\n return valueKeys.reduce(function (prev, curr) {\n var val = valueEncoder(value[curr]);\n var middleChar = explode ? '=' : '.';\n var prefix = prev ? \"\".concat(prev, \".\") : '.';\n\n return \"\".concat(prefix).concat(curr).concat(middleChar).concat(val);\n }, '');\n }\n\n if (style === 'matrix' && explode) {\n return valueKeys.reduce(function (prev, curr) {\n var val = valueEncoder(value[curr]);\n var prefix = prev ? \"\".concat(prev, \";\") : ';';\n\n return \"\".concat(prefix).concat(curr, \"=\").concat(val);\n }, '');\n }\n\n if (style === 'matrix') {\n // no explode\n return valueKeys.reduce(function (prev, curr) {\n var val = valueEncoder(value[curr]);\n var prefix = prev ? \"\".concat(prev, \",\") : \";\".concat(key, \"=\");\n\n return \"\".concat(prefix).concat(curr, \",\").concat(val);\n }, '');\n }\n\n if (style === 'form') {\n return valueKeys.reduce(function (prev, curr) {\n var val = valueEncoder(value[curr]);\n var prefix = prev ? \"\".concat(prev).concat(explode ? '&' : ',') : '';\n var separator = explode ? '=' : ',';\n\n return \"\".concat(prefix).concat(curr).concat(separator).concat(val);\n }, '');\n }\n}\n\nfunction encodePrimitive(_ref4) {var key = _ref4.key,value = _ref4.value,style = _ref4.style,escape = _ref4.escape;\n var valueEncoder = function valueEncoder(str) {return encodeDisallowedCharacters(str, {\n escape: escape });};\n\n\n if (style === 'simple') {\n return valueEncoder(value);\n }\n\n if (style === 'label') {\n return \".\".concat(valueEncoder(value));\n }\n\n if (style === 'matrix') {\n return \";\".concat(key, \"=\").concat(valueEncoder(value));\n }\n\n if (style === 'form') {\n return valueEncoder(value);\n }\n\n if (style === 'deepObject') {\n return valueEncoder(value, {}, true);\n }\n}\n\n/***/ }),\n/* 20 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"@babel/runtime-corejs2/core-js/array/from\");\n\n/***/ }),\n/* 21 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"lodash/isFunction\");\n\n/***/ }),\n/* 22 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"@babel/runtime-corejs2/core-js/get-iterator\");\n\n/***/ }),\n/* 23 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"@babel/runtime-corejs2/core-js/symbol/iterator\");\n\n/***/ }),\n/* 24 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"@babel/runtime-corejs2/core-js/symbol\");\n\n/***/ }),\n/* 25 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"@babel/runtime-corejs2/helpers/asyncToGenerator\");\n\n/***/ }),\n/* 26 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"lodash/pick\");\n\n/***/ }),\n/* 27 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"@babel/runtime-corejs2/helpers/classCallCheck\");\n\n/***/ }),\n/* 28 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"@babel/runtime-corejs2/helpers/createClass\");\n\n/***/ }),\n/* 29 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"fast-json-patch\");\n\n/***/ }),\n/* 30 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"btoa\");\n\n/***/ }),\n/* 31 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"lodash/startsWith\");\n\n/***/ }),\n/* 32 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"@babel/runtime-corejs2/core-js/reflect/construct\");\n\n/***/ }),\n/* 33 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"js-yaml\");\n\n/***/ }),\n/* 34 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"qs\");\n\n/***/ }),\n/* 35 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"@babel/runtime-corejs2/helpers/getPrototypeOf\");\n\n/***/ }),\n/* 36 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"@babel/runtime-corejs2/core-js/object/create\");\n\n/***/ }),\n/* 37 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"lodash/noop\");\n\n/***/ }),\n/* 38 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"querystring-browser\");\n\n/***/ }),\n/* 39 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"lodash/isObject\");\n\n/***/ }),\n/* 40 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"@babel/runtime-corejs2/core-js/object/entries\");\n\n/***/ }),\n/* 41 */\n/***/ (function(module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\n/* unused harmony export patch */\n/* harmony import */ var _babel_runtime_corejs2_core_js_reflect_construct__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(32);\n/* harmony import */ var _babel_runtime_corejs2_core_js_reflect_construct__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_corejs2_core_js_reflect_construct__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _babel_runtime_corejs2_helpers_classCallCheck__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(27);\n/* harmony import */ var _babel_runtime_corejs2_helpers_classCallCheck__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_corejs2_helpers_classCallCheck__WEBPACK_IMPORTED_MODULE_1__);\n/* harmony import */ var _babel_runtime_corejs2_helpers_createClass__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(28);\n/* harmony import */ var _babel_runtime_corejs2_helpers_createClass__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_corejs2_helpers_createClass__WEBPACK_IMPORTED_MODULE_2__);\n/* harmony import */ var _babel_runtime_corejs2_helpers_get__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(42);\n/* harmony import */ var _babel_runtime_corejs2_helpers_get__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_corejs2_helpers_get__WEBPACK_IMPORTED_MODULE_3__);\n/* harmony import */ var _babel_runtime_corejs2_helpers_possibleConstructorReturn__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(43);\n/* harmony import */ var _babel_runtime_corejs2_helpers_possibleConstructorReturn__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_corejs2_helpers_possibleConstructorReturn__WEBPACK_IMPORTED_MODULE_4__);\n/* harmony import */ var _babel_runtime_corejs2_helpers_getPrototypeOf__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(35);\n/* harmony import */ var _babel_runtime_corejs2_helpers_getPrototypeOf__WEBPACK_IMPORTED_MODULE_5___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_corejs2_helpers_getPrototypeOf__WEBPACK_IMPORTED_MODULE_5__);\n/* harmony import */ var _babel_runtime_corejs2_helpers_inherits__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(44);\n/* harmony import */ var _babel_runtime_corejs2_helpers_inherits__WEBPACK_IMPORTED_MODULE_6___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_corejs2_helpers_inherits__WEBPACK_IMPORTED_MODULE_6__);\n/* harmony import */ var lodash_isFunction__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(21);\n/* harmony import */ var lodash_isFunction__WEBPACK_IMPORTED_MODULE_7___default = /*#__PURE__*/__webpack_require__.n(lodash_isFunction__WEBPACK_IMPORTED_MODULE_7__);\n/* harmony import */ var isomorphic_form_data__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(45);\n/* harmony import */ var isomorphic_form_data__WEBPACK_IMPORTED_MODULE_8___default = /*#__PURE__*/__webpack_require__.n(isomorphic_form_data__WEBPACK_IMPORTED_MODULE_8__);\nfunction _createSuper(Derived) {return function () {var Super = _babel_runtime_corejs2_helpers_getPrototypeOf__WEBPACK_IMPORTED_MODULE_5___default()(Derived),result;if (_isNativeReflectConstruct()) {var NewTarget = _babel_runtime_corejs2_helpers_getPrototypeOf__WEBPACK_IMPORTED_MODULE_5___default()(this).constructor;result = _babel_runtime_corejs2_core_js_reflect_construct__WEBPACK_IMPORTED_MODULE_0___default()(Super, arguments, NewTarget);} else {result = Super.apply(this, arguments);}return _babel_runtime_corejs2_helpers_possibleConstructorReturn__WEBPACK_IMPORTED_MODULE_4___default()(this, result);};}function _isNativeReflectConstruct() {if (typeof Reflect === \"undefined\" || !_babel_runtime_corejs2_core_js_reflect_construct__WEBPACK_IMPORTED_MODULE_0___default.a) return false;if (_babel_runtime_corejs2_core_js_reflect_construct__WEBPACK_IMPORTED_MODULE_0___default.a.sham) return false;if (typeof Proxy === \"function\") return true;try {Date.prototype.toString.call(_babel_runtime_corejs2_core_js_reflect_construct__WEBPACK_IMPORTED_MODULE_0___default()(Date, [], function () {}));return true;} catch (e) {return false;}}\n\n\n// patches FormData type by mutating it.\n// patch :: FormData -> PatchedFormData\nvar patch = function patch(FormData) {\n var createEntry = function createEntry(field, value) {return { name: field, value: value };};\n /** We return original type if prototype already contains one of methods we're trying to patch.\n * Reasoning: if one of the methods already exists, it would access data in other\n * property than our `_entryList`. That could potentially create nasty\n * hardly detectable bugs if `form-data` library implements only couple of\n * methods that it misses, instead of implementing all of them.\n * Current solution will fail the tests to let us know that form-data library\n * already implements some of the methods that we try to monkey-patch, and our\n * monkey-patch code should then compensate the library changes easily.\n */\n if (\n lodash_isFunction__WEBPACK_IMPORTED_MODULE_7___default()(FormData.prototype.set) ||\n lodash_isFunction__WEBPACK_IMPORTED_MODULE_7___default()(FormData.prototype.get) ||\n lodash_isFunction__WEBPACK_IMPORTED_MODULE_7___default()(FormData.prototype.getAll) ||\n lodash_isFunction__WEBPACK_IMPORTED_MODULE_7___default()(FormData.prototype.has))\n {\n return FormData;\n }var\n PatchedFormData = /*#__PURE__*/function (_FormData) {_babel_runtime_corejs2_helpers_inherits__WEBPACK_IMPORTED_MODULE_6___default()(PatchedFormData, _FormData);var _super = _createSuper(PatchedFormData);\n function PatchedFormData(form) {var _this;_babel_runtime_corejs2_helpers_classCallCheck__WEBPACK_IMPORTED_MODULE_1___default()(this, PatchedFormData);\n _this = _super.call(this, form);\n _this._entryList = [];return _this;\n }_babel_runtime_corejs2_helpers_createClass__WEBPACK_IMPORTED_MODULE_2___default()(PatchedFormData, [{ key: \"append\", value: function append(\n\n field, value, options) {\n this._entryList.push(createEntry(field, value));\n return _babel_runtime_corejs2_helpers_get__WEBPACK_IMPORTED_MODULE_3___default()(_babel_runtime_corejs2_helpers_getPrototypeOf__WEBPACK_IMPORTED_MODULE_5___default()(PatchedFormData.prototype), \"append\", this).call(this, field, value, options);\n } }, { key: \"set\", value: function set(\n\n field, value) {\n var newEntry = createEntry(field, value);\n\n this._entryList = this._entryList.filter(function (entry) {\n return entry.name !== field;\n });\n\n this._entryList.push(newEntry);\n } }, { key: \"get\", value: function get(\n\n field) {\n var foundEntry = this._entryList.find(function (entry) {\n return entry.name === field;\n });\n\n return foundEntry === undefined ? null : foundEntry;\n } }, { key: \"getAll\", value: function getAll(\n\n field) {\n return this._entryList.\n filter(function (entry) {\n return entry.name === field;\n }).\n map(function (entry) {\n return entry.value;\n });\n } }, { key: \"has\", value: function has(\n\n field) {\n return this._entryList.some(function (entry) {\n return entry.name === field;\n });\n } }]);return PatchedFormData;}(FormData);\n\n\n return PatchedFormData;\n};\n\n/* harmony default export */ __webpack_exports__[\"a\"] = (patch(isomorphic_form_data__WEBPACK_IMPORTED_MODULE_8___default.a));\n\n/***/ }),\n/* 42 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"@babel/runtime-corejs2/helpers/get\");\n\n/***/ }),\n/* 43 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"@babel/runtime-corejs2/helpers/possibleConstructorReturn\");\n\n/***/ }),\n/* 44 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"@babel/runtime-corejs2/helpers/inherits\");\n\n/***/ }),\n/* 45 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"isomorphic-form-data\");\n\n/***/ }),\n/* 46 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"utf8-bytes\");\n\n/***/ }),\n/* 47 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"utfstring\");\n\n/***/ }),\n/* 48 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"lodash/find\");\n\n/***/ }),\n/* 49 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"deep-extend\");\n\n/***/ }),\n/* 50 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"@kyleshockey/object-assign-deep\");\n\n/***/ }),\n/* 51 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"@babel/runtime-corejs2/core-js/weak-map\");\n\n/***/ }),\n/* 52 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"cross-fetch\");\n\n/***/ }),\n/* 53 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"traverse\");\n\n/***/ }),\n/* 54 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"@babel/runtime-corejs2/helpers/objectWithoutProperties\");\n\n/***/ }),\n/* 55 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"lodash/isPlainObject\");\n\n/***/ }),\n/* 56 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"lodash/isArray\");\n\n/***/ }),\n/* 57 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"cookie\");\n\n/***/ }),\n/* 58 */\n/***/ (function(module, exports, __webpack_require__) {\n\nmodule.exports = __webpack_require__(67);\n\n\n/***/ }),\n/* 59 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"lodash/cloneDeep\");\n\n/***/ }),\n/* 60 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n/* WEBPACK VAR INJECTION */(function(global) {/*!\n * The buffer module from node.js, for the browser.\n *\n * @author Feross Aboukhadijeh \n * @license MIT\n */\n/* eslint-disable no-proto */\n\n\n\nvar base64 = __webpack_require__(62)\nvar ieee754 = __webpack_require__(63)\nvar isArray = __webpack_require__(64)\n\nexports.Buffer = Buffer\nexports.SlowBuffer = SlowBuffer\nexports.INSPECT_MAX_BYTES = 50\n\n/**\n * If `Buffer.TYPED_ARRAY_SUPPORT`:\n * === true Use Uint8Array implementation (fastest)\n * === false Use Object implementation (most compatible, even IE6)\n *\n * Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari 5.1+,\n * Opera 11.6+, iOS 4.2+.\n *\n * Due to various browser bugs, sometimes the Object implementation will be used even\n * when the browser supports typed arrays.\n *\n * Note:\n *\n * - Firefox 4-29 lacks support for adding new properties to `Uint8Array` instances,\n * See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438.\n *\n * - Chrome 9-10 is missing the `TypedArray.prototype.subarray` function.\n *\n * - IE10 has a broken `TypedArray.prototype.subarray` function which returns arrays of\n * incorrect length in some situations.\n\n * We detect these buggy browsers and set `Buffer.TYPED_ARRAY_SUPPORT` to `false` so they\n * get the Object implementation, which is slower but behaves correctly.\n */\nBuffer.TYPED_ARRAY_SUPPORT = global.TYPED_ARRAY_SUPPORT !== undefined\n ? global.TYPED_ARRAY_SUPPORT\n : typedArraySupport()\n\n/*\n * Export kMaxLength after typed array support is determined.\n */\nexports.kMaxLength = kMaxLength()\n\nfunction typedArraySupport () {\n try {\n var arr = new Uint8Array(1)\n arr.__proto__ = {__proto__: Uint8Array.prototype, foo: function () { return 42 }}\n return arr.foo() === 42 && // typed array instances can be augmented\n typeof arr.subarray === 'function' && // chrome 9-10 lack `subarray`\n arr.subarray(1, 1).byteLength === 0 // ie10 has broken `subarray`\n } catch (e) {\n return false\n }\n}\n\nfunction kMaxLength () {\n return Buffer.TYPED_ARRAY_SUPPORT\n ? 0x7fffffff\n : 0x3fffffff\n}\n\nfunction createBuffer (that, length) {\n if (kMaxLength() < length) {\n throw new RangeError('Invalid typed array length')\n }\n if (Buffer.TYPED_ARRAY_SUPPORT) {\n // Return an augmented `Uint8Array` instance, for best performance\n that = new Uint8Array(length)\n that.__proto__ = Buffer.prototype\n } else {\n // Fallback: Return an object instance of the Buffer class\n if (that === null) {\n that = new Buffer(length)\n }\n that.length = length\n }\n\n return that\n}\n\n/**\n * The Buffer constructor returns instances of `Uint8Array` that have their\n * prototype changed to `Buffer.prototype`. Furthermore, `Buffer` is a subclass of\n * `Uint8Array`, so the returned instances will have all the node `Buffer` methods\n * and the `Uint8Array` methods. Square bracket notation works as expected -- it\n * returns a single octet.\n *\n * The `Uint8Array` prototype remains unmodified.\n */\n\nfunction Buffer (arg, encodingOrOffset, length) {\n if (!Buffer.TYPED_ARRAY_SUPPORT && !(this instanceof Buffer)) {\n return new Buffer(arg, encodingOrOffset, length)\n }\n\n // Common case.\n if (typeof arg === 'number') {\n if (typeof encodingOrOffset === 'string') {\n throw new Error(\n 'If encoding is specified then the first argument must be a string'\n )\n }\n return allocUnsafe(this, arg)\n }\n return from(this, arg, encodingOrOffset, length)\n}\n\nBuffer.poolSize = 8192 // not used by this implementation\n\n// TODO: Legacy, not needed anymore. Remove in next major version.\nBuffer._augment = function (arr) {\n arr.__proto__ = Buffer.prototype\n return arr\n}\n\nfunction from (that, value, encodingOrOffset, length) {\n if (typeof value === 'number') {\n throw new TypeError('\"value\" argument must not be a number')\n }\n\n if (typeof ArrayBuffer !== 'undefined' && value instanceof ArrayBuffer) {\n return fromArrayBuffer(that, value, encodingOrOffset, length)\n }\n\n if (typeof value === 'string') {\n return fromString(that, value, encodingOrOffset)\n }\n\n return fromObject(that, value)\n}\n\n/**\n * Functionally equivalent to Buffer(arg, encoding) but throws a TypeError\n * if value is a number.\n * Buffer.from(str[, encoding])\n * Buffer.from(array)\n * Buffer.from(buffer)\n * Buffer.from(arrayBuffer[, byteOffset[, length]])\n **/\nBuffer.from = function (value, encodingOrOffset, length) {\n return from(null, value, encodingOrOffset, length)\n}\n\nif (Buffer.TYPED_ARRAY_SUPPORT) {\n Buffer.prototype.__proto__ = Uint8Array.prototype\n Buffer.__proto__ = Uint8Array\n if (typeof Symbol !== 'undefined' && Symbol.species &&\n Buffer[Symbol.species] === Buffer) {\n // Fix subarray() in ES2016. See: https://github.com/feross/buffer/pull/97\n Object.defineProperty(Buffer, Symbol.species, {\n value: null,\n configurable: true\n })\n }\n}\n\nfunction assertSize (size) {\n if (typeof size !== 'number') {\n throw new TypeError('\"size\" argument must be a number')\n } else if (size < 0) {\n throw new RangeError('\"size\" argument must not be negative')\n }\n}\n\nfunction alloc (that, size, fill, encoding) {\n assertSize(size)\n if (size <= 0) {\n return createBuffer(that, size)\n }\n if (fill !== undefined) {\n // Only pay attention to encoding if it's a string. This\n // prevents accidentally sending in a number that would\n // be interpretted as a start offset.\n return typeof encoding === 'string'\n ? createBuffer(that, size).fill(fill, encoding)\n : createBuffer(that, size).fill(fill)\n }\n return createBuffer(that, size)\n}\n\n/**\n * Creates a new filled Buffer instance.\n * alloc(size[, fill[, encoding]])\n **/\nBuffer.alloc = function (size, fill, encoding) {\n return alloc(null, size, fill, encoding)\n}\n\nfunction allocUnsafe (that, size) {\n assertSize(size)\n that = createBuffer(that, size < 0 ? 0 : checked(size) | 0)\n if (!Buffer.TYPED_ARRAY_SUPPORT) {\n for (var i = 0; i < size; ++i) {\n that[i] = 0\n }\n }\n return that\n}\n\n/**\n * Equivalent to Buffer(num), by default creates a non-zero-filled Buffer instance.\n * */\nBuffer.allocUnsafe = function (size) {\n return allocUnsafe(null, size)\n}\n/**\n * Equivalent to SlowBuffer(num), by default creates a non-zero-filled Buffer instance.\n */\nBuffer.allocUnsafeSlow = function (size) {\n return allocUnsafe(null, size)\n}\n\nfunction fromString (that, string, encoding) {\n if (typeof encoding !== 'string' || encoding === '') {\n encoding = 'utf8'\n }\n\n if (!Buffer.isEncoding(encoding)) {\n throw new TypeError('\"encoding\" must be a valid string encoding')\n }\n\n var length = byteLength(string, encoding) | 0\n that = createBuffer(that, length)\n\n var actual = that.write(string, encoding)\n\n if (actual !== length) {\n // Writing a hex string, for example, that contains invalid characters will\n // cause everything after the first invalid character to be ignored. (e.g.\n // 'abxxcd' will be treated as 'ab')\n that = that.slice(0, actual)\n }\n\n return that\n}\n\nfunction fromArrayLike (that, array) {\n var length = array.length < 0 ? 0 : checked(array.length) | 0\n that = createBuffer(that, length)\n for (var i = 0; i < length; i += 1) {\n that[i] = array[i] & 255\n }\n return that\n}\n\nfunction fromArrayBuffer (that, array, byteOffset, length) {\n array.byteLength // this throws if `array` is not a valid ArrayBuffer\n\n if (byteOffset < 0 || array.byteLength < byteOffset) {\n throw new RangeError('\\'offset\\' is out of bounds')\n }\n\n if (array.byteLength < byteOffset + (length || 0)) {\n throw new RangeError('\\'length\\' is out of bounds')\n }\n\n if (byteOffset === undefined && length === undefined) {\n array = new Uint8Array(array)\n } else if (length === undefined) {\n array = new Uint8Array(array, byteOffset)\n } else {\n array = new Uint8Array(array, byteOffset, length)\n }\n\n if (Buffer.TYPED_ARRAY_SUPPORT) {\n // Return an augmented `Uint8Array` instance, for best performance\n that = array\n that.__proto__ = Buffer.prototype\n } else {\n // Fallback: Return an object instance of the Buffer class\n that = fromArrayLike(that, array)\n }\n return that\n}\n\nfunction fromObject (that, obj) {\n if (Buffer.isBuffer(obj)) {\n var len = checked(obj.length) | 0\n that = createBuffer(that, len)\n\n if (that.length === 0) {\n return that\n }\n\n obj.copy(that, 0, 0, len)\n return that\n }\n\n if (obj) {\n if ((typeof ArrayBuffer !== 'undefined' &&\n obj.buffer instanceof ArrayBuffer) || 'length' in obj) {\n if (typeof obj.length !== 'number' || isnan(obj.length)) {\n return createBuffer(that, 0)\n }\n return fromArrayLike(that, obj)\n }\n\n if (obj.type === 'Buffer' && isArray(obj.data)) {\n return fromArrayLike(that, obj.data)\n }\n }\n\n throw new TypeError('First argument must be a string, Buffer, ArrayBuffer, Array, or array-like object.')\n}\n\nfunction checked (length) {\n // Note: cannot use `length < kMaxLength()` here because that fails when\n // length is NaN (which is otherwise coerced to zero.)\n if (length >= kMaxLength()) {\n throw new RangeError('Attempt to allocate Buffer larger than maximum ' +\n 'size: 0x' + kMaxLength().toString(16) + ' bytes')\n }\n return length | 0\n}\n\nfunction SlowBuffer (length) {\n if (+length != length) { // eslint-disable-line eqeqeq\n length = 0\n }\n return Buffer.alloc(+length)\n}\n\nBuffer.isBuffer = function isBuffer (b) {\n return !!(b != null && b._isBuffer)\n}\n\nBuffer.compare = function compare (a, b) {\n if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) {\n throw new TypeError('Arguments must be Buffers')\n }\n\n if (a === b) return 0\n\n var x = a.length\n var y = b.length\n\n for (var i = 0, len = Math.min(x, y); i < len; ++i) {\n if (a[i] !== b[i]) {\n x = a[i]\n y = b[i]\n break\n }\n }\n\n if (x < y) return -1\n if (y < x) return 1\n return 0\n}\n\nBuffer.isEncoding = function isEncoding (encoding) {\n switch (String(encoding).toLowerCase()) {\n case 'hex':\n case 'utf8':\n case 'utf-8':\n case 'ascii':\n case 'latin1':\n case 'binary':\n case 'base64':\n case 'ucs2':\n case 'ucs-2':\n case 'utf16le':\n case 'utf-16le':\n return true\n default:\n return false\n }\n}\n\nBuffer.concat = function concat (list, length) {\n if (!isArray(list)) {\n throw new TypeError('\"list\" argument must be an Array of Buffers')\n }\n\n if (list.length === 0) {\n return Buffer.alloc(0)\n }\n\n var i\n if (length === undefined) {\n length = 0\n for (i = 0; i < list.length; ++i) {\n length += list[i].length\n }\n }\n\n var buffer = Buffer.allocUnsafe(length)\n var pos = 0\n for (i = 0; i < list.length; ++i) {\n var buf = list[i]\n if (!Buffer.isBuffer(buf)) {\n throw new TypeError('\"list\" argument must be an Array of Buffers')\n }\n buf.copy(buffer, pos)\n pos += buf.length\n }\n return buffer\n}\n\nfunction byteLength (string, encoding) {\n if (Buffer.isBuffer(string)) {\n return string.length\n }\n if (typeof ArrayBuffer !== 'undefined' && typeof ArrayBuffer.isView === 'function' &&\n (ArrayBuffer.isView(string) || string instanceof ArrayBuffer)) {\n return string.byteLength\n }\n if (typeof string !== 'string') {\n string = '' + string\n }\n\n var len = string.length\n if (len === 0) return 0\n\n // Use a for loop to avoid recursion\n var loweredCase = false\n for (;;) {\n switch (encoding) {\n case 'ascii':\n case 'latin1':\n case 'binary':\n return len\n case 'utf8':\n case 'utf-8':\n case undefined:\n return utf8ToBytes(string).length\n case 'ucs2':\n case 'ucs-2':\n case 'utf16le':\n case 'utf-16le':\n return len * 2\n case 'hex':\n return len >>> 1\n case 'base64':\n return base64ToBytes(string).length\n default:\n if (loweredCase) return utf8ToBytes(string).length // assume utf8\n encoding = ('' + encoding).toLowerCase()\n loweredCase = true\n }\n }\n}\nBuffer.byteLength = byteLength\n\nfunction slowToString (encoding, start, end) {\n var loweredCase = false\n\n // No need to verify that \"this.length <= MAX_UINT32\" since it's a read-only\n // property of a typed array.\n\n // This behaves neither like String nor Uint8Array in that we set start/end\n // to their upper/lower bounds if the value passed is out of range.\n // undefined is handled specially as per ECMA-262 6th Edition,\n // Section 13.3.3.7 Runtime Semantics: KeyedBindingInitialization.\n if (start === undefined || start < 0) {\n start = 0\n }\n // Return early if start > this.length. Done here to prevent potential uint32\n // coercion fail below.\n if (start > this.length) {\n return ''\n }\n\n if (end === undefined || end > this.length) {\n end = this.length\n }\n\n if (end <= 0) {\n return ''\n }\n\n // Force coersion to uint32. This will also coerce falsey/NaN values to 0.\n end >>>= 0\n start >>>= 0\n\n if (end <= start) {\n return ''\n }\n\n if (!encoding) encoding = 'utf8'\n\n while (true) {\n switch (encoding) {\n case 'hex':\n return hexSlice(this, start, end)\n\n case 'utf8':\n case 'utf-8':\n return utf8Slice(this, start, end)\n\n case 'ascii':\n return asciiSlice(this, start, end)\n\n case 'latin1':\n case 'binary':\n return latin1Slice(this, start, end)\n\n case 'base64':\n return base64Slice(this, start, end)\n\n case 'ucs2':\n case 'ucs-2':\n case 'utf16le':\n case 'utf-16le':\n return utf16leSlice(this, start, end)\n\n default:\n if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)\n encoding = (encoding + '').toLowerCase()\n loweredCase = true\n }\n }\n}\n\n// The property is used by `Buffer.isBuffer` and `is-buffer` (in Safari 5-7) to detect\n// Buffer instances.\nBuffer.prototype._isBuffer = true\n\nfunction swap (b, n, m) {\n var i = b[n]\n b[n] = b[m]\n b[m] = i\n}\n\nBuffer.prototype.swap16 = function swap16 () {\n var len = this.length\n if (len % 2 !== 0) {\n throw new RangeError('Buffer size must be a multiple of 16-bits')\n }\n for (var i = 0; i < len; i += 2) {\n swap(this, i, i + 1)\n }\n return this\n}\n\nBuffer.prototype.swap32 = function swap32 () {\n var len = this.length\n if (len % 4 !== 0) {\n throw new RangeError('Buffer size must be a multiple of 32-bits')\n }\n for (var i = 0; i < len; i += 4) {\n swap(this, i, i + 3)\n swap(this, i + 1, i + 2)\n }\n return this\n}\n\nBuffer.prototype.swap64 = function swap64 () {\n var len = this.length\n if (len % 8 !== 0) {\n throw new RangeError('Buffer size must be a multiple of 64-bits')\n }\n for (var i = 0; i < len; i += 8) {\n swap(this, i, i + 7)\n swap(this, i + 1, i + 6)\n swap(this, i + 2, i + 5)\n swap(this, i + 3, i + 4)\n }\n return this\n}\n\nBuffer.prototype.toString = function toString () {\n var length = this.length | 0\n if (length === 0) return ''\n if (arguments.length === 0) return utf8Slice(this, 0, length)\n return slowToString.apply(this, arguments)\n}\n\nBuffer.prototype.equals = function equals (b) {\n if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer')\n if (this === b) return true\n return Buffer.compare(this, b) === 0\n}\n\nBuffer.prototype.inspect = function inspect () {\n var str = ''\n var max = exports.INSPECT_MAX_BYTES\n if (this.length > 0) {\n str = this.toString('hex', 0, max).match(/.{2}/g).join(' ')\n if (this.length > max) str += ' ... '\n }\n return ''\n}\n\nBuffer.prototype.compare = function compare (target, start, end, thisStart, thisEnd) {\n if (!Buffer.isBuffer(target)) {\n throw new TypeError('Argument must be a Buffer')\n }\n\n if (start === undefined) {\n start = 0\n }\n if (end === undefined) {\n end = target ? target.length : 0\n }\n if (thisStart === undefined) {\n thisStart = 0\n }\n if (thisEnd === undefined) {\n thisEnd = this.length\n }\n\n if (start < 0 || end > target.length || thisStart < 0 || thisEnd > this.length) {\n throw new RangeError('out of range index')\n }\n\n if (thisStart >= thisEnd && start >= end) {\n return 0\n }\n if (thisStart >= thisEnd) {\n return -1\n }\n if (start >= end) {\n return 1\n }\n\n start >>>= 0\n end >>>= 0\n thisStart >>>= 0\n thisEnd >>>= 0\n\n if (this === target) return 0\n\n var x = thisEnd - thisStart\n var y = end - start\n var len = Math.min(x, y)\n\n var thisCopy = this.slice(thisStart, thisEnd)\n var targetCopy = target.slice(start, end)\n\n for (var i = 0; i < len; ++i) {\n if (thisCopy[i] !== targetCopy[i]) {\n x = thisCopy[i]\n y = targetCopy[i]\n break\n }\n }\n\n if (x < y) return -1\n if (y < x) return 1\n return 0\n}\n\n// Finds either the first index of `val` in `buffer` at offset >= `byteOffset`,\n// OR the last index of `val` in `buffer` at offset <= `byteOffset`.\n//\n// Arguments:\n// - buffer - a Buffer to search\n// - val - a string, Buffer, or number\n// - byteOffset - an index into `buffer`; will be clamped to an int32\n// - encoding - an optional encoding, relevant is val is a string\n// - dir - true for indexOf, false for lastIndexOf\nfunction bidirectionalIndexOf (buffer, val, byteOffset, encoding, dir) {\n // Empty buffer means no match\n if (buffer.length === 0) return -1\n\n // Normalize byteOffset\n if (typeof byteOffset === 'string') {\n encoding = byteOffset\n byteOffset = 0\n } else if (byteOffset > 0x7fffffff) {\n byteOffset = 0x7fffffff\n } else if (byteOffset < -0x80000000) {\n byteOffset = -0x80000000\n }\n byteOffset = +byteOffset // Coerce to Number.\n if (isNaN(byteOffset)) {\n // byteOffset: it it's undefined, null, NaN, \"foo\", etc, search whole buffer\n byteOffset = dir ? 0 : (buffer.length - 1)\n }\n\n // Normalize byteOffset: negative offsets start from the end of the buffer\n if (byteOffset < 0) byteOffset = buffer.length + byteOffset\n if (byteOffset >= buffer.length) {\n if (dir) return -1\n else byteOffset = buffer.length - 1\n } else if (byteOffset < 0) {\n if (dir) byteOffset = 0\n else return -1\n }\n\n // Normalize val\n if (typeof val === 'string') {\n val = Buffer.from(val, encoding)\n }\n\n // Finally, search either indexOf (if dir is true) or lastIndexOf\n if (Buffer.isBuffer(val)) {\n // Special case: looking for empty string/buffer always fails\n if (val.length === 0) {\n return -1\n }\n return arrayIndexOf(buffer, val, byteOffset, encoding, dir)\n } else if (typeof val === 'number') {\n val = val & 0xFF // Search for a byte value [0-255]\n if (Buffer.TYPED_ARRAY_SUPPORT &&\n typeof Uint8Array.prototype.indexOf === 'function') {\n if (dir) {\n return Uint8Array.prototype.indexOf.call(buffer, val, byteOffset)\n } else {\n return Uint8Array.prototype.lastIndexOf.call(buffer, val, byteOffset)\n }\n }\n return arrayIndexOf(buffer, [ val ], byteOffset, encoding, dir)\n }\n\n throw new TypeError('val must be string, number or Buffer')\n}\n\nfunction arrayIndexOf (arr, val, byteOffset, encoding, dir) {\n var indexSize = 1\n var arrLength = arr.length\n var valLength = val.length\n\n if (encoding !== undefined) {\n encoding = String(encoding).toLowerCase()\n if (encoding === 'ucs2' || encoding === 'ucs-2' ||\n encoding === 'utf16le' || encoding === 'utf-16le') {\n if (arr.length < 2 || val.length < 2) {\n return -1\n }\n indexSize = 2\n arrLength /= 2\n valLength /= 2\n byteOffset /= 2\n }\n }\n\n function read (buf, i) {\n if (indexSize === 1) {\n return buf[i]\n } else {\n return buf.readUInt16BE(i * indexSize)\n }\n }\n\n var i\n if (dir) {\n var foundIndex = -1\n for (i = byteOffset; i < arrLength; i++) {\n if (read(arr, i) === read(val, foundIndex === -1 ? 0 : i - foundIndex)) {\n if (foundIndex === -1) foundIndex = i\n if (i - foundIndex + 1 === valLength) return foundIndex * indexSize\n } else {\n if (foundIndex !== -1) i -= i - foundIndex\n foundIndex = -1\n }\n }\n } else {\n if (byteOffset + valLength > arrLength) byteOffset = arrLength - valLength\n for (i = byteOffset; i >= 0; i--) {\n var found = true\n for (var j = 0; j < valLength; j++) {\n if (read(arr, i + j) !== read(val, j)) {\n found = false\n break\n }\n }\n if (found) return i\n }\n }\n\n return -1\n}\n\nBuffer.prototype.includes = function includes (val, byteOffset, encoding) {\n return this.indexOf(val, byteOffset, encoding) !== -1\n}\n\nBuffer.prototype.indexOf = function indexOf (val, byteOffset, encoding) {\n return bidirectionalIndexOf(this, val, byteOffset, encoding, true)\n}\n\nBuffer.prototype.lastIndexOf = function lastIndexOf (val, byteOffset, encoding) {\n return bidirectionalIndexOf(this, val, byteOffset, encoding, false)\n}\n\nfunction hexWrite (buf, string, offset, length) {\n offset = Number(offset) || 0\n var remaining = buf.length - offset\n if (!length) {\n length = remaining\n } else {\n length = Number(length)\n if (length > remaining) {\n length = remaining\n }\n }\n\n // must be an even number of digits\n var strLen = string.length\n if (strLen % 2 !== 0) throw new TypeError('Invalid hex string')\n\n if (length > strLen / 2) {\n length = strLen / 2\n }\n for (var i = 0; i < length; ++i) {\n var parsed = parseInt(string.substr(i * 2, 2), 16)\n if (isNaN(parsed)) return i\n buf[offset + i] = parsed\n }\n return i\n}\n\nfunction utf8Write (buf, string, offset, length) {\n return blitBuffer(utf8ToBytes(string, buf.length - offset), buf, offset, length)\n}\n\nfunction asciiWrite (buf, string, offset, length) {\n return blitBuffer(asciiToBytes(string), buf, offset, length)\n}\n\nfunction latin1Write (buf, string, offset, length) {\n return asciiWrite(buf, string, offset, length)\n}\n\nfunction base64Write (buf, string, offset, length) {\n return blitBuffer(base64ToBytes(string), buf, offset, length)\n}\n\nfunction ucs2Write (buf, string, offset, length) {\n return blitBuffer(utf16leToBytes(string, buf.length - offset), buf, offset, length)\n}\n\nBuffer.prototype.write = function write (string, offset, length, encoding) {\n // Buffer#write(string)\n if (offset === undefined) {\n encoding = 'utf8'\n length = this.length\n offset = 0\n // Buffer#write(string, encoding)\n } else if (length === undefined && typeof offset === 'string') {\n encoding = offset\n length = this.length\n offset = 0\n // Buffer#write(string, offset[, length][, encoding])\n } else if (isFinite(offset)) {\n offset = offset | 0\n if (isFinite(length)) {\n length = length | 0\n if (encoding === undefined) encoding = 'utf8'\n } else {\n encoding = length\n length = undefined\n }\n // legacy write(string, encoding, offset, length) - remove in v0.13\n } else {\n throw new Error(\n 'Buffer.write(string, encoding, offset[, length]) is no longer supported'\n )\n }\n\n var remaining = this.length - offset\n if (length === undefined || length > remaining) length = remaining\n\n if ((string.length > 0 && (length < 0 || offset < 0)) || offset > this.length) {\n throw new RangeError('Attempt to write outside buffer bounds')\n }\n\n if (!encoding) encoding = 'utf8'\n\n var loweredCase = false\n for (;;) {\n switch (encoding) {\n case 'hex':\n return hexWrite(this, string, offset, length)\n\n case 'utf8':\n case 'utf-8':\n return utf8Write(this, string, offset, length)\n\n case 'ascii':\n return asciiWrite(this, string, offset, length)\n\n case 'latin1':\n case 'binary':\n return latin1Write(this, string, offset, length)\n\n case 'base64':\n // Warning: maxLength not taken into account in base64Write\n return base64Write(this, string, offset, length)\n\n case 'ucs2':\n case 'ucs-2':\n case 'utf16le':\n case 'utf-16le':\n return ucs2Write(this, string, offset, length)\n\n default:\n if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)\n encoding = ('' + encoding).toLowerCase()\n loweredCase = true\n }\n }\n}\n\nBuffer.prototype.toJSON = function toJSON () {\n return {\n type: 'Buffer',\n data: Array.prototype.slice.call(this._arr || this, 0)\n }\n}\n\nfunction base64Slice (buf, start, end) {\n if (start === 0 && end === buf.length) {\n return base64.fromByteArray(buf)\n } else {\n return base64.fromByteArray(buf.slice(start, end))\n }\n}\n\nfunction utf8Slice (buf, start, end) {\n end = Math.min(buf.length, end)\n var res = []\n\n var i = start\n while (i < end) {\n var firstByte = buf[i]\n var codePoint = null\n var bytesPerSequence = (firstByte > 0xEF) ? 4\n : (firstByte > 0xDF) ? 3\n : (firstByte > 0xBF) ? 2\n : 1\n\n if (i + bytesPerSequence <= end) {\n var secondByte, thirdByte, fourthByte, tempCodePoint\n\n switch (bytesPerSequence) {\n case 1:\n if (firstByte < 0x80) {\n codePoint = firstByte\n }\n break\n case 2:\n secondByte = buf[i + 1]\n if ((secondByte & 0xC0) === 0x80) {\n tempCodePoint = (firstByte & 0x1F) << 0x6 | (secondByte & 0x3F)\n if (tempCodePoint > 0x7F) {\n codePoint = tempCodePoint\n }\n }\n break\n case 3:\n secondByte = buf[i + 1]\n thirdByte = buf[i + 2]\n if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80) {\n tempCodePoint = (firstByte & 0xF) << 0xC | (secondByte & 0x3F) << 0x6 | (thirdByte & 0x3F)\n if (tempCodePoint > 0x7FF && (tempCodePoint < 0xD800 || tempCodePoint > 0xDFFF)) {\n codePoint = tempCodePoint\n }\n }\n break\n case 4:\n secondByte = buf[i + 1]\n thirdByte = buf[i + 2]\n fourthByte = buf[i + 3]\n if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80 && (fourthByte & 0xC0) === 0x80) {\n tempCodePoint = (firstByte & 0xF) << 0x12 | (secondByte & 0x3F) << 0xC | (thirdByte & 0x3F) << 0x6 | (fourthByte & 0x3F)\n if (tempCodePoint > 0xFFFF && tempCodePoint < 0x110000) {\n codePoint = tempCodePoint\n }\n }\n }\n }\n\n if (codePoint === null) {\n // we did not generate a valid codePoint so insert a\n // replacement char (U+FFFD) and advance only 1 byte\n codePoint = 0xFFFD\n bytesPerSequence = 1\n } else if (codePoint > 0xFFFF) {\n // encode to utf16 (surrogate pair dance)\n codePoint -= 0x10000\n res.push(codePoint >>> 10 & 0x3FF | 0xD800)\n codePoint = 0xDC00 | codePoint & 0x3FF\n }\n\n res.push(codePoint)\n i += bytesPerSequence\n }\n\n return decodeCodePointsArray(res)\n}\n\n// Based on http://stackoverflow.com/a/22747272/680742, the browser with\n// the lowest limit is Chrome, with 0x10000 args.\n// We go 1 magnitude less, for safety\nvar MAX_ARGUMENTS_LENGTH = 0x1000\n\nfunction decodeCodePointsArray (codePoints) {\n var len = codePoints.length\n if (len <= MAX_ARGUMENTS_LENGTH) {\n return String.fromCharCode.apply(String, codePoints) // avoid extra slice()\n }\n\n // Decode in chunks to avoid \"call stack size exceeded\".\n var res = ''\n var i = 0\n while (i < len) {\n res += String.fromCharCode.apply(\n String,\n codePoints.slice(i, i += MAX_ARGUMENTS_LENGTH)\n )\n }\n return res\n}\n\nfunction asciiSlice (buf, start, end) {\n var ret = ''\n end = Math.min(buf.length, end)\n\n for (var i = start; i < end; ++i) {\n ret += String.fromCharCode(buf[i] & 0x7F)\n }\n return ret\n}\n\nfunction latin1Slice (buf, start, end) {\n var ret = ''\n end = Math.min(buf.length, end)\n\n for (var i = start; i < end; ++i) {\n ret += String.fromCharCode(buf[i])\n }\n return ret\n}\n\nfunction hexSlice (buf, start, end) {\n var len = buf.length\n\n if (!start || start < 0) start = 0\n if (!end || end < 0 || end > len) end = len\n\n var out = ''\n for (var i = start; i < end; ++i) {\n out += toHex(buf[i])\n }\n return out\n}\n\nfunction utf16leSlice (buf, start, end) {\n var bytes = buf.slice(start, end)\n var res = ''\n for (var i = 0; i < bytes.length; i += 2) {\n res += String.fromCharCode(bytes[i] + bytes[i + 1] * 256)\n }\n return res\n}\n\nBuffer.prototype.slice = function slice (start, end) {\n var len = this.length\n start = ~~start\n end = end === undefined ? len : ~~end\n\n if (start < 0) {\n start += len\n if (start < 0) start = 0\n } else if (start > len) {\n start = len\n }\n\n if (end < 0) {\n end += len\n if (end < 0) end = 0\n } else if (end > len) {\n end = len\n }\n\n if (end < start) end = start\n\n var newBuf\n if (Buffer.TYPED_ARRAY_SUPPORT) {\n newBuf = this.subarray(start, end)\n newBuf.__proto__ = Buffer.prototype\n } else {\n var sliceLen = end - start\n newBuf = new Buffer(sliceLen, undefined)\n for (var i = 0; i < sliceLen; ++i) {\n newBuf[i] = this[i + start]\n }\n }\n\n return newBuf\n}\n\n/*\n * Need to make sure that buffer isn't trying to write out of bounds.\n */\nfunction checkOffset (offset, ext, length) {\n if ((offset % 1) !== 0 || offset < 0) throw new RangeError('offset is not uint')\n if (offset + ext > length) throw new RangeError('Trying to access beyond buffer length')\n}\n\nBuffer.prototype.readUIntLE = function readUIntLE (offset, byteLength, noAssert) {\n offset = offset | 0\n byteLength = byteLength | 0\n if (!noAssert) checkOffset(offset, byteLength, this.length)\n\n var val = this[offset]\n var mul = 1\n var i = 0\n while (++i < byteLength && (mul *= 0x100)) {\n val += this[offset + i] * mul\n }\n\n return val\n}\n\nBuffer.prototype.readUIntBE = function readUIntBE (offset, byteLength, noAssert) {\n offset = offset | 0\n byteLength = byteLength | 0\n if (!noAssert) {\n checkOffset(offset, byteLength, this.length)\n }\n\n var val = this[offset + --byteLength]\n var mul = 1\n while (byteLength > 0 && (mul *= 0x100)) {\n val += this[offset + --byteLength] * mul\n }\n\n return val\n}\n\nBuffer.prototype.readUInt8 = function readUInt8 (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 1, this.length)\n return this[offset]\n}\n\nBuffer.prototype.readUInt16LE = function readUInt16LE (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 2, this.length)\n return this[offset] | (this[offset + 1] << 8)\n}\n\nBuffer.prototype.readUInt16BE = function readUInt16BE (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 2, this.length)\n return (this[offset] << 8) | this[offset + 1]\n}\n\nBuffer.prototype.readUInt32LE = function readUInt32LE (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 4, this.length)\n\n return ((this[offset]) |\n (this[offset + 1] << 8) |\n (this[offset + 2] << 16)) +\n (this[offset + 3] * 0x1000000)\n}\n\nBuffer.prototype.readUInt32BE = function readUInt32BE (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 4, this.length)\n\n return (this[offset] * 0x1000000) +\n ((this[offset + 1] << 16) |\n (this[offset + 2] << 8) |\n this[offset + 3])\n}\n\nBuffer.prototype.readIntLE = function readIntLE (offset, byteLength, noAssert) {\n offset = offset | 0\n byteLength = byteLength | 0\n if (!noAssert) checkOffset(offset, byteLength, this.length)\n\n var val = this[offset]\n var mul = 1\n var i = 0\n while (++i < byteLength && (mul *= 0x100)) {\n val += this[offset + i] * mul\n }\n mul *= 0x80\n\n if (val >= mul) val -= Math.pow(2, 8 * byteLength)\n\n return val\n}\n\nBuffer.prototype.readIntBE = function readIntBE (offset, byteLength, noAssert) {\n offset = offset | 0\n byteLength = byteLength | 0\n if (!noAssert) checkOffset(offset, byteLength, this.length)\n\n var i = byteLength\n var mul = 1\n var val = this[offset + --i]\n while (i > 0 && (mul *= 0x100)) {\n val += this[offset + --i] * mul\n }\n mul *= 0x80\n\n if (val >= mul) val -= Math.pow(2, 8 * byteLength)\n\n return val\n}\n\nBuffer.prototype.readInt8 = function readInt8 (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 1, this.length)\n if (!(this[offset] & 0x80)) return (this[offset])\n return ((0xff - this[offset] + 1) * -1)\n}\n\nBuffer.prototype.readInt16LE = function readInt16LE (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 2, this.length)\n var val = this[offset] | (this[offset + 1] << 8)\n return (val & 0x8000) ? val | 0xFFFF0000 : val\n}\n\nBuffer.prototype.readInt16BE = function readInt16BE (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 2, this.length)\n var val = this[offset + 1] | (this[offset] << 8)\n return (val & 0x8000) ? val | 0xFFFF0000 : val\n}\n\nBuffer.prototype.readInt32LE = function readInt32LE (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 4, this.length)\n\n return (this[offset]) |\n (this[offset + 1] << 8) |\n (this[offset + 2] << 16) |\n (this[offset + 3] << 24)\n}\n\nBuffer.prototype.readInt32BE = function readInt32BE (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 4, this.length)\n\n return (this[offset] << 24) |\n (this[offset + 1] << 16) |\n (this[offset + 2] << 8) |\n (this[offset + 3])\n}\n\nBuffer.prototype.readFloatLE = function readFloatLE (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 4, this.length)\n return ieee754.read(this, offset, true, 23, 4)\n}\n\nBuffer.prototype.readFloatBE = function readFloatBE (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 4, this.length)\n return ieee754.read(this, offset, false, 23, 4)\n}\n\nBuffer.prototype.readDoubleLE = function readDoubleLE (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 8, this.length)\n return ieee754.read(this, offset, true, 52, 8)\n}\n\nBuffer.prototype.readDoubleBE = function readDoubleBE (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 8, this.length)\n return ieee754.read(this, offset, false, 52, 8)\n}\n\nfunction checkInt (buf, value, offset, ext, max, min) {\n if (!Buffer.isBuffer(buf)) throw new TypeError('\"buffer\" argument must be a Buffer instance')\n if (value > max || value < min) throw new RangeError('\"value\" argument is out of bounds')\n if (offset + ext > buf.length) throw new RangeError('Index out of range')\n}\n\nBuffer.prototype.writeUIntLE = function writeUIntLE (value, offset, byteLength, noAssert) {\n value = +value\n offset = offset | 0\n byteLength = byteLength | 0\n if (!noAssert) {\n var maxBytes = Math.pow(2, 8 * byteLength) - 1\n checkInt(this, value, offset, byteLength, maxBytes, 0)\n }\n\n var mul = 1\n var i = 0\n this[offset] = value & 0xFF\n while (++i < byteLength && (mul *= 0x100)) {\n this[offset + i] = (value / mul) & 0xFF\n }\n\n return offset + byteLength\n}\n\nBuffer.prototype.writeUIntBE = function writeUIntBE (value, offset, byteLength, noAssert) {\n value = +value\n offset = offset | 0\n byteLength = byteLength | 0\n if (!noAssert) {\n var maxBytes = Math.pow(2, 8 * byteLength) - 1\n checkInt(this, value, offset, byteLength, maxBytes, 0)\n }\n\n var i = byteLength - 1\n var mul = 1\n this[offset + i] = value & 0xFF\n while (--i >= 0 && (mul *= 0x100)) {\n this[offset + i] = (value / mul) & 0xFF\n }\n\n return offset + byteLength\n}\n\nBuffer.prototype.writeUInt8 = function writeUInt8 (value, offset, noAssert) {\n value = +value\n offset = offset | 0\n if (!noAssert) checkInt(this, value, offset, 1, 0xff, 0)\n if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value)\n this[offset] = (value & 0xff)\n return offset + 1\n}\n\nfunction objectWriteUInt16 (buf, value, offset, littleEndian) {\n if (value < 0) value = 0xffff + value + 1\n for (var i = 0, j = Math.min(buf.length - offset, 2); i < j; ++i) {\n buf[offset + i] = (value & (0xff << (8 * (littleEndian ? i : 1 - i)))) >>>\n (littleEndian ? i : 1 - i) * 8\n }\n}\n\nBuffer.prototype.writeUInt16LE = function writeUInt16LE (value, offset, noAssert) {\n value = +value\n offset = offset | 0\n if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)\n if (Buffer.TYPED_ARRAY_SUPPORT) {\n this[offset] = (value & 0xff)\n this[offset + 1] = (value >>> 8)\n } else {\n objectWriteUInt16(this, value, offset, true)\n }\n return offset + 2\n}\n\nBuffer.prototype.writeUInt16BE = function writeUInt16BE (value, offset, noAssert) {\n value = +value\n offset = offset | 0\n if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)\n if (Buffer.TYPED_ARRAY_SUPPORT) {\n this[offset] = (value >>> 8)\n this[offset + 1] = (value & 0xff)\n } else {\n objectWriteUInt16(this, value, offset, false)\n }\n return offset + 2\n}\n\nfunction objectWriteUInt32 (buf, value, offset, littleEndian) {\n if (value < 0) value = 0xffffffff + value + 1\n for (var i = 0, j = Math.min(buf.length - offset, 4); i < j; ++i) {\n buf[offset + i] = (value >>> (littleEndian ? i : 3 - i) * 8) & 0xff\n }\n}\n\nBuffer.prototype.writeUInt32LE = function writeUInt32LE (value, offset, noAssert) {\n value = +value\n offset = offset | 0\n if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)\n if (Buffer.TYPED_ARRAY_SUPPORT) {\n this[offset + 3] = (value >>> 24)\n this[offset + 2] = (value >>> 16)\n this[offset + 1] = (value >>> 8)\n this[offset] = (value & 0xff)\n } else {\n objectWriteUInt32(this, value, offset, true)\n }\n return offset + 4\n}\n\nBuffer.prototype.writeUInt32BE = function writeUInt32BE (value, offset, noAssert) {\n value = +value\n offset = offset | 0\n if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)\n if (Buffer.TYPED_ARRAY_SUPPORT) {\n this[offset] = (value >>> 24)\n this[offset + 1] = (value >>> 16)\n this[offset + 2] = (value >>> 8)\n this[offset + 3] = (value & 0xff)\n } else {\n objectWriteUInt32(this, value, offset, false)\n }\n return offset + 4\n}\n\nBuffer.prototype.writeIntLE = function writeIntLE (value, offset, byteLength, noAssert) {\n value = +value\n offset = offset | 0\n if (!noAssert) {\n var limit = Math.pow(2, 8 * byteLength - 1)\n\n checkInt(this, value, offset, byteLength, limit - 1, -limit)\n }\n\n var i = 0\n var mul = 1\n var sub = 0\n this[offset] = value & 0xFF\n while (++i < byteLength && (mul *= 0x100)) {\n if (value < 0 && sub === 0 && this[offset + i - 1] !== 0) {\n sub = 1\n }\n this[offset + i] = ((value / mul) >> 0) - sub & 0xFF\n }\n\n return offset + byteLength\n}\n\nBuffer.prototype.writeIntBE = function writeIntBE (value, offset, byteLength, noAssert) {\n value = +value\n offset = offset | 0\n if (!noAssert) {\n var limit = Math.pow(2, 8 * byteLength - 1)\n\n checkInt(this, value, offset, byteLength, limit - 1, -limit)\n }\n\n var i = byteLength - 1\n var mul = 1\n var sub = 0\n this[offset + i] = value & 0xFF\n while (--i >= 0 && (mul *= 0x100)) {\n if (value < 0 && sub === 0 && this[offset + i + 1] !== 0) {\n sub = 1\n }\n this[offset + i] = ((value / mul) >> 0) - sub & 0xFF\n }\n\n return offset + byteLength\n}\n\nBuffer.prototype.writeInt8 = function writeInt8 (value, offset, noAssert) {\n value = +value\n offset = offset | 0\n if (!noAssert) checkInt(this, value, offset, 1, 0x7f, -0x80)\n if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value)\n if (value < 0) value = 0xff + value + 1\n this[offset] = (value & 0xff)\n return offset + 1\n}\n\nBuffer.prototype.writeInt16LE = function writeInt16LE (value, offset, noAssert) {\n value = +value\n offset = offset | 0\n if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)\n if (Buffer.TYPED_ARRAY_SUPPORT) {\n this[offset] = (value & 0xff)\n this[offset + 1] = (value >>> 8)\n } else {\n objectWriteUInt16(this, value, offset, true)\n }\n return offset + 2\n}\n\nBuffer.prototype.writeInt16BE = function writeInt16BE (value, offset, noAssert) {\n value = +value\n offset = offset | 0\n if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)\n if (Buffer.TYPED_ARRAY_SUPPORT) {\n this[offset] = (value >>> 8)\n this[offset + 1] = (value & 0xff)\n } else {\n objectWriteUInt16(this, value, offset, false)\n }\n return offset + 2\n}\n\nBuffer.prototype.writeInt32LE = function writeInt32LE (value, offset, noAssert) {\n value = +value\n offset = offset | 0\n if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)\n if (Buffer.TYPED_ARRAY_SUPPORT) {\n this[offset] = (value & 0xff)\n this[offset + 1] = (value >>> 8)\n this[offset + 2] = (value >>> 16)\n this[offset + 3] = (value >>> 24)\n } else {\n objectWriteUInt32(this, value, offset, true)\n }\n return offset + 4\n}\n\nBuffer.prototype.writeInt32BE = function writeInt32BE (value, offset, noAssert) {\n value = +value\n offset = offset | 0\n if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)\n if (value < 0) value = 0xffffffff + value + 1\n if (Buffer.TYPED_ARRAY_SUPPORT) {\n this[offset] = (value >>> 24)\n this[offset + 1] = (value >>> 16)\n this[offset + 2] = (value >>> 8)\n this[offset + 3] = (value & 0xff)\n } else {\n objectWriteUInt32(this, value, offset, false)\n }\n return offset + 4\n}\n\nfunction checkIEEE754 (buf, value, offset, ext, max, min) {\n if (offset + ext > buf.length) throw new RangeError('Index out of range')\n if (offset < 0) throw new RangeError('Index out of range')\n}\n\nfunction writeFloat (buf, value, offset, littleEndian, noAssert) {\n if (!noAssert) {\n checkIEEE754(buf, value, offset, 4, 3.4028234663852886e+38, -3.4028234663852886e+38)\n }\n ieee754.write(buf, value, offset, littleEndian, 23, 4)\n return offset + 4\n}\n\nBuffer.prototype.writeFloatLE = function writeFloatLE (value, offset, noAssert) {\n return writeFloat(this, value, offset, true, noAssert)\n}\n\nBuffer.prototype.writeFloatBE = function writeFloatBE (value, offset, noAssert) {\n return writeFloat(this, value, offset, false, noAssert)\n}\n\nfunction writeDouble (buf, value, offset, littleEndian, noAssert) {\n if (!noAssert) {\n checkIEEE754(buf, value, offset, 8, 1.7976931348623157E+308, -1.7976931348623157E+308)\n }\n ieee754.write(buf, value, offset, littleEndian, 52, 8)\n return offset + 8\n}\n\nBuffer.prototype.writeDoubleLE = function writeDoubleLE (value, offset, noAssert) {\n return writeDouble(this, value, offset, true, noAssert)\n}\n\nBuffer.prototype.writeDoubleBE = function writeDoubleBE (value, offset, noAssert) {\n return writeDouble(this, value, offset, false, noAssert)\n}\n\n// copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length)\nBuffer.prototype.copy = function copy (target, targetStart, start, end) {\n if (!start) start = 0\n if (!end && end !== 0) end = this.length\n if (targetStart >= target.length) targetStart = target.length\n if (!targetStart) targetStart = 0\n if (end > 0 && end < start) end = start\n\n // Copy 0 bytes; we're done\n if (end === start) return 0\n if (target.length === 0 || this.length === 0) return 0\n\n // Fatal error conditions\n if (targetStart < 0) {\n throw new RangeError('targetStart out of bounds')\n }\n if (start < 0 || start >= this.length) throw new RangeError('sourceStart out of bounds')\n if (end < 0) throw new RangeError('sourceEnd out of bounds')\n\n // Are we oob?\n if (end > this.length) end = this.length\n if (target.length - targetStart < end - start) {\n end = target.length - targetStart + start\n }\n\n var len = end - start\n var i\n\n if (this === target && start < targetStart && targetStart < end) {\n // descending copy from end\n for (i = len - 1; i >= 0; --i) {\n target[i + targetStart] = this[i + start]\n }\n } else if (len < 1000 || !Buffer.TYPED_ARRAY_SUPPORT) {\n // ascending copy from start\n for (i = 0; i < len; ++i) {\n target[i + targetStart] = this[i + start]\n }\n } else {\n Uint8Array.prototype.set.call(\n target,\n this.subarray(start, start + len),\n targetStart\n )\n }\n\n return len\n}\n\n// Usage:\n// buffer.fill(number[, offset[, end]])\n// buffer.fill(buffer[, offset[, end]])\n// buffer.fill(string[, offset[, end]][, encoding])\nBuffer.prototype.fill = function fill (val, start, end, encoding) {\n // Handle string cases:\n if (typeof val === 'string') {\n if (typeof start === 'string') {\n encoding = start\n start = 0\n end = this.length\n } else if (typeof end === 'string') {\n encoding = end\n end = this.length\n }\n if (val.length === 1) {\n var code = val.charCodeAt(0)\n if (code < 256) {\n val = code\n }\n }\n if (encoding !== undefined && typeof encoding !== 'string') {\n throw new TypeError('encoding must be a string')\n }\n if (typeof encoding === 'string' && !Buffer.isEncoding(encoding)) {\n throw new TypeError('Unknown encoding: ' + encoding)\n }\n } else if (typeof val === 'number') {\n val = val & 255\n }\n\n // Invalid ranges are not set to a default, so can range check early.\n if (start < 0 || this.length < start || this.length < end) {\n throw new RangeError('Out of range index')\n }\n\n if (end <= start) {\n return this\n }\n\n start = start >>> 0\n end = end === undefined ? this.length : end >>> 0\n\n if (!val) val = 0\n\n var i\n if (typeof val === 'number') {\n for (i = start; i < end; ++i) {\n this[i] = val\n }\n } else {\n var bytes = Buffer.isBuffer(val)\n ? val\n : utf8ToBytes(new Buffer(val, encoding).toString())\n var len = bytes.length\n for (i = 0; i < end - start; ++i) {\n this[i + start] = bytes[i % len]\n }\n }\n\n return this\n}\n\n// HELPER FUNCTIONS\n// ================\n\nvar INVALID_BASE64_RE = /[^+\\/0-9A-Za-z-_]/g\n\nfunction base64clean (str) {\n // Node strips out invalid characters like \\n and \\t from the string, base64-js does not\n str = stringtrim(str).replace(INVALID_BASE64_RE, '')\n // Node converts strings with length < 2 to ''\n if (str.length < 2) return ''\n // Node allows for non-padded base64 strings (missing trailing ===), base64-js does not\n while (str.length % 4 !== 0) {\n str = str + '='\n }\n return str\n}\n\nfunction stringtrim (str) {\n if (str.trim) return str.trim()\n return str.replace(/^\\s+|\\s+$/g, '')\n}\n\nfunction toHex (n) {\n if (n < 16) return '0' + n.toString(16)\n return n.toString(16)\n}\n\nfunction utf8ToBytes (string, units) {\n units = units || Infinity\n var codePoint\n var length = string.length\n var leadSurrogate = null\n var bytes = []\n\n for (var i = 0; i < length; ++i) {\n codePoint = string.charCodeAt(i)\n\n // is surrogate component\n if (codePoint > 0xD7FF && codePoint < 0xE000) {\n // last char was a lead\n if (!leadSurrogate) {\n // no lead yet\n if (codePoint > 0xDBFF) {\n // unexpected trail\n if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)\n continue\n } else if (i + 1 === length) {\n // unpaired lead\n if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)\n continue\n }\n\n // valid lead\n leadSurrogate = codePoint\n\n continue\n }\n\n // 2 leads in a row\n if (codePoint < 0xDC00) {\n if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)\n leadSurrogate = codePoint\n continue\n }\n\n // valid surrogate pair\n codePoint = (leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00) + 0x10000\n } else if (leadSurrogate) {\n // valid bmp char, but last char was a lead\n if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)\n }\n\n leadSurrogate = null\n\n // encode utf8\n if (codePoint < 0x80) {\n if ((units -= 1) < 0) break\n bytes.push(codePoint)\n } else if (codePoint < 0x800) {\n if ((units -= 2) < 0) break\n bytes.push(\n codePoint >> 0x6 | 0xC0,\n codePoint & 0x3F | 0x80\n )\n } else if (codePoint < 0x10000) {\n if ((units -= 3) < 0) break\n bytes.push(\n codePoint >> 0xC | 0xE0,\n codePoint >> 0x6 & 0x3F | 0x80,\n codePoint & 0x3F | 0x80\n )\n } else if (codePoint < 0x110000) {\n if ((units -= 4) < 0) break\n bytes.push(\n codePoint >> 0x12 | 0xF0,\n codePoint >> 0xC & 0x3F | 0x80,\n codePoint >> 0x6 & 0x3F | 0x80,\n codePoint & 0x3F | 0x80\n )\n } else {\n throw new Error('Invalid code point')\n }\n }\n\n return bytes\n}\n\nfunction asciiToBytes (str) {\n var byteArray = []\n for (var i = 0; i < str.length; ++i) {\n // Node's code seems to be doing this and not & 0x7F..\n byteArray.push(str.charCodeAt(i) & 0xFF)\n }\n return byteArray\n}\n\nfunction utf16leToBytes (str, units) {\n var c, hi, lo\n var byteArray = []\n for (var i = 0; i < str.length; ++i) {\n if ((units -= 2) < 0) break\n\n c = str.charCodeAt(i)\n hi = c >> 8\n lo = c % 256\n byteArray.push(lo)\n byteArray.push(hi)\n }\n\n return byteArray\n}\n\nfunction base64ToBytes (str) {\n return base64.toByteArray(base64clean(str))\n}\n\nfunction blitBuffer (src, dst, offset, length) {\n for (var i = 0; i < length; ++i) {\n if ((i + offset >= dst.length) || (i >= src.length)) break\n dst[i + offset] = src[i]\n }\n return i\n}\n\nfunction isnan (val) {\n return val !== val // eslint-disable-line no-self-compare\n}\n\n/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(61)))\n\n/***/ }),\n/* 61 */\n/***/ (function(module, exports) {\n\nvar g;\n\n// This works in non-strict mode\ng = (function() {\n\treturn this;\n})();\n\ntry {\n\t// This works if eval is allowed (see CSP)\n\tg = g || new Function(\"return this\")();\n} catch (e) {\n\t// This works if the window reference is available\n\tif (typeof window === \"object\") g = window;\n}\n\n// g can still be undefined, but nothing to do about it...\n// We return undefined, instead of nothing here, so it's\n// easier to handle this case. if(!global) { ...}\n\nmodule.exports = g;\n\n\n/***/ }),\n/* 62 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"base64-js\");\n\n/***/ }),\n/* 63 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"ieee754\");\n\n/***/ }),\n/* 64 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"isarray\");\n\n/***/ }),\n/* 65 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"cross-fetch/polyfill\");\n\n/***/ }),\n/* 66 */\n/***/ (function(module, exports) {\n\nmodule.exports = require(\"encode-3986\");\n\n/***/ }),\n/* 67 */\n/***/ (function(module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\n// ESM COMPAT FLAG\n__webpack_require__.r(__webpack_exports__);\n\n// NAMESPACE OBJECT: ./src/execute/oas3/parameter-builders.js\nvar oas3_parameter_builders_namespaceObject = {};\n__webpack_require__.r(oas3_parameter_builders_namespaceObject);\n__webpack_require__.d(oas3_parameter_builders_namespaceObject, \"path\", function() { return parameter_builders_path; });\n__webpack_require__.d(oas3_parameter_builders_namespaceObject, \"query\", function() { return query; });\n__webpack_require__.d(oas3_parameter_builders_namespaceObject, \"header\", function() { return header; });\n__webpack_require__.d(oas3_parameter_builders_namespaceObject, \"cookie\", function() { return cookie; });\n\n// EXTERNAL MODULE: external \"@babel/runtime-corejs2/core-js/object/define-property\"\nvar define_property_ = __webpack_require__(10);\nvar define_property_default = /*#__PURE__*/__webpack_require__.n(define_property_);\n\n// EXTERNAL MODULE: external \"@babel/runtime-corejs2/core-js/object/define-properties\"\nvar define_properties_ = __webpack_require__(11);\nvar define_properties_default = /*#__PURE__*/__webpack_require__.n(define_properties_);\n\n// EXTERNAL MODULE: external \"@babel/runtime-corejs2/core-js/object/get-own-property-descriptors\"\nvar get_own_property_descriptors_ = __webpack_require__(5);\nvar get_own_property_descriptors_default = /*#__PURE__*/__webpack_require__.n(get_own_property_descriptors_);\n\n// EXTERNAL MODULE: external \"@babel/runtime-corejs2/core-js/object/get-own-property-descriptor\"\nvar get_own_property_descriptor_ = __webpack_require__(6);\nvar get_own_property_descriptor_default = /*#__PURE__*/__webpack_require__.n(get_own_property_descriptor_);\n\n// EXTERNAL MODULE: external \"@babel/runtime-corejs2/core-js/object/get-own-property-symbols\"\nvar get_own_property_symbols_ = __webpack_require__(7);\nvar get_own_property_symbols_default = /*#__PURE__*/__webpack_require__.n(get_own_property_symbols_);\n\n// EXTERNAL MODULE: external \"@babel/runtime-corejs2/core-js/object/keys\"\nvar keys_ = __webpack_require__(0);\nvar keys_default = /*#__PURE__*/__webpack_require__.n(keys_);\n\n// EXTERNAL MODULE: external \"@babel/runtime-corejs2/helpers/defineProperty\"\nvar defineProperty_ = __webpack_require__(8);\nvar defineProperty_default = /*#__PURE__*/__webpack_require__.n(defineProperty_);\n\n// EXTERNAL MODULE: external \"lodash/cloneDeep\"\nvar cloneDeep_ = __webpack_require__(59);\n\n// EXTERNAL MODULE: external \"lodash/assign\"\nvar assign_ = __webpack_require__(16);\nvar assign_default = /*#__PURE__*/__webpack_require__.n(assign_);\n\n// EXTERNAL MODULE: external \"lodash/startsWith\"\nvar startsWith_ = __webpack_require__(31);\nvar startsWith_default = /*#__PURE__*/__webpack_require__.n(startsWith_);\n\n// EXTERNAL MODULE: external \"url\"\nvar external_url_ = __webpack_require__(12);\nvar external_url_default = /*#__PURE__*/__webpack_require__.n(external_url_);\n\n// EXTERNAL MODULE: ./src/http.js\nvar src_http = __webpack_require__(9);\n\n// EXTERNAL MODULE: external \"@babel/runtime-corejs2/regenerator\"\nvar regenerator_ = __webpack_require__(4);\nvar regenerator_default = /*#__PURE__*/__webpack_require__.n(regenerator_);\n\n// EXTERNAL MODULE: external \"@babel/runtime-corejs2/helpers/asyncToGenerator\"\nvar asyncToGenerator_ = __webpack_require__(25);\nvar asyncToGenerator_default = /*#__PURE__*/__webpack_require__.n(asyncToGenerator_);\n\n// EXTERNAL MODULE: external \"@babel/runtime-corejs2/core-js/get-iterator\"\nvar get_iterator_ = __webpack_require__(22);\nvar get_iterator_default = /*#__PURE__*/__webpack_require__.n(get_iterator_);\n\n// EXTERNAL MODULE: external \"@babel/runtime-corejs2/core-js/symbol/iterator\"\nvar iterator_ = __webpack_require__(23);\nvar iterator_default = /*#__PURE__*/__webpack_require__.n(iterator_);\n\n// EXTERNAL MODULE: external \"@babel/runtime-corejs2/core-js/symbol\"\nvar symbol_ = __webpack_require__(24);\nvar symbol_default = /*#__PURE__*/__webpack_require__.n(symbol_);\n\n// EXTERNAL MODULE: external \"@babel/runtime-corejs2/core-js/array/from\"\nvar from_ = __webpack_require__(20);\nvar from_default = /*#__PURE__*/__webpack_require__.n(from_);\n\n// EXTERNAL MODULE: external \"@babel/runtime-corejs2/core-js/json/stringify\"\nvar stringify_ = __webpack_require__(13);\nvar stringify_default = /*#__PURE__*/__webpack_require__.n(stringify_);\n\n// EXTERNAL MODULE: external \"@babel/runtime-corejs2/helpers/typeof\"\nvar typeof_ = __webpack_require__(2);\nvar typeof_default = /*#__PURE__*/__webpack_require__.n(typeof_);\n\n// EXTERNAL MODULE: external \"@babel/runtime-corejs2/core-js/promise\"\nvar promise_ = __webpack_require__(15);\nvar promise_default = /*#__PURE__*/__webpack_require__.n(promise_);\n\n// EXTERNAL MODULE: external \"@babel/runtime-corejs2/core-js/array/is-array\"\nvar is_array_ = __webpack_require__(1);\nvar is_array_default = /*#__PURE__*/__webpack_require__.n(is_array_);\n\n// EXTERNAL MODULE: external \"@babel/runtime-corejs2/core-js/object/create\"\nvar create_ = __webpack_require__(36);\nvar create_default = /*#__PURE__*/__webpack_require__.n(create_);\n\n// EXTERNAL MODULE: external \"@babel/runtime-corejs2/core-js/object/assign\"\nvar object_assign_ = __webpack_require__(3);\nvar object_assign_default = /*#__PURE__*/__webpack_require__.n(object_assign_);\n\n// EXTERNAL MODULE: external \"@babel/runtime-corejs2/helpers/classCallCheck\"\nvar classCallCheck_ = __webpack_require__(27);\nvar classCallCheck_default = /*#__PURE__*/__webpack_require__.n(classCallCheck_);\n\n// EXTERNAL MODULE: external \"@babel/runtime-corejs2/helpers/createClass\"\nvar createClass_ = __webpack_require__(28);\nvar createClass_default = /*#__PURE__*/__webpack_require__.n(createClass_);\n\n// EXTERNAL MODULE: external \"lodash/find\"\nvar find_ = __webpack_require__(48);\nvar find_default = /*#__PURE__*/__webpack_require__.n(find_);\n\n// EXTERNAL MODULE: external \"lodash/noop\"\nvar noop_ = __webpack_require__(37);\nvar noop_default = /*#__PURE__*/__webpack_require__.n(noop_);\n\n// EXTERNAL MODULE: external \"@babel/runtime-corejs2/helpers/toConsumableArray\"\nvar toConsumableArray_ = __webpack_require__(14);\nvar toConsumableArray_default = /*#__PURE__*/__webpack_require__.n(toConsumableArray_);\n\n// EXTERNAL MODULE: external \"fast-json-patch\"\nvar external_fast_json_patch_ = __webpack_require__(29);\nvar external_fast_json_patch_default = /*#__PURE__*/__webpack_require__.n(external_fast_json_patch_);\n\n// EXTERNAL MODULE: external \"deep-extend\"\nvar external_deep_extend_ = __webpack_require__(49);\nvar external_deep_extend_default = /*#__PURE__*/__webpack_require__.n(external_deep_extend_);\n\n// EXTERNAL MODULE: external \"@kyleshockey/object-assign-deep\"\nvar object_assign_deep_ = __webpack_require__(50);\nvar object_assign_deep_default = /*#__PURE__*/__webpack_require__.n(object_assign_deep_);\n\n// CONCATENATED MODULE: ./src/specmap/lib/index.js\n\n\n\n\n\n/* harmony default export */ var lib = ({\n add: add,\n replace: replace,\n remove: remove,\n merge: merge,\n mergeDeep: mergeDeep,\n context: context,\n getIn: getIn,\n applyPatch: applyPatch,\n parentPathMatch: parentPathMatch,\n flatten: flatten,\n fullyNormalizeArray: fullyNormalizeArray,\n normalizeArray: lib_normalizeArray,\n isPromise: isPromise,\n forEachNew: forEachNew,\n forEachNewPrimitive: forEachNewPrimitive,\n isJsonPatch: isJsonPatch,\n isContextPatch: isContextPatch,\n isPatch: isPatch,\n isMutation: isMutation,\n isAdditiveMutation: isAdditiveMutation,\n isGenerator: isGenerator,\n isFunction: isFunction,\n isObject: isObject,\n isError: isError });\n\n\nfunction applyPatch(obj, patch, opts) {\n opts = opts || {};\n\n patch = object_assign_default()({}, patch, {\n path: patch.path && normalizeJSONPath(patch.path) });\n\n\n if (patch.op === 'merge') {\n var newValue = getInByJsonPath(obj, patch.path);\n object_assign_default()(newValue, patch.value);\n external_fast_json_patch_default.a.applyPatch(obj, [replace(patch.path, newValue)]);\n } else\n if (patch.op === 'mergeDeep') {\n var currentValue = getInByJsonPath(obj, patch.path);\n\n // Iterate the properties of the patch\n for (var prop in patch.value) {\n var propVal = patch.value[prop];\n var isArray = is_array_default()(propVal);\n if (isArray) {\n // deepExtend doesn't merge arrays, so we will do it manually\n var existing = currentValue[prop] || [];\n currentValue[prop] = existing.concat(propVal);\n } else\n if (isObject(propVal) && !isArray) {\n // If it's an object, iterate it's keys and merge\n // if there are conflicting keys, merge deep, otherwise shallow merge\n var currentObj = object_assign_default()({}, currentValue[prop]);\n for (var key in propVal) {\n if (Object.prototype.hasOwnProperty.call(currentObj, key)) {\n // if there is a single conflicting key, just deepExtend the entire value\n // and break from the loop (since all future keys are also merged)\n // We do this because we can't deepExtend two primitives\n // (currentObj[key] & propVal[key] may be primitives).\n //\n // we also deeply assign here, since we aren't in control of\n // how deepExtend affects existing nested objects\n currentObj = external_deep_extend_default()(object_assign_deep_default()({}, currentObj), propVal);\n break;\n } else\n {\n object_assign_default()(currentObj, defineProperty_default()({}, key, propVal[key]));\n }\n }\n currentValue[prop] = currentObj;\n } else\n {\n // It's a primitive, just replace existing\n currentValue[prop] = propVal;\n }\n }\n } else\n if (patch.op === 'add' && patch.path === '' && isObject(patch.value)) {\n // { op: 'add', path: '', value: { a: 1, b: 2 }}\n // has no effect: json patch refuses to do anything.\n // so let's break that patch down into a set of patches,\n // one for each key in the intended root value.\n\n var patches = keys_default()(patch.value).\n reduce(function (arr, key) {\n arr.push({\n op: 'add',\n path: \"/\".concat(normalizeJSONPath(key)),\n value: patch.value[key] });\n\n return arr;\n }, []);\n\n external_fast_json_patch_default.a.applyPatch(obj, patches);\n } else\n if (patch.op === 'replace' && patch.path === '') {\n var value = patch.value;\n\n if (opts.allowMetaPatches && patch.meta && isAdditiveMutation(patch) && (\n is_array_default()(patch.value) || isObject(patch.value))) {\n value = object_assign_default()({}, value, patch.meta);\n }\n obj = value;\n } else\n {\n external_fast_json_patch_default.a.applyPatch(obj, [patch]);\n\n // Attach metadata to the resulting value.\n if (opts.allowMetaPatches && patch.meta && isAdditiveMutation(patch) && (\n is_array_default()(patch.value) || isObject(patch.value))) {\n var _currentValue = getInByJsonPath(obj, patch.path);\n var _newValue = object_assign_default()({}, _currentValue, patch.meta);\n external_fast_json_patch_default.a.applyPatch(obj, [replace(patch.path, _newValue)]);\n }\n }\n\n return obj;\n}\n\nfunction normalizeJSONPath(path) {\n if (is_array_default()(path)) {\n if (path.length < 1) {\n return '';\n }\n\n return '/' + path.map(function (item) {// eslint-disable-line prefer-template\n return (item + '').replace(/~/g, '~0').replace(/\\//g, '~1'); // eslint-disable-line prefer-template\n }).join('/');\n }\n\n return path;\n}\n\n\n// =========================\n// JSON-Patch Wrappers\n// =========================\n\nfunction add(path, value) {\n return { op: 'add', path: path, value: value };\n}\n\nfunction lib_get(path) {\n return { op: '_get', path: path };\n}\n\nfunction replace(path, value, meta) {\n return { op: 'replace', path: path, value: value, meta: meta };\n}\n\nfunction remove(path, value) {\n return { op: 'remove', path: path };\n}\n\n// Custom wrappers\nfunction merge(path, value) {\n return { type: 'mutation', op: 'merge', path: path, value: value };\n}\n\n// Custom wrappers\nfunction mergeDeep(path, value) {\n return { type: 'mutation', op: 'mergeDeep', path: path, value: value };\n}\n\nfunction context(path, value) {\n return { type: 'context', path: path, value: value };\n}\n\n\n// =========================\n// Iterators\n// =========================\n\nfunction forEachNew(mutations, fn) {\n try {\n return forEachNewPatch(mutations, forEach, fn);\n }\n catch (e) {\n return e;\n }\n}\n\nfunction forEachNewPrimitive(mutations, fn) {\n try {\n return forEachNewPatch(mutations, forEachPrimitive, fn);\n }\n catch (e) {\n return e;\n }\n}\n\nfunction forEachNewPatch(mutations, fn, callback) {\n var res = mutations.filter(isAdditiveMutation).map(function (mutation) {\n return fn(mutation.value, callback, mutation.path);\n }) || [];\n var flat = flatten(res);\n var clean = cleanArray(flat);\n return clean;\n}\n\nfunction forEachPrimitive(obj, fn, basePath) {\n basePath = basePath || [];\n\n if (is_array_default()(obj)) {\n return obj.map(function (val, key) {\n return forEachPrimitive(val, fn, basePath.concat(key));\n });\n }\n\n if (isObject(obj)) {\n return keys_default()(obj).map(function (key) {\n return forEachPrimitive(obj[key], fn, basePath.concat(key));\n });\n }\n\n return fn(obj, basePath[basePath.length - 1], basePath);\n}\n\nfunction forEach(obj, fn, basePath) {\n basePath = basePath || [];\n\n var results = [];\n if (basePath.length > 0) {\n var newResults = fn(obj, basePath[basePath.length - 1], basePath);\n if (newResults) {\n results = results.concat(newResults);\n }\n }\n\n if (is_array_default()(obj)) {\n var arrayResults = obj.map(function (val, key) {\n return forEach(val, fn, basePath.concat(key));\n });\n if (arrayResults) {\n results = results.concat(arrayResults);\n }\n } else\n if (isObject(obj)) {\n var moreResults = keys_default()(obj).map(function (key) {\n return forEach(obj[key], fn, basePath.concat(key));\n });\n if (moreResults) {\n results = results.concat(moreResults);\n }\n }\n\n results = flatten(results);\n return results;\n}\n\n\n// =========================\n// Paths\n// =========================\n\nfunction parentPathMatch(path, arr) {\n if (!is_array_default()(arr)) {\n return false;\n }\n\n for (var i = 0, len = arr.length; i < len; i++) {\n if (arr[i] !== path[i]) {\n return false;\n }\n }\n\n return true;\n}\n\nfunction getIn(obj, path) {\n return path.reduce(function (val, token) {\n if (typeof token !== 'undefined' && val) {\n return val[token];\n }\n return val;\n }, obj);\n}\n\n// =========================\n// Array\n// =========================\n\nfunction fullyNormalizeArray(arr) {\n return cleanArray(flatten(lib_normalizeArray(arr)));\n}\n\nfunction lib_normalizeArray(arr) {\n return is_array_default()(arr) ? arr : [arr];\n}\n\nfunction flatten(arr) {var _ref;\n return (_ref = []).concat.apply(_ref, toConsumableArray_default()(arr.map(function (val) {\n return is_array_default()(val) ? flatten(val) : val;\n })));\n}\n\nfunction cleanArray(arr) {\n return arr.filter(function (elm) {return typeof elm !== 'undefined';});\n}\n\n\n// =========================\n// Is-Thing.\n// =========================\n\nfunction isObject(val) {\n return val && typeof_default()(val) === 'object';\n}\n\nfunction isPromise(val) {\n return isObject(val) && isFunction(val.then);\n}\n\nfunction isFunction(val) {\n return val && typeof val === 'function';\n}\n\nfunction isError(patch) {\n return patch instanceof Error;\n}\n\nfunction isJsonPatch(patch) {\n if (isPatch(patch)) {\n var op = patch.op;\n return op === 'add' || op === 'remove' || op === 'replace';\n }\n return false;\n}\n\nfunction isGenerator(thing) {\n return regenerator_default.a.isGeneratorFunction(thing);\n}\n\nfunction isMutation(patch) {\n return isJsonPatch(patch) || isPatch(patch) && patch.type === 'mutation';\n}\n\nfunction isAdditiveMutation(patch) {\n return isMutation(patch) && (patch.op === 'add' || patch.op === 'replace' || patch.op === 'merge' || patch.op === 'mergeDeep');\n}\n\nfunction isContextPatch(patch) {\n return isPatch(patch) && patch.type === 'context';\n}\n\nfunction isPatch(patch) {\n return patch && typeof_default()(patch) === 'object';\n}\n\nfunction getInByJsonPath(obj, jsonPath) {\n try {\n return external_fast_json_patch_default.a.getValueByPointer(obj, jsonPath);\n }\n catch (e) {\n console.error(e); // eslint-disable-line no-console\n return {};\n }\n}\n// EXTERNAL MODULE: external \"@babel/runtime-corejs2/core-js/weak-map\"\nvar weak_map_ = __webpack_require__(51);\nvar weak_map_default = /*#__PURE__*/__webpack_require__.n(weak_map_);\n\n// EXTERNAL MODULE: external \"cross-fetch\"\nvar external_cross_fetch_ = __webpack_require__(52);\n\n// EXTERNAL MODULE: external \"js-yaml\"\nvar external_js_yaml_ = __webpack_require__(33);\nvar external_js_yaml_default = /*#__PURE__*/__webpack_require__.n(external_js_yaml_);\n\n// EXTERNAL MODULE: external \"querystring-browser\"\nvar external_querystring_browser_ = __webpack_require__(38);\nvar external_querystring_browser_default = /*#__PURE__*/__webpack_require__.n(external_querystring_browser_);\n\n// CONCATENATED MODULE: ./src/specmap/lib/create-error.js\nfunction createErrorType(name, init) {\n function E() {\n if (!Error.captureStackTrace) {\n this.stack = new Error().stack;\n } else\n {\n Error.captureStackTrace(this, this.constructor);\n }for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {args[_key] = arguments[_key];}\n this.message = args[0];\n init && init.apply(this, args);\n }\n\n E.prototype = new Error();\n E.prototype.name = name;\n E.prototype.constructor = E;\n\n return E;\n}\n// EXTERNAL MODULE: external \"@babel/runtime-corejs2/helpers/slicedToArray\"\nvar slicedToArray_ = __webpack_require__(18);\nvar slicedToArray_default = /*#__PURE__*/__webpack_require__.n(slicedToArray_);\n\n// EXTERNAL MODULE: external \"traverse\"\nvar external_traverse_ = __webpack_require__(53);\nvar external_traverse_default = /*#__PURE__*/__webpack_require__.n(external_traverse_);\n\n// CONCATENATED MODULE: ./src/specmap/helpers.js\n\n\n\n// This will match if the direct parent's key exactly matches an item.\nvar freelyNamedKeyParents = [\n'properties'];\n\n\n// This will match if the grandparent's key exactly matches an item.\n// NOTE that this is for finding non-free paths!\nvar nonFreelyNamedKeyGrandparents = [\n'properties'];\n\n\n// This will match if the joined parent path exactly matches an item.\n//\n// This is mostly useful for filtering out root-level reusable item names,\n// for example `[\"definitions\", \"$ref\"]`\nvar freelyNamedPaths = [\n// Swagger 2.0\n'definitions',\n'parameters',\n'responses',\n'securityDefinitions',\n\n// OpenAPI 3.0\n'components/schemas',\n'components/responses',\n'components/parameters',\n'components/securitySchemes'];\n\n\n// This will match if any of these items are substrings of the joined\n// parent path.\n//\n// Warning! These are powerful. Beware of edge cases.\nvar freelyNamedAncestors = [\n'schema/example',\n'items/example'];\n\n\nfunction isFreelyNamed(parentPath) {\n var parentKey = parentPath[parentPath.length - 1];\n var grandparentKey = parentPath[parentPath.length - 2];\n var parentStr = parentPath.join('/');\n\n return (\n // eslint-disable-next-line max-len\n freelyNamedKeyParents.indexOf(parentKey) > -1 && nonFreelyNamedKeyGrandparents.indexOf(grandparentKey) === -1 ||\n freelyNamedPaths.indexOf(parentStr) > -1 ||\n freelyNamedAncestors.some(function (el) {return parentStr.indexOf(el) > -1;}));\n\n}\n\nfunction generateAbsoluteRefPatches(obj, basePath)\n\n\n\n{var _ref = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {},specmap = _ref.specmap,_ref$getBaseUrlForNod = _ref.getBaseUrlForNodePath,getBaseUrlForNodePath = _ref$getBaseUrlForNod === void 0 ? function (path) {return specmap.getContext([].concat(toConsumableArray_default()(basePath), toConsumableArray_default()(path))).baseDoc;} : _ref$getBaseUrlForNod,_ref$targetKeys = _ref.targetKeys,targetKeys = _ref$targetKeys === void 0 ? ['$ref', '$$ref'] : _ref$targetKeys;\n var patches = [];\n\n external_traverse_default()(obj).forEach(function () {\n if (targetKeys.indexOf(this.key) > -1) {\n var nodePath = this.path; // this node's path, relative to `obj`\n var fullPath = basePath.concat(this.path);\n\n var absolutifiedRefValue = absolutifyPointer(this.node, getBaseUrlForNodePath(nodePath));\n\n patches.push(specmap.replace(fullPath, absolutifiedRefValue));\n }\n });\n\n return patches;\n}\n\nfunction absolutifyPointer(pointer, baseUrl) {var _pointer$split =\n pointer.split('#'),_pointer$split2 = slicedToArray_default()(_pointer$split, 2),urlPart = _pointer$split2[0],fragmentPart = _pointer$split2[1];\n var newRefUrlPart = external_url_default.a.resolve(urlPart || '', baseUrl || '');\n\n return fragmentPart ? \"\".concat(newRefUrlPart, \"#\").concat(fragmentPart) : newRefUrlPart;\n}\n// CONCATENATED MODULE: ./src/constants.js\nvar ACCEPT_HEADER_VALUE_FOR_DOCUMENTS = 'application/json, application/yaml';\n// CONCATENATED MODULE: ./src/specmap/lib/refs.js\n\n\n\n\n\n\n\n\n\nvar ABSOLUTE_URL_REGEXP = new RegExp('^([a-z]+://|//)', 'i');\n\nvar JSONRefError = createErrorType('JSONRefError', function (message, extra, oriError) {\n this.originalError = oriError;\n object_assign_default()(this, extra || {});\n});\n\nvar docCache = {};\nvar specmapRefs = new weak_map_default.a();\n\nvar skipResolutionTestFns = [\nfunction (path) {return (\n // OpenAPI 3.0 Response Media Type Example\n // [\"paths\", *, *, \"responses\", *, \"content\", *, \"example\"]\n path[0] === 'paths' &&\n path[3] === 'responses' &&\n path[5] === 'content' &&\n path[7] === 'example');},\n\nfunction (path) {return (\n // OpenAPI 3.0 Request Body Media Type Example\n // [\"paths\", *, *, \"responses\", *, \"content\", *, \"example\"]\n path[0] === 'paths' &&\n path[3] === 'requestBody' &&\n path[4] === 'content' &&\n path[6] === 'example');}];\n\n\n\nvar shouldSkipResolution = function shouldSkipResolution(path) {return skipResolutionTestFns.some(function (fn) {return fn(path);});};\n\n// =========================\n// Core\n// =========================\n\n/**\n * This plugin resolves the JSON pointers.\n * A major part of this plugin deals with cyclic references via 2 mechanisms.\n * 1. If a pointer was already resolved before in this path, halt.\n * 2. If the patch value points to one of the ancestors in this path, halt.\n *\n * Note that either one of these mechanism is sufficient, both must be in place.\n * For examples:\n *\n * Given the following spec, #1 alone is insufficient because after the 2nd\n * application, there will be a cyclic object reference.\n * a.b.c: $ref-d\n * d.e.f: $ref-a (per #1, safe to return patch as no immediate cycle)\n *\n * Given the following spec, #2 alone is insufficient because although there will\n * never be any cyclic object reference, the plugin will keep producing patches.\n * a: $ref-b\n * b: $ref-a\n */\nvar refs_plugin = {\n key: '$ref',\n plugin: function plugin(ref, key, fullPath, specmap) {\n var specmapInstance = specmap.getInstance();\n var parent = fullPath.slice(0, -1);\n\n if (isFreelyNamed(parent) || shouldSkipResolution(parent)) {\n return;\n }\n\n var baseDoc = specmap.getContext(fullPath).baseDoc;\n if (typeof ref !== 'string') {\n return new JSONRefError('$ref: must be a string (JSON-Ref)', {\n $ref: ref,\n baseDoc: baseDoc,\n fullPath: fullPath });\n\n }\n\n var splitString = split(ref);\n var refPath = splitString[0];\n var pointer = splitString[1] || '';\n\n var basePath;\n try {\n basePath = baseDoc || refPath ? absoluteify(refPath, baseDoc) : null;\n }\n catch (e) {\n return wrapError(e, {\n pointer: pointer,\n $ref: ref,\n basePath: basePath,\n fullPath: fullPath });\n\n }\n\n var promOrVal;\n var tokens;\n\n if (pointerAlreadyInPath(pointer, basePath, parent, specmap)) {\n // Cyclic reference!\n // if `useCircularStructures` is not set, just leave the reference\n // unresolved, but absolutify it so that we don't leave an invalid $ref\n // path in the content\n if (!specmapInstance.useCircularStructures) {\n var _absolutifiedRef = absolutifyPointer(ref, basePath);\n\n if (ref === _absolutifiedRef) {\n // avoids endless looping\n // without this, the ref plugin never stops seeing this $ref\n return null;\n }\n return lib.replace(fullPath, _absolutifiedRef);\n }\n }\n\n if (basePath == null) {\n tokens = jsonPointerToArray(pointer);\n promOrVal = specmap.get(tokens);\n\n if (typeof promOrVal === 'undefined') {\n promOrVal = new JSONRefError(\"Could not resolve reference: \".concat(ref), {\n pointer: pointer,\n $ref: ref,\n baseDoc: baseDoc,\n fullPath: fullPath });\n\n }\n } else\n {\n promOrVal = extractFromDoc(basePath, pointer);\n if (promOrVal.__value != null) {\n promOrVal = promOrVal.__value;\n } else\n {\n promOrVal = promOrVal.catch(function (e) {\n throw wrapError(e, {\n pointer: pointer,\n $ref: ref,\n baseDoc: baseDoc,\n fullPath: fullPath });\n\n });\n }\n }\n\n if (promOrVal instanceof Error) {\n return [lib.remove(fullPath), promOrVal];\n }\n\n var absolutifiedRef = absolutifyPointer(ref, basePath);\n\n var patch = lib.replace(parent, promOrVal, { $$ref: absolutifiedRef });\n if (basePath && basePath !== baseDoc) {\n return [patch, lib.context(parent, { baseDoc: basePath })];\n }\n\n try {\n // prevents circular values from being constructed, unless we specifically\n // want that to happen\n if (!patchValueAlreadyInPath(specmap.state, patch) || specmapInstance.useCircularStructures) {\n return patch;\n }\n }\n catch (e) {\n // if we're catching here, path traversal failed, so we should\n // ditch without sending any patches back up.\n //\n // this is a narrow fix for the larger problem of patches being queued\n // and then having the state they were generated against be modified\n // before they are applied.\n //\n // TODO: re-engineer specmap patch/state management to avoid this\n return null;\n }\n } };\n\n\n\nvar mod = object_assign_default()(refs_plugin, {\n docCache: docCache,\n absoluteify: absoluteify,\n clearCache: clearCache,\n JSONRefError: JSONRefError,\n wrapError: wrapError,\n getDoc: getDoc,\n split: split,\n extractFromDoc: extractFromDoc,\n fetchJSON: fetchJSON,\n extract: extract,\n jsonPointerToArray: jsonPointerToArray,\n unescapeJsonPointerToken: unescapeJsonPointerToken });\n\n\n/* harmony default export */ var refs = (mod);\n\n\n// =========================\n// Utilities\n// =========================\n\n/**\n * Resolves a path and its base to an abolute URL.\n * @api public\n */\nfunction absoluteify(path, basePath) {\n if (!ABSOLUTE_URL_REGEXP.test(path)) {\n if (!basePath) {\n throw new JSONRefError(\"Tried to resolve a relative URL, without having a basePath. path: '\".concat(path, \"' basePath: '\").concat(basePath, \"'\"));\n }\n return external_url_default.a.resolve(basePath, path);\n }\n return path;\n}\n\n/**\n * Wraps an error as JSONRefError.\n * @param {Error} e the error.\n * @param {Object} extra (optional) optional data.\n * @return {Error} an instance of JSONRefError.\n * @api public\n */\nfunction wrapError(e, extra) {\n var message;\n\n if (e && e.response && e.response.body) {\n message = \"\".concat(e.response.body.code, \" \").concat(e.response.body.message);\n } else\n {\n message = e.message;\n }\n\n return new JSONRefError(\"Could not resolve reference: \".concat(message), extra, e);\n}\n\n/**\n * Splits a pointer by the hash delimiter.\n * @api public\n */\nfunction split(ref) {\n return (ref + '').split('#'); // eslint-disable-line prefer-template\n}\n\n/**\n * Extracts a pointer from its document.\n * @param {String} docPath the absolute document URL.\n * @param {String} pointer the pointer whose value is to be extracted.\n * @return {Promise} a promise of the pointer value.\n * @api public\n */\nfunction extractFromDoc(docPath, pointer) {\n var doc = docCache[docPath];\n if (doc && !lib.isPromise(doc)) {\n // If doc is already available, return __value together with the promise.\n // __value is for special handling in cycle check:\n // pointerAlreadyInPath() won't work if patch.value is a promise,\n // thus when that promise is finally resolved, cycle might happen (because\n // `spec` and `docCache[basePath]` refer to the exact same object).\n // See test \"should resolve a cyclic spec when baseDoc is specified\".\n try {\n var v = extract(pointer, doc);\n return object_assign_default()(promise_default.a.resolve(v), { __value: v });\n }\n catch (e) {\n return promise_default.a.reject(e);\n }\n }\n\n return getDoc(docPath).then(function (_doc) {return extract(pointer, _doc);});\n}\n\n/**\n * Clears all document caches.\n * @param {String} item (optional) the name of the cache item to be cleared.\n * @api public\n */\nfunction clearCache(item) {\n if (typeof item !== 'undefined') {\n delete docCache[item];\n } else\n {\n keys_default()(docCache).forEach(function (key) {\n delete docCache[key];\n });\n }\n}\n\n/**\n * Fetches and caches a document.\n * @param {String} docPath the absolute URL of the document.\n * @return {Promise} a promise of the document content.\n * @api public\n */\nfunction getDoc(docPath) {\n var val = docCache[docPath];\n if (val) {\n return lib.isPromise(val) ? val : promise_default.a.resolve(val);\n }\n\n // NOTE: we need to use `mod.fetchJSON` in order to be able to overwrite it.\n // Any tips on how to make this cleaner, please ping!\n docCache[docPath] = mod.fetchJSON(docPath).then(function (doc) {\n docCache[docPath] = doc;\n return doc;\n });\n return docCache[docPath];\n}\n\n/**\n * Fetches a document.\n * @param {String} docPath the absolute URL of the document.\n * @return {Promise} a promise of the document content.\n * @api public\n */\nfunction fetchJSON(docPath) {\n return Object(external_cross_fetch_[\"fetch\"])(docPath, { headers: { Accept: ACCEPT_HEADER_VALUE_FOR_DOCUMENTS }, loadSpec: true }).\n then(function (res) {return res.text();}).\n then(function (text) {return external_js_yaml_default.a.safeLoad(text);});\n}\n\n/**\n * Extracts a pointer from an object.\n * @param {String[]} pointer the JSON pointer.\n * @param {Object} obj an object whose value is to be extracted.\n * @return {Object} the value to be extracted.\n * @api public\n */\nfunction extract(pointer, obj) {\n var tokens = jsonPointerToArray(pointer);\n if (tokens.length < 1) {\n return obj;\n }\n\n var val = lib.getIn(obj, tokens);\n if (typeof val === 'undefined') {\n throw new JSONRefError(\"Could not resolve pointer: \".concat(pointer, \" does not exist in document\"), { pointer: pointer });\n }\n return val;\n}\n\n/**\n * Converts a JSON pointer to array.\n * @api public\n */\nfunction jsonPointerToArray(pointer) {\n if (typeof pointer !== 'string') {\n throw new TypeError(\"Expected a string, got a \".concat(typeof_default()(pointer)));\n }\n\n if (pointer[0] === '/') {\n pointer = pointer.substr(1);\n }\n\n if (pointer === '') {\n return [];\n }\n\n return pointer.split('/').map(unescapeJsonPointerToken);\n}\n\n/**\n * Unescapes a JSON pointer.\n * @api public\n */\nfunction unescapeJsonPointerToken(token) {\n if (typeof token !== 'string') {\n return token;\n }\n return external_querystring_browser_default.a.unescape(token.replace(/~1/g, '/').replace(/~0/g, '~'));\n}\n\n/**\n * Escapes a JSON pointer.\n * @api public\n */\nfunction escapeJsonPointerToken(token) {\n return external_querystring_browser_default.a.escape(token.replace(/~/g, '~0').replace(/\\//g, '~1'));\n}\n\nfunction arrayToJsonPointer(arr) {\n if (arr.length === 0) {\n return '';\n }\n\n return \"/\".concat(arr.map(escapeJsonPointerToken).join('/'));\n}\n\nvar pointerBoundaryChar = function pointerBoundaryChar(c) {return !c || c === '/' || c === '#';};\n\nfunction pointerIsAParent(pointer, parentPointer) {\n if (pointerBoundaryChar(parentPointer)) {\n // This is the root of the document, so its naturally a parent\n return true;\n }\n var nextChar = pointer.charAt(parentPointer.length);\n var lastParentChar = parentPointer.slice(-1);\n\n return pointer.indexOf(parentPointer) === 0 && (\n !nextChar || nextChar === '/' || nextChar === '#') &&\n lastParentChar !== '#';\n}\n\n\n// =========================\n// Private\n// =========================\n\n/**\n * Checks if this pointer points back to one or more pointers along the path.\n */\nfunction pointerAlreadyInPath(pointer, basePath, parent, specmap) {\n var refs = specmapRefs.get(specmap);\n if (!refs) {\n // Stores all resolved references of a specmap instance.\n // Schema: path -> pointer (path's $ref value).\n refs = {};\n specmapRefs.set(specmap, refs);\n }\n\n var parentPointer = arrayToJsonPointer(parent);\n var fullyQualifiedPointer = \"\".concat(basePath || '', \"#\").concat(pointer);\n\n // dirty hack to strip `allof/[index]` from the path, in order to avoid cases\n // where we get false negatives because:\n // - we resolve a path, then\n // - allOf plugin collapsed `allOf/[index]` out of the path, then\n // - we try to work on a child $ref within that collapsed path.\n //\n // because of the path collapse, we lose track of it in our specmapRefs hash\n // solution: always throw the allOf constructs out of paths we store\n // TODO: solve this with a global register, or by writing more metadata in\n // either allOf or refs plugin\n var safeParentPointer = parentPointer.replace(/allOf\\/\\d+\\/?/g, '');\n\n // Case 1: direct cycle, e.g. a.b.c.$ref: '/a.b'\n // Detect by checking that the parent path doesn't start with pointer.\n // This only applies if the pointer is internal, i.e. basePath === rootPath (could be null)\n var rootDoc = specmap.contextTree.get([]).baseDoc;\n if (basePath == rootDoc && pointerIsAParent(safeParentPointer, pointer)) {// eslint-disable-line\n return true;\n }\n\n\n // Case 2: indirect cycle\n // ex1: a.$ref: '/b' & b.c.$ref: '/b/c'\n // ex2: a.$ref: '/b/c' & b.c.$ref: '/b'\n // Detect by retrieving all the $refs along the path of parent\n // and checking if any starts with pointer or vice versa.\n var currPath = '';\n var hasIndirectCycle = parent.some(function (token) {\n currPath = \"\".concat(currPath, \"/\").concat(escapeJsonPointerToken(token));\n return refs[currPath] && refs[currPath].some(function (ref) {\n return (\n pointerIsAParent(ref, fullyQualifiedPointer) ||\n pointerIsAParent(fullyQualifiedPointer, ref));\n\n });\n });\n if (hasIndirectCycle) {\n return true;\n }\n\n // No cycle, this ref will be resolved, so stores it now for future detection.\n // No need to store if has cycle, as parent path is a dead-end and won't be checked again.\n\n refs[safeParentPointer] = (refs[safeParentPointer] || []).concat(fullyQualifiedPointer);\n}\n\n/**\n * Checks if the value of this patch ends up pointing to an ancestor along the path.\n */\nfunction patchValueAlreadyInPath(root, patch) {\n var ancestors = [root];\n patch.path.reduce(function (parent, p) {\n ancestors.push(parent[p]);\n return parent[p];\n }, root);\n return pointToAncestor(patch.value);\n\n function pointToAncestor(obj) {\n return lib.isObject(obj) && (ancestors.indexOf(obj) >= 0 || keys_default()(obj).some(function (k) {\n return pointToAncestor(obj[k]);\n }));\n }\n}\n// CONCATENATED MODULE: ./src/specmap/lib/all-of.js\n\n\n/* harmony default export */ var all_of = ({\n key: 'allOf',\n plugin: function plugin(val, key, fullPath, specmap, patch) {\n // Ignore replace patches created by $ref because the changes will\n // occur in the original \"add\" patch and we don't want this plugin\n // to redundantly processes those \"relace\" patches.\n if (patch.meta && patch.meta.$$ref) {\n return;\n }\n\n var parent = fullPath.slice(0, -1);\n if (isFreelyNamed(parent)) {\n return;\n }\n\n if (!is_array_default()(val)) {\n var err = new TypeError('allOf must be an array');\n err.fullPath = fullPath; // This is an array\n return err;\n }\n\n\n var alreadyAddError = false;\n\n // Find the original definition from the `patch.value` object\n // Remove the `allOf` property so it doesn't get added to the result of the `allOf` plugin\n var originalDefinitionObj = patch.value;\n parent.forEach(function (part) {\n if (!originalDefinitionObj) return; // bail out if we've lost sight of our target\n originalDefinitionObj = originalDefinitionObj[part];\n });\n originalDefinitionObj = object_assign_default()({}, originalDefinitionObj);\n delete originalDefinitionObj.allOf;\n\n var patches = [];\n\n // remove existing content\n patches.push(specmap.replace(parent, {}));\n\n val.forEach(function (toMerge, i) {\n if (!specmap.isObject(toMerge)) {\n if (alreadyAddError) {\n return null;\n }\n alreadyAddError = true;\n\n var _err = new TypeError('Elements in allOf must be objects');\n _err.fullPath = fullPath; // This is an array\n return patches.push(_err);\n }\n\n // Deeply merge the member's contents onto the parent location\n patches.push(specmap.mergeDeep(parent, toMerge));\n\n // Generate patches that migrate $ref values based on ContextTree information\n\n // remove [\"allOf\"], which will not be present when these patches are applied\n var collapsedFullPath = fullPath.slice(0, -1);\n\n var absoluteRefPatches = generateAbsoluteRefPatches(toMerge, collapsedFullPath, {\n getBaseUrlForNodePath: function getBaseUrlForNodePath(nodePath) {\n return specmap.getContext([].concat(toConsumableArray_default()(fullPath), [i], toConsumableArray_default()(nodePath))).baseDoc;\n },\n specmap: specmap });\n\n\n patches.push.apply(patches, toConsumableArray_default()(absoluteRefPatches));\n });\n\n // Merge back the values from the original definition\n patches.push(specmap.mergeDeep(parent, originalDefinitionObj));\n\n // If there was not an original $$ref value, make sure to remove\n // any $$ref value that may exist from the result of `allOf` merges\n if (!originalDefinitionObj.$$ref) {\n patches.push(specmap.remove([].concat(parent, '$$ref')));\n }\n\n return patches;\n } });\n// CONCATENATED MODULE: ./src/specmap/lib/parameters.js\n\n\n/* harmony default export */ var lib_parameters = ({\n key: 'parameters',\n plugin: function plugin(parameters, key, fullPath, specmap, patch) {\n if (is_array_default()(parameters) && parameters.length) {\n var val = object_assign_default()([], parameters);\n var opPath = fullPath.slice(0, -1);\n var op = object_assign_default()({}, lib.getIn(specmap.spec, opPath));\n\n parameters.forEach(function (param, i) {\n try {\n val[i].default = specmap.parameterMacro(op, param);\n }\n catch (e) {\n var err = new Error(e);\n err.fullPath = fullPath;\n return err;\n }\n });\n\n return lib.replace(fullPath, val);\n }\n\n return lib.replace(fullPath, parameters);\n } });\n// CONCATENATED MODULE: ./src/specmap/lib/properties.js\n\n\n/* harmony default export */ var lib_properties = ({\n key: 'properties',\n plugin: function plugin(properties, key, fullPath, specmap) {\n var val = object_assign_default()({}, properties);\n\n for (var k in properties) {\n try {\n val[k].default = specmap.modelPropertyMacro(val[k]);\n }\n catch (e) {\n var err = new Error(e);\n err.fullPath = fullPath; // This is an array\n return err;\n }\n }\n\n var patch = lib.replace(fullPath, val);\n\n return patch;\n } });\n// CONCATENATED MODULE: ./src/specmap/lib/context-tree.js\nfunction ownKeys(object, enumerableOnly) {var keys = keys_default()(object);if (get_own_property_symbols_default.a) {var symbols = get_own_property_symbols_default()(object);if (enumerableOnly) symbols = symbols.filter(function (sym) {return get_own_property_descriptor_default()(object, sym).enumerable;});keys.push.apply(keys, symbols);}return keys;}function _objectSpread(target) {for (var i = 1; i < arguments.length; i++) {var source = arguments[i] != null ? arguments[i] : {};if (i % 2) {ownKeys(Object(source), true).forEach(function (key) {defineProperty_default()(target, key, source[key]);});} else if (get_own_property_descriptors_default.a) {define_properties_default()(target, get_own_property_descriptors_default()(source));} else {ownKeys(Object(source)).forEach(function (key) {define_property_default()(target, key, get_own_property_descriptor_default()(source, key));});}}return target;}var context_tree_ContextTree = /*#__PURE__*/function () {\n function ContextTree(value) {classCallCheck_default()(this, ContextTree);\n this.root = createNode(value || {});\n }createClass_default()(ContextTree, [{ key: \"set\", value: function set(\n\n path, value) {\n var parent = this.getParent(path, true);\n if (!parent) {\n updateNode(this.root, value, null);\n return;\n }\n\n var key = path[path.length - 1];\n var children = parent.children;\n if (children[key]) {\n updateNode(children[key], value, parent);\n return;\n }\n\n children[key] = createNode(value, parent);\n }\n\n // Get the \"best\" node (node or nearest parent) and return its value.\n }, { key: \"get\", value: function get(path) {\n path = path || [];\n\n if (path.length < 1) {\n return this.root.value;\n }\n\n var branch = this.root;\n var child;\n var token;\n for (var i = 0; i < path.length; i++) {\n token = path[i];\n child = branch.children;\n if (!child[token]) {\n break;\n }\n branch = child[token];\n }\n\n return branch && branch.protoValue;\n } }, { key: \"getParent\", value: function getParent(\n\n path, ensureExists) {\n if (!path || path.length < 1) {\n return null;\n }\n\n if (path.length < 2) {\n return this.root;\n }\n\n return path.slice(0, -1).reduce(function (branch, token) {\n if (!branch) {\n return branch;\n }\n\n var children = branch.children;\n\n if (!children[token] && ensureExists) {\n children[token] = createNode(null, branch);\n }\n\n return children[token];\n }, this.root);\n } }]);return ContextTree;}();\n\n\n// =========================\n// Utilities\n// =========================\n\nfunction createNode(value, parent) {\n return updateNode({ children: {} }, value, parent);\n}\n\nfunction updateNode(node, value, parent) {\n node.value = value || {};\n node.protoValue = parent ? _objectSpread({},\n parent.protoValue, {}, node.value) :\n node.value;\n\n keys_default()(node.children).forEach(function (prop) {\n var child = node.children[prop];\n node.children[prop] = updateNode(child, child.value, node);\n });\n\n return node;\n}\n// CONCATENATED MODULE: ./src/specmap/index.js\nfunction _createForOfIteratorHelper(o) {if (typeof symbol_default.a === \"undefined\" || o[iterator_default.a] == null) {if (is_array_default()(o) || (o = _unsupportedIterableToArray(o))) {var i = 0;var F = function F() {};return { s: F, n: function n() {if (i >= o.length) return { done: true };return { done: false, value: o[i++] };}, e: function e(_e) {throw _e;}, f: F };}throw new TypeError(\"Invalid attempt to iterate non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.\");}var it,normalCompletion = true,didErr = false,err;return { s: function s() {it = get_iterator_default()(o);}, n: function n() {var step = it.next();normalCompletion = step.done;return step;}, e: function e(_e2) {didErr = true;err = _e2;}, f: function f() {try {if (!normalCompletion && it.return != null) it.return();} finally {if (didErr) throw err;}} };}function _unsupportedIterableToArray(o, minLen) {if (!o) return;if (typeof o === \"string\") return _arrayLikeToArray(o, minLen);var n = Object.prototype.toString.call(o).slice(8, -1);if (n === \"Object\" && o.constructor) n = o.constructor.name;if (n === \"Map\" || n === \"Set\") return from_default()(n);if (n === \"Arguments\" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);}function _arrayLikeToArray(arr, len) {if (len == null || len > arr.length) len = arr.length;for (var i = 0, arr2 = new Array(len); i < len; i++) {arr2[i] = arr[i];}return arr2;}\n\n\n\n\n\n\n\n\n\nvar HARD_LIMIT = 100;var\n\nspecmap_SpecMap = /*#__PURE__*/function () {\n function SpecMap(opts) {var _this = this;classCallCheck_default()(this, SpecMap);\n object_assign_default()(this, {\n spec: '',\n debugLevel: 'info',\n plugins: [],\n pluginHistory: {},\n errors: [],\n mutations: [],\n promisedPatches: [],\n state: {},\n patches: [],\n context: {},\n contextTree: new context_tree_ContextTree(),\n showDebug: false,\n allPatches: [], // only populated if showDebug is true\n pluginProp: 'specMap',\n libMethods: object_assign_default()(create_default()(this), lib, {\n getInstance: function getInstance() {return _this;} }),\n\n allowMetaPatches: false },\n opts);\n\n // Lib methods bound\n this.get = this._get.bind(this);\n this.getContext = this._getContext.bind(this);\n this.hasRun = this._hasRun.bind(this);\n\n this.wrappedPlugins = this.plugins.\n map(this.wrapPlugin.bind(this)).\n filter(lib.isFunction);\n\n // Initial patch(s)\n this.patches.push(lib.add([], this.spec));\n this.patches.push(lib.context([], this.context));\n this.updatePatches(this.patches);\n }createClass_default()(SpecMap, [{ key: \"debug\", value: function debug(\n\n level) {\n if (this.debugLevel === level) {var _console;for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {args[_key - 1] = arguments[_key];}\n (_console = console).log.apply(_console, args); // eslint-disable-line no-console\n }\n } }, { key: \"verbose\", value: function verbose(\n\n header) {\n if (this.debugLevel === 'verbose') {var _console2;for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {args[_key2 - 1] = arguments[_key2];}\n (_console2 = console).log.apply(_console2, [\"[\".concat(header, \"] \")].concat(args)); // eslint-disable-line no-console\n }\n } }, { key: \"wrapPlugin\", value: function wrapPlugin(\n\n plugin, name) {\n var pathDiscriminator = this.pathDiscriminator;\n var ctx = null;\n var fn;\n\n if (plugin[this.pluginProp]) {\n ctx = plugin;\n fn = plugin[this.pluginProp];\n } else\n if (lib.isFunction(plugin)) {\n fn = plugin;\n } else\n if (lib.isObject(plugin)) {\n fn = createKeyBasedPlugin(plugin);\n }\n\n return object_assign_default()(fn.bind(ctx), {\n pluginName: plugin.name || name,\n isGenerator: lib.isGenerator(fn) });\n\n\n // Expected plugin interface: {key: string, plugin: fn*}\n // This traverses depth-first and immediately applies yielded patches.\n // This strategy should work well for most plugins (including the built-ins).\n // We might consider making this (traversing & application) configurable later.\n function createKeyBasedPlugin(pluginObj) {\n var isSubPath = function isSubPath(path, tested) {\n if (!is_array_default()(path)) {\n return true;\n }\n\n return path.every(function (val, i) {\n return val === tested[i];\n });\n };\n\n return /*#__PURE__*/regenerator_default.a.mark(function _callee(patches, specmap) {var _marked, refCache, _iterator, _step, patch,\n\n\n\n\n\n\n traverse;return regenerator_default.a.wrap(function _callee$(_context2) {while (1) {switch (_context2.prev = _context2.next) {case 0:traverse = function _traverse(obj, path, patch) {var parentIndex, parent, indexOfFirstProperties, isRootProperties, traversed, _i, _Object$keys, key, val, updatedPath, isObj, objRef, isWithinPathDiscriminator;return regenerator_default.a.wrap(function traverse$(_context) {while (1) {switch (_context.prev = _context.next) {case 0:if (\n lib.isObject(obj)) {_context.next = 6;break;}if (!(\n pluginObj.key === path[path.length - 1])) {_context.next = 4;break;}_context.next = 4;\n return pluginObj.plugin(obj, pluginObj.key, path, specmap);case 4:_context.next = 30;break;case 6:\n\n\n\n parentIndex = path.length - 1;\n parent = path[parentIndex];\n indexOfFirstProperties = path.indexOf('properties');\n isRootProperties = parent === 'properties' && parentIndex === indexOfFirstProperties;\n traversed = specmap.allowMetaPatches && refCache[obj.$$ref];_i = 0, _Object$keys =\n\n keys_default()(obj);case 12:if (!(_i < _Object$keys.length)) {_context.next = 30;break;}key = _Object$keys[_i];\n val = obj[key];\n updatedPath = path.concat(key);\n isObj = lib.isObject(val);\n objRef = obj.$$ref;if (\n\n traversed) {_context.next = 22;break;}if (!\n isObj) {_context.next = 22;break;}\n // Only store the ref if it exists\n if (specmap.allowMetaPatches && objRef) {\n refCache[objRef] = true;\n }\n return _context.delegateYield(traverse(val, updatedPath, patch), \"t0\", 22);case 22:if (!(\n\n\n\n !isRootProperties && key === pluginObj.key)) {_context.next = 27;break;}\n isWithinPathDiscriminator = isSubPath(pathDiscriminator, path);if (!(\n !pathDiscriminator || isWithinPathDiscriminator)) {_context.next = 27;break;}_context.next = 27;\n return pluginObj.plugin(val, key, updatedPath, specmap, patch);case 27:_i++;_context.next = 12;break;case 30:case \"end\":return _context.stop();}}}, _marked);};_marked = /*#__PURE__*/regenerator_default.a.mark(traverse);refCache = {};_iterator = _createForOfIteratorHelper(patches.filter(lib.isAdditiveMutation));_context2.prev = 4;_iterator.s();case 6:if ((_step = _iterator.n()).done) {_context2.next = 11;break;}patch = _step.value;return _context2.delegateYield(traverse(patch.value, patch.path, patch), \"t0\", 9);case 9:_context2.next = 6;break;case 11:_context2.next = 16;break;case 13:_context2.prev = 13;_context2.t1 = _context2[\"catch\"](4);_iterator.e(_context2.t1);case 16:_context2.prev = 16;_iterator.f();return _context2.finish(16);case 19:case \"end\":return _context2.stop();}}}, _callee, null, [[4, 13, 16, 19]]);});\n\n\n\n\n\n\n }\n } }, { key: \"nextPlugin\", value: function nextPlugin()\n\n {var _this2 = this;\n // Array.prototype.find doesn't work in IE 11 :(\n return find_default()(this.wrappedPlugins, function (plugin) {\n var mutations = _this2.getMutationsForPlugin(plugin);\n return mutations.length > 0;\n });\n } }, { key: \"nextPromisedPatch\", value: function nextPromisedPatch()\n\n {\n if (this.promisedPatches.length > 0) {\n return promise_default.a.race(this.promisedPatches.map(function (patch) {return patch.value;}));\n }\n } }, { key: \"getPluginHistory\", value: function getPluginHistory(\n\n plugin) {\n var name = this.getPluginName(plugin);\n return this.pluginHistory[name] || [];\n } }, { key: \"getPluginRunCount\", value: function getPluginRunCount(\n\n plugin) {\n return this.getPluginHistory(plugin).length;\n } }, { key: \"getPluginHistoryTip\", value: function getPluginHistoryTip(\n\n plugin) {\n var history = this.getPluginHistory(plugin);\n var val = history && history[history.length - 1];\n return val || {};\n } }, { key: \"getPluginMutationIndex\", value: function getPluginMutationIndex(\n\n plugin) {\n var mi = this.getPluginHistoryTip(plugin).mutationIndex;\n return typeof mi !== 'number' ? -1 : mi;\n } }, { key: \"getPluginName\", value: function getPluginName(\n\n plugin) {\n return plugin.pluginName;\n } }, { key: \"updatePluginHistory\", value: function updatePluginHistory(\n\n plugin, val) {\n var name = this.getPluginName(plugin);\n var history = this.pluginHistory[name] = this.pluginHistory[name] || [];\n history.push(val);\n } }, { key: \"updatePatches\", value: function updatePatches(\n\n patches, plugin) {var _this3 = this;\n lib.normalizeArray(patches).forEach(function (patch) {\n if (patch instanceof Error) {\n _this3.errors.push(patch);\n return;\n }\n\n try {\n if (!lib.isObject(patch)) {\n _this3.debug('updatePatches', 'Got a non-object patch', patch);\n return;\n }\n\n if (_this3.showDebug) {\n _this3.allPatches.push(patch);\n }\n\n if (lib.isPromise(patch.value)) {\n _this3.promisedPatches.push(patch);\n _this3.promisedPatchThen(patch);\n return;\n }\n\n if (lib.isContextPatch(patch)) {\n _this3.setContext(patch.path, patch.value);\n return;\n }\n\n if (lib.isMutation(patch)) {\n _this3.updateMutations(patch);\n return;\n }\n }\n catch (e) {\n console.error(e); // eslint-disable-line no-console\n _this3.errors.push(e);\n }\n });\n } }, { key: \"updateMutations\", value: function updateMutations(\n\n patch) {\n if (typeof_default()(patch.value) === 'object' && !is_array_default()(patch.value) && this.allowMetaPatches) {\n patch.value = object_assign_default()({}, patch.value);\n }\n\n var result = lib.applyPatch(this.state, patch, { allowMetaPatches: this.allowMetaPatches });\n if (result) {\n this.mutations.push(patch);\n this.state = result;\n }\n } }, { key: \"removePromisedPatch\", value: function removePromisedPatch(\n\n patch) {\n var index = this.promisedPatches.indexOf(patch);\n if (index < 0) {\n this.debug('Tried to remove a promisedPatch that isn\\'t there!');\n return;\n }\n this.promisedPatches.splice(index, 1);\n } }, { key: \"promisedPatchThen\", value: function promisedPatchThen(\n\n patch) {var _this4 = this;\n var value = patch.value = patch.value.\n then(function (val) {\n var promisedPatch = object_assign_default()({}, patch, { value: val });\n _this4.removePromisedPatch(patch);\n _this4.updatePatches(promisedPatch);\n }).\n catch(function (e) {\n _this4.removePromisedPatch(patch);\n _this4.updatePatches(e);\n });\n return value;\n } }, { key: \"getMutations\", value: function getMutations(\n\n from, to) {\n from = from || 0;\n if (typeof to !== 'number') {\n to = this.mutations.length;\n }\n return this.mutations.slice(from, to);\n } }, { key: \"getCurrentMutations\", value: function getCurrentMutations()\n\n {\n return this.getMutationsForPlugin(this.getCurrentPlugin());\n } }, { key: \"getMutationsForPlugin\", value: function getMutationsForPlugin(\n\n plugin) {\n var tip = this.getPluginMutationIndex(plugin);\n return this.getMutations(tip + 1);\n } }, { key: \"getCurrentPlugin\", value: function getCurrentPlugin()\n\n {\n return this.currentPlugin;\n } }, { key: \"getPatchesOfType\", value: function getPatchesOfType(\n\n patches, fn) {\n return patches.filter(fn);\n } }, { key: \"getLib\", value: function getLib()\n\n {\n return this.libMethods;\n } }, { key: \"_get\", value: function _get(\n\n path) {\n return lib.getIn(this.state, path);\n } }, { key: \"_getContext\", value: function _getContext(\n\n path) {\n return this.contextTree.get(path);\n } }, { key: \"setContext\", value: function setContext(\n\n path, value) {\n return this.contextTree.set(path, value);\n } }, { key: \"_hasRun\", value: function _hasRun(\n\n count) {\n var times = this.getPluginRunCount(this.getCurrentPlugin());\n return times > (count || 0);\n } }, { key: \"_clone\", value: function _clone(\n\n obj) {\n // For debugging only\n return JSON.parse(stringify_default()(obj));\n } }, { key: \"dispatch\", value: function dispatch()\n\n {var _this5 = this;\n var that = this;\n var plugin = this.nextPlugin();\n\n if (!plugin) {\n var nextPromise = this.nextPromisedPatch();\n if (nextPromise) {\n return nextPromise.\n then(function () {return _this5.dispatch();}).\n catch(function () {return _this5.dispatch();});\n }\n\n // We're done!\n var result = { spec: this.state, errors: this.errors };\n if (this.showDebug) {\n result.patches = this.allPatches;\n }\n return promise_default.a.resolve(result);\n }\n\n // Makes sure plugin isn't running an endless loop\n that.pluginCount = that.pluginCount || {};\n that.pluginCount[plugin] = (that.pluginCount[plugin] || 0) + 1;\n if (that.pluginCount[plugin] > HARD_LIMIT) {\n return promise_default.a.resolve({\n spec: that.state,\n errors: that.errors.concat(new Error(\"We've reached a hard limit of \".concat(HARD_LIMIT, \" plugin runs\"))) });\n\n }\n\n // A different plugin runs, wait for all promises to resolve, then retry\n if (plugin !== this.currentPlugin && this.promisedPatches.length) {\n var promises = this.promisedPatches.map(function (p) {return p.value;});\n\n // Waits for all to settle instead of Promise.all which stops on rejection\n return promise_default.a.all(promises.map(function (promise) {\n return promise.then(noop_default.a, noop_default.a);\n })).then(function () {return _this5.dispatch();});\n }\n\n // Ok, run the plugin\n return executePlugin();\n\n function executePlugin() {\n that.currentPlugin = plugin;\n var mutations = that.getCurrentMutations();\n var lastMutationIndex = that.mutations.length - 1;\n\n try {\n if (plugin.isGenerator) {var _iterator2 = _createForOfIteratorHelper(\n plugin(mutations, that.getLib())),_step2;try {for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {var yieldedPatches = _step2.value;\n updatePatches(yieldedPatches);\n }} catch (err) {_iterator2.e(err);} finally {_iterator2.f();}\n } else\n {\n var newPatches = plugin(mutations, that.getLib());\n updatePatches(newPatches);\n }\n }\n catch (e) {\n console.error(e); // eslint-disable-line no-console\n updatePatches([object_assign_default()(create_default()(e), { plugin: plugin })]);\n } finally\n {\n that.updatePluginHistory(plugin, { mutationIndex: lastMutationIndex });\n }\n\n return that.dispatch();\n }\n\n function updatePatches(patches) {\n if (patches) {\n patches = lib.fullyNormalizeArray(patches);\n that.updatePatches(patches, plugin);\n }\n }\n } }]);return SpecMap;}();\n\n\nfunction mapSpec(opts) {\n return new specmap_SpecMap(opts).dispatch();\n}\n\nvar plugins = { refs: refs, allOf: all_of, parameters: lib_parameters, properties: lib_properties };\n\n// EXTERNAL MODULE: external \"lodash/isObject\"\nvar isObject_ = __webpack_require__(39);\nvar isObject_default = /*#__PURE__*/__webpack_require__.n(isObject_);\n\n// CONCATENATED MODULE: ./src/helpers.js\nfunction helpers_createForOfIteratorHelper(o) {if (typeof symbol_default.a === \"undefined\" || o[iterator_default.a] == null) {if (is_array_default()(o) || (o = helpers_unsupportedIterableToArray(o))) {var i = 0;var F = function F() {};return { s: F, n: function n() {if (i >= o.length) return { done: true };return { done: false, value: o[i++] };}, e: function e(_e) {throw _e;}, f: F };}throw new TypeError(\"Invalid attempt to iterate non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.\");}var it,normalCompletion = true,didErr = false,err;return { s: function s() {it = get_iterator_default()(o);}, n: function n() {var step = it.next();normalCompletion = step.done;return step;}, e: function e(_e2) {didErr = true;err = _e2;}, f: function f() {try {if (!normalCompletion && it.return != null) it.return();} finally {if (didErr) throw err;}} };}function helpers_unsupportedIterableToArray(o, minLen) {if (!o) return;if (typeof o === \"string\") return helpers_arrayLikeToArray(o, minLen);var n = Object.prototype.toString.call(o).slice(8, -1);if (n === \"Object\" && o.constructor) n = o.constructor.name;if (n === \"Map\" || n === \"Set\") return from_default()(n);if (n === \"Arguments\" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return helpers_arrayLikeToArray(o, minLen);}function helpers_arrayLikeToArray(arr, len) {if (len == null || len > arr.length) len = arr.length;for (var i = 0, arr2 = new Array(len); i < len; i++) {arr2[i] = arr[i];}return arr2;}\n\n\nvar toLower = function toLower(str) {return String.prototype.toLowerCase.call(str);};\nvar escapeString = function escapeString(str) {\n return str.replace(/[^\\w]/gi, '_');\n};\n\n// Spec version detection\nfunction isOAS3(spec) {\n var oasVersion = spec.openapi;\n if (!oasVersion) {\n return false;\n }\n\n return startsWith_default()(oasVersion, '3');\n}\n\nfunction isSwagger2(spec) {\n var swaggerVersion = spec.swagger;\n if (!swaggerVersion) {\n return false;\n }\n\n return startsWith_default()(swaggerVersion, '2');\n}\n\n// Strategy for determining operationId\nfunction opId(operation, pathName) {var method = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : '';var _ref = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {},v2OperationIdCompatibilityMode = _ref.v2OperationIdCompatibilityMode;\n if (!operation || typeof_default()(operation) !== 'object') {\n return null;\n }\n var idWithoutWhitespace = (operation.operationId || '').replace(/\\s/g, '');\n if (idWithoutWhitespace.length) {\n return escapeString(operation.operationId);\n }\n return idFromPathMethod(pathName, method, { v2OperationIdCompatibilityMode: v2OperationIdCompatibilityMode });\n}\n\n\n// Create a generated operationId from pathName + method\nfunction idFromPathMethod(pathName, method) {var _ref2 = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {},v2OperationIdCompatibilityMode = _ref2.v2OperationIdCompatibilityMode;\n if (v2OperationIdCompatibilityMode) {\n var res = \"\".concat(method.toLowerCase(), \"_\").concat(pathName).\n replace(/[\\s!@#$%^&*()_+=[{\\]};:<>|./?,\\\\'\"\"-]/g, '_');\n\n res = res || \"\".concat(pathName.substring(1), \"_\").concat(method);\n\n return res.\n replace(/((_){2,})/g, '_').\n replace(/^(_)*/g, '').\n replace(/([_])*$/g, '');\n }\n return \"\".concat(toLower(method)).concat(escapeString(pathName));\n}\n\nfunction legacyIdFromPathMethod(pathName, method) {\n return \"\".concat(toLower(method), \"-\").concat(pathName);\n}\n\n// Get the operation, based on operationId ( just return the object, no inheritence )\nfunction getOperationRaw(spec, id) {\n if (!spec || !spec.paths) {\n return null;\n }\n\n\n return findOperation(spec, function (_ref3) {var pathName = _ref3.pathName,method = _ref3.method,operation = _ref3.operation;\n if (!operation || typeof_default()(operation) !== 'object') {\n return false;\n }\n\n var rawOperationId = operation.operationId; // straight from the source\n var operationId = opId(operation, pathName, method);\n var legacyOperationId = legacyIdFromPathMethod(pathName, method);\n\n return [operationId, legacyOperationId, rawOperationId].\n some(function (val) {return val && val === id;});\n });\n}\n\n// Will stop iterating over the operations and return the operationObj\n// as soon as predicate returns true\nfunction findOperation(spec, predicate) {\n return eachOperation(spec, predicate, true) || null;\n}\n\n// iterate over each operation, and fire a callback with details\n// `find=true` will stop iterating, when the cb returns truthy\nfunction eachOperation(spec, cb, find) {\n if (!spec || typeof_default()(spec) !== 'object' || !spec.paths || typeof_default()(spec.paths) !== 'object') {\n return null;\n }var\n\n paths = spec.paths;\n\n // Iterate over the spec, collecting operations\n for (var pathName in paths) {\n for (var method in paths[pathName]) {\n if (method.toUpperCase() === 'PARAMETERS') {\n continue;\n }\n var operation = paths[pathName][method];\n if (!operation || typeof_default()(operation) !== 'object') {\n continue;\n }\n\n var operationObj = {\n spec: spec,\n pathName: pathName,\n method: method.toUpperCase(),\n operation: operation };\n\n var cbValue = cb(operationObj);\n\n if (find && cbValue) {\n return operationObj;\n }\n }\n }\n}\n\n// REVIEW: OAS3: identify normalization steps that need changes\n// ...maybe create `normalizeOAS3`?\n\nfunction normalizeSwagger(parsedSpec) {var\n spec = parsedSpec.spec;var\n paths = spec.paths;\n var map = {};\n\n if (!paths || spec.$$normalized) {\n return parsedSpec;\n }\n\n for (var pathName in paths) {\n var path = paths[pathName];\n\n if (!isObject_default()(path)) {\n continue;\n }\n\n var pathParameters = path.parameters;var _loop = function _loop(\n\n method) {\n var operation = path[method];\n if (!isObject_default()(operation)) {\n return \"continue\";\n }\n\n var oid = opId(operation, pathName, method);\n\n if (oid) {\n if (map[oid]) {\n map[oid].push(operation);\n } else\n {\n map[oid] = [operation];\n }\n\n var opList = map[oid];\n if (opList.length > 1) {\n opList.forEach(function (o, i) {\n o.__originalOperationId = o.__originalOperationId || o.operationId;\n o.operationId = \"\".concat(oid).concat(i + 1);\n });\n } else\n if (typeof operation.operationId !== 'undefined') {\n // Ensure we always add the normalized operation ID if one already exists\n // ( potentially different, given that we normalize our IDs)\n // ... _back_ to the spec. Otherwise, they might not line up\n var obj = opList[0];\n obj.__originalOperationId = obj.__originalOperationId || operation.operationId;\n obj.operationId = oid;\n }\n }\n\n if (method !== 'parameters') {\n // Add inherited consumes, produces, parameters, securities\n var inheritsList = [];\n var toBeInherit = {};\n\n // Global-levels\n for (var key in spec) {\n if (key === 'produces' || key === 'consumes' || key === 'security') {\n toBeInherit[key] = spec[key];\n inheritsList.push(toBeInherit);\n }\n }\n\n // Path-levels\n if (pathParameters) {\n toBeInherit.parameters = pathParameters;\n inheritsList.push(toBeInherit);\n }\n\n if (inheritsList.length) {var _iterator = helpers_createForOfIteratorHelper(\n inheritsList),_step;try {for (_iterator.s(); !(_step = _iterator.n()).done;) {var inherits = _step.value;\n for (var inheritName in inherits) {\n if (!operation[inheritName]) {\n operation[inheritName] = inherits[inheritName];\n } else\n if (inheritName === 'parameters') {var _iterator2 = helpers_createForOfIteratorHelper(\n inherits[inheritName]),_step2;try {var _loop2 = function _loop2() {var param = _step2.value;\n var exists = operation[inheritName].some(function (opParam) {\n return opParam.name && opParam.name === param.name ||\n opParam.$ref && opParam.$ref === param.$ref ||\n opParam.$$ref && opParam.$$ref === param.$$ref ||\n opParam === param;\n });\n\n if (!exists) {\n operation[inheritName].push(param);\n }};for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {_loop2();\n }} catch (err) {_iterator2.e(err);} finally {_iterator2.f();}\n }\n }\n }} catch (err) {_iterator.e(err);} finally {_iterator.f();}\n }\n }};for (var method in path) {var _ret = _loop(method);if (_ret === \"continue\") continue;\n }\n }\n\n spec.$$normalized = true;\n\n return parsedSpec;\n}\n// CONCATENATED MODULE: ./src/resolver.js\n\n\n\n\n\nfunction makeFetchJSON(http) {var opts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};var\n requestInterceptor = opts.requestInterceptor,responseInterceptor = opts.responseInterceptor;\n // Set credentials with 'http.withCredentials' value\n var credentials = http.withCredentials ? 'include' : 'same-origin';\n return function (docPath) {\n return http({\n url: docPath,\n loadSpec: true,\n requestInterceptor: requestInterceptor,\n responseInterceptor: responseInterceptor,\n headers: {\n Accept: ACCEPT_HEADER_VALUE_FOR_DOCUMENTS },\n\n credentials: credentials }).\n\n then(function (res) {\n return res.body;\n });\n };\n}\n\n// Wipe out the http cache\nfunction resolver_clearCache() {\n plugins.refs.clearCache();\n}\n\nfunction resolve(obj) {var\n\n fetch =\n\n\n obj.fetch,spec = obj.spec,url = obj.url,mode = obj.mode,_obj$allowMetaPatches = obj.allowMetaPatches,allowMetaPatches = _obj$allowMetaPatches === void 0 ? true : _obj$allowMetaPatches,pathDiscriminator = obj.pathDiscriminator,modelPropertyMacro = obj.modelPropertyMacro,parameterMacro = obj.parameterMacro,requestInterceptor = obj.requestInterceptor,responseInterceptor = obj.responseInterceptor,skipNormalization = obj.skipNormalization,useCircularStructures = obj.useCircularStructures;var\n\n http = obj.http,baseDoc = obj.baseDoc;\n\n // @TODO Swagger-UI uses baseDoc instead of url, this is to allow both\n // need to fix and pick one.\n baseDoc = baseDoc || url;\n\n // Provide a default fetch implementation\n // TODO fetch should be removed, and http used instead\n http = fetch || http || src_http[\"a\" /* default */];\n\n if (!spec) {\n return makeFetchJSON(http, { requestInterceptor: requestInterceptor, responseInterceptor: responseInterceptor })(baseDoc).then(doResolve);\n }\n\n return doResolve(spec);\n\n function doResolve(_spec) {\n if (baseDoc) {\n plugins.refs.docCache[baseDoc] = _spec;\n }\n\n // Build a json-fetcher ( ie: give it a URL and get json out )\n plugins.refs.fetchJSON = makeFetchJSON(http, { requestInterceptor: requestInterceptor, responseInterceptor: responseInterceptor });\n\n var plugs = [plugins.refs];\n\n if (typeof parameterMacro === 'function') {\n plugs.push(plugins.parameters);\n }\n\n if (typeof modelPropertyMacro === 'function') {\n plugs.push(plugins.properties);\n }\n\n if (mode !== 'strict') {\n plugs.push(plugins.allOf);\n }\n\n // mapSpec is where the hard work happens, see https://github.com/swagger-api/specmap for more details\n return mapSpec({\n spec: _spec,\n context: { baseDoc: baseDoc },\n plugins: plugs,\n allowMetaPatches: allowMetaPatches, // allows adding .meta patches, which include adding `$$ref`s to the spec\n pathDiscriminator: pathDiscriminator, // for lazy resolution\n parameterMacro: parameterMacro,\n modelPropertyMacro: modelPropertyMacro,\n useCircularStructures: useCircularStructures }).\n then(skipNormalization ? /*#__PURE__*/function () {var _ref = asyncToGenerator_default()( /*#__PURE__*/regenerator_default.a.mark(function _callee(a) {return regenerator_default.a.wrap(function _callee$(_context) {while (1) {switch (_context.prev = _context.next) {case 0:return _context.abrupt(\"return\", a);case 1:case \"end\":return _context.stop();}}}, _callee);}));return function (_x) {return _ref.apply(this, arguments);};}() : normalizeSwagger);\n }\n}\n// EXTERNAL MODULE: external \"lodash/get\"\nvar get_ = __webpack_require__(17);\nvar get_default = /*#__PURE__*/__webpack_require__.n(get_);\n\n// CONCATENATED MODULE: ./src/subtree-resolver/index.js\nfunction subtree_resolver_ownKeys(object, enumerableOnly) {var keys = keys_default()(object);if (get_own_property_symbols_default.a) {var symbols = get_own_property_symbols_default()(object);if (enumerableOnly) symbols = symbols.filter(function (sym) {return get_own_property_descriptor_default()(object, sym).enumerable;});keys.push.apply(keys, symbols);}return keys;}function subtree_resolver_objectSpread(target) {for (var i = 1; i < arguments.length; i++) {var source = arguments[i] != null ? arguments[i] : {};if (i % 2) {subtree_resolver_ownKeys(Object(source), true).forEach(function (key) {defineProperty_default()(target, key, source[key]);});} else if (get_own_property_descriptors_default.a) {define_properties_default()(target, get_own_property_descriptors_default()(source));} else {subtree_resolver_ownKeys(Object(source)).forEach(function (key) {define_property_default()(target, key, get_own_property_descriptor_default()(source, key));});}}return target;} // The subtree resolver is a higher-level interface that allows you to\n// get the same result that you would from `Swagger.resolve`, but focuses on\n// a subtree of your object.\n//\n// It makes several assumptions that allow you to think less about what resolve,\n// specmap, and normalizeSwagger are doing: if this is not suitable for you,\n// you can emulate `resolveSubtree`'s behavior by talking to the traditional\n// resolver directly.\n//\n// By providing a top-level `obj` and a `path` to resolve within, the subtree\n// at `path` will be resolved and normalized in the context of your top-level\n// `obj`. You'll get the resolved subtree you're interest in as a return value\n// (or, you can use `returnEntireTree` to get everything back).\n//\n// This is useful for cases where resolving your entire object is unnecessary\n// and/or non-performant; we use this interface for lazily resolving operations\n// and models in Swagger-UI, which allows us to handle larger definitions.\n//\n// It's likely that Swagger-Client will rely entirely on lazy resolving in\n// future versions.\n//\n// TODO: move the remarks above into project documentation\n\n\n\n\n\n\nfunction resolveSubtree(_x, _x2) {return _resolveSubtree.apply(this, arguments);}function _resolveSubtree() {_resolveSubtree = asyncToGenerator_default()( /*#__PURE__*/regenerator_default.a.mark(function _callee(obj, path) {var opts,returnEntireTree,baseDoc,requestInterceptor,responseInterceptor,parameterMacro,modelPropertyMacro,useCircularStructures,resolveOptions,_normalizeSwagger,normalized,result,_args = arguments;return regenerator_default.a.wrap(function _callee$(_context) {while (1) {switch (_context.prev = _context.next) {case 0:opts = _args.length > 2 && _args[2] !== undefined ? _args[2] : {};\n\n returnEntireTree =\n\n\n\n\n\n\n opts.returnEntireTree, baseDoc = opts.baseDoc, requestInterceptor = opts.requestInterceptor, responseInterceptor = opts.responseInterceptor, parameterMacro = opts.parameterMacro, modelPropertyMacro = opts.modelPropertyMacro, useCircularStructures = opts.useCircularStructures;\n\n resolveOptions = {\n pathDiscriminator: path,\n baseDoc: baseDoc,\n requestInterceptor: requestInterceptor,\n responseInterceptor: responseInterceptor,\n parameterMacro: parameterMacro,\n modelPropertyMacro: modelPropertyMacro,\n useCircularStructures: useCircularStructures };_normalizeSwagger =\n\n\n normalizeSwagger({\n spec: obj }), normalized = _normalizeSwagger.spec;_context.next = 6;return (\n\n\n resolve(subtree_resolver_objectSpread({},\n resolveOptions, {\n spec: normalized,\n allowMetaPatches: true,\n skipNormalization: true })));case 6:result = _context.sent;\n\n\n if (!returnEntireTree && is_array_default()(path) && path.length) {\n result.spec = get_default()(result.spec, path) || null;\n }return _context.abrupt(\"return\",\n\n result);case 9:case \"end\":return _context.stop();}}}, _callee);}));return _resolveSubtree.apply(this, arguments);}\n// EXTERNAL MODULE: external \"lodash/pick\"\nvar pick_ = __webpack_require__(26);\nvar pick_default = /*#__PURE__*/__webpack_require__.n(pick_);\n\n// CONCATENATED MODULE: ./src/interfaces.js\nfunction interfaces_ownKeys(object, enumerableOnly) {var keys = keys_default()(object);if (get_own_property_symbols_default.a) {var symbols = get_own_property_symbols_default()(object);if (enumerableOnly) symbols = symbols.filter(function (sym) {return get_own_property_descriptor_default()(object, sym).enumerable;});keys.push.apply(keys, symbols);}return keys;}function interfaces_objectSpread(target) {for (var i = 1; i < arguments.length; i++) {var source = arguments[i] != null ? arguments[i] : {};if (i % 2) {interfaces_ownKeys(Object(source), true).forEach(function (key) {defineProperty_default()(target, key, source[key]);});} else if (get_own_property_descriptors_default.a) {define_properties_default()(target, get_own_property_descriptors_default()(source));} else {interfaces_ownKeys(Object(source)).forEach(function (key) {define_property_default()(target, key, get_own_property_descriptor_default()(source, key));});}}return target;}\n\n\nvar nullFn = function nullFn() {return null;};\n\nvar interfaces_normalizeArray = function normalizeArray(arg) {\n return is_array_default()(arg) ? arg : [arg];\n};\n\n// To allow stubbing of functions\nvar interfaces_self = {\n mapTagOperations: mapTagOperations,\n makeExecute: makeExecute };\n\n\n// Make an execute, bound to arguments defined in mapTagOperation's callback (cb)\nfunction makeExecute() {var swaggerJs = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n return function (_ref) {var pathName = _ref.pathName,method = _ref.method,operationId = _ref.operationId;return function (parameters) {var opts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n return swaggerJs.execute(interfaces_objectSpread({\n spec: swaggerJs.spec },\n pick_default()(swaggerJs, 'requestInterceptor', 'responseInterceptor', 'userFetch'), {\n pathName: pathName,\n method: method,\n parameters: parameters,\n operationId: operationId },\n opts));\n\n };};\n}\n\n// Creates an interface with tags+operations = execute\n// The shape\n// { apis: { [tag]: { operations: [operation]: { execute }}}}\n// NOTE: this is mostly for compatibility\nfunction makeApisTagOperationsOperationExecute() {var swaggerJs = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n // { apis: tag: operations: execute }\n var cb = interfaces_self.makeExecute(swaggerJs);\n var tagOperations = interfaces_self.mapTagOperations({\n v2OperationIdCompatibilityMode: swaggerJs.v2OperationIdCompatibilityMode,\n spec: swaggerJs.spec,\n cb: cb });\n\n\n var apis = {};\n for (var tag in tagOperations) {\n apis[tag] = {\n operations: {} };\n\n for (var op in tagOperations[tag]) {\n apis[tag].operations[op] = { execute: tagOperations[tag][op] };\n }\n }\n\n return { apis: apis };\n}\n\n// .apis[tag][operationId]:ExecuteFunction interface\nfunction makeApisTagOperation() {var swaggerJs = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n var cb = interfaces_self.makeExecute(swaggerJs);\n return {\n apis: interfaces_self.mapTagOperations({\n v2OperationIdCompatibilityMode: swaggerJs.v2OperationIdCompatibilityMode,\n spec: swaggerJs.spec,\n cb: cb }) };\n\n\n}\n\n/**\n * Iterates over a spec, creating a hash of {[tag]: { [operationId], ... }, ...}\n * with the value of calling `cb`.\n *\n * `spec` is a OAI v2.0 compliant specification object\n * `cb` is called with ({ spec, operation, path, method })\n * `defaultTag` will house all non-tagged operations\n *\n */\nfunction mapTagOperations(_ref2) {var spec = _ref2.spec,_ref2$cb = _ref2.cb,cb = _ref2$cb === void 0 ? nullFn : _ref2$cb,_ref2$defaultTag = _ref2.defaultTag,defaultTag = _ref2$defaultTag === void 0 ? 'default' : _ref2$defaultTag,v2OperationIdCompatibilityMode = _ref2.v2OperationIdCompatibilityMode;\n var operationIdCounter = {};\n var tagOperations = {}; // Will house all tags + operations\n eachOperation(spec, function (_ref3) {var pathName = _ref3.pathName,method = _ref3.method,operation = _ref3.operation;\n var tags = operation.tags ? interfaces_normalizeArray(operation.tags) : [defaultTag];\n\n tags.forEach(function (tag) {\n if (typeof tag !== 'string') {\n return;\n }\n var tagObj = tagOperations[tag] = tagOperations[tag] || {};\n var id = opId(operation, pathName, method, { v2OperationIdCompatibilityMode: v2OperationIdCompatibilityMode });\n var cbResult = cb({ spec: spec, pathName: pathName, method: method, operation: operation, operationId: id });\n\n if (operationIdCounter[id]) {\n operationIdCounter[id]++;\n tagObj[\"\".concat(id).concat(operationIdCounter[id])] = cbResult;\n } else\n if (typeof tagObj[id] !== 'undefined') {\n // Bump counter ( for this operationId )\n var originalCounterValue = operationIdCounter[id] || 1;\n operationIdCounter[id] = originalCounterValue + 1;\n // Append _x to the operationId\n tagObj[\"\".concat(id).concat(operationIdCounter[id])] = cbResult;\n\n // Rename the first operationId\n var temp = tagObj[id];\n delete tagObj[id];\n tagObj[\"\".concat(id).concat(originalCounterValue)] = temp;\n } else\n {\n // Assign callback result ( usually a bound function )\n tagObj[id] = cbResult;\n }\n });\n });\n\n return tagOperations;\n}\n// EXTERNAL MODULE: external \"@babel/runtime-corejs2/helpers/objectWithoutProperties\"\nvar objectWithoutProperties_ = __webpack_require__(54);\nvar objectWithoutProperties_default = /*#__PURE__*/__webpack_require__.n(objectWithoutProperties_);\n\n// EXTERNAL MODULE: external \"lodash/isPlainObject\"\nvar isPlainObject_ = __webpack_require__(55);\nvar isPlainObject_default = /*#__PURE__*/__webpack_require__.n(isPlainObject_);\n\n// EXTERNAL MODULE: external \"lodash/isArray\"\nvar isArray_ = __webpack_require__(56);\nvar isArray_default = /*#__PURE__*/__webpack_require__.n(isArray_);\n\n// EXTERNAL MODULE: external \"btoa\"\nvar external_btoa_ = __webpack_require__(30);\nvar external_btoa_default = /*#__PURE__*/__webpack_require__.n(external_btoa_);\n\n// EXTERNAL MODULE: external \"cookie\"\nvar external_cookie_ = __webpack_require__(57);\nvar external_cookie_default = /*#__PURE__*/__webpack_require__.n(external_cookie_);\n\n// CONCATENATED MODULE: ./src/execute/swagger2/parameter-builders.js\n// These functions will update the request.\n// They'll be given {req, value, paramter, spec, operation}.\n\n\n/* harmony default export */ var parameter_builders = ({\n body: bodyBuilder,\n header: headerBuilder,\n query: queryBuilder,\n path: pathBuilder,\n formData: formDataBuilder });\n\n\n\n// Add the body to the request\nfunction bodyBuilder(_ref) {var req = _ref.req,value = _ref.value;\n req.body = value;\n}\n\n// Add a form data object.\nfunction formDataBuilder(_ref2) {var req = _ref2.req,value = _ref2.value,parameter = _ref2.parameter;\n if (value || parameter.allowEmptyValue) {\n req.form = req.form || {};\n req.form[parameter.name] = {\n value: value,\n allowEmptyValue: parameter.allowEmptyValue,\n collectionFormat: parameter.collectionFormat };\n\n }\n}\n\n// Add a header to the request\nfunction headerBuilder(_ref3) {var req = _ref3.req,parameter = _ref3.parameter,value = _ref3.value;\n req.headers = req.headers || {};\n if (typeof value !== 'undefined') {\n req.headers[parameter.name] = value;\n }\n}\n\n// Replace path paramters, with values ( ie: the URL )\nfunction pathBuilder(_ref4) {var req = _ref4.req,value = _ref4.value,parameter = _ref4.parameter;\n req.url = req.url.split(\"{\".concat(parameter.name, \"}\")).join(encodeURIComponent(value));\n}\n\n// Add a query to the `query` object, which will later be stringified into the URL's search\nfunction queryBuilder(_ref5) {var req = _ref5.req,value = _ref5.value,parameter = _ref5.parameter;\n req.query = req.query || {};\n\n if (value === false && parameter.type === 'boolean') {\n value = 'false';\n }\n\n if (value === 0 && ['number', 'integer'].indexOf(parameter.type) > -1) {\n value = '0';\n }\n\n if (value) {\n req.query[parameter.name] = {\n collectionFormat: parameter.collectionFormat,\n value: value };\n\n } else\n if (parameter.allowEmptyValue && value !== undefined) {\n var paramName = parameter.name;\n req.query[paramName] = req.query[paramName] || {};\n req.query[paramName].allowEmptyValue = true;\n }\n}\n// EXTERNAL MODULE: ./src/execute/oas3/style-serializer.js\nvar style_serializer = __webpack_require__(19);\n\n// CONCATENATED MODULE: ./src/execute/oas3/content-serializer.js\n /*\n Serializer that serializes according to a media type instead of OpenAPI's\n `style` + `explode` constructs.\n */\n\nfunction serialize(value, mediaType) {\n if (mediaType.includes('application/json')) {\n if (typeof value === 'string') {\n // Assume the user has a JSON string\n return value;\n }\n return stringify_default()(value);\n }\n\n return value.toString();\n}\n// CONCATENATED MODULE: ./src/execute/oas3/parameter-builders.js\n\n\n\n\nfunction parameter_builders_path(_ref) {var req = _ref.req,value = _ref.value,parameter = _ref.parameter;var\n name = parameter.name,style = parameter.style,explode = parameter.explode,content = parameter.content;\n\n if (content) {\n var effectiveMediaType = keys_default()(content)[0];\n\n req.url = req.url.split(\"{\".concat(name, \"}\")).join(\n Object(style_serializer[\"b\" /* encodeDisallowedCharacters */])(\n serialize(value, effectiveMediaType),\n { escape: true }));\n\n\n return;\n }\n\n var styledValue = Object(style_serializer[\"a\" /* default */])({\n key: parameter.name,\n value: value,\n style: style || 'simple',\n explode: explode || false,\n escape: true });\n\n\n req.url = req.url.split(\"{\".concat(name, \"}\")).join(styledValue);\n}\n\nfunction query(_ref2) {var req = _ref2.req,value = _ref2.value,parameter = _ref2.parameter;\n req.query = req.query || {};\n\n if (parameter.content) {\n var effectiveMediaType = keys_default()(parameter.content)[0];\n\n req.query[parameter.name] = serialize(value, effectiveMediaType);\n return;\n }\n\n if (value === false) {\n value = 'false';\n }\n\n if (value === 0) {\n value = '0';\n }\n\n if (value) {\n req.query[parameter.name] = {\n value: value,\n serializationOption: pick_default()(parameter, ['style', 'explode', 'allowReserved']) };\n\n } else\n if (parameter.allowEmptyValue && value !== undefined) {\n var paramName = parameter.name;\n req.query[paramName] = req.query[paramName] || {};\n req.query[paramName].allowEmptyValue = true;\n }\n}\n\nvar PARAMETER_HEADER_BLACKLIST = [\n'accept',\n'authorization',\n'content-type'];\n\n\nfunction header(_ref3) {var req = _ref3.req,parameter = _ref3.parameter,value = _ref3.value;\n req.headers = req.headers || {};\n\n if (PARAMETER_HEADER_BLACKLIST.indexOf(parameter.name.toLowerCase()) > -1) {\n return;\n }\n\n if (parameter.content) {\n var effectiveMediaType = keys_default()(parameter.content)[0];\n\n req.headers[parameter.name] = serialize(value, effectiveMediaType);\n return;\n }\n\n if (typeof value !== 'undefined') {\n req.headers[parameter.name] = Object(style_serializer[\"a\" /* default */])({\n key: parameter.name,\n value: value,\n style: parameter.style || 'simple',\n explode: typeof parameter.explode === 'undefined' ? false : parameter.explode,\n escape: false });\n\n }\n}\n\nfunction cookie(_ref4) {var req = _ref4.req,parameter = _ref4.parameter,value = _ref4.value;\n req.headers = req.headers || {};\n var type = typeof_default()(value);\n\n if (parameter.content) {\n var effectiveMediaType = keys_default()(parameter.content)[0];\n\n req.headers.Cookie = \"\".concat(parameter.name, \"=\").concat(serialize(value, effectiveMediaType));\n return;\n }\n\n if (type !== 'undefined') {\n var prefix =\n type === 'object' &&\n !is_array_default()(value) &&\n parameter.explode ?\n '' : \"\".concat(parameter.name, \"=\");\n\n req.headers.Cookie = prefix + Object(style_serializer[\"a\" /* default */])({\n key: parameter.name,\n value: value,\n escape: false,\n style: parameter.style || 'form',\n explode: typeof parameter.explode === 'undefined' ? false : parameter.explode });\n\n }\n}\n// CONCATENATED MODULE: ./src/execute/oas3/build-request.js\n // This function runs after the common function,\n// `src/execute/index.js#buildRequest`\n\n\n\n\n/* harmony default export */ var build_request = (function (options, req) {var\n\n operation =\n\n\n\n\n options.operation,requestBody = options.requestBody,securities = options.securities,spec = options.spec,attachContentTypeForEmptyPayload = options.attachContentTypeForEmptyPayload;var\n\n\n requestContentType =\n options.requestContentType;\n\n req = applySecurities({ request: req, securities: securities, operation: operation, spec: spec });\n\n var requestBodyDef = operation.requestBody || {};\n var requestBodyMediaTypes = keys_default()(requestBodyDef.content || {});\n var isExplicitContentTypeValid = requestContentType &&\n requestBodyMediaTypes.indexOf(requestContentType) > -1;\n\n // for OAS3: set the Content-Type\n if (requestBody || attachContentTypeForEmptyPayload) {\n // does the passed requestContentType appear in the requestBody definition?\n\n if (requestContentType && isExplicitContentTypeValid) {\n req.headers['Content-Type'] = requestContentType;\n } else\n if (!requestContentType) {\n var firstMediaType = requestBodyMediaTypes[0];\n if (firstMediaType) {\n req.headers['Content-Type'] = firstMediaType;\n requestContentType = firstMediaType;\n }\n }\n } else\n if (requestContentType && isExplicitContentTypeValid) {\n req.headers['Content-Type'] = requestContentType;\n }\n\n // for OAS3: add requestBody to request\n if (requestBody) {\n if (requestContentType) {\n if (requestBodyMediaTypes.indexOf(requestContentType) > -1) {\n // only attach body if the requestBody has a definition for the\n // contentType that has been explicitly set\n if (requestContentType === 'application/x-www-form-urlencoded' || requestContentType === 'multipart/form-data') {\n if (typeof_default()(requestBody) === 'object') {\n var encoding = (requestBodyDef.content[requestContentType] || {}).encoding || {};\n\n req.form = {};\n keys_default()(requestBody).forEach(function (k) {\n req.form[k] = {\n value: requestBody[k],\n encoding: encoding[k] || {} };\n\n });\n } else\n {\n req.form = requestBody;\n }\n } else\n {\n req.body = requestBody;\n }\n }\n } else\n {\n req.body = requestBody;\n }\n }\n\n return req;\n});\n\n// Add security values, to operations - that declare their need on them\n// Adapted from the Swagger2 implementation\nfunction applySecurities(_ref) {var request = _ref.request,_ref$securities = _ref.securities,securities = _ref$securities === void 0 ? {} : _ref$securities,_ref$operation = _ref.operation,operation = _ref$operation === void 0 ? {} : _ref$operation,spec = _ref.spec;\n var result = assign_default()({}, request);var _securities$authorize =\n securities.authorized,authorized = _securities$authorize === void 0 ? {} : _securities$authorize;\n var security = operation.security || spec.security || [];\n var isAuthorized = authorized && !!keys_default()(authorized).length;\n var securityDef = get_default()(spec, ['components', 'securitySchemes']) || {};\n\n result.headers = result.headers || {};\n result.query = result.query || {};\n\n if (!keys_default()(securities).length || !isAuthorized || !security ||\n is_array_default()(operation.security) && !operation.security.length) {\n return request;\n }\n\n security.forEach(function (securityObj, index) {\n for (var key in securityObj) {\n var auth = authorized[key];\n var schema = securityDef[key];\n\n if (!auth) {\n continue;\n }\n\n var value = auth.value || auth;var\n type = schema.type;\n\n if (auth) {\n if (type === 'apiKey') {\n if (schema.in === 'query') {\n result.query[schema.name] = value;\n }\n if (schema.in === 'header') {\n result.headers[schema.name] = value;\n }\n if (schema.in === 'cookie') {\n result.cookies[schema.name] = value;\n }\n } else\n if (type === 'http') {\n if (schema.scheme === 'basic') {\n var username = value.username || '';\n var password = value.password || '';\n var encoded = external_btoa_default()(\"\".concat(username, \":\").concat(password));\n result.headers.Authorization = \"Basic \".concat(encoded);\n }\n\n if (schema.scheme === 'bearer') {\n result.headers.Authorization = \"Bearer \".concat(value);\n }\n } else\n if (type === 'oauth2') {\n var token = auth.token || {};\n var tokenName = schema['x-tokenName'] || 'access_token';\n var tokenValue = token[tokenName];\n var tokenType = token.token_type;\n\n if (!tokenType || tokenType.toLowerCase() === 'bearer') {\n tokenType = 'Bearer';\n }\n\n result.headers.Authorization = \"\".concat(tokenType, \" \").concat(tokenValue);\n }\n }\n }\n });\n\n return result;\n}\n// CONCATENATED MODULE: ./src/execute/swagger2/build-request.js\n // This function runs after the common function,\n// `src/execute/index.js#buildRequest`\n\n\n\n\n\n\n/* harmony default export */ var swagger2_build_request = (function (options, req) {var\n\n spec =\n\n\n\n\n options.spec,operation = options.operation,securities = options.securities,requestContentType = options.requestContentType,attachContentTypeForEmptyPayload = options.attachContentTypeForEmptyPayload;\n // Add securities, which are applicable\n req = build_request_applySecurities({ request: req, securities: securities, operation: operation, spec: spec });\n\n if (req.body || req.form || attachContentTypeForEmptyPayload) {\n // all following conditionals are Swagger2 only\n if (requestContentType) {\n req.headers['Content-Type'] = requestContentType;\n } else\n if (is_array_default()(operation.consumes)) {\n req.headers['Content-Type'] = operation.consumes[0];\n } else\n if (is_array_default()(spec.consumes)) {\n req.headers['Content-Type'] = spec.consumes[0];\n } else\n if (operation.parameters && operation.parameters.filter(function (p) {return p.type === 'file';}).length) {\n req.headers['Content-Type'] = 'multipart/form-data';\n } else\n if (operation.parameters && operation.parameters.filter(function (p) {return p.in === 'formData';}).length) {\n req.headers['Content-Type'] = 'application/x-www-form-urlencoded';\n }\n } else\n if (requestContentType) {\n var isBodyParamPresent = operation.parameters && operation.parameters.filter(function (p) {return p.in === 'body';}).length > 0;\n var isFormDataParamPresent = operation.parameters && operation.parameters.filter(function (p) {return p.in === 'formData';}).length > 0;\n if (isBodyParamPresent || isFormDataParamPresent) {\n req.headers['Content-Type'] = requestContentType;\n }\n }\n\n return req;\n});\n\n// Add security values, to operations - that declare their need on them\nfunction build_request_applySecurities(_ref) {var request = _ref.request,_ref$securities = _ref.securities,securities = _ref$securities === void 0 ? {} : _ref$securities,_ref$operation = _ref.operation,operation = _ref$operation === void 0 ? {} : _ref$operation,spec = _ref.spec;\n var result = assign_default()({}, request);var _securities$authorize =\n securities.authorized,authorized = _securities$authorize === void 0 ? {} : _securities$authorize,_securities$specSecur = securities.specSecurity,specSecurity = _securities$specSecur === void 0 ? [] : _securities$specSecur;\n var security = operation.security || specSecurity;\n var isAuthorized = authorized && !!keys_default()(authorized).length;\n var securityDef = spec.securityDefinitions;\n\n result.headers = result.headers || {};\n result.query = result.query || {};\n\n if (!keys_default()(securities).length || !isAuthorized || !security ||\n is_array_default()(operation.security) && !operation.security.length) {\n return request;\n }\n\n security.forEach(function (securityObj, index) {\n for (var key in securityObj) {\n var auth = authorized[key];\n if (!auth) {\n continue;\n }\n\n var token = auth.token;\n var value = auth.value || auth;\n var schema = securityDef[key];var\n type = schema.type;\n var tokenName = schema['x-tokenName'] || 'access_token';\n var oauthToken = token && token[tokenName];\n var tokenType = token && token.token_type;\n\n if (auth) {\n if (type === 'apiKey') {\n var inType = schema.in === 'query' ? 'query' : 'headers';\n result[inType] = result[inType] || {};\n result[inType][schema.name] = value;\n } else\n if (type === 'basic') {\n if (value.header) {\n result.headers.authorization = value.header;\n } else\n {\n var username = value.username || '';\n var password = value.password || '';\n value.base64 = external_btoa_default()(\"\".concat(username, \":\").concat(password));\n result.headers.authorization = \"Basic \".concat(value.base64);\n }\n } else\n if (type === 'oauth2' && oauthToken) {\n tokenType = !tokenType || tokenType.toLowerCase() === 'bearer' ? 'Bearer' : tokenType;\n result.headers.authorization = \"\".concat(tokenType, \" \").concat(oauthToken);\n }\n }\n }\n });\n\n return result;\n}\n// CONCATENATED MODULE: ./src/execute/index.js\nfunction execute_ownKeys(object, enumerableOnly) {var keys = keys_default()(object);if (get_own_property_symbols_default.a) {var symbols = get_own_property_symbols_default()(object);if (enumerableOnly) symbols = symbols.filter(function (sym) {return get_own_property_descriptor_default()(object, sym).enumerable;});keys.push.apply(keys, symbols);}return keys;}function execute_objectSpread(target) {for (var i = 1; i < arguments.length; i++) {var source = arguments[i] != null ? arguments[i] : {};if (i % 2) {execute_ownKeys(Object(source), true).forEach(function (key) {defineProperty_default()(target, key, source[key]);});} else if (get_own_property_descriptors_default.a) {define_properties_default()(target, get_own_property_descriptors_default()(source));} else {execute_ownKeys(Object(source)).forEach(function (key) {define_property_default()(target, key, get_own_property_descriptor_default()(source, key));});}}return target;}\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nvar execute_arrayOrEmpty = function arrayOrEmpty(ar) {\n return is_array_default()(ar) ? ar : [];\n};\n\nvar OperationNotFoundError = createErrorType('OperationNotFoundError', function (message, extra, oriError) {\n this.originalError = oriError;\n object_assign_default()(this, extra || {});\n});\n\nvar findParametersWithName = function findParametersWithName(name, parameters) {\n return parameters.filter(function (p) {return p.name === name;});\n};\n\n// removes parameters that have duplicate 'in' and 'name' properties\nvar execute_deduplicateParameters = function deduplicateParameters(parameters) {\n var paramsMap = {};\n parameters.forEach(function (p) {\n if (!paramsMap[p.in]) {\n paramsMap[p.in] = {};\n }\n paramsMap[p.in][p.name] = p;\n });\n\n var dedupedParameters = [];\n keys_default()(paramsMap).forEach(function (i) {\n keys_default()(paramsMap[i]).forEach(function (p) {\n dedupedParameters.push(paramsMap[i][p]);\n });\n });\n return dedupedParameters;\n};\n\n// For stubbing in tests\nvar execute_self = {\n buildRequest: buildRequest };\n\n\n// Execute request, with the given operationId and parameters\n// pathName/method or operationId is optional\nfunction execute(_ref)\n\n\n\n\n\n\n\n\n\n{var userHttp = _ref.http,fetch = _ref.fetch,spec = _ref.spec,operationId = _ref.operationId,pathName = _ref.pathName,method = _ref.method,parameters = _ref.parameters,securities = _ref.securities,extras = objectWithoutProperties_default()(_ref, [\"http\", \"fetch\", \"spec\", \"operationId\", \"pathName\", \"method\", \"parameters\", \"securities\"]);\n // Provide default fetch implementation\n var http = userHttp || fetch || src_http[\"a\" /* default */]; // Default to _our_ http\n\n if (pathName && method && !operationId) {\n operationId = legacyIdFromPathMethod(pathName, method);\n }\n\n var request = execute_self.buildRequest(execute_objectSpread({ spec: spec, operationId: operationId, parameters: parameters, securities: securities, http: http }, extras));\n\n if (request.body && (isPlainObject_default()(request.body) || isArray_default()(request.body))) {\n request.body = stringify_default()(request.body);\n }\n\n // Build request and execute it\n return http(request);\n}\n\n// Build a request, which can be handled by the `http.js` implementation.\nfunction buildRequest(options) {var\n\n spec =\n\n\n\n\n\n\n\n\n\n\n\n\n\n options.spec,operationId = options.operationId,securities = options.securities,requestContentType = options.requestContentType,responseContentType = options.responseContentType,scheme = options.scheme,requestInterceptor = options.requestInterceptor,responseInterceptor = options.responseInterceptor,contextUrl = options.contextUrl,userFetch = options.userFetch,requestBody = options.requestBody,server = options.server,serverVariables = options.serverVariables,http = options.http;var\n\n\n parameters =\n\n options.parameters,parameterBuilders = options.parameterBuilders;\n\n var specIsOAS3 = isOAS3(spec);\n if (!parameterBuilders) {\n // user did not provide custom parameter builders\n if (specIsOAS3) {\n parameterBuilders = oas3_parameter_builders_namespaceObject;\n } else\n {\n parameterBuilders = parameter_builders;\n }\n }\n\n // Set credentials with 'http.withCredentials' value\n var credentials = http && http.withCredentials ? 'include' : 'same-origin';\n\n // Base Template\n var req = {\n url: '',\n credentials: credentials,\n headers: {},\n cookies: {} };\n\n\n if (requestInterceptor) {\n req.requestInterceptor = requestInterceptor;\n }\n if (responseInterceptor) {\n req.responseInterceptor = responseInterceptor;\n }\n if (userFetch) {\n req.userFetch = userFetch;\n }\n\n var operationRaw = getOperationRaw(spec, operationId);\n if (!operationRaw) {\n throw new OperationNotFoundError(\"Operation \".concat(operationId, \" not found\"));\n }var _operationRaw$operati =\n\n operationRaw.operation,operation = _operationRaw$operati === void 0 ? {} : _operationRaw$operati,method = operationRaw.method,pathName = operationRaw.pathName;\n\n req.url += execute_baseUrl({ spec: spec, scheme: scheme, contextUrl: contextUrl, server: server, serverVariables: serverVariables, pathName: pathName, method: method });\n\n // Mostly for testing\n if (!operationId) {\n // Not removing req.cookies causes testing issues and would\n // change our interface, so we're always sure to remove it.\n // See the same statement lower down in this function for\n // more context.\n delete req.cookies;\n return req;\n }\n\n req.url += pathName; // Have not yet replaced the path parameters\n req.method = \"\".concat(method).toUpperCase();\n\n parameters = parameters || {};\n var path = spec.paths[pathName] || {};\n\n if (responseContentType) {\n req.headers.accept = responseContentType;\n }\n\n var combinedParameters = execute_deduplicateParameters([].\n concat(execute_arrayOrEmpty(operation.parameters)) // operation parameters\n .concat(execute_arrayOrEmpty(path.parameters)) // path parameters\n );\n\n // REVIEW: OAS3: have any key names or parameter shapes changed?\n // Any new features that need to be plugged in here?\n\n\n // Add values to request\n combinedParameters.forEach(function (parameter) {\n var builder = parameterBuilders[parameter.in];\n var value;\n\n if (parameter.in === 'body' && parameter.schema && parameter.schema.properties) {\n value = parameters;\n }\n\n value = parameter && parameter.name && parameters[parameter.name];\n\n if (typeof value === 'undefined') {\n // check for `name-in` formatted key\n value = parameter && parameter.name && parameters[\"\".concat(parameter.in, \".\").concat(parameter.name)];\n } else\n if (findParametersWithName(parameter.name, combinedParameters).length > 1) {\n // value came from `parameters[parameter.name]`\n // check to see if this is an ambiguous parameter\n // eslint-disable-next-line no-console\n console.warn(\"Parameter '\".concat(parameter.name, \"' is ambiguous because the defined spec has more than one parameter with the name: '\").concat(parameter.name, \"' and the passed-in parameter values did not define an 'in' value.\"));\n }\n\n if (value === null) {\n return;\n }\n\n if (typeof parameter.default !== 'undefined' && typeof value === 'undefined') {\n value = parameter.default;\n }\n\n if (typeof value === 'undefined' && parameter.required && !parameter.allowEmptyValue) {\n throw new Error(\"Required parameter \".concat(parameter.name, \" is not provided\"));\n }\n\n if (specIsOAS3 && parameter.schema && parameter.schema.type === 'object' && typeof value === 'string') {\n try {\n value = JSON.parse(value);\n }\n catch (e) {\n throw new Error('Could not parse object parameter value string as JSON');\n }\n }\n\n if (builder) {\n builder({ req: req, parameter: parameter, value: value, operation: operation, spec: spec });\n }\n });\n\n // Do version-specific tasks, then return those results.\n var versionSpecificOptions = execute_objectSpread({}, options, { operation: operation });\n\n if (specIsOAS3) {\n req = build_request(versionSpecificOptions, req);\n } else\n {\n // If not OAS3, then treat as Swagger2.\n req = swagger2_build_request(versionSpecificOptions, req);\n }\n\n\n // If the cookie convenience object exists in our request,\n // serialize its content and then delete the cookie object.\n if (req.cookies && keys_default()(req.cookies).length) {\n var cookieString = keys_default()(req.cookies).reduce(function (prev, cookieName) {\n var cookieValue = req.cookies[cookieName];\n var prefix = prev ? '&' : '';\n var stringified = external_cookie_default.a.serialize(cookieName, cookieValue);\n return prev + prefix + stringified;\n }, '');\n req.headers.Cookie = cookieString;\n }\n\n if (req.cookies) {\n // even if no cookies were defined, we need to remove\n // the cookies key from our request, or many many legacy\n // tests will break.\n delete req.cookies;\n }\n\n // Will add the query object into the URL, if it exists\n // ... will also create a FormData instance, if multipart/form-data (eg: a file)\n Object(src_http[\"c\" /* mergeInQueryOrForm */])(req);\n\n return req;\n}\n\nvar stripNonAlpha = function stripNonAlpha(str) {return str ? str.replace(/\\W/g, '') : null;};\n\n// be careful when modifying this! it is a publicly-exposed method.\nfunction execute_baseUrl(obj) {\n var specIsOAS3 = isOAS3(obj.spec);\n\n return specIsOAS3 ? oas3BaseUrl(obj) : swagger2BaseUrl(obj);\n}\n\nfunction oas3BaseUrl(_ref2) {var spec = _ref2.spec,pathName = _ref2.pathName,method = _ref2.method,server = _ref2.server,contextUrl = _ref2.contextUrl,_ref2$serverVariables = _ref2.serverVariables,serverVariables = _ref2$serverVariables === void 0 ? {} : _ref2$serverVariables;\n var servers =\n get_default()(spec, ['paths', pathName, (method || '').toLowerCase(), 'servers']) ||\n get_default()(spec, ['paths', pathName, 'servers']) ||\n get_default()(spec, ['servers']);\n\n var selectedServerUrl = '';\n var selectedServerObj = null;\n\n if (server && servers && servers.length) {\n var serverUrls = servers.map(function (srv) {return srv.url;});\n\n if (serverUrls.indexOf(server) > -1) {\n selectedServerUrl = server;\n selectedServerObj = servers[serverUrls.indexOf(server)];\n }\n }\n\n if (!selectedServerUrl && servers && servers.length) {\n // default to the first server if we don't have one by now\n selectedServerUrl = servers[0].url;\n selectedServerObj = servers[0];\n }\n\n if (selectedServerUrl.indexOf('{') > -1) {\n // do variable substitution\n var varNames = getVariableTemplateNames(selectedServerUrl);\n varNames.forEach(function (vari) {\n if (selectedServerObj.variables && selectedServerObj.variables[vari]) {\n // variable is defined in server\n var variableDefinition = selectedServerObj.variables[vari];\n var variableValue = serverVariables[vari] || variableDefinition.default;\n\n var re = new RegExp(\"{\".concat(vari, \"}\"), 'g');\n selectedServerUrl = selectedServerUrl.replace(re, variableValue);\n }\n });\n }\n\n return buildOas3UrlWithContext(selectedServerUrl, contextUrl);\n}\n\nfunction buildOas3UrlWithContext() {var ourUrl = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';var contextUrl = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '';\n var parsedUrl = external_url_default.a.parse(ourUrl);\n var parsedContextUrl = external_url_default.a.parse(contextUrl);\n\n var computedScheme = stripNonAlpha(parsedUrl.protocol) || stripNonAlpha(parsedContextUrl.protocol) || '';\n var computedHost = parsedUrl.host || parsedContextUrl.host;\n var computedPath = parsedUrl.pathname || '';\n var res;\n\n if (computedScheme && computedHost) {\n res = \"\".concat(computedScheme, \"://\").concat(computedHost + computedPath);\n\n // If last character is '/', trim it off\n } else\n {\n res = computedPath;\n }\n\n return res[res.length - 1] === '/' ? res.slice(0, -1) : res;\n}\n\nfunction getVariableTemplateNames(str) {\n var results = [];\n var re = /{([^}]+)}/g;\n var text;\n\n // eslint-disable-next-line no-cond-assign\n while (text = re.exec(str)) {\n results.push(text[1]);\n }\n return results;\n}\n\n// Compose the baseUrl ( scheme + host + basePath )\nfunction swagger2BaseUrl(_ref3) {var spec = _ref3.spec,scheme = _ref3.scheme,_ref3$contextUrl = _ref3.contextUrl,contextUrl = _ref3$contextUrl === void 0 ? '' : _ref3$contextUrl;\n var parsedContextUrl = external_url_default.a.parse(contextUrl);\n var firstSchemeInSpec = is_array_default()(spec.schemes) ? spec.schemes[0] : null;\n\n var computedScheme = scheme || firstSchemeInSpec || stripNonAlpha(parsedContextUrl.protocol) || 'http';\n var computedHost = spec.host || parsedContextUrl.host || '';\n var computedPath = spec.basePath || '';\n var res;\n\n if (computedScheme && computedHost) {\n // we have what we need for an absolute URL\n res = \"\".concat(computedScheme, \"://\").concat(computedHost + computedPath);\n } else\n {\n // if not, a relative URL will have to do\n res = computedPath;\n }\n\n // If last character is '/', trim it off\n return res[res.length - 1] === '/' ? res.slice(0, -1) : res;\n}\n// CONCATENATED MODULE: ./src/index.js\nfunction src_ownKeys(object, enumerableOnly) {var keys = keys_default()(object);if (get_own_property_symbols_default.a) {var symbols = get_own_property_symbols_default()(object);if (enumerableOnly) symbols = symbols.filter(function (sym) {return get_own_property_descriptor_default()(object, sym).enumerable;});keys.push.apply(keys, symbols);}return keys;}function src_objectSpread(target) {for (var i = 1; i < arguments.length; i++) {var source = arguments[i] != null ? arguments[i] : {};if (i % 2) {src_ownKeys(Object(source), true).forEach(function (key) {defineProperty_default()(target, key, source[key]);});} else if (get_own_property_descriptors_default.a) {define_properties_default()(target, get_own_property_descriptors_default()(source));} else {src_ownKeys(Object(source)).forEach(function (key) {define_property_default()(target, key, get_own_property_descriptor_default()(source, key));});}}return target;}\n\n\n\n\n\n\n\n\n\n\nSwagger.http = src_http[\"a\" /* default */];\nSwagger.makeHttp = src_http[\"b\" /* makeHttp */].bind(null, Swagger.http);\nSwagger.resolve = resolve;\nSwagger.resolveSubtree = resolveSubtree;\nSwagger.execute = execute;\nSwagger.serializeRes = src_http[\"e\" /* serializeRes */];\nSwagger.serializeHeaders = src_http[\"d\" /* serializeHeaders */];\nSwagger.clearCache = resolver_clearCache;\nSwagger.makeApisTagOperation = makeApisTagOperation;\nSwagger.buildRequest = buildRequest;\nSwagger.helpers = { opId: opId };\nSwagger.getBaseUrl = execute_baseUrl;\n\nfunction Swagger(url) {var _this = this;var opts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n // Allow url as a separate argument\n if (typeof url === 'string') {\n opts.url = url;\n } else\n {\n opts = url;\n }\n\n if (!(this instanceof Swagger)) {\n return new Swagger(opts);\n }\n\n assign_default()(this, opts);\n\n var prom = this.resolve().\n then(function () {\n if (!_this.disableInterfaces) {\n assign_default()(_this, Swagger.makeApisTagOperation(_this));\n }\n return _this;\n });\n\n // Expose this instance on the promise that gets returned\n prom.client = this;\n return prom;\n}\n\nSwagger.prototype = {\n\n http: src_http[\"a\" /* default */],\n\n execute: function execute(argHash) {\n this.applyDefaults();\n\n return Swagger.execute(src_objectSpread({\n spec: this.spec,\n http: this.http,\n securities: { authorized: this.authorizations },\n contextUrl: typeof this.url === 'string' ? this.url : undefined },\n argHash));\n\n },\n\n resolve: function resolve() {var _this2 = this;\n return Swagger.resolve({\n spec: this.spec,\n url: this.url,\n allowMetaPatches: this.allowMetaPatches,\n useCircularStructures: this.useCircularStructures,\n requestInterceptor: this.requestInterceptor || null,\n responseInterceptor: this.responseInterceptor || null }).\n then(function (obj) {\n _this2.originalSpec = _this2.spec;\n _this2.spec = obj.spec;\n _this2.errors = obj.errors;\n return _this2;\n });\n } };\n\n\nSwagger.prototype.applyDefaults = function () {\n var spec = this.spec;\n var specUrl = this.url;\n // TODO: OAS3: support servers here\n if (specUrl && startsWith_default()(specUrl, 'http')) {\n var parsed = external_url_default.a.parse(specUrl);\n if (!spec.host) {\n spec.host = parsed.host;\n }\n if (!spec.schemes) {\n spec.schemes = [parsed.protocol.replace(':', '')];\n }\n if (!spec.basePath) {\n spec.basePath = '/';\n }\n }\n};\n\n/* harmony default export */ var src = __webpack_exports__[\"default\"] = (Swagger);\n\n/***/ })\n/******/ ])[\"default\"];\n//# sourceMappingURL=index.js.map","\"use strict\";\n\n/**\n * Copyright (c) 2013-present, Facebook, Inc.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n *\n * \n */\n\nfunction makeEmptyFunction(arg) {\n return function () {\n return arg;\n };\n}\n\n/**\n * This function accepts and discards inputs; it has no side effects. This is\n * primarily useful idiomatically for overridable function endpoints which\n * always need to be callable, since JS lacks a null-call idiom ala Cocoa.\n */\nvar emptyFunction = function emptyFunction() {};\n\nemptyFunction.thatReturns = makeEmptyFunction;\nemptyFunction.thatReturnsFalse = makeEmptyFunction(false);\nemptyFunction.thatReturnsTrue = makeEmptyFunction(true);\nemptyFunction.thatReturnsNull = makeEmptyFunction(null);\nemptyFunction.thatReturnsThis = function () {\n return this;\n};\nemptyFunction.thatReturnsArgument = function (arg) {\n return arg;\n};\n\nmodule.exports = emptyFunction;","/**\n * Copyright (c) 2013-present, Facebook, Inc.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n *\n */\n\n'use strict';\n\nvar _prodInvariant = require('./reactProdInvariant'),\n _assign = require('object-assign');\n\nvar CallbackQueue = require('./CallbackQueue');\nvar PooledClass = require('./PooledClass');\nvar ReactFeatureFlags = require('./ReactFeatureFlags');\nvar ReactReconciler = require('./ReactReconciler');\nvar Transaction = require('./Transaction');\n\nvar invariant = require('fbjs/lib/invariant');\n\nvar dirtyComponents = [];\nvar updateBatchNumber = 0;\nvar asapCallbackQueue = CallbackQueue.getPooled();\nvar asapEnqueued = false;\n\nvar batchingStrategy = null;\n\nfunction ensureInjected() {\n !(ReactUpdates.ReactReconcileTransaction && batchingStrategy) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'ReactUpdates: must inject a reconcile transaction class and batching strategy') : _prodInvariant('123') : void 0;\n}\n\nvar NESTED_UPDATES = {\n initialize: function () {\n this.dirtyComponentsLength = dirtyComponents.length;\n },\n close: function () {\n if (this.dirtyComponentsLength !== dirtyComponents.length) {\n // Additional updates were enqueued by componentDidUpdate handlers or\n // similar; before our own UPDATE_QUEUEING wrapper closes, we want to run\n // these new updates so that if A's componentDidUpdate calls setState on\n // B, B will update before the callback A's updater provided when calling\n // setState.\n dirtyComponents.splice(0, this.dirtyComponentsLength);\n flushBatchedUpdates();\n } else {\n dirtyComponents.length = 0;\n }\n }\n};\n\nvar UPDATE_QUEUEING = {\n initialize: function () {\n this.callbackQueue.reset();\n },\n close: function () {\n this.callbackQueue.notifyAll();\n }\n};\n\nvar TRANSACTION_WRAPPERS = [NESTED_UPDATES, UPDATE_QUEUEING];\n\nfunction ReactUpdatesFlushTransaction() {\n this.reinitializeTransaction();\n this.dirtyComponentsLength = null;\n this.callbackQueue = CallbackQueue.getPooled();\n this.reconcileTransaction = ReactUpdates.ReactReconcileTransaction.getPooled(\n /* useCreateElement */true);\n}\n\n_assign(ReactUpdatesFlushTransaction.prototype, Transaction, {\n getTransactionWrappers: function () {\n return TRANSACTION_WRAPPERS;\n },\n\n destructor: function () {\n this.dirtyComponentsLength = null;\n CallbackQueue.release(this.callbackQueue);\n this.callbackQueue = null;\n ReactUpdates.ReactReconcileTransaction.release(this.reconcileTransaction);\n this.reconcileTransaction = null;\n },\n\n perform: function (method, scope, a) {\n // Essentially calls `this.reconcileTransaction.perform(method, scope, a)`\n // with this transaction's wrappers around it.\n return Transaction.perform.call(this, this.reconcileTransaction.perform, this.reconcileTransaction, method, scope, a);\n }\n});\n\nPooledClass.addPoolingTo(ReactUpdatesFlushTransaction);\n\nfunction batchedUpdates(callback, a, b, c, d, e) {\n ensureInjected();\n return batchingStrategy.batchedUpdates(callback, a, b, c, d, e);\n}\n\n/**\n * Array comparator for ReactComponents by mount ordering.\n *\n * @param {ReactComponent} c1 first component you're comparing\n * @param {ReactComponent} c2 second component you're comparing\n * @return {number} Return value usable by Array.prototype.sort().\n */\nfunction mountOrderComparator(c1, c2) {\n return c1._mountOrder - c2._mountOrder;\n}\n\nfunction runBatchedUpdates(transaction) {\n var len = transaction.dirtyComponentsLength;\n !(len === dirtyComponents.length) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Expected flush transaction\\'s stored dirty-components length (%s) to match dirty-components array length (%s).', len, dirtyComponents.length) : _prodInvariant('124', len, dirtyComponents.length) : void 0;\n\n // Since reconciling a component higher in the owner hierarchy usually (not\n // always -- see shouldComponentUpdate()) will reconcile children, reconcile\n // them before their children by sorting the array.\n dirtyComponents.sort(mountOrderComparator);\n\n // Any updates enqueued while reconciling must be performed after this entire\n // batch. Otherwise, if dirtyComponents is [A, B] where A has children B and\n // C, B could update twice in a single batch if C's render enqueues an update\n // to B (since B would have already updated, we should skip it, and the only\n // way we can know to do so is by checking the batch counter).\n updateBatchNumber++;\n\n for (var i = 0; i < len; i++) {\n // If a component is unmounted before pending changes apply, it will still\n // be here, but we assume that it has cleared its _pendingCallbacks and\n // that performUpdateIfNecessary is a noop.\n var component = dirtyComponents[i];\n\n // If performUpdateIfNecessary happens to enqueue any new updates, we\n // shouldn't execute the callbacks until the next render happens, so\n // stash the callbacks first\n var callbacks = component._pendingCallbacks;\n component._pendingCallbacks = null;\n\n var markerName;\n if (ReactFeatureFlags.logTopLevelRenders) {\n var namedComponent = component;\n // Duck type TopLevelWrapper. This is probably always true.\n if (component._currentElement.type.isReactTopLevelWrapper) {\n namedComponent = component._renderedComponent;\n }\n markerName = 'React update: ' + namedComponent.getName();\n console.time(markerName);\n }\n\n ReactReconciler.performUpdateIfNecessary(component, transaction.reconcileTransaction, updateBatchNumber);\n\n if (markerName) {\n console.timeEnd(markerName);\n }\n\n if (callbacks) {\n for (var j = 0; j < callbacks.length; j++) {\n transaction.callbackQueue.enqueue(callbacks[j], component.getPublicInstance());\n }\n }\n }\n}\n\nvar flushBatchedUpdates = function () {\n // ReactUpdatesFlushTransaction's wrappers will clear the dirtyComponents\n // array and perform any updates enqueued by mount-ready handlers (i.e.,\n // componentDidUpdate) but we need to check here too in order to catch\n // updates enqueued by setState callbacks and asap calls.\n while (dirtyComponents.length || asapEnqueued) {\n if (dirtyComponents.length) {\n var transaction = ReactUpdatesFlushTransaction.getPooled();\n transaction.perform(runBatchedUpdates, null, transaction);\n ReactUpdatesFlushTransaction.release(transaction);\n }\n\n if (asapEnqueued) {\n asapEnqueued = false;\n var queue = asapCallbackQueue;\n asapCallbackQueue = CallbackQueue.getPooled();\n queue.notifyAll();\n CallbackQueue.release(queue);\n }\n }\n};\n\n/**\n * Mark a component as needing a rerender, adding an optional callback to a\n * list of functions which will be executed once the rerender occurs.\n */\nfunction enqueueUpdate(component) {\n ensureInjected();\n\n // Various parts of our code (such as ReactCompositeComponent's\n // _renderValidatedComponent) assume that calls to render aren't nested;\n // verify that that's the case. (This is called by each top-level update\n // function, like setState, forceUpdate, etc.; creation and\n // destruction of top-level components is guarded in ReactMount.)\n\n if (!batchingStrategy.isBatchingUpdates) {\n batchingStrategy.batchedUpdates(enqueueUpdate, component);\n return;\n }\n\n dirtyComponents.push(component);\n if (component._updateBatchNumber == null) {\n component._updateBatchNumber = updateBatchNumber + 1;\n }\n}\n\n/**\n * Enqueue a callback to be run at the end of the current batching cycle. Throws\n * if no updates are currently being performed.\n */\nfunction asap(callback, context) {\n invariant(batchingStrategy.isBatchingUpdates, \"ReactUpdates.asap: Can't enqueue an asap callback in a context where\" + 'updates are not being batched.');\n asapCallbackQueue.enqueue(callback, context);\n asapEnqueued = true;\n}\n\nvar ReactUpdatesInjection = {\n injectReconcileTransaction: function (ReconcileTransaction) {\n !ReconcileTransaction ? process.env.NODE_ENV !== 'production' ? invariant(false, 'ReactUpdates: must provide a reconcile transaction class') : _prodInvariant('126') : void 0;\n ReactUpdates.ReactReconcileTransaction = ReconcileTransaction;\n },\n\n injectBatchingStrategy: function (_batchingStrategy) {\n !_batchingStrategy ? process.env.NODE_ENV !== 'production' ? invariant(false, 'ReactUpdates: must provide a batching strategy') : _prodInvariant('127') : void 0;\n !(typeof _batchingStrategy.batchedUpdates === 'function') ? process.env.NODE_ENV !== 'production' ? invariant(false, 'ReactUpdates: must provide a batchedUpdates() function') : _prodInvariant('128') : void 0;\n !(typeof _batchingStrategy.isBatchingUpdates === 'boolean') ? process.env.NODE_ENV !== 'production' ? invariant(false, 'ReactUpdates: must provide an isBatchingUpdates boolean attribute') : _prodInvariant('129') : void 0;\n batchingStrategy = _batchingStrategy;\n }\n};\n\nvar ReactUpdates = {\n /**\n * React references `ReactReconcileTransaction` using this property in order\n * to allow dependency injection.\n *\n * @internal\n */\n ReactReconcileTransaction: null,\n\n batchedUpdates: batchedUpdates,\n enqueueUpdate: enqueueUpdate,\n flushBatchedUpdates: flushBatchedUpdates,\n injection: ReactUpdatesInjection,\n asap: asap\n};\n\nmodule.exports = ReactUpdates;","/*!\n Copyright (c) 2017 Jed Watson.\n Licensed under the MIT License (MIT), see\n http://jedwatson.github.io/classnames\n*/\n/* global define */\n\n(function () {\n\t'use strict';\n\n\tvar hasOwn = {}.hasOwnProperty;\n\n\tfunction classNames () {\n\t\tvar classes = [];\n\n\t\tfor (var i = 0; i < arguments.length; i++) {\n\t\t\tvar arg = arguments[i];\n\t\t\tif (!arg) continue;\n\n\t\t\tvar argType = typeof arg;\n\n\t\t\tif (argType === 'string' || argType === 'number') {\n\t\t\t\tclasses.push(arg);\n\t\t\t} else if (Array.isArray(arg) && arg.length) {\n\t\t\t\tvar inner = classNames.apply(null, arg);\n\t\t\t\tif (inner) {\n\t\t\t\t\tclasses.push(inner);\n\t\t\t\t}\n\t\t\t} else if (argType === 'object') {\n\t\t\t\tfor (var key in arg) {\n\t\t\t\t\tif (hasOwn.call(arg, key) && arg[key]) {\n\t\t\t\t\t\tclasses.push(key);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn classes.join(' ');\n\t}\n\n\tif (typeof module !== 'undefined' && module.exports) {\n\t\tclassNames.default = classNames;\n\t\tmodule.exports = classNames;\n\t} else if (typeof define === 'function' && typeof define.amd === 'object' && define.amd) {\n\t\t// register as 'classnames', consistent with npm package name\n\t\tdefine('classnames', [], function () {\n\t\t\treturn classNames;\n\t\t});\n\t} else {\n\t\twindow.classNames = classNames;\n\t}\n}());\n","module.exports = require(\"core-js/library/fn/object/get-own-property-descriptors\");","var hasOwnProperty = {}.hasOwnProperty;\nmodule.exports = function (it, key) {\n return hasOwnProperty.call(it, key);\n};\n","// to indexed object, toObject with fallback for non-array-like ES3 strings\nvar IObject = require('./_iobject');\nvar defined = require('./_defined');\nmodule.exports = function (it) {\n return IObject(defined(it));\n};\n","// optional / simple context binding\nvar aFunction = require('./_a-function');\nmodule.exports = function (fn, that, length) {\n aFunction(fn);\n if (that === undefined) return fn;\n switch (length) {\n case 1: return function (a) {\n return fn.call(that, a);\n };\n case 2: return function (a, b) {\n return fn.call(that, a, b);\n };\n case 3: return function (a, b, c) {\n return fn.call(that, a, b, c);\n };\n }\n return function (/* ...args */) {\n return fn.apply(that, arguments);\n };\n};\n","/**\n * Copyright (c) 2013-present, Facebook, Inc.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n *\n * \n */\n\n'use strict';\n\n/**\n * Keeps track of the current owner.\n *\n * The current owner is the component who should own any components that are\n * currently being constructed.\n */\nvar ReactCurrentOwner = {\n /**\n * @internal\n * @type {ReactComponent}\n */\n current: null\n};\n\nmodule.exports = ReactCurrentOwner;","/**\n * Checks if `value` is object-like. A value is object-like if it's not `null`\n * and has a `typeof` result of \"object\".\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is object-like, else `false`.\n * @example\n *\n * _.isObjectLike({});\n * // => true\n *\n * _.isObjectLike([1, 2, 3]);\n * // => true\n *\n * _.isObjectLike(_.noop);\n * // => false\n *\n * _.isObjectLike(null);\n * // => false\n */\nfunction isObjectLike(value) {\n return value != null && typeof value == 'object';\n}\n\nmodule.exports = isObjectLike;\n","// shim for using process in browser\nvar process = module.exports = {};\n\n// cached from whatever global is present so that test runners that stub it\n// don't break things. But we need to wrap it in a try catch in case it is\n// wrapped in strict mode code which doesn't define any globals. It's inside a\n// function because try/catches deoptimize in certain engines.\n\nvar cachedSetTimeout;\nvar cachedClearTimeout;\n\nfunction defaultSetTimout() {\n throw new Error('setTimeout has not been defined');\n}\nfunction defaultClearTimeout () {\n throw new Error('clearTimeout has not been defined');\n}\n(function () {\n try {\n if (typeof setTimeout === 'function') {\n cachedSetTimeout = setTimeout;\n } else {\n cachedSetTimeout = defaultSetTimout;\n }\n } catch (e) {\n cachedSetTimeout = defaultSetTimout;\n }\n try {\n if (typeof clearTimeout === 'function') {\n cachedClearTimeout = clearTimeout;\n } else {\n cachedClearTimeout = defaultClearTimeout;\n }\n } catch (e) {\n cachedClearTimeout = defaultClearTimeout;\n }\n} ())\nfunction runTimeout(fun) {\n if (cachedSetTimeout === setTimeout) {\n //normal enviroments in sane situations\n return setTimeout(fun, 0);\n }\n // if setTimeout wasn't available but was latter defined\n if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {\n cachedSetTimeout = setTimeout;\n return setTimeout(fun, 0);\n }\n try {\n // when when somebody has screwed with setTimeout but no I.E. maddness\n return cachedSetTimeout(fun, 0);\n } catch(e){\n try {\n // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally\n return cachedSetTimeout.call(null, fun, 0);\n } catch(e){\n // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error\n return cachedSetTimeout.call(this, fun, 0);\n }\n }\n\n\n}\nfunction runClearTimeout(marker) {\n if (cachedClearTimeout === clearTimeout) {\n //normal enviroments in sane situations\n return clearTimeout(marker);\n }\n // if clearTimeout wasn't available but was latter defined\n if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {\n cachedClearTimeout = clearTimeout;\n return clearTimeout(marker);\n }\n try {\n // when when somebody has screwed with setTimeout but no I.E. maddness\n return cachedClearTimeout(marker);\n } catch (e){\n try {\n // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally\n return cachedClearTimeout.call(null, marker);\n } catch (e){\n // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.\n // Some versions of I.E. have different rules for clearTimeout vs setTimeout\n return cachedClearTimeout.call(this, marker);\n }\n }\n\n\n\n}\nvar queue = [];\nvar draining = false;\nvar currentQueue;\nvar queueIndex = -1;\n\nfunction cleanUpNextTick() {\n if (!draining || !currentQueue) {\n return;\n }\n draining = false;\n if (currentQueue.length) {\n queue = currentQueue.concat(queue);\n } else {\n queueIndex = -1;\n }\n if (queue.length) {\n drainQueue();\n }\n}\n\nfunction drainQueue() {\n if (draining) {\n return;\n }\n var timeout = runTimeout(cleanUpNextTick);\n draining = true;\n\n var len = queue.length;\n while(len) {\n currentQueue = queue;\n queue = [];\n while (++queueIndex < len) {\n if (currentQueue) {\n currentQueue[queueIndex].run();\n }\n }\n queueIndex = -1;\n len = queue.length;\n }\n currentQueue = null;\n draining = false;\n runClearTimeout(timeout);\n}\n\nprocess.nextTick = function (fun) {\n var args = new Array(arguments.length - 1);\n if (arguments.length > 1) {\n for (var i = 1; i < arguments.length; i++) {\n args[i - 1] = arguments[i];\n }\n }\n queue.push(new Item(fun, args));\n if (queue.length === 1 && !draining) {\n runTimeout(drainQueue);\n }\n};\n\n// v8 likes predictible objects\nfunction Item(fun, array) {\n this.fun = fun;\n this.array = array;\n}\nItem.prototype.run = function () {\n this.fun.apply(null, this.array);\n};\nprocess.title = 'browser';\nprocess.browser = true;\nprocess.env = {};\nprocess.argv = [];\nprocess.version = ''; // empty string to avoid regexp issues\nprocess.versions = {};\n\nfunction noop() {}\n\nprocess.on = noop;\nprocess.addListener = noop;\nprocess.once = noop;\nprocess.off = noop;\nprocess.removeListener = noop;\nprocess.removeAllListeners = noop;\nprocess.emit = noop;\nprocess.prependListener = noop;\nprocess.prependOnceListener = noop;\n\nprocess.listeners = function (name) { return [] }\n\nprocess.binding = function (name) {\n throw new Error('process.binding is not supported');\n};\n\nprocess.cwd = function () { return '/' };\nprocess.chdir = function (dir) {\n throw new Error('process.chdir is not supported');\n};\nprocess.umask = function() { return 0; };\n","/**\n * Copyright (c) 2013-present, Facebook, Inc.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n *\n */\n\n'use strict';\n\nvar _assign = require('object-assign');\n\nvar PooledClass = require('./PooledClass');\n\nvar emptyFunction = require('fbjs/lib/emptyFunction');\nvar warning = require('fbjs/lib/warning');\n\nvar didWarnForAddedNewProperty = false;\nvar isProxySupported = typeof Proxy === 'function';\n\nvar shouldBeReleasedProperties = ['dispatchConfig', '_targetInst', 'nativeEvent', 'isDefaultPrevented', 'isPropagationStopped', '_dispatchListeners', '_dispatchInstances'];\n\n/**\n * @interface Event\n * @see http://www.w3.org/TR/DOM-Level-3-Events/\n */\nvar EventInterface = {\n type: null,\n target: null,\n // currentTarget is set when dispatching; no use in copying it here\n currentTarget: emptyFunction.thatReturnsNull,\n eventPhase: null,\n bubbles: null,\n cancelable: null,\n timeStamp: function (event) {\n return event.timeStamp || Date.now();\n },\n defaultPrevented: null,\n isTrusted: null\n};\n\n/**\n * Synthetic events are dispatched by event plugins, typically in response to a\n * top-level event delegation handler.\n *\n * These systems should generally use pooling to reduce the frequency of garbage\n * collection. The system should check `isPersistent` to determine whether the\n * event should be released into the pool after being dispatched. Users that\n * need a persisted event should invoke `persist`.\n *\n * Synthetic events (and subclasses) implement the DOM Level 3 Events API by\n * normalizing browser quirks. Subclasses do not necessarily have to implement a\n * DOM interface; custom application-specific events can also subclass this.\n *\n * @param {object} dispatchConfig Configuration used to dispatch this event.\n * @param {*} targetInst Marker identifying the event target.\n * @param {object} nativeEvent Native browser event.\n * @param {DOMEventTarget} nativeEventTarget Target node.\n */\nfunction SyntheticEvent(dispatchConfig, targetInst, nativeEvent, nativeEventTarget) {\n if (process.env.NODE_ENV !== 'production') {\n // these have a getter/setter for warnings\n delete this.nativeEvent;\n delete this.preventDefault;\n delete this.stopPropagation;\n }\n\n this.dispatchConfig = dispatchConfig;\n this._targetInst = targetInst;\n this.nativeEvent = nativeEvent;\n\n var Interface = this.constructor.Interface;\n for (var propName in Interface) {\n if (!Interface.hasOwnProperty(propName)) {\n continue;\n }\n if (process.env.NODE_ENV !== 'production') {\n delete this[propName]; // this has a getter/setter for warnings\n }\n var normalize = Interface[propName];\n if (normalize) {\n this[propName] = normalize(nativeEvent);\n } else {\n if (propName === 'target') {\n this.target = nativeEventTarget;\n } else {\n this[propName] = nativeEvent[propName];\n }\n }\n }\n\n var defaultPrevented = nativeEvent.defaultPrevented != null ? nativeEvent.defaultPrevented : nativeEvent.returnValue === false;\n if (defaultPrevented) {\n this.isDefaultPrevented = emptyFunction.thatReturnsTrue;\n } else {\n this.isDefaultPrevented = emptyFunction.thatReturnsFalse;\n }\n this.isPropagationStopped = emptyFunction.thatReturnsFalse;\n return this;\n}\n\n_assign(SyntheticEvent.prototype, {\n preventDefault: function () {\n this.defaultPrevented = true;\n var event = this.nativeEvent;\n if (!event) {\n return;\n }\n\n if (event.preventDefault) {\n event.preventDefault();\n // eslint-disable-next-line valid-typeof\n } else if (typeof event.returnValue !== 'unknown') {\n event.returnValue = false;\n }\n this.isDefaultPrevented = emptyFunction.thatReturnsTrue;\n },\n\n stopPropagation: function () {\n var event = this.nativeEvent;\n if (!event) {\n return;\n }\n\n if (event.stopPropagation) {\n event.stopPropagation();\n // eslint-disable-next-line valid-typeof\n } else if (typeof event.cancelBubble !== 'unknown') {\n // The ChangeEventPlugin registers a \"propertychange\" event for\n // IE. This event does not support bubbling or cancelling, and\n // any references to cancelBubble throw \"Member not found\". A\n // typeof check of \"unknown\" circumvents this issue (and is also\n // IE specific).\n event.cancelBubble = true;\n }\n\n this.isPropagationStopped = emptyFunction.thatReturnsTrue;\n },\n\n /**\n * We release all dispatched `SyntheticEvent`s after each event loop, adding\n * them back into the pool. This allows a way to hold onto a reference that\n * won't be added back into the pool.\n */\n persist: function () {\n this.isPersistent = emptyFunction.thatReturnsTrue;\n },\n\n /**\n * Checks if this event should be released back into the pool.\n *\n * @return {boolean} True if this should not be released, false otherwise.\n */\n isPersistent: emptyFunction.thatReturnsFalse,\n\n /**\n * `PooledClass` looks for `destructor` on each instance it releases.\n */\n destructor: function () {\n var Interface = this.constructor.Interface;\n for (var propName in Interface) {\n if (process.env.NODE_ENV !== 'production') {\n Object.defineProperty(this, propName, getPooledWarningPropertyDefinition(propName, Interface[propName]));\n } else {\n this[propName] = null;\n }\n }\n for (var i = 0; i < shouldBeReleasedProperties.length; i++) {\n this[shouldBeReleasedProperties[i]] = null;\n }\n if (process.env.NODE_ENV !== 'production') {\n Object.defineProperty(this, 'nativeEvent', getPooledWarningPropertyDefinition('nativeEvent', null));\n Object.defineProperty(this, 'preventDefault', getPooledWarningPropertyDefinition('preventDefault', emptyFunction));\n Object.defineProperty(this, 'stopPropagation', getPooledWarningPropertyDefinition('stopPropagation', emptyFunction));\n }\n }\n});\n\nSyntheticEvent.Interface = EventInterface;\n\n/**\n * Helper to reduce boilerplate when creating subclasses.\n *\n * @param {function} Class\n * @param {?object} Interface\n */\nSyntheticEvent.augmentClass = function (Class, Interface) {\n var Super = this;\n\n var E = function () {};\n E.prototype = Super.prototype;\n var prototype = new E();\n\n _assign(prototype, Class.prototype);\n Class.prototype = prototype;\n Class.prototype.constructor = Class;\n\n Class.Interface = _assign({}, Super.Interface, Interface);\n Class.augmentClass = Super.augmentClass;\n\n PooledClass.addPoolingTo(Class, PooledClass.fourArgumentPooler);\n};\n\n/** Proxying after everything set on SyntheticEvent\n * to resolve Proxy issue on some WebKit browsers\n * in which some Event properties are set to undefined (GH#10010)\n */\nif (process.env.NODE_ENV !== 'production') {\n if (isProxySupported) {\n /*eslint-disable no-func-assign */\n SyntheticEvent = new Proxy(SyntheticEvent, {\n construct: function (target, args) {\n return this.apply(target, Object.create(target.prototype), args);\n },\n apply: function (constructor, that, args) {\n return new Proxy(constructor.apply(that, args), {\n set: function (target, prop, value) {\n if (prop !== 'isPersistent' && !target.constructor.Interface.hasOwnProperty(prop) && shouldBeReleasedProperties.indexOf(prop) === -1) {\n process.env.NODE_ENV !== 'production' ? warning(didWarnForAddedNewProperty || target.isPersistent(), \"This synthetic event is reused for performance reasons. If you're \" + \"seeing this, you're adding a new property in the synthetic event object. \" + 'The property is never released. See ' + 'https://fb.me/react-event-pooling for more information.') : void 0;\n didWarnForAddedNewProperty = true;\n }\n target[prop] = value;\n return true;\n }\n });\n }\n });\n /*eslint-enable no-func-assign */\n }\n}\n\nPooledClass.addPoolingTo(SyntheticEvent, PooledClass.fourArgumentPooler);\n\nmodule.exports = SyntheticEvent;\n\n/**\n * Helper to nullify syntheticEvent instance properties when destructing\n *\n * @param {object} SyntheticEvent\n * @param {String} propName\n * @return {object} defineProperty object\n */\nfunction getPooledWarningPropertyDefinition(propName, getVal) {\n var isFunction = typeof getVal === 'function';\n return {\n configurable: true,\n set: set,\n get: get\n };\n\n function set(val) {\n var action = isFunction ? 'setting the method' : 'setting the property';\n warn(action, 'This is effectively a no-op');\n return val;\n }\n\n function get() {\n var action = isFunction ? 'accessing the method' : 'accessing the property';\n var result = isFunction ? 'This is a no-op function' : 'This is set to null';\n warn(action, result);\n return getVal;\n }\n\n function warn(action, result) {\n var warningCondition = false;\n process.env.NODE_ENV !== 'production' ? warning(warningCondition, \"This synthetic event is reused for performance reasons. If you're seeing this, \" + \"you're %s `%s` on a released/nullified synthetic event. %s. \" + 'If you must keep the original synthetic event around, use event.persist(). ' + 'See https://fb.me/react-event-pooling for more information.', action, propName, result) : void 0;\n }\n}","var baseToString = require('./_baseToString');\n\n/**\n * Converts `value` to a string. An empty string is returned for `null`\n * and `undefined` values. The sign of `-0` is preserved.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to convert.\n * @returns {string} Returns the converted string.\n * @example\n *\n * _.toString(null);\n * // => ''\n *\n * _.toString(-0);\n * // => '-0'\n *\n * _.toString([1, 2, 3]);\n * // => '1,2,3'\n */\nfunction toString(value) {\n return value == null ? '' : baseToString(value);\n}\n\nmodule.exports = toString;\n","import { createSelector } from \"reselect\"\nimport { sorters } from \"core/utils\"\nimport { fromJS, Set, Map, OrderedMap, List } from \"immutable\"\nimport { paramToIdentifier } from \"../../utils\"\n\nconst DEFAULT_TAG = \"default\"\n\nconst OPERATION_METHODS = [\n \"get\", \"put\", \"post\", \"delete\", \"options\", \"head\", \"patch\", \"trace\"\n]\n\nconst state = state => {\n return state || Map()\n}\n\nexport const lastError = createSelector(\n state,\n spec => spec.get(\"lastError\")\n)\n\nexport const url = createSelector(\n state,\n spec => spec.get(\"url\")\n)\n\nexport const specStr = createSelector(\n state,\n spec => spec.get(\"spec\") || \"\"\n)\n\nexport const specSource = createSelector(\n state,\n spec => spec.get(\"specSource\") || \"not-editor\"\n)\n\nexport const specJson = createSelector(\n state,\n spec => spec.get(\"json\", Map())\n)\n\nexport const specResolved = createSelector(\n state,\n spec => spec.get(\"resolved\", Map())\n)\n\nexport const specResolvedSubtree = (state, path) => {\n return state.getIn([\"resolvedSubtrees\", ...path], undefined)\n}\n\nconst mergerFn = (oldVal, newVal) => {\n if(Map.isMap(oldVal) && Map.isMap(newVal)) {\n if(newVal.get(\"$$ref\")) {\n // resolver artifacts indicated that this key was directly resolved\n // so we should drop the old value entirely\n return newVal\n }\n\n return OrderedMap().mergeWith(\n mergerFn,\n oldVal,\n newVal\n )\n }\n\n return newVal\n}\n\nexport const specJsonWithResolvedSubtrees = createSelector(\n state,\n spec => OrderedMap().mergeWith(\n mergerFn,\n spec.get(\"json\"),\n spec.get(\"resolvedSubtrees\")\n )\n)\n\n// Default Spec ( as an object )\nexport const spec = state => {\n let res = specJson(state)\n return res\n}\n\nexport const isOAS3 = createSelector(\n // isOAS3 is stubbed out here to work around an issue with injecting more selectors\n // in the OAS3 plugin, and to ensure that the function is always available.\n // It's not perfect, but our hybrid (core+plugin code) implementation for OAS3\n // needs this. //KS\n spec,\n\t() => false\n)\n\nexport const info = createSelector(\n spec,\n\tspec => returnSelfOrNewMap(spec && spec.get(\"info\"))\n)\n\nexport const externalDocs = createSelector(\n spec,\n\tspec => returnSelfOrNewMap(spec && spec.get(\"externalDocs\"))\n)\n\nexport const version = createSelector(\n\tinfo,\n\tinfo => info && info.get(\"version\")\n)\n\nexport const semver = createSelector(\n\tversion,\n\tversion => /v?([0-9]*)\\.([0-9]*)\\.([0-9]*)/i.exec(version).slice(1)\n)\n\nexport const paths = createSelector(\n\tspecJsonWithResolvedSubtrees,\n\tspec => spec.get(\"paths\")\n)\n\nexport const operations = createSelector(\n paths,\n paths => {\n if(!paths || paths.size < 1)\n return List()\n\n let list = List()\n\n if(!paths || !paths.forEach) {\n return List()\n }\n\n paths.forEach((path, pathName) => {\n if(!path || !path.forEach) {\n return {}\n }\n path.forEach((operation, method) => {\n if(OPERATION_METHODS.indexOf(method) < 0) {\n return\n }\n list = list.push(fromJS({\n path: pathName,\n method,\n operation,\n id: `${method}-${pathName}`\n }))\n })\n })\n\n return list\n }\n)\n\nexport const consumes = createSelector(\n spec,\n spec => Set(spec.get(\"consumes\"))\n)\n\nexport const produces = createSelector(\n spec,\n spec => Set(spec.get(\"produces\"))\n)\n\nexport const security = createSelector(\n spec,\n spec => spec.get(\"security\", List())\n)\n\nexport const securityDefinitions = createSelector(\n spec,\n spec => spec.get(\"securityDefinitions\")\n)\n\n\nexport const findDefinition = ( state, name ) => {\n const resolvedRes = state.getIn([\"resolvedSubtrees\", \"definitions\", name], null)\n const unresolvedRes = state.getIn([\"json\", \"definitions\", name], null)\n return resolvedRes || unresolvedRes || null\n}\n\nexport const definitions = createSelector(\n spec,\n spec => {\n const res = spec.get(\"definitions\")\n return Map.isMap(res) ? res : Map()\n }\n)\n\nexport const basePath = createSelector(\n spec,\n spec => spec.get(\"basePath\")\n)\n\nexport const host = createSelector(\n spec,\n spec => spec.get(\"host\")\n)\n\nexport const schemes = createSelector(\n spec,\n spec => spec.get(\"schemes\", Map())\n)\n\nexport const operationsWithRootInherited = createSelector(\n operations,\n consumes,\n produces,\n (operations, consumes, produces) => {\n return operations.map( ops => ops.update(\"operation\", op => {\n if(op) {\n if(!Map.isMap(op)) { return }\n return op.withMutations( op => {\n if ( !op.get(\"consumes\") ) {\n op.update(\"consumes\", a => Set(a).merge(consumes))\n }\n if ( !op.get(\"produces\") ) {\n op.update(\"produces\", a => Set(a).merge(produces))\n }\n return op\n })\n } else {\n // return something with Immutable methods\n return Map()\n }\n\n }))\n }\n)\n\nexport const tags = createSelector(\n spec,\n json => {\n const tags = json.get(\"tags\", List())\n return List.isList(tags) ? tags.filter(tag => Map.isMap(tag)) : List()\n }\n)\n\nexport const tagDetails = (state, tag) => {\n let currentTags = tags(state) || List()\n return currentTags.filter(Map.isMap).find(t => t.get(\"name\") === tag, Map())\n}\n\nexport const operationsWithTags = createSelector(\n operationsWithRootInherited,\n tags,\n (operations, tags) => {\n return operations.reduce( (taggedMap, op) => {\n let tags = Set(op.getIn([\"operation\",\"tags\"]))\n if(tags.count() < 1)\n return taggedMap.update(DEFAULT_TAG, List(), ar => ar.push(op))\n return tags.reduce( (res, tag) => res.update(tag, List(), (ar) => ar.push(op)), taggedMap )\n }, tags.reduce( (taggedMap, tag) => {\n return taggedMap.set(tag.get(\"name\"), List())\n } , OrderedMap()))\n }\n)\n\nexport const taggedOperations = (state) => ({ getConfigs }) => {\n let { tagsSorter, operationsSorter } = getConfigs()\n return operationsWithTags(state)\n .sortBy(\n (val, key) => key, // get the name of the tag to be passed to the sorter\n (tagA, tagB) => {\n let sortFn = (typeof tagsSorter === \"function\" ? tagsSorter : sorters.tagsSorter[ tagsSorter ])\n return (!sortFn ? null : sortFn(tagA, tagB))\n }\n )\n .map((ops, tag) => {\n let sortFn = (typeof operationsSorter === \"function\" ? operationsSorter : sorters.operationsSorter[ operationsSorter ])\n let operations = (!sortFn ? ops : ops.sort(sortFn))\n\n return Map({ tagDetails: tagDetails(state, tag), operations: operations })\n })\n}\n\nexport const responses = createSelector(\n state,\n state => state.get( \"responses\", Map() )\n)\n\nexport const requests = createSelector(\n state,\n state => state.get( \"requests\", Map() )\n)\n\nexport const mutatedRequests = createSelector(\n state,\n state => state.get( \"mutatedRequests\", Map() )\n)\n\nexport const responseFor = (state, path, method) => {\n return responses(state).getIn([path, method], null)\n}\n\nexport const requestFor = (state, path, method) => {\n return requests(state).getIn([path, method], null)\n}\n\nexport const mutatedRequestFor = (state, path, method) => {\n return mutatedRequests(state).getIn([path, method], null)\n}\n\nexport const allowTryItOutFor = () => {\n // This is just a hook for now.\n return true\n}\n\nexport const parameterWithMetaByIdentity = (state, pathMethod, param) => {\n const opParams = specJsonWithResolvedSubtrees(state).getIn([\"paths\", ...pathMethod, \"parameters\"], OrderedMap())\n const metaParams = state.getIn([\"meta\", \"paths\", ...pathMethod, \"parameters\"], OrderedMap())\n\n const mergedParams = opParams.map((currentParam) => {\n const inNameKeyedMeta = metaParams.get(`${param.get(\"in\")}.${param.get(\"name\")}`)\n const hashKeyedMeta = metaParams.get(`${param.get(\"in\")}.${param.get(\"name\")}.hash-${param.hashCode()}`)\n return OrderedMap().merge(\n currentParam,\n inNameKeyedMeta,\n hashKeyedMeta\n )\n })\n\n return mergedParams.find(curr => curr.get(\"in\") === param.get(\"in\") && curr.get(\"name\") === param.get(\"name\"), OrderedMap())\n}\n\nexport const parameterInclusionSettingFor = (state, pathMethod, paramName, paramIn) => {\n const paramKey = `${paramIn}.${paramName}`\n return state.getIn([\"meta\", \"paths\", ...pathMethod, \"parameter_inclusions\", paramKey], false)\n}\n\n\nexport const parameterWithMeta = (state, pathMethod, paramName, paramIn) => {\n const opParams = specJsonWithResolvedSubtrees(state).getIn([\"paths\", ...pathMethod, \"parameters\"], OrderedMap())\n const currentParam = opParams.find(param => param.get(\"in\") === paramIn && param.get(\"name\") === paramName, OrderedMap())\n\n return parameterWithMetaByIdentity(state, pathMethod, currentParam)\n}\n\nexport const operationWithMeta = (state, path, method) => {\n const op = specJsonWithResolvedSubtrees(state).getIn([\"paths\", path, method], OrderedMap())\n const meta = state.getIn([\"meta\", \"paths\", path, method], OrderedMap())\n\n const mergedParams = op.get(\"parameters\", List()).map((param) => {\n return parameterWithMetaByIdentity(state, [path, method], param)\n })\n\n return OrderedMap()\n .merge(op, meta)\n .set(\"parameters\", mergedParams)\n}\n\n// Get the parameter value by parameter name\nexport function getParameter(state, pathMethod, name, inType) {\n pathMethod = pathMethod || []\n let params = state.getIn([\"meta\", \"paths\", ...pathMethod, \"parameters\"], fromJS([]))\n return params.find( (p) => {\n return Map.isMap(p) && p.get(\"name\") === name && p.get(\"in\") === inType\n }) || Map() // Always return a map\n}\n\nexport const hasHost = createSelector(\n spec,\n spec => {\n const host = spec.get(\"host\")\n return typeof host === \"string\" && host.length > 0 && host[0] !== \"/\"\n }\n)\n\n// Get the parameter values, that the user filled out\nexport function parameterValues(state, pathMethod, isXml) {\n pathMethod = pathMethod || []\n // let paramValues = state.getIn([\"meta\", \"paths\", ...pathMethod, \"parameters\"], fromJS([]))\n let paramValues = operationWithMeta(state, ...pathMethod).get(\"parameters\", List())\n return paramValues.reduce( (hash, p) => {\n let value = isXml && p.get(\"in\") === \"body\" ? p.get(\"value_xml\") : p.get(\"value\")\n return hash.set(paramToIdentifier(p, { allowHashes: false }), value)\n }, fromJS({}))\n}\n\n// True if any parameter includes `in: ?`\nexport function parametersIncludeIn(parameters, inValue=\"\") {\n if(List.isList(parameters)) {\n return parameters.some( p => Map.isMap(p) && p.get(\"in\") === inValue )\n }\n}\n\n// True if any parameter includes `type: ?`\nexport function parametersIncludeType(parameters, typeValue=\"\") {\n if(List.isList(parameters)) {\n return parameters.some( p => Map.isMap(p) && p.get(\"type\") === typeValue )\n }\n}\n\n// Get the consumes/produces value that the user selected\nexport function contentTypeValues(state, pathMethod) {\n pathMethod = pathMethod || []\n let op = specJsonWithResolvedSubtrees(state).getIn([\"paths\", ...pathMethod], fromJS({}))\n let meta = state.getIn([\"meta\", \"paths\", ...pathMethod], fromJS({}))\n let producesValue = currentProducesFor(state, pathMethod)\n\n const parameters = op.get(\"parameters\") || new List()\n\n const requestContentType = (\n meta.get(\"consumes_value\") ? meta.get(\"consumes_value\")\n : parametersIncludeType(parameters, \"file\") ? \"multipart/form-data\"\n : parametersIncludeType(parameters, \"formData\") ? \"application/x-www-form-urlencoded\"\n : undefined\n )\n\n return fromJS({\n requestContentType,\n responseContentType: producesValue\n })\n}\n\n// Get the currently selected produces value for an operation\nexport function currentProducesFor(state, pathMethod) {\n pathMethod = pathMethod || []\n\n const operation = specJsonWithResolvedSubtrees(state).getIn([ \"paths\", ...pathMethod], null)\n\n if(operation === null) {\n // return nothing if the operation does not exist\n return\n }\n\n const currentProducesValue = state.getIn([\"meta\", \"paths\", ...pathMethod, \"produces_value\"], null)\n const firstProducesArrayItem = operation.getIn([\"produces\", 0], null)\n\n return currentProducesValue || firstProducesArrayItem || \"application/json\"\n\n}\n\n// Get the produces options for an operation\nexport function producesOptionsFor(state, pathMethod) {\n pathMethod = pathMethod || []\n\n const spec = specJsonWithResolvedSubtrees(state)\n const operation = spec.getIn([ \"paths\", ...pathMethod], null)\n\n if(operation === null) {\n // return nothing if the operation does not exist\n return\n }\n\n const [path] = pathMethod\n\n const operationProduces = operation.get(\"produces\", null)\n const pathItemProduces = spec.getIn([\"paths\", path, \"produces\"], null)\n const globalProduces = spec.getIn([\"produces\"], null)\n\n return operationProduces || pathItemProduces || globalProduces\n}\n\n// Get the consumes options for an operation\nexport function consumesOptionsFor(state, pathMethod) {\n pathMethod = pathMethod || []\n\n const spec = specJsonWithResolvedSubtrees(state)\n const operation = spec.getIn([\"paths\", ...pathMethod], null)\n\n if (operation === null) {\n // return nothing if the operation does not exist\n return\n }\n\n const [path] = pathMethod\n\n const operationConsumes = operation.get(\"consumes\", null)\n const pathItemConsumes = spec.getIn([\"paths\", path, \"consumes\"], null)\n const globalConsumes = spec.getIn([\"consumes\"], null)\n\n return operationConsumes || pathItemConsumes || globalConsumes\n}\n\nexport const operationScheme = ( state, path, method ) => {\n let url = state.get(\"url\")\n let matchResult = url.match(/^([a-z][a-z0-9+\\-.]*):/)\n let urlScheme = Array.isArray(matchResult) ? matchResult[1] : null\n\n return state.getIn([\"scheme\", path, method]) || state.getIn([\"scheme\", \"_defaultScheme\"]) || urlScheme || \"\"\n}\n\nexport const canExecuteScheme = ( state, path, method ) => {\n return [\"http\", \"https\"].indexOf(operationScheme(state, path, method)) > -1\n}\n\nexport const validateBeforeExecute = ( state, pathMethod ) => {\n pathMethod = pathMethod || []\n let paramValues = state.getIn([\"meta\", \"paths\", ...pathMethod, \"parameters\"], fromJS([]))\n let isValid = true\n\n paramValues.forEach( (p) => {\n let errors = p.get(\"errors\")\n if ( errors && errors.count() ) {\n isValid = false\n }\n })\n\n return isValid\n}\n\nfunction returnSelfOrNewMap(obj) {\n // returns obj if obj is an Immutable map, else returns a new Map\n return Map.isMap(obj) ? obj : new Map()\n}\n","import parseUrl from \"url-parse\"\nimport win from \"core/window\"\nimport { btoa, buildFormData } from \"core/utils\"\n\nexport const SHOW_AUTH_POPUP = \"show_popup\"\nexport const AUTHORIZE = \"authorize\"\nexport const LOGOUT = \"logout\"\nexport const PRE_AUTHORIZE_OAUTH2 = \"pre_authorize_oauth2\"\nexport const AUTHORIZE_OAUTH2 = \"authorize_oauth2\"\nexport const VALIDATE = \"validate\"\nexport const CONFIGURE_AUTH = \"configure_auth\"\n\nconst scopeSeparator = \" \"\n\nexport function showDefinitions(payload) {\n return {\n type: SHOW_AUTH_POPUP,\n payload: payload\n }\n}\n\nexport function authorize(payload) {\n return {\n type: AUTHORIZE,\n payload: payload\n }\n}\n\nexport function logout(payload) {\n return {\n type: LOGOUT,\n payload: payload\n }\n}\n\nexport const preAuthorizeImplicit = (payload) => ( { authActions, errActions } ) => {\n let { auth , token, isValid } = payload\n let { schema, name } = auth\n let flow = schema.get(\"flow\")\n\n // remove oauth2 property from window after redirect from authentication\n delete win.swaggerUIRedirectOauth2\n\n if ( flow !== \"accessCode\" && !isValid ) {\n errActions.newAuthErr( {\n authId: name,\n source: \"auth\",\n level: \"warning\",\n message: \"Authorization may be unsafe, passed state was changed in server Passed state wasn't returned from auth server\"\n })\n }\n\n if ( token.error ) {\n errActions.newAuthErr({\n authId: name,\n source: \"auth\",\n level: \"error\",\n message: JSON.stringify(token)\n })\n return\n }\n\n authActions.authorizeOauth2({ auth, token })\n}\n\nexport function authorizeOauth2(payload) {\n return {\n type: AUTHORIZE_OAUTH2,\n payload: payload\n }\n}\n\nexport const authorizePassword = ( auth ) => ( { authActions } ) => {\n let { schema, name, username, password, passwordType, clientId, clientSecret } = auth\n let form = {\n grant_type: \"password\",\n scope: auth.scopes.join(scopeSeparator),\n username,\n password\n }\n let query = {}\n let headers = {}\n\n switch (passwordType) {\n case \"request-body\":\n setClientIdAndSecret(form, clientId, clientSecret)\n break\n\n case \"basic\":\n headers.Authorization = \"Basic \" + btoa(clientId + \":\" + clientSecret)\n break\n default:\n console.warn(`Warning: invalid passwordType ${passwordType} was passed, not including client id and secret`)\n }\n\n return authActions.authorizeRequest({ body: buildFormData(form), url: schema.get(\"tokenUrl\"), name, headers, query, auth})\n}\n\nfunction setClientIdAndSecret(target, clientId, clientSecret) {\n if ( clientId ) {\n Object.assign(target, {client_id: clientId})\n }\n\n if ( clientSecret ) {\n Object.assign(target, {client_secret: clientSecret})\n }\n}\n\nexport const authorizeApplication = ( auth ) => ( { authActions } ) => {\n let { schema, scopes, name, clientId, clientSecret } = auth\n let headers = {\n Authorization: \"Basic \" + btoa(clientId + \":\" + clientSecret)\n }\n let form = {\n grant_type: \"client_credentials\",\n scope: scopes.join(scopeSeparator)\n }\n\n return authActions.authorizeRequest({body: buildFormData(form), name, url: schema.get(\"tokenUrl\"), auth, headers })\n}\n\nexport const authorizeAccessCodeWithFormParams = ( { auth, redirectUrl } ) => ( { authActions } ) => {\n let { schema, name, clientId, clientSecret, codeVerifier } = auth\n let form = {\n grant_type: \"authorization_code\",\n code: auth.code,\n client_id: clientId,\n client_secret: clientSecret,\n redirect_uri: redirectUrl,\n code_verifier: codeVerifier\n }\n\n return authActions.authorizeRequest({body: buildFormData(form), name, url: schema.get(\"tokenUrl\"), auth})\n}\n\nexport const authorizeAccessCodeWithBasicAuthentication = ( { auth, redirectUrl } ) => ( { authActions } ) => {\n let { schema, name, clientId, clientSecret } = auth\n let headers = {\n Authorization: \"Basic \" + btoa(clientId + \":\" + clientSecret)\n }\n let form = {\n grant_type: \"authorization_code\",\n code: auth.code,\n client_id: clientId,\n redirect_uri: redirectUrl\n }\n\n return authActions.authorizeRequest({body: buildFormData(form), name, url: schema.get(\"tokenUrl\"), auth, headers})\n}\n\nexport const authorizeRequest = ( data ) => ( { fn, getConfigs, authActions, errActions, oas3Selectors, specSelectors, authSelectors } ) => {\n let { body, query={}, headers={}, name, url, auth } = data\n\n let { additionalQueryStringParams } = authSelectors.getConfigs() || {}\n\n let parsedUrl\n\n if (specSelectors.isOAS3()) {\n parsedUrl = parseUrl(url, oas3Selectors.selectedServer(), true)\n } else {\n parsedUrl = parseUrl(url, specSelectors.url(), true)\n }\n\n if(typeof additionalQueryStringParams === \"object\") {\n parsedUrl.query = Object.assign({}, parsedUrl.query, additionalQueryStringParams)\n }\n\n const fetchUrl = parsedUrl.toString()\n\n let _headers = Object.assign({\n \"Accept\":\"application/json, text/plain, */*\",\n \"Content-Type\": \"application/x-www-form-urlencoded\",\n \"X-Requested-With\": \"XMLHttpRequest\"\n }, headers)\n\n fn.fetch({\n url: fetchUrl,\n method: \"post\",\n headers: _headers,\n query: query,\n body: body,\n requestInterceptor: getConfigs().requestInterceptor,\n responseInterceptor: getConfigs().responseInterceptor\n })\n .then(function (response) {\n let token = JSON.parse(response.data)\n let error = token && ( token.error || \"\" )\n let parseError = token && ( token.parseError || \"\" )\n\n if ( !response.ok ) {\n errActions.newAuthErr( {\n authId: name,\n level: \"error\",\n source: \"auth\",\n message: response.statusText\n } )\n return\n }\n\n if ( error || parseError ) {\n errActions.newAuthErr({\n authId: name,\n level: \"error\",\n source: \"auth\",\n message: JSON.stringify(token)\n })\n return\n }\n\n authActions.authorizeOauth2({ auth, token})\n })\n .catch(e => {\n let err = new Error(e)\n let message = err.message\n // swagger-js wraps the response (if available) into the e.response property;\n // investigate to check whether there are more details on why the authorization\n // request failed (according to RFC 6479).\n // See also https://github.com/swagger-api/swagger-ui/issues/4048\n if (e.response && e.response.data) {\n const errData = e.response.data\n try {\n const jsonResponse = typeof errData === \"string\" ? JSON.parse(errData) : errData\n if (jsonResponse.error)\n message += `, error: ${jsonResponse.error}`\n if (jsonResponse.error_description)\n message += `, description: ${jsonResponse.error_description}`\n } catch (jsonError) {\n // Ignore\n }\n }\n errActions.newAuthErr( {\n authId: name,\n level: \"error\",\n source: \"auth\",\n message: message\n } )\n })\n}\n\nexport function configureAuth(payload) {\n return {\n type: CONFIGURE_AUTH,\n payload: payload\n }\n}\n","var core = module.exports = { version: '2.6.5' };\nif (typeof __e == 'number') __e = core; // eslint-disable-line no-undef\n","// 7.2.1 RequireObjectCoercible(argument)\nmodule.exports = function (it) {\n if (it == undefined) throw TypeError(\"Can't call method on \" + it);\n return it;\n};\n","// 7.1.15 ToLength\nvar toInteger = require('./_to-integer');\nvar min = Math.min;\nmodule.exports = function (it) {\n return it > 0 ? min(toInteger(it), 0x1fffffffffffff) : 0; // pow(2, 53) - 1 == 9007199254740991\n};\n","var dP = require('./_object-dp');\nvar createDesc = require('./_property-desc');\nmodule.exports = require('./_descriptors') ? function (object, key, value) {\n return dP.f(object, key, createDesc(1, value));\n} : function (object, key, value) {\n object[key] = value;\n return object;\n};\n","module.exports = function (exec) {\n try {\n return !!exec();\n } catch (e) {\n return true;\n }\n};\n","/*!\n * The buffer module from node.js, for the browser.\n *\n * @author Feross Aboukhadijeh \n * @license MIT\n */\n/* eslint-disable no-proto */\n\n'use strict'\n\nvar base64 = require('base64-js')\nvar ieee754 = require('ieee754')\nvar isArray = require('isarray')\n\nexports.Buffer = Buffer\nexports.SlowBuffer = SlowBuffer\nexports.INSPECT_MAX_BYTES = 50\n\n/**\n * If `Buffer.TYPED_ARRAY_SUPPORT`:\n * === true Use Uint8Array implementation (fastest)\n * === false Use Object implementation (most compatible, even IE6)\n *\n * Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari 5.1+,\n * Opera 11.6+, iOS 4.2+.\n *\n * Due to various browser bugs, sometimes the Object implementation will be used even\n * when the browser supports typed arrays.\n *\n * Note:\n *\n * - Firefox 4-29 lacks support for adding new properties to `Uint8Array` instances,\n * See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438.\n *\n * - Chrome 9-10 is missing the `TypedArray.prototype.subarray` function.\n *\n * - IE10 has a broken `TypedArray.prototype.subarray` function which returns arrays of\n * incorrect length in some situations.\n\n * We detect these buggy browsers and set `Buffer.TYPED_ARRAY_SUPPORT` to `false` so they\n * get the Object implementation, which is slower but behaves correctly.\n */\nBuffer.TYPED_ARRAY_SUPPORT = global.TYPED_ARRAY_SUPPORT !== undefined\n ? global.TYPED_ARRAY_SUPPORT\n : typedArraySupport()\n\n/*\n * Export kMaxLength after typed array support is determined.\n */\nexports.kMaxLength = kMaxLength()\n\nfunction typedArraySupport () {\n try {\n var arr = new Uint8Array(1)\n arr.__proto__ = {__proto__: Uint8Array.prototype, foo: function () { return 42 }}\n return arr.foo() === 42 && // typed array instances can be augmented\n typeof arr.subarray === 'function' && // chrome 9-10 lack `subarray`\n arr.subarray(1, 1).byteLength === 0 // ie10 has broken `subarray`\n } catch (e) {\n return false\n }\n}\n\nfunction kMaxLength () {\n return Buffer.TYPED_ARRAY_SUPPORT\n ? 0x7fffffff\n : 0x3fffffff\n}\n\nfunction createBuffer (that, length) {\n if (kMaxLength() < length) {\n throw new RangeError('Invalid typed array length')\n }\n if (Buffer.TYPED_ARRAY_SUPPORT) {\n // Return an augmented `Uint8Array` instance, for best performance\n that = new Uint8Array(length)\n that.__proto__ = Buffer.prototype\n } else {\n // Fallback: Return an object instance of the Buffer class\n if (that === null) {\n that = new Buffer(length)\n }\n that.length = length\n }\n\n return that\n}\n\n/**\n * The Buffer constructor returns instances of `Uint8Array` that have their\n * prototype changed to `Buffer.prototype`. Furthermore, `Buffer` is a subclass of\n * `Uint8Array`, so the returned instances will have all the node `Buffer` methods\n * and the `Uint8Array` methods. Square bracket notation works as expected -- it\n * returns a single octet.\n *\n * The `Uint8Array` prototype remains unmodified.\n */\n\nfunction Buffer (arg, encodingOrOffset, length) {\n if (!Buffer.TYPED_ARRAY_SUPPORT && !(this instanceof Buffer)) {\n return new Buffer(arg, encodingOrOffset, length)\n }\n\n // Common case.\n if (typeof arg === 'number') {\n if (typeof encodingOrOffset === 'string') {\n throw new Error(\n 'If encoding is specified then the first argument must be a string'\n )\n }\n return allocUnsafe(this, arg)\n }\n return from(this, arg, encodingOrOffset, length)\n}\n\nBuffer.poolSize = 8192 // not used by this implementation\n\n// TODO: Legacy, not needed anymore. Remove in next major version.\nBuffer._augment = function (arr) {\n arr.__proto__ = Buffer.prototype\n return arr\n}\n\nfunction from (that, value, encodingOrOffset, length) {\n if (typeof value === 'number') {\n throw new TypeError('\"value\" argument must not be a number')\n }\n\n if (typeof ArrayBuffer !== 'undefined' && value instanceof ArrayBuffer) {\n return fromArrayBuffer(that, value, encodingOrOffset, length)\n }\n\n if (typeof value === 'string') {\n return fromString(that, value, encodingOrOffset)\n }\n\n return fromObject(that, value)\n}\n\n/**\n * Functionally equivalent to Buffer(arg, encoding) but throws a TypeError\n * if value is a number.\n * Buffer.from(str[, encoding])\n * Buffer.from(array)\n * Buffer.from(buffer)\n * Buffer.from(arrayBuffer[, byteOffset[, length]])\n **/\nBuffer.from = function (value, encodingOrOffset, length) {\n return from(null, value, encodingOrOffset, length)\n}\n\nif (Buffer.TYPED_ARRAY_SUPPORT) {\n Buffer.prototype.__proto__ = Uint8Array.prototype\n Buffer.__proto__ = Uint8Array\n if (typeof Symbol !== 'undefined' && Symbol.species &&\n Buffer[Symbol.species] === Buffer) {\n // Fix subarray() in ES2016. See: https://github.com/feross/buffer/pull/97\n Object.defineProperty(Buffer, Symbol.species, {\n value: null,\n configurable: true\n })\n }\n}\n\nfunction assertSize (size) {\n if (typeof size !== 'number') {\n throw new TypeError('\"size\" argument must be a number')\n } else if (size < 0) {\n throw new RangeError('\"size\" argument must not be negative')\n }\n}\n\nfunction alloc (that, size, fill, encoding) {\n assertSize(size)\n if (size <= 0) {\n return createBuffer(that, size)\n }\n if (fill !== undefined) {\n // Only pay attention to encoding if it's a string. This\n // prevents accidentally sending in a number that would\n // be interpretted as a start offset.\n return typeof encoding === 'string'\n ? createBuffer(that, size).fill(fill, encoding)\n : createBuffer(that, size).fill(fill)\n }\n return createBuffer(that, size)\n}\n\n/**\n * Creates a new filled Buffer instance.\n * alloc(size[, fill[, encoding]])\n **/\nBuffer.alloc = function (size, fill, encoding) {\n return alloc(null, size, fill, encoding)\n}\n\nfunction allocUnsafe (that, size) {\n assertSize(size)\n that = createBuffer(that, size < 0 ? 0 : checked(size) | 0)\n if (!Buffer.TYPED_ARRAY_SUPPORT) {\n for (var i = 0; i < size; ++i) {\n that[i] = 0\n }\n }\n return that\n}\n\n/**\n * Equivalent to Buffer(num), by default creates a non-zero-filled Buffer instance.\n * */\nBuffer.allocUnsafe = function (size) {\n return allocUnsafe(null, size)\n}\n/**\n * Equivalent to SlowBuffer(num), by default creates a non-zero-filled Buffer instance.\n */\nBuffer.allocUnsafeSlow = function (size) {\n return allocUnsafe(null, size)\n}\n\nfunction fromString (that, string, encoding) {\n if (typeof encoding !== 'string' || encoding === '') {\n encoding = 'utf8'\n }\n\n if (!Buffer.isEncoding(encoding)) {\n throw new TypeError('\"encoding\" must be a valid string encoding')\n }\n\n var length = byteLength(string, encoding) | 0\n that = createBuffer(that, length)\n\n var actual = that.write(string, encoding)\n\n if (actual !== length) {\n // Writing a hex string, for example, that contains invalid characters will\n // cause everything after the first invalid character to be ignored. (e.g.\n // 'abxxcd' will be treated as 'ab')\n that = that.slice(0, actual)\n }\n\n return that\n}\n\nfunction fromArrayLike (that, array) {\n var length = array.length < 0 ? 0 : checked(array.length) | 0\n that = createBuffer(that, length)\n for (var i = 0; i < length; i += 1) {\n that[i] = array[i] & 255\n }\n return that\n}\n\nfunction fromArrayBuffer (that, array, byteOffset, length) {\n array.byteLength // this throws if `array` is not a valid ArrayBuffer\n\n if (byteOffset < 0 || array.byteLength < byteOffset) {\n throw new RangeError('\\'offset\\' is out of bounds')\n }\n\n if (array.byteLength < byteOffset + (length || 0)) {\n throw new RangeError('\\'length\\' is out of bounds')\n }\n\n if (byteOffset === undefined && length === undefined) {\n array = new Uint8Array(array)\n } else if (length === undefined) {\n array = new Uint8Array(array, byteOffset)\n } else {\n array = new Uint8Array(array, byteOffset, length)\n }\n\n if (Buffer.TYPED_ARRAY_SUPPORT) {\n // Return an augmented `Uint8Array` instance, for best performance\n that = array\n that.__proto__ = Buffer.prototype\n } else {\n // Fallback: Return an object instance of the Buffer class\n that = fromArrayLike(that, array)\n }\n return that\n}\n\nfunction fromObject (that, obj) {\n if (Buffer.isBuffer(obj)) {\n var len = checked(obj.length) | 0\n that = createBuffer(that, len)\n\n if (that.length === 0) {\n return that\n }\n\n obj.copy(that, 0, 0, len)\n return that\n }\n\n if (obj) {\n if ((typeof ArrayBuffer !== 'undefined' &&\n obj.buffer instanceof ArrayBuffer) || 'length' in obj) {\n if (typeof obj.length !== 'number' || isnan(obj.length)) {\n return createBuffer(that, 0)\n }\n return fromArrayLike(that, obj)\n }\n\n if (obj.type === 'Buffer' && isArray(obj.data)) {\n return fromArrayLike(that, obj.data)\n }\n }\n\n throw new TypeError('First argument must be a string, Buffer, ArrayBuffer, Array, or array-like object.')\n}\n\nfunction checked (length) {\n // Note: cannot use `length < kMaxLength()` here because that fails when\n // length is NaN (which is otherwise coerced to zero.)\n if (length >= kMaxLength()) {\n throw new RangeError('Attempt to allocate Buffer larger than maximum ' +\n 'size: 0x' + kMaxLength().toString(16) + ' bytes')\n }\n return length | 0\n}\n\nfunction SlowBuffer (length) {\n if (+length != length) { // eslint-disable-line eqeqeq\n length = 0\n }\n return Buffer.alloc(+length)\n}\n\nBuffer.isBuffer = function isBuffer (b) {\n return !!(b != null && b._isBuffer)\n}\n\nBuffer.compare = function compare (a, b) {\n if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) {\n throw new TypeError('Arguments must be Buffers')\n }\n\n if (a === b) return 0\n\n var x = a.length\n var y = b.length\n\n for (var i = 0, len = Math.min(x, y); i < len; ++i) {\n if (a[i] !== b[i]) {\n x = a[i]\n y = b[i]\n break\n }\n }\n\n if (x < y) return -1\n if (y < x) return 1\n return 0\n}\n\nBuffer.isEncoding = function isEncoding (encoding) {\n switch (String(encoding).toLowerCase()) {\n case 'hex':\n case 'utf8':\n case 'utf-8':\n case 'ascii':\n case 'latin1':\n case 'binary':\n case 'base64':\n case 'ucs2':\n case 'ucs-2':\n case 'utf16le':\n case 'utf-16le':\n return true\n default:\n return false\n }\n}\n\nBuffer.concat = function concat (list, length) {\n if (!isArray(list)) {\n throw new TypeError('\"list\" argument must be an Array of Buffers')\n }\n\n if (list.length === 0) {\n return Buffer.alloc(0)\n }\n\n var i\n if (length === undefined) {\n length = 0\n for (i = 0; i < list.length; ++i) {\n length += list[i].length\n }\n }\n\n var buffer = Buffer.allocUnsafe(length)\n var pos = 0\n for (i = 0; i < list.length; ++i) {\n var buf = list[i]\n if (!Buffer.isBuffer(buf)) {\n throw new TypeError('\"list\" argument must be an Array of Buffers')\n }\n buf.copy(buffer, pos)\n pos += buf.length\n }\n return buffer\n}\n\nfunction byteLength (string, encoding) {\n if (Buffer.isBuffer(string)) {\n return string.length\n }\n if (typeof ArrayBuffer !== 'undefined' && typeof ArrayBuffer.isView === 'function' &&\n (ArrayBuffer.isView(string) || string instanceof ArrayBuffer)) {\n return string.byteLength\n }\n if (typeof string !== 'string') {\n string = '' + string\n }\n\n var len = string.length\n if (len === 0) return 0\n\n // Use a for loop to avoid recursion\n var loweredCase = false\n for (;;) {\n switch (encoding) {\n case 'ascii':\n case 'latin1':\n case 'binary':\n return len\n case 'utf8':\n case 'utf-8':\n case undefined:\n return utf8ToBytes(string).length\n case 'ucs2':\n case 'ucs-2':\n case 'utf16le':\n case 'utf-16le':\n return len * 2\n case 'hex':\n return len >>> 1\n case 'base64':\n return base64ToBytes(string).length\n default:\n if (loweredCase) return utf8ToBytes(string).length // assume utf8\n encoding = ('' + encoding).toLowerCase()\n loweredCase = true\n }\n }\n}\nBuffer.byteLength = byteLength\n\nfunction slowToString (encoding, start, end) {\n var loweredCase = false\n\n // No need to verify that \"this.length <= MAX_UINT32\" since it's a read-only\n // property of a typed array.\n\n // This behaves neither like String nor Uint8Array in that we set start/end\n // to their upper/lower bounds if the value passed is out of range.\n // undefined is handled specially as per ECMA-262 6th Edition,\n // Section 13.3.3.7 Runtime Semantics: KeyedBindingInitialization.\n if (start === undefined || start < 0) {\n start = 0\n }\n // Return early if start > this.length. Done here to prevent potential uint32\n // coercion fail below.\n if (start > this.length) {\n return ''\n }\n\n if (end === undefined || end > this.length) {\n end = this.length\n }\n\n if (end <= 0) {\n return ''\n }\n\n // Force coersion to uint32. This will also coerce falsey/NaN values to 0.\n end >>>= 0\n start >>>= 0\n\n if (end <= start) {\n return ''\n }\n\n if (!encoding) encoding = 'utf8'\n\n while (true) {\n switch (encoding) {\n case 'hex':\n return hexSlice(this, start, end)\n\n case 'utf8':\n case 'utf-8':\n return utf8Slice(this, start, end)\n\n case 'ascii':\n return asciiSlice(this, start, end)\n\n case 'latin1':\n case 'binary':\n return latin1Slice(this, start, end)\n\n case 'base64':\n return base64Slice(this, start, end)\n\n case 'ucs2':\n case 'ucs-2':\n case 'utf16le':\n case 'utf-16le':\n return utf16leSlice(this, start, end)\n\n default:\n if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)\n encoding = (encoding + '').toLowerCase()\n loweredCase = true\n }\n }\n}\n\n// The property is used by `Buffer.isBuffer` and `is-buffer` (in Safari 5-7) to detect\n// Buffer instances.\nBuffer.prototype._isBuffer = true\n\nfunction swap (b, n, m) {\n var i = b[n]\n b[n] = b[m]\n b[m] = i\n}\n\nBuffer.prototype.swap16 = function swap16 () {\n var len = this.length\n if (len % 2 !== 0) {\n throw new RangeError('Buffer size must be a multiple of 16-bits')\n }\n for (var i = 0; i < len; i += 2) {\n swap(this, i, i + 1)\n }\n return this\n}\n\nBuffer.prototype.swap32 = function swap32 () {\n var len = this.length\n if (len % 4 !== 0) {\n throw new RangeError('Buffer size must be a multiple of 32-bits')\n }\n for (var i = 0; i < len; i += 4) {\n swap(this, i, i + 3)\n swap(this, i + 1, i + 2)\n }\n return this\n}\n\nBuffer.prototype.swap64 = function swap64 () {\n var len = this.length\n if (len % 8 !== 0) {\n throw new RangeError('Buffer size must be a multiple of 64-bits')\n }\n for (var i = 0; i < len; i += 8) {\n swap(this, i, i + 7)\n swap(this, i + 1, i + 6)\n swap(this, i + 2, i + 5)\n swap(this, i + 3, i + 4)\n }\n return this\n}\n\nBuffer.prototype.toString = function toString () {\n var length = this.length | 0\n if (length === 0) return ''\n if (arguments.length === 0) return utf8Slice(this, 0, length)\n return slowToString.apply(this, arguments)\n}\n\nBuffer.prototype.equals = function equals (b) {\n if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer')\n if (this === b) return true\n return Buffer.compare(this, b) === 0\n}\n\nBuffer.prototype.inspect = function inspect () {\n var str = ''\n var max = exports.INSPECT_MAX_BYTES\n if (this.length > 0) {\n str = this.toString('hex', 0, max).match(/.{2}/g).join(' ')\n if (this.length > max) str += ' ... '\n }\n return ''\n}\n\nBuffer.prototype.compare = function compare (target, start, end, thisStart, thisEnd) {\n if (!Buffer.isBuffer(target)) {\n throw new TypeError('Argument must be a Buffer')\n }\n\n if (start === undefined) {\n start = 0\n }\n if (end === undefined) {\n end = target ? target.length : 0\n }\n if (thisStart === undefined) {\n thisStart = 0\n }\n if (thisEnd === undefined) {\n thisEnd = this.length\n }\n\n if (start < 0 || end > target.length || thisStart < 0 || thisEnd > this.length) {\n throw new RangeError('out of range index')\n }\n\n if (thisStart >= thisEnd && start >= end) {\n return 0\n }\n if (thisStart >= thisEnd) {\n return -1\n }\n if (start >= end) {\n return 1\n }\n\n start >>>= 0\n end >>>= 0\n thisStart >>>= 0\n thisEnd >>>= 0\n\n if (this === target) return 0\n\n var x = thisEnd - thisStart\n var y = end - start\n var len = Math.min(x, y)\n\n var thisCopy = this.slice(thisStart, thisEnd)\n var targetCopy = target.slice(start, end)\n\n for (var i = 0; i < len; ++i) {\n if (thisCopy[i] !== targetCopy[i]) {\n x = thisCopy[i]\n y = targetCopy[i]\n break\n }\n }\n\n if (x < y) return -1\n if (y < x) return 1\n return 0\n}\n\n// Finds either the first index of `val` in `buffer` at offset >= `byteOffset`,\n// OR the last index of `val` in `buffer` at offset <= `byteOffset`.\n//\n// Arguments:\n// - buffer - a Buffer to search\n// - val - a string, Buffer, or number\n// - byteOffset - an index into `buffer`; will be clamped to an int32\n// - encoding - an optional encoding, relevant is val is a string\n// - dir - true for indexOf, false for lastIndexOf\nfunction bidirectionalIndexOf (buffer, val, byteOffset, encoding, dir) {\n // Empty buffer means no match\n if (buffer.length === 0) return -1\n\n // Normalize byteOffset\n if (typeof byteOffset === 'string') {\n encoding = byteOffset\n byteOffset = 0\n } else if (byteOffset > 0x7fffffff) {\n byteOffset = 0x7fffffff\n } else if (byteOffset < -0x80000000) {\n byteOffset = -0x80000000\n }\n byteOffset = +byteOffset // Coerce to Number.\n if (isNaN(byteOffset)) {\n // byteOffset: it it's undefined, null, NaN, \"foo\", etc, search whole buffer\n byteOffset = dir ? 0 : (buffer.length - 1)\n }\n\n // Normalize byteOffset: negative offsets start from the end of the buffer\n if (byteOffset < 0) byteOffset = buffer.length + byteOffset\n if (byteOffset >= buffer.length) {\n if (dir) return -1\n else byteOffset = buffer.length - 1\n } else if (byteOffset < 0) {\n if (dir) byteOffset = 0\n else return -1\n }\n\n // Normalize val\n if (typeof val === 'string') {\n val = Buffer.from(val, encoding)\n }\n\n // Finally, search either indexOf (if dir is true) or lastIndexOf\n if (Buffer.isBuffer(val)) {\n // Special case: looking for empty string/buffer always fails\n if (val.length === 0) {\n return -1\n }\n return arrayIndexOf(buffer, val, byteOffset, encoding, dir)\n } else if (typeof val === 'number') {\n val = val & 0xFF // Search for a byte value [0-255]\n if (Buffer.TYPED_ARRAY_SUPPORT &&\n typeof Uint8Array.prototype.indexOf === 'function') {\n if (dir) {\n return Uint8Array.prototype.indexOf.call(buffer, val, byteOffset)\n } else {\n return Uint8Array.prototype.lastIndexOf.call(buffer, val, byteOffset)\n }\n }\n return arrayIndexOf(buffer, [ val ], byteOffset, encoding, dir)\n }\n\n throw new TypeError('val must be string, number or Buffer')\n}\n\nfunction arrayIndexOf (arr, val, byteOffset, encoding, dir) {\n var indexSize = 1\n var arrLength = arr.length\n var valLength = val.length\n\n if (encoding !== undefined) {\n encoding = String(encoding).toLowerCase()\n if (encoding === 'ucs2' || encoding === 'ucs-2' ||\n encoding === 'utf16le' || encoding === 'utf-16le') {\n if (arr.length < 2 || val.length < 2) {\n return -1\n }\n indexSize = 2\n arrLength /= 2\n valLength /= 2\n byteOffset /= 2\n }\n }\n\n function read (buf, i) {\n if (indexSize === 1) {\n return buf[i]\n } else {\n return buf.readUInt16BE(i * indexSize)\n }\n }\n\n var i\n if (dir) {\n var foundIndex = -1\n for (i = byteOffset; i < arrLength; i++) {\n if (read(arr, i) === read(val, foundIndex === -1 ? 0 : i - foundIndex)) {\n if (foundIndex === -1) foundIndex = i\n if (i - foundIndex + 1 === valLength) return foundIndex * indexSize\n } else {\n if (foundIndex !== -1) i -= i - foundIndex\n foundIndex = -1\n }\n }\n } else {\n if (byteOffset + valLength > arrLength) byteOffset = arrLength - valLength\n for (i = byteOffset; i >= 0; i--) {\n var found = true\n for (var j = 0; j < valLength; j++) {\n if (read(arr, i + j) !== read(val, j)) {\n found = false\n break\n }\n }\n if (found) return i\n }\n }\n\n return -1\n}\n\nBuffer.prototype.includes = function includes (val, byteOffset, encoding) {\n return this.indexOf(val, byteOffset, encoding) !== -1\n}\n\nBuffer.prototype.indexOf = function indexOf (val, byteOffset, encoding) {\n return bidirectionalIndexOf(this, val, byteOffset, encoding, true)\n}\n\nBuffer.prototype.lastIndexOf = function lastIndexOf (val, byteOffset, encoding) {\n return bidirectionalIndexOf(this, val, byteOffset, encoding, false)\n}\n\nfunction hexWrite (buf, string, offset, length) {\n offset = Number(offset) || 0\n var remaining = buf.length - offset\n if (!length) {\n length = remaining\n } else {\n length = Number(length)\n if (length > remaining) {\n length = remaining\n }\n }\n\n // must be an even number of digits\n var strLen = string.length\n if (strLen % 2 !== 0) throw new TypeError('Invalid hex string')\n\n if (length > strLen / 2) {\n length = strLen / 2\n }\n for (var i = 0; i < length; ++i) {\n var parsed = parseInt(string.substr(i * 2, 2), 16)\n if (isNaN(parsed)) return i\n buf[offset + i] = parsed\n }\n return i\n}\n\nfunction utf8Write (buf, string, offset, length) {\n return blitBuffer(utf8ToBytes(string, buf.length - offset), buf, offset, length)\n}\n\nfunction asciiWrite (buf, string, offset, length) {\n return blitBuffer(asciiToBytes(string), buf, offset, length)\n}\n\nfunction latin1Write (buf, string, offset, length) {\n return asciiWrite(buf, string, offset, length)\n}\n\nfunction base64Write (buf, string, offset, length) {\n return blitBuffer(base64ToBytes(string), buf, offset, length)\n}\n\nfunction ucs2Write (buf, string, offset, length) {\n return blitBuffer(utf16leToBytes(string, buf.length - offset), buf, offset, length)\n}\n\nBuffer.prototype.write = function write (string, offset, length, encoding) {\n // Buffer#write(string)\n if (offset === undefined) {\n encoding = 'utf8'\n length = this.length\n offset = 0\n // Buffer#write(string, encoding)\n } else if (length === undefined && typeof offset === 'string') {\n encoding = offset\n length = this.length\n offset = 0\n // Buffer#write(string, offset[, length][, encoding])\n } else if (isFinite(offset)) {\n offset = offset | 0\n if (isFinite(length)) {\n length = length | 0\n if (encoding === undefined) encoding = 'utf8'\n } else {\n encoding = length\n length = undefined\n }\n // legacy write(string, encoding, offset, length) - remove in v0.13\n } else {\n throw new Error(\n 'Buffer.write(string, encoding, offset[, length]) is no longer supported'\n )\n }\n\n var remaining = this.length - offset\n if (length === undefined || length > remaining) length = remaining\n\n if ((string.length > 0 && (length < 0 || offset < 0)) || offset > this.length) {\n throw new RangeError('Attempt to write outside buffer bounds')\n }\n\n if (!encoding) encoding = 'utf8'\n\n var loweredCase = false\n for (;;) {\n switch (encoding) {\n case 'hex':\n return hexWrite(this, string, offset, length)\n\n case 'utf8':\n case 'utf-8':\n return utf8Write(this, string, offset, length)\n\n case 'ascii':\n return asciiWrite(this, string, offset, length)\n\n case 'latin1':\n case 'binary':\n return latin1Write(this, string, offset, length)\n\n case 'base64':\n // Warning: maxLength not taken into account in base64Write\n return base64Write(this, string, offset, length)\n\n case 'ucs2':\n case 'ucs-2':\n case 'utf16le':\n case 'utf-16le':\n return ucs2Write(this, string, offset, length)\n\n default:\n if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)\n encoding = ('' + encoding).toLowerCase()\n loweredCase = true\n }\n }\n}\n\nBuffer.prototype.toJSON = function toJSON () {\n return {\n type: 'Buffer',\n data: Array.prototype.slice.call(this._arr || this, 0)\n }\n}\n\nfunction base64Slice (buf, start, end) {\n if (start === 0 && end === buf.length) {\n return base64.fromByteArray(buf)\n } else {\n return base64.fromByteArray(buf.slice(start, end))\n }\n}\n\nfunction utf8Slice (buf, start, end) {\n end = Math.min(buf.length, end)\n var res = []\n\n var i = start\n while (i < end) {\n var firstByte = buf[i]\n var codePoint = null\n var bytesPerSequence = (firstByte > 0xEF) ? 4\n : (firstByte > 0xDF) ? 3\n : (firstByte > 0xBF) ? 2\n : 1\n\n if (i + bytesPerSequence <= end) {\n var secondByte, thirdByte, fourthByte, tempCodePoint\n\n switch (bytesPerSequence) {\n case 1:\n if (firstByte < 0x80) {\n codePoint = firstByte\n }\n break\n case 2:\n secondByte = buf[i + 1]\n if ((secondByte & 0xC0) === 0x80) {\n tempCodePoint = (firstByte & 0x1F) << 0x6 | (secondByte & 0x3F)\n if (tempCodePoint > 0x7F) {\n codePoint = tempCodePoint\n }\n }\n break\n case 3:\n secondByte = buf[i + 1]\n thirdByte = buf[i + 2]\n if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80) {\n tempCodePoint = (firstByte & 0xF) << 0xC | (secondByte & 0x3F) << 0x6 | (thirdByte & 0x3F)\n if (tempCodePoint > 0x7FF && (tempCodePoint < 0xD800 || tempCodePoint > 0xDFFF)) {\n codePoint = tempCodePoint\n }\n }\n break\n case 4:\n secondByte = buf[i + 1]\n thirdByte = buf[i + 2]\n fourthByte = buf[i + 3]\n if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80 && (fourthByte & 0xC0) === 0x80) {\n tempCodePoint = (firstByte & 0xF) << 0x12 | (secondByte & 0x3F) << 0xC | (thirdByte & 0x3F) << 0x6 | (fourthByte & 0x3F)\n if (tempCodePoint > 0xFFFF && tempCodePoint < 0x110000) {\n codePoint = tempCodePoint\n }\n }\n }\n }\n\n if (codePoint === null) {\n // we did not generate a valid codePoint so insert a\n // replacement char (U+FFFD) and advance only 1 byte\n codePoint = 0xFFFD\n bytesPerSequence = 1\n } else if (codePoint > 0xFFFF) {\n // encode to utf16 (surrogate pair dance)\n codePoint -= 0x10000\n res.push(codePoint >>> 10 & 0x3FF | 0xD800)\n codePoint = 0xDC00 | codePoint & 0x3FF\n }\n\n res.push(codePoint)\n i += bytesPerSequence\n }\n\n return decodeCodePointsArray(res)\n}\n\n// Based on http://stackoverflow.com/a/22747272/680742, the browser with\n// the lowest limit is Chrome, with 0x10000 args.\n// We go 1 magnitude less, for safety\nvar MAX_ARGUMENTS_LENGTH = 0x1000\n\nfunction decodeCodePointsArray (codePoints) {\n var len = codePoints.length\n if (len <= MAX_ARGUMENTS_LENGTH) {\n return String.fromCharCode.apply(String, codePoints) // avoid extra slice()\n }\n\n // Decode in chunks to avoid \"call stack size exceeded\".\n var res = ''\n var i = 0\n while (i < len) {\n res += String.fromCharCode.apply(\n String,\n codePoints.slice(i, i += MAX_ARGUMENTS_LENGTH)\n )\n }\n return res\n}\n\nfunction asciiSlice (buf, start, end) {\n var ret = ''\n end = Math.min(buf.length, end)\n\n for (var i = start; i < end; ++i) {\n ret += String.fromCharCode(buf[i] & 0x7F)\n }\n return ret\n}\n\nfunction latin1Slice (buf, start, end) {\n var ret = ''\n end = Math.min(buf.length, end)\n\n for (var i = start; i < end; ++i) {\n ret += String.fromCharCode(buf[i])\n }\n return ret\n}\n\nfunction hexSlice (buf, start, end) {\n var len = buf.length\n\n if (!start || start < 0) start = 0\n if (!end || end < 0 || end > len) end = len\n\n var out = ''\n for (var i = start; i < end; ++i) {\n out += toHex(buf[i])\n }\n return out\n}\n\nfunction utf16leSlice (buf, start, end) {\n var bytes = buf.slice(start, end)\n var res = ''\n for (var i = 0; i < bytes.length; i += 2) {\n res += String.fromCharCode(bytes[i] + bytes[i + 1] * 256)\n }\n return res\n}\n\nBuffer.prototype.slice = function slice (start, end) {\n var len = this.length\n start = ~~start\n end = end === undefined ? len : ~~end\n\n if (start < 0) {\n start += len\n if (start < 0) start = 0\n } else if (start > len) {\n start = len\n }\n\n if (end < 0) {\n end += len\n if (end < 0) end = 0\n } else if (end > len) {\n end = len\n }\n\n if (end < start) end = start\n\n var newBuf\n if (Buffer.TYPED_ARRAY_SUPPORT) {\n newBuf = this.subarray(start, end)\n newBuf.__proto__ = Buffer.prototype\n } else {\n var sliceLen = end - start\n newBuf = new Buffer(sliceLen, undefined)\n for (var i = 0; i < sliceLen; ++i) {\n newBuf[i] = this[i + start]\n }\n }\n\n return newBuf\n}\n\n/*\n * Need to make sure that buffer isn't trying to write out of bounds.\n */\nfunction checkOffset (offset, ext, length) {\n if ((offset % 1) !== 0 || offset < 0) throw new RangeError('offset is not uint')\n if (offset + ext > length) throw new RangeError('Trying to access beyond buffer length')\n}\n\nBuffer.prototype.readUIntLE = function readUIntLE (offset, byteLength, noAssert) {\n offset = offset | 0\n byteLength = byteLength | 0\n if (!noAssert) checkOffset(offset, byteLength, this.length)\n\n var val = this[offset]\n var mul = 1\n var i = 0\n while (++i < byteLength && (mul *= 0x100)) {\n val += this[offset + i] * mul\n }\n\n return val\n}\n\nBuffer.prototype.readUIntBE = function readUIntBE (offset, byteLength, noAssert) {\n offset = offset | 0\n byteLength = byteLength | 0\n if (!noAssert) {\n checkOffset(offset, byteLength, this.length)\n }\n\n var val = this[offset + --byteLength]\n var mul = 1\n while (byteLength > 0 && (mul *= 0x100)) {\n val += this[offset + --byteLength] * mul\n }\n\n return val\n}\n\nBuffer.prototype.readUInt8 = function readUInt8 (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 1, this.length)\n return this[offset]\n}\n\nBuffer.prototype.readUInt16LE = function readUInt16LE (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 2, this.length)\n return this[offset] | (this[offset + 1] << 8)\n}\n\nBuffer.prototype.readUInt16BE = function readUInt16BE (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 2, this.length)\n return (this[offset] << 8) | this[offset + 1]\n}\n\nBuffer.prototype.readUInt32LE = function readUInt32LE (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 4, this.length)\n\n return ((this[offset]) |\n (this[offset + 1] << 8) |\n (this[offset + 2] << 16)) +\n (this[offset + 3] * 0x1000000)\n}\n\nBuffer.prototype.readUInt32BE = function readUInt32BE (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 4, this.length)\n\n return (this[offset] * 0x1000000) +\n ((this[offset + 1] << 16) |\n (this[offset + 2] << 8) |\n this[offset + 3])\n}\n\nBuffer.prototype.readIntLE = function readIntLE (offset, byteLength, noAssert) {\n offset = offset | 0\n byteLength = byteLength | 0\n if (!noAssert) checkOffset(offset, byteLength, this.length)\n\n var val = this[offset]\n var mul = 1\n var i = 0\n while (++i < byteLength && (mul *= 0x100)) {\n val += this[offset + i] * mul\n }\n mul *= 0x80\n\n if (val >= mul) val -= Math.pow(2, 8 * byteLength)\n\n return val\n}\n\nBuffer.prototype.readIntBE = function readIntBE (offset, byteLength, noAssert) {\n offset = offset | 0\n byteLength = byteLength | 0\n if (!noAssert) checkOffset(offset, byteLength, this.length)\n\n var i = byteLength\n var mul = 1\n var val = this[offset + --i]\n while (i > 0 && (mul *= 0x100)) {\n val += this[offset + --i] * mul\n }\n mul *= 0x80\n\n if (val >= mul) val -= Math.pow(2, 8 * byteLength)\n\n return val\n}\n\nBuffer.prototype.readInt8 = function readInt8 (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 1, this.length)\n if (!(this[offset] & 0x80)) return (this[offset])\n return ((0xff - this[offset] + 1) * -1)\n}\n\nBuffer.prototype.readInt16LE = function readInt16LE (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 2, this.length)\n var val = this[offset] | (this[offset + 1] << 8)\n return (val & 0x8000) ? val | 0xFFFF0000 : val\n}\n\nBuffer.prototype.readInt16BE = function readInt16BE (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 2, this.length)\n var val = this[offset + 1] | (this[offset] << 8)\n return (val & 0x8000) ? val | 0xFFFF0000 : val\n}\n\nBuffer.prototype.readInt32LE = function readInt32LE (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 4, this.length)\n\n return (this[offset]) |\n (this[offset + 1] << 8) |\n (this[offset + 2] << 16) |\n (this[offset + 3] << 24)\n}\n\nBuffer.prototype.readInt32BE = function readInt32BE (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 4, this.length)\n\n return (this[offset] << 24) |\n (this[offset + 1] << 16) |\n (this[offset + 2] << 8) |\n (this[offset + 3])\n}\n\nBuffer.prototype.readFloatLE = function readFloatLE (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 4, this.length)\n return ieee754.read(this, offset, true, 23, 4)\n}\n\nBuffer.prototype.readFloatBE = function readFloatBE (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 4, this.length)\n return ieee754.read(this, offset, false, 23, 4)\n}\n\nBuffer.prototype.readDoubleLE = function readDoubleLE (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 8, this.length)\n return ieee754.read(this, offset, true, 52, 8)\n}\n\nBuffer.prototype.readDoubleBE = function readDoubleBE (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 8, this.length)\n return ieee754.read(this, offset, false, 52, 8)\n}\n\nfunction checkInt (buf, value, offset, ext, max, min) {\n if (!Buffer.isBuffer(buf)) throw new TypeError('\"buffer\" argument must be a Buffer instance')\n if (value > max || value < min) throw new RangeError('\"value\" argument is out of bounds')\n if (offset + ext > buf.length) throw new RangeError('Index out of range')\n}\n\nBuffer.prototype.writeUIntLE = function writeUIntLE (value, offset, byteLength, noAssert) {\n value = +value\n offset = offset | 0\n byteLength = byteLength | 0\n if (!noAssert) {\n var maxBytes = Math.pow(2, 8 * byteLength) - 1\n checkInt(this, value, offset, byteLength, maxBytes, 0)\n }\n\n var mul = 1\n var i = 0\n this[offset] = value & 0xFF\n while (++i < byteLength && (mul *= 0x100)) {\n this[offset + i] = (value / mul) & 0xFF\n }\n\n return offset + byteLength\n}\n\nBuffer.prototype.writeUIntBE = function writeUIntBE (value, offset, byteLength, noAssert) {\n value = +value\n offset = offset | 0\n byteLength = byteLength | 0\n if (!noAssert) {\n var maxBytes = Math.pow(2, 8 * byteLength) - 1\n checkInt(this, value, offset, byteLength, maxBytes, 0)\n }\n\n var i = byteLength - 1\n var mul = 1\n this[offset + i] = value & 0xFF\n while (--i >= 0 && (mul *= 0x100)) {\n this[offset + i] = (value / mul) & 0xFF\n }\n\n return offset + byteLength\n}\n\nBuffer.prototype.writeUInt8 = function writeUInt8 (value, offset, noAssert) {\n value = +value\n offset = offset | 0\n if (!noAssert) checkInt(this, value, offset, 1, 0xff, 0)\n if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value)\n this[offset] = (value & 0xff)\n return offset + 1\n}\n\nfunction objectWriteUInt16 (buf, value, offset, littleEndian) {\n if (value < 0) value = 0xffff + value + 1\n for (var i = 0, j = Math.min(buf.length - offset, 2); i < j; ++i) {\n buf[offset + i] = (value & (0xff << (8 * (littleEndian ? i : 1 - i)))) >>>\n (littleEndian ? i : 1 - i) * 8\n }\n}\n\nBuffer.prototype.writeUInt16LE = function writeUInt16LE (value, offset, noAssert) {\n value = +value\n offset = offset | 0\n if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)\n if (Buffer.TYPED_ARRAY_SUPPORT) {\n this[offset] = (value & 0xff)\n this[offset + 1] = (value >>> 8)\n } else {\n objectWriteUInt16(this, value, offset, true)\n }\n return offset + 2\n}\n\nBuffer.prototype.writeUInt16BE = function writeUInt16BE (value, offset, noAssert) {\n value = +value\n offset = offset | 0\n if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)\n if (Buffer.TYPED_ARRAY_SUPPORT) {\n this[offset] = (value >>> 8)\n this[offset + 1] = (value & 0xff)\n } else {\n objectWriteUInt16(this, value, offset, false)\n }\n return offset + 2\n}\n\nfunction objectWriteUInt32 (buf, value, offset, littleEndian) {\n if (value < 0) value = 0xffffffff + value + 1\n for (var i = 0, j = Math.min(buf.length - offset, 4); i < j; ++i) {\n buf[offset + i] = (value >>> (littleEndian ? i : 3 - i) * 8) & 0xff\n }\n}\n\nBuffer.prototype.writeUInt32LE = function writeUInt32LE (value, offset, noAssert) {\n value = +value\n offset = offset | 0\n if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)\n if (Buffer.TYPED_ARRAY_SUPPORT) {\n this[offset + 3] = (value >>> 24)\n this[offset + 2] = (value >>> 16)\n this[offset + 1] = (value >>> 8)\n this[offset] = (value & 0xff)\n } else {\n objectWriteUInt32(this, value, offset, true)\n }\n return offset + 4\n}\n\nBuffer.prototype.writeUInt32BE = function writeUInt32BE (value, offset, noAssert) {\n value = +value\n offset = offset | 0\n if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)\n if (Buffer.TYPED_ARRAY_SUPPORT) {\n this[offset] = (value >>> 24)\n this[offset + 1] = (value >>> 16)\n this[offset + 2] = (value >>> 8)\n this[offset + 3] = (value & 0xff)\n } else {\n objectWriteUInt32(this, value, offset, false)\n }\n return offset + 4\n}\n\nBuffer.prototype.writeIntLE = function writeIntLE (value, offset, byteLength, noAssert) {\n value = +value\n offset = offset | 0\n if (!noAssert) {\n var limit = Math.pow(2, 8 * byteLength - 1)\n\n checkInt(this, value, offset, byteLength, limit - 1, -limit)\n }\n\n var i = 0\n var mul = 1\n var sub = 0\n this[offset] = value & 0xFF\n while (++i < byteLength && (mul *= 0x100)) {\n if (value < 0 && sub === 0 && this[offset + i - 1] !== 0) {\n sub = 1\n }\n this[offset + i] = ((value / mul) >> 0) - sub & 0xFF\n }\n\n return offset + byteLength\n}\n\nBuffer.prototype.writeIntBE = function writeIntBE (value, offset, byteLength, noAssert) {\n value = +value\n offset = offset | 0\n if (!noAssert) {\n var limit = Math.pow(2, 8 * byteLength - 1)\n\n checkInt(this, value, offset, byteLength, limit - 1, -limit)\n }\n\n var i = byteLength - 1\n var mul = 1\n var sub = 0\n this[offset + i] = value & 0xFF\n while (--i >= 0 && (mul *= 0x100)) {\n if (value < 0 && sub === 0 && this[offset + i + 1] !== 0) {\n sub = 1\n }\n this[offset + i] = ((value / mul) >> 0) - sub & 0xFF\n }\n\n return offset + byteLength\n}\n\nBuffer.prototype.writeInt8 = function writeInt8 (value, offset, noAssert) {\n value = +value\n offset = offset | 0\n if (!noAssert) checkInt(this, value, offset, 1, 0x7f, -0x80)\n if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value)\n if (value < 0) value = 0xff + value + 1\n this[offset] = (value & 0xff)\n return offset + 1\n}\n\nBuffer.prototype.writeInt16LE = function writeInt16LE (value, offset, noAssert) {\n value = +value\n offset = offset | 0\n if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)\n if (Buffer.TYPED_ARRAY_SUPPORT) {\n this[offset] = (value & 0xff)\n this[offset + 1] = (value >>> 8)\n } else {\n objectWriteUInt16(this, value, offset, true)\n }\n return offset + 2\n}\n\nBuffer.prototype.writeInt16BE = function writeInt16BE (value, offset, noAssert) {\n value = +value\n offset = offset | 0\n if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)\n if (Buffer.TYPED_ARRAY_SUPPORT) {\n this[offset] = (value >>> 8)\n this[offset + 1] = (value & 0xff)\n } else {\n objectWriteUInt16(this, value, offset, false)\n }\n return offset + 2\n}\n\nBuffer.prototype.writeInt32LE = function writeInt32LE (value, offset, noAssert) {\n value = +value\n offset = offset | 0\n if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)\n if (Buffer.TYPED_ARRAY_SUPPORT) {\n this[offset] = (value & 0xff)\n this[offset + 1] = (value >>> 8)\n this[offset + 2] = (value >>> 16)\n this[offset + 3] = (value >>> 24)\n } else {\n objectWriteUInt32(this, value, offset, true)\n }\n return offset + 4\n}\n\nBuffer.prototype.writeInt32BE = function writeInt32BE (value, offset, noAssert) {\n value = +value\n offset = offset | 0\n if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)\n if (value < 0) value = 0xffffffff + value + 1\n if (Buffer.TYPED_ARRAY_SUPPORT) {\n this[offset] = (value >>> 24)\n this[offset + 1] = (value >>> 16)\n this[offset + 2] = (value >>> 8)\n this[offset + 3] = (value & 0xff)\n } else {\n objectWriteUInt32(this, value, offset, false)\n }\n return offset + 4\n}\n\nfunction checkIEEE754 (buf, value, offset, ext, max, min) {\n if (offset + ext > buf.length) throw new RangeError('Index out of range')\n if (offset < 0) throw new RangeError('Index out of range')\n}\n\nfunction writeFloat (buf, value, offset, littleEndian, noAssert) {\n if (!noAssert) {\n checkIEEE754(buf, value, offset, 4, 3.4028234663852886e+38, -3.4028234663852886e+38)\n }\n ieee754.write(buf, value, offset, littleEndian, 23, 4)\n return offset + 4\n}\n\nBuffer.prototype.writeFloatLE = function writeFloatLE (value, offset, noAssert) {\n return writeFloat(this, value, offset, true, noAssert)\n}\n\nBuffer.prototype.writeFloatBE = function writeFloatBE (value, offset, noAssert) {\n return writeFloat(this, value, offset, false, noAssert)\n}\n\nfunction writeDouble (buf, value, offset, littleEndian, noAssert) {\n if (!noAssert) {\n checkIEEE754(buf, value, offset, 8, 1.7976931348623157E+308, -1.7976931348623157E+308)\n }\n ieee754.write(buf, value, offset, littleEndian, 52, 8)\n return offset + 8\n}\n\nBuffer.prototype.writeDoubleLE = function writeDoubleLE (value, offset, noAssert) {\n return writeDouble(this, value, offset, true, noAssert)\n}\n\nBuffer.prototype.writeDoubleBE = function writeDoubleBE (value, offset, noAssert) {\n return writeDouble(this, value, offset, false, noAssert)\n}\n\n// copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length)\nBuffer.prototype.copy = function copy (target, targetStart, start, end) {\n if (!start) start = 0\n if (!end && end !== 0) end = this.length\n if (targetStart >= target.length) targetStart = target.length\n if (!targetStart) targetStart = 0\n if (end > 0 && end < start) end = start\n\n // Copy 0 bytes; we're done\n if (end === start) return 0\n if (target.length === 0 || this.length === 0) return 0\n\n // Fatal error conditions\n if (targetStart < 0) {\n throw new RangeError('targetStart out of bounds')\n }\n if (start < 0 || start >= this.length) throw new RangeError('sourceStart out of bounds')\n if (end < 0) throw new RangeError('sourceEnd out of bounds')\n\n // Are we oob?\n if (end > this.length) end = this.length\n if (target.length - targetStart < end - start) {\n end = target.length - targetStart + start\n }\n\n var len = end - start\n var i\n\n if (this === target && start < targetStart && targetStart < end) {\n // descending copy from end\n for (i = len - 1; i >= 0; --i) {\n target[i + targetStart] = this[i + start]\n }\n } else if (len < 1000 || !Buffer.TYPED_ARRAY_SUPPORT) {\n // ascending copy from start\n for (i = 0; i < len; ++i) {\n target[i + targetStart] = this[i + start]\n }\n } else {\n Uint8Array.prototype.set.call(\n target,\n this.subarray(start, start + len),\n targetStart\n )\n }\n\n return len\n}\n\n// Usage:\n// buffer.fill(number[, offset[, end]])\n// buffer.fill(buffer[, offset[, end]])\n// buffer.fill(string[, offset[, end]][, encoding])\nBuffer.prototype.fill = function fill (val, start, end, encoding) {\n // Handle string cases:\n if (typeof val === 'string') {\n if (typeof start === 'string') {\n encoding = start\n start = 0\n end = this.length\n } else if (typeof end === 'string') {\n encoding = end\n end = this.length\n }\n if (val.length === 1) {\n var code = val.charCodeAt(0)\n if (code < 256) {\n val = code\n }\n }\n if (encoding !== undefined && typeof encoding !== 'string') {\n throw new TypeError('encoding must be a string')\n }\n if (typeof encoding === 'string' && !Buffer.isEncoding(encoding)) {\n throw new TypeError('Unknown encoding: ' + encoding)\n }\n } else if (typeof val === 'number') {\n val = val & 255\n }\n\n // Invalid ranges are not set to a default, so can range check early.\n if (start < 0 || this.length < start || this.length < end) {\n throw new RangeError('Out of range index')\n }\n\n if (end <= start) {\n return this\n }\n\n start = start >>> 0\n end = end === undefined ? this.length : end >>> 0\n\n if (!val) val = 0\n\n var i\n if (typeof val === 'number') {\n for (i = start; i < end; ++i) {\n this[i] = val\n }\n } else {\n var bytes = Buffer.isBuffer(val)\n ? val\n : utf8ToBytes(new Buffer(val, encoding).toString())\n var len = bytes.length\n for (i = 0; i < end - start; ++i) {\n this[i + start] = bytes[i % len]\n }\n }\n\n return this\n}\n\n// HELPER FUNCTIONS\n// ================\n\nvar INVALID_BASE64_RE = /[^+\\/0-9A-Za-z-_]/g\n\nfunction base64clean (str) {\n // Node strips out invalid characters like \\n and \\t from the string, base64-js does not\n str = stringtrim(str).replace(INVALID_BASE64_RE, '')\n // Node converts strings with length < 2 to ''\n if (str.length < 2) return ''\n // Node allows for non-padded base64 strings (missing trailing ===), base64-js does not\n while (str.length % 4 !== 0) {\n str = str + '='\n }\n return str\n}\n\nfunction stringtrim (str) {\n if (str.trim) return str.trim()\n return str.replace(/^\\s+|\\s+$/g, '')\n}\n\nfunction toHex (n) {\n if (n < 16) return '0' + n.toString(16)\n return n.toString(16)\n}\n\nfunction utf8ToBytes (string, units) {\n units = units || Infinity\n var codePoint\n var length = string.length\n var leadSurrogate = null\n var bytes = []\n\n for (var i = 0; i < length; ++i) {\n codePoint = string.charCodeAt(i)\n\n // is surrogate component\n if (codePoint > 0xD7FF && codePoint < 0xE000) {\n // last char was a lead\n if (!leadSurrogate) {\n // no lead yet\n if (codePoint > 0xDBFF) {\n // unexpected trail\n if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)\n continue\n } else if (i + 1 === length) {\n // unpaired lead\n if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)\n continue\n }\n\n // valid lead\n leadSurrogate = codePoint\n\n continue\n }\n\n // 2 leads in a row\n if (codePoint < 0xDC00) {\n if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)\n leadSurrogate = codePoint\n continue\n }\n\n // valid surrogate pair\n codePoint = (leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00) + 0x10000\n } else if (leadSurrogate) {\n // valid bmp char, but last char was a lead\n if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)\n }\n\n leadSurrogate = null\n\n // encode utf8\n if (codePoint < 0x80) {\n if ((units -= 1) < 0) break\n bytes.push(codePoint)\n } else if (codePoint < 0x800) {\n if ((units -= 2) < 0) break\n bytes.push(\n codePoint >> 0x6 | 0xC0,\n codePoint & 0x3F | 0x80\n )\n } else if (codePoint < 0x10000) {\n if ((units -= 3) < 0) break\n bytes.push(\n codePoint >> 0xC | 0xE0,\n codePoint >> 0x6 & 0x3F | 0x80,\n codePoint & 0x3F | 0x80\n )\n } else if (codePoint < 0x110000) {\n if ((units -= 4) < 0) break\n bytes.push(\n codePoint >> 0x12 | 0xF0,\n codePoint >> 0xC & 0x3F | 0x80,\n codePoint >> 0x6 & 0x3F | 0x80,\n codePoint & 0x3F | 0x80\n )\n } else {\n throw new Error('Invalid code point')\n }\n }\n\n return bytes\n}\n\nfunction asciiToBytes (str) {\n var byteArray = []\n for (var i = 0; i < str.length; ++i) {\n // Node's code seems to be doing this and not & 0x7F..\n byteArray.push(str.charCodeAt(i) & 0xFF)\n }\n return byteArray\n}\n\nfunction utf16leToBytes (str, units) {\n var c, hi, lo\n var byteArray = []\n for (var i = 0; i < str.length; ++i) {\n if ((units -= 2) < 0) break\n\n c = str.charCodeAt(i)\n hi = c >> 8\n lo = c % 256\n byteArray.push(lo)\n byteArray.push(hi)\n }\n\n return byteArray\n}\n\nfunction base64ToBytes (str) {\n return base64.toByteArray(base64clean(str))\n}\n\nfunction blitBuffer (src, dst, offset, length) {\n for (var i = 0; i < length; ++i) {\n if ((i + offset >= dst.length) || (i >= src.length)) break\n dst[i + offset] = src[i]\n }\n return i\n}\n\nfunction isnan (val) {\n return val !== val // eslint-disable-line no-self-compare\n}\n","\"use strict\";\n\nmodule.exports = function (fn) {\n\tif (typeof fn !== \"function\") throw new TypeError(fn + \" is not a function\");\n\treturn fn;\n};\n","import { normalizeArray } from \"core/utils\"\n\nexport const UPDATE_LAYOUT = \"layout_update_layout\"\nexport const UPDATE_FILTER = \"layout_update_filter\"\nexport const UPDATE_MODE = \"layout_update_mode\"\nexport const SHOW = \"layout_show\"\n\n// export const ONLY_SHOW = \"layout_only_show\"\n\nexport function updateLayout(layout) {\n return {\n type: UPDATE_LAYOUT,\n payload: layout\n }\n}\n\nexport function updateFilter(filter) {\n return {\n type: UPDATE_FILTER,\n payload: filter\n }\n}\n\nexport function show(thing, shown=true) {\n thing = normalizeArray(thing)\n return {\n type: SHOW,\n payload: {thing, shown}\n }\n}\n\n// Simple string key-store, used for\nexport function changeMode(thing, mode=\"\") {\n thing = normalizeArray(thing)\n return {\n type: UPDATE_MODE,\n payload: {thing, mode}\n }\n}\n","/*!\n * @description Recursive object extending\n * @author Viacheslav Lotsmanov \n * @license MIT\n *\n * The MIT License (MIT)\n *\n * Copyright (c) 2013-2018 Viacheslav Lotsmanov\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy of\n * this software and associated documentation files (the \"Software\"), to deal in\n * the Software without restriction, including without limitation the rights to\n * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\n * the Software, and to permit persons to whom the Software is furnished to do so,\n * subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\n * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\n * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\n * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\n * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\n'use strict';\n\nfunction isSpecificValue(val) {\n\treturn (\n\t\tval instanceof Buffer\n\t\t|| val instanceof Date\n\t\t|| val instanceof RegExp\n\t) ? true : false;\n}\n\nfunction cloneSpecificValue(val) {\n\tif (val instanceof Buffer) {\n\t\tvar x = Buffer.alloc\n\t\t\t? Buffer.alloc(val.length)\n\t\t\t: new Buffer(val.length);\n\t\tval.copy(x);\n\t\treturn x;\n\t} else if (val instanceof Date) {\n\t\treturn new Date(val.getTime());\n\t} else if (val instanceof RegExp) {\n\t\treturn new RegExp(val);\n\t} else {\n\t\tthrow new Error('Unexpected situation');\n\t}\n}\n\n/**\n * Recursive cloning array.\n */\nfunction deepCloneArray(arr) {\n\tvar clone = [];\n\tarr.forEach(function (item, index) {\n\t\tif (typeof item === 'object' && item !== null) {\n\t\t\tif (Array.isArray(item)) {\n\t\t\t\tclone[index] = deepCloneArray(item);\n\t\t\t} else if (isSpecificValue(item)) {\n\t\t\t\tclone[index] = cloneSpecificValue(item);\n\t\t\t} else {\n\t\t\t\tclone[index] = deepExtend({}, item);\n\t\t\t}\n\t\t} else {\n\t\t\tclone[index] = item;\n\t\t}\n\t});\n\treturn clone;\n}\n\nfunction safeGetProperty(object, property) {\n\treturn property === '__proto__' ? undefined : object[property];\n}\n\n/**\n * Extening object that entered in first argument.\n *\n * Returns extended object or false if have no target object or incorrect type.\n *\n * If you wish to clone source object (without modify it), just use empty new\n * object as first argument, like this:\n * deepExtend({}, yourObj_1, [yourObj_N]);\n */\nvar deepExtend = module.exports = function (/*obj_1, [obj_2], [obj_N]*/) {\n\tif (arguments.length < 1 || typeof arguments[0] !== 'object') {\n\t\treturn false;\n\t}\n\n\tif (arguments.length < 2) {\n\t\treturn arguments[0];\n\t}\n\n\tvar target = arguments[0];\n\n\t// convert arguments to array and cut off target object\n\tvar args = Array.prototype.slice.call(arguments, 1);\n\n\tvar val, src, clone;\n\n\targs.forEach(function (obj) {\n\t\t// skip argument if isn't an object, is null, or is an array\n\t\tif (typeof obj !== 'object' || obj === null || Array.isArray(obj)) {\n\t\t\treturn;\n\t\t}\n\n\t\tObject.keys(obj).forEach(function (key) {\n\t\t\tsrc = safeGetProperty(target, key); // source value\n\t\t\tval = safeGetProperty(obj, key); // new value\n\n\t\t\t// recursion prevention\n\t\t\tif (val === target) {\n\t\t\t\treturn;\n\n\t\t\t/**\n\t\t\t * if new value isn't object then just overwrite by new value\n\t\t\t * instead of extending.\n\t\t\t */\n\t\t\t} else if (typeof val !== 'object' || val === null) {\n\t\t\t\ttarget[key] = val;\n\t\t\t\treturn;\n\n\t\t\t// just clone arrays (and recursive clone objects inside)\n\t\t\t} else if (Array.isArray(val)) {\n\t\t\t\ttarget[key] = deepCloneArray(val);\n\t\t\t\treturn;\n\n\t\t\t// custom cloning and overwrite for specific objects\n\t\t\t} else if (isSpecificValue(val)) {\n\t\t\t\ttarget[key] = cloneSpecificValue(val);\n\t\t\t\treturn;\n\n\t\t\t// overwrite by new value if source isn't object or array\n\t\t\t} else if (typeof src !== 'object' || src === null || Array.isArray(src)) {\n\t\t\t\ttarget[key] = deepExtend({}, val);\n\t\t\t\treturn;\n\n\t\t\t// source value and new value is objects both, extending...\n\t\t\t} else {\n\t\t\t\ttarget[key] = deepExtend(src, val);\n\t\t\t\treturn;\n\t\t\t}\n\t\t});\n\t});\n\n\treturn target;\n};\n","var dP = require('./_object-dp');\nvar createDesc = require('./_property-desc');\nmodule.exports = require('./_descriptors') ? function (object, key, value) {\n return dP.f(object, key, createDesc(1, value));\n} : function (object, key, value) {\n object[key] = value;\n return object;\n};\n","module.exports = function (it) {\n if (typeof it != 'function') throw TypeError(it + ' is not a function!');\n return it;\n};\n","var Symbol = require('./_Symbol'),\n getRawTag = require('./_getRawTag'),\n objectToString = require('./_objectToString');\n\n/** `Object#toString` result references. */\nvar nullTag = '[object Null]',\n undefinedTag = '[object Undefined]';\n\n/** Built-in value references. */\nvar symToStringTag = Symbol ? Symbol.toStringTag : undefined;\n\n/**\n * The base implementation of `getTag` without fallbacks for buggy environments.\n *\n * @private\n * @param {*} value The value to query.\n * @returns {string} Returns the `toStringTag`.\n */\nfunction baseGetTag(value) {\n if (value == null) {\n return value === undefined ? undefinedTag : nullTag;\n }\n return (symToStringTag && symToStringTag in Object(value))\n ? getRawTag(value)\n : objectToString(value);\n}\n\nmodule.exports = baseGetTag;\n","var baseIsNative = require('./_baseIsNative'),\n getValue = require('./_getValue');\n\n/**\n * Gets the native function at `key` of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {string} key The key of the method to get.\n * @returns {*} Returns the function if it's native, else `undefined`.\n */\nfunction getNative(object, key) {\n var value = getValue(object, key);\n return baseIsNative(value) ? value : undefined;\n}\n\nmodule.exports = getNative;\n","var arrayLikeKeys = require('./_arrayLikeKeys'),\n baseKeys = require('./_baseKeys'),\n isArrayLike = require('./isArrayLike');\n\n/**\n * Creates an array of the own enumerable property names of `object`.\n *\n * **Note:** Non-object values are coerced to objects. See the\n * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)\n * for more details.\n *\n * @static\n * @since 0.1.0\n * @memberOf _\n * @category Object\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names.\n * @example\n *\n * function Foo() {\n * this.a = 1;\n * this.b = 2;\n * }\n *\n * Foo.prototype.c = 3;\n *\n * _.keys(new Foo);\n * // => ['a', 'b'] (iteration order is not guaranteed)\n *\n * _.keys('hi');\n * // => ['0', '1']\n */\nfunction keys(object) {\n return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object);\n}\n\nmodule.exports = keys;\n","// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n// a duplex stream is just a stream that is both readable and writable.\n// Since JS doesn't have multiple prototypal inheritance, this class\n// prototypally inherits from Readable, and then parasitically from\n// Writable.\n\n'use strict';\n\n/**/\n\nvar pna = require('process-nextick-args');\n/**/\n\n/**/\nvar objectKeys = Object.keys || function (obj) {\n var keys = [];\n for (var key in obj) {\n keys.push(key);\n }return keys;\n};\n/**/\n\nmodule.exports = Duplex;\n\n/**/\nvar util = require('core-util-is');\nutil.inherits = require('inherits');\n/**/\n\nvar Readable = require('./_stream_readable');\nvar Writable = require('./_stream_writable');\n\nutil.inherits(Duplex, Readable);\n\n{\n // avoid scope creep, the keys array can then be collected\n var keys = objectKeys(Writable.prototype);\n for (var v = 0; v < keys.length; v++) {\n var method = keys[v];\n if (!Duplex.prototype[method]) Duplex.prototype[method] = Writable.prototype[method];\n }\n}\n\nfunction Duplex(options) {\n if (!(this instanceof Duplex)) return new Duplex(options);\n\n Readable.call(this, options);\n Writable.call(this, options);\n\n if (options && options.readable === false) this.readable = false;\n\n if (options && options.writable === false) this.writable = false;\n\n this.allowHalfOpen = true;\n if (options && options.allowHalfOpen === false) this.allowHalfOpen = false;\n\n this.once('end', onend);\n}\n\nObject.defineProperty(Duplex.prototype, 'writableHighWaterMark', {\n // making it explicit this property is not enumerable\n // because otherwise some prototype manipulation in\n // userland will fail\n enumerable: false,\n get: function () {\n return this._writableState.highWaterMark;\n }\n});\n\n// the no-half-open enforcer\nfunction onend() {\n // if we allow half-open state, or if the writable side ended,\n // then we're ok.\n if (this.allowHalfOpen || this._writableState.ended) return;\n\n // no more data can be written.\n // But allow more writes to happen in this tick.\n pna.nextTick(onEndNT, this);\n}\n\nfunction onEndNT(self) {\n self.end();\n}\n\nObject.defineProperty(Duplex.prototype, 'destroyed', {\n get: function () {\n if (this._readableState === undefined || this._writableState === undefined) {\n return false;\n }\n return this._readableState.destroyed && this._writableState.destroyed;\n },\n set: function (value) {\n // we ignore the value if the stream\n // has not been initialized yet\n if (this._readableState === undefined || this._writableState === undefined) {\n return;\n }\n\n // backward compatibility, the user is explicitly\n // managing destroyed\n this._readableState.destroyed = value;\n this._writableState.destroyed = value;\n }\n});\n\nDuplex.prototype._destroy = function (err, cb) {\n this.push(null);\n this.end();\n\n pna.nextTick(cb, err);\n};","\"use strict\";\n\nvar _undefined = require(\"../function/noop\")(); // Support ES3 engines\n\nmodule.exports = function (val) {\n return (val !== _undefined) && (val !== null);\n};\n","\"use strict\";\n\nvar toInteger = require(\"./to-integer\")\n\n , max = Math.max;\n\nmodule.exports = function (value) {\n return max(0, toInteger(value));\n};\n","/**\n * Copyright (c) 2013-present, Facebook, Inc.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n *\n * \n */\n\n'use strict';\n\nvar _prodInvariant = require('./reactProdInvariant');\n\nvar invariant = require('fbjs/lib/invariant');\n\n/**\n * Static poolers. Several custom versions for each potential number of\n * arguments. A completely generic pooler is easy to implement, but would\n * require accessing the `arguments` object. In each of these, `this` refers to\n * the Class itself, not an instance. If any others are needed, simply add them\n * here, or in their own files.\n */\nvar oneArgumentPooler = function (copyFieldsFrom) {\n var Klass = this;\n if (Klass.instancePool.length) {\n var instance = Klass.instancePool.pop();\n Klass.call(instance, copyFieldsFrom);\n return instance;\n } else {\n return new Klass(copyFieldsFrom);\n }\n};\n\nvar twoArgumentPooler = function (a1, a2) {\n var Klass = this;\n if (Klass.instancePool.length) {\n var instance = Klass.instancePool.pop();\n Klass.call(instance, a1, a2);\n return instance;\n } else {\n return new Klass(a1, a2);\n }\n};\n\nvar threeArgumentPooler = function (a1, a2, a3) {\n var Klass = this;\n if (Klass.instancePool.length) {\n var instance = Klass.instancePool.pop();\n Klass.call(instance, a1, a2, a3);\n return instance;\n } else {\n return new Klass(a1, a2, a3);\n }\n};\n\nvar fourArgumentPooler = function (a1, a2, a3, a4) {\n var Klass = this;\n if (Klass.instancePool.length) {\n var instance = Klass.instancePool.pop();\n Klass.call(instance, a1, a2, a3, a4);\n return instance;\n } else {\n return new Klass(a1, a2, a3, a4);\n }\n};\n\nvar standardReleaser = function (instance) {\n var Klass = this;\n !(instance instanceof Klass) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Trying to release an instance into a pool of a different type.') : _prodInvariant('25') : void 0;\n instance.destructor();\n if (Klass.instancePool.length < Klass.poolSize) {\n Klass.instancePool.push(instance);\n }\n};\n\nvar DEFAULT_POOL_SIZE = 10;\nvar DEFAULT_POOLER = oneArgumentPooler;\n\n/**\n * Augments `CopyConstructor` to be a poolable class, augmenting only the class\n * itself (statically) not adding any prototypical fields. Any CopyConstructor\n * you give this may have a `poolSize` property, and will look for a\n * prototypical `destructor` on instances.\n *\n * @param {Function} CopyConstructor Constructor that can be used to reset.\n * @param {Function} pooler Customizable pooler.\n */\nvar addPoolingTo = function (CopyConstructor, pooler) {\n // Casting as any so that flow ignores the actual implementation and trusts\n // it to match the type we declared\n var NewKlass = CopyConstructor;\n NewKlass.instancePool = [];\n NewKlass.getPooled = pooler || DEFAULT_POOLER;\n if (!NewKlass.poolSize) {\n NewKlass.poolSize = DEFAULT_POOL_SIZE;\n }\n NewKlass.release = standardReleaser;\n return NewKlass;\n};\n\nvar PooledClass = {\n addPoolingTo: addPoolingTo,\n oneArgumentPooler: oneArgumentPooler,\n twoArgumentPooler: twoArgumentPooler,\n threeArgumentPooler: threeArgumentPooler,\n fourArgumentPooler: fourArgumentPooler\n};\n\nmodule.exports = PooledClass;","/**\n * Performs a\n * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)\n * comparison between two values to determine if they are equivalent.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to compare.\n * @param {*} other The other value to compare.\n * @returns {boolean} Returns `true` if the values are equivalent, else `false`.\n * @example\n *\n * var object = { 'a': 1 };\n * var other = { 'a': 1 };\n *\n * _.eq(object, object);\n * // => true\n *\n * _.eq(object, other);\n * // => false\n *\n * _.eq('a', 'a');\n * // => true\n *\n * _.eq('a', Object('a'));\n * // => false\n *\n * _.eq(NaN, NaN);\n * // => true\n */\nfunction eq(value, other) {\n return value === other || (value !== value && other !== other);\n}\n\nmodule.exports = eq;\n","var baseGet = require('./_baseGet');\n\n/**\n * Gets the value at `path` of `object`. If the resolved value is\n * `undefined`, the `defaultValue` is returned in its place.\n *\n * @static\n * @memberOf _\n * @since 3.7.0\n * @category Object\n * @param {Object} object The object to query.\n * @param {Array|string} path The path of the property to get.\n * @param {*} [defaultValue] The value returned for `undefined` resolved values.\n * @returns {*} Returns the resolved value.\n * @example\n *\n * var object = { 'a': [{ 'b': { 'c': 3 } }] };\n *\n * _.get(object, 'a[0].b.c');\n * // => 3\n *\n * _.get(object, ['a', '0', 'b', 'c']);\n * // => 3\n *\n * _.get(object, 'a.b.c', 'default');\n * // => 'default'\n */\nfunction get(object, path, defaultValue) {\n var result = object == null ? undefined : baseGet(object, path);\n return result === undefined ? defaultValue : result;\n}\n\nmodule.exports = get;\n","module.exports = require(\"core-js/library/fn/object/define-properties\");","'use strict';\n\nvar required = require('requires-port')\n , qs = require('querystringify')\n , slashes = /^[A-Za-z][A-Za-z0-9+-.]*:\\/\\//\n , protocolre = /^([a-z][a-z0-9.+-]*:)?(\\/\\/)?([\\S\\s]*)/i\n , whitespace = '[\\\\x09\\\\x0A\\\\x0B\\\\x0C\\\\x0D\\\\x20\\\\xA0\\\\u1680\\\\u180E\\\\u2000\\\\u2001\\\\u2002\\\\u2003\\\\u2004\\\\u2005\\\\u2006\\\\u2007\\\\u2008\\\\u2009\\\\u200A\\\\u202F\\\\u205F\\\\u3000\\\\u2028\\\\u2029\\\\uFEFF]'\n , left = new RegExp('^'+ whitespace +'+');\n\n/**\n * Trim a given string.\n *\n * @param {String} str String to trim.\n * @public\n */\nfunction trimLeft(str) {\n return (str ? str : '').toString().replace(left, '');\n}\n\n/**\n * These are the parse rules for the URL parser, it informs the parser\n * about:\n *\n * 0. The char it Needs to parse, if it's a string it should be done using\n * indexOf, RegExp using exec and NaN means set as current value.\n * 1. The property we should set when parsing this value.\n * 2. Indication if it's backwards or forward parsing, when set as number it's\n * the value of extra chars that should be split off.\n * 3. Inherit from location if non existing in the parser.\n * 4. `toLowerCase` the resulting value.\n */\nvar rules = [\n ['#', 'hash'], // Extract from the back.\n ['?', 'query'], // Extract from the back.\n function sanitize(address) { // Sanitize what is left of the address\n return address.replace('\\\\', '/');\n },\n ['/', 'pathname'], // Extract from the back.\n ['@', 'auth', 1], // Extract from the front.\n [NaN, 'host', undefined, 1, 1], // Set left over value.\n [/:(\\d+)$/, 'port', undefined, 1], // RegExp the back.\n [NaN, 'hostname', undefined, 1, 1] // Set left over.\n];\n\n/**\n * These properties should not be copied or inherited from. This is only needed\n * for all non blob URL's as a blob URL does not include a hash, only the\n * origin.\n *\n * @type {Object}\n * @private\n */\nvar ignore = { hash: 1, query: 1 };\n\n/**\n * The location object differs when your code is loaded through a normal page,\n * Worker or through a worker using a blob. And with the blobble begins the\n * trouble as the location object will contain the URL of the blob, not the\n * location of the page where our code is loaded in. The actual origin is\n * encoded in the `pathname` so we can thankfully generate a good \"default\"\n * location from it so we can generate proper relative URL's again.\n *\n * @param {Object|String} loc Optional default location object.\n * @returns {Object} lolcation object.\n * @public\n */\nfunction lolcation(loc) {\n var globalVar;\n\n if (typeof window !== 'undefined') globalVar = window;\n else if (typeof global !== 'undefined') globalVar = global;\n else if (typeof self !== 'undefined') globalVar = self;\n else globalVar = {};\n\n var location = globalVar.location || {};\n loc = loc || location;\n\n var finaldestination = {}\n , type = typeof loc\n , key;\n\n if ('blob:' === loc.protocol) {\n finaldestination = new Url(unescape(loc.pathname), {});\n } else if ('string' === type) {\n finaldestination = new Url(loc, {});\n for (key in ignore) delete finaldestination[key];\n } else if ('object' === type) {\n for (key in loc) {\n if (key in ignore) continue;\n finaldestination[key] = loc[key];\n }\n\n if (finaldestination.slashes === undefined) {\n finaldestination.slashes = slashes.test(loc.href);\n }\n }\n\n return finaldestination;\n}\n\n/**\n * @typedef ProtocolExtract\n * @type Object\n * @property {String} protocol Protocol matched in the URL, in lowercase.\n * @property {Boolean} slashes `true` if protocol is followed by \"//\", else `false`.\n * @property {String} rest Rest of the URL that is not part of the protocol.\n */\n\n/**\n * Extract protocol information from a URL with/without double slash (\"//\").\n *\n * @param {String} address URL we want to extract from.\n * @return {ProtocolExtract} Extracted information.\n * @private\n */\nfunction extractProtocol(address) {\n address = trimLeft(address);\n var match = protocolre.exec(address);\n\n return {\n protocol: match[1] ? match[1].toLowerCase() : '',\n slashes: !!match[2],\n rest: match[3]\n };\n}\n\n/**\n * Resolve a relative URL pathname against a base URL pathname.\n *\n * @param {String} relative Pathname of the relative URL.\n * @param {String} base Pathname of the base URL.\n * @return {String} Resolved pathname.\n * @private\n */\nfunction resolve(relative, base) {\n if (relative === '') return base;\n\n var path = (base || '/').split('/').slice(0, -1).concat(relative.split('/'))\n , i = path.length\n , last = path[i - 1]\n , unshift = false\n , up = 0;\n\n while (i--) {\n if (path[i] === '.') {\n path.splice(i, 1);\n } else if (path[i] === '..') {\n path.splice(i, 1);\n up++;\n } else if (up) {\n if (i === 0) unshift = true;\n path.splice(i, 1);\n up--;\n }\n }\n\n if (unshift) path.unshift('');\n if (last === '.' || last === '..') path.push('');\n\n return path.join('/');\n}\n\n/**\n * The actual URL instance. Instead of returning an object we've opted-in to\n * create an actual constructor as it's much more memory efficient and\n * faster and it pleases my OCD.\n *\n * It is worth noting that we should not use `URL` as class name to prevent\n * clashes with the global URL instance that got introduced in browsers.\n *\n * @constructor\n * @param {String} address URL we want to parse.\n * @param {Object|String} [location] Location defaults for relative paths.\n * @param {Boolean|Function} [parser] Parser for the query string.\n * @private\n */\nfunction Url(address, location, parser) {\n address = trimLeft(address);\n\n if (!(this instanceof Url)) {\n return new Url(address, location, parser);\n }\n\n var relative, extracted, parse, instruction, index, key\n , instructions = rules.slice()\n , type = typeof location\n , url = this\n , i = 0;\n\n //\n // The following if statements allows this module two have compatibility with\n // 2 different API:\n //\n // 1. Node.js's `url.parse` api which accepts a URL, boolean as arguments\n // where the boolean indicates that the query string should also be parsed.\n //\n // 2. The `URL` interface of the browser which accepts a URL, object as\n // arguments. The supplied object will be used as default values / fall-back\n // for relative paths.\n //\n if ('object' !== type && 'string' !== type) {\n parser = location;\n location = null;\n }\n\n if (parser && 'function' !== typeof parser) parser = qs.parse;\n\n location = lolcation(location);\n\n //\n // Extract protocol information before running the instructions.\n //\n extracted = extractProtocol(address || '');\n relative = !extracted.protocol && !extracted.slashes;\n url.slashes = extracted.slashes || relative && location.slashes;\n url.protocol = extracted.protocol || location.protocol || '';\n address = extracted.rest;\n\n //\n // When the authority component is absent the URL starts with a path\n // component.\n //\n if (!extracted.slashes) instructions[3] = [/(.*)/, 'pathname'];\n\n for (; i < instructions.length; i++) {\n instruction = instructions[i];\n\n if (typeof instruction === 'function') {\n address = instruction(address);\n continue;\n }\n\n parse = instruction[0];\n key = instruction[1];\n\n if (parse !== parse) {\n url[key] = address;\n } else if ('string' === typeof parse) {\n if (~(index = address.indexOf(parse))) {\n if ('number' === typeof instruction[2]) {\n url[key] = address.slice(0, index);\n address = address.slice(index + instruction[2]);\n } else {\n url[key] = address.slice(index);\n address = address.slice(0, index);\n }\n }\n } else if ((index = parse.exec(address))) {\n url[key] = index[1];\n address = address.slice(0, index.index);\n }\n\n url[key] = url[key] || (\n relative && instruction[3] ? location[key] || '' : ''\n );\n\n //\n // Hostname, host and protocol should be lowercased so they can be used to\n // create a proper `origin`.\n //\n if (instruction[4]) url[key] = url[key].toLowerCase();\n }\n\n //\n // Also parse the supplied query string in to an object. If we're supplied\n // with a custom parser as function use that instead of the default build-in\n // parser.\n //\n if (parser) url.query = parser(url.query);\n\n //\n // If the URL is relative, resolve the pathname against the base URL.\n //\n if (\n relative\n && location.slashes\n && url.pathname.charAt(0) !== '/'\n && (url.pathname !== '' || location.pathname !== '')\n ) {\n url.pathname = resolve(url.pathname, location.pathname);\n }\n\n //\n // We should not add port numbers if they are already the default port number\n // for a given protocol. As the host also contains the port number we're going\n // override it with the hostname which contains no port number.\n //\n if (!required(url.port, url.protocol)) {\n url.host = url.hostname;\n url.port = '';\n }\n\n //\n // Parse down the `auth` for the username and password.\n //\n url.username = url.password = '';\n if (url.auth) {\n instruction = url.auth.split(':');\n url.username = instruction[0] || '';\n url.password = instruction[1] || '';\n }\n\n url.origin = url.protocol && url.host && url.protocol !== 'file:'\n ? url.protocol +'//'+ url.host\n : 'null';\n\n //\n // The href is just the compiled result.\n //\n url.href = url.toString();\n}\n\n/**\n * This is convenience method for changing properties in the URL instance to\n * insure that they all propagate correctly.\n *\n * @param {String} part Property we need to adjust.\n * @param {Mixed} value The newly assigned value.\n * @param {Boolean|Function} fn When setting the query, it will be the function\n * used to parse the query.\n * When setting the protocol, double slash will be\n * removed from the final url if it is true.\n * @returns {URL} URL instance for chaining.\n * @public\n */\nfunction set(part, value, fn) {\n var url = this;\n\n switch (part) {\n case 'query':\n if ('string' === typeof value && value.length) {\n value = (fn || qs.parse)(value);\n }\n\n url[part] = value;\n break;\n\n case 'port':\n url[part] = value;\n\n if (!required(value, url.protocol)) {\n url.host = url.hostname;\n url[part] = '';\n } else if (value) {\n url.host = url.hostname +':'+ value;\n }\n\n break;\n\n case 'hostname':\n url[part] = value;\n\n if (url.port) value += ':'+ url.port;\n url.host = value;\n break;\n\n case 'host':\n url[part] = value;\n\n if (/:\\d+$/.test(value)) {\n value = value.split(':');\n url.port = value.pop();\n url.hostname = value.join(':');\n } else {\n url.hostname = value;\n url.port = '';\n }\n\n break;\n\n case 'protocol':\n url.protocol = value.toLowerCase();\n url.slashes = !fn;\n break;\n\n case 'pathname':\n case 'hash':\n if (value) {\n var char = part === 'pathname' ? '/' : '#';\n url[part] = value.charAt(0) !== char ? char + value : value;\n } else {\n url[part] = value;\n }\n break;\n\n default:\n url[part] = value;\n }\n\n for (var i = 0; i < rules.length; i++) {\n var ins = rules[i];\n\n if (ins[4]) url[ins[1]] = url[ins[1]].toLowerCase();\n }\n\n url.origin = url.protocol && url.host && url.protocol !== 'file:'\n ? url.protocol +'//'+ url.host\n : 'null';\n\n url.href = url.toString();\n\n return url;\n}\n\n/**\n * Transform the properties back in to a valid and full URL string.\n *\n * @param {Function} stringify Optional query stringify function.\n * @returns {String} Compiled version of the URL.\n * @public\n */\nfunction toString(stringify) {\n if (!stringify || 'function' !== typeof stringify) stringify = qs.stringify;\n\n var query\n , url = this\n , protocol = url.protocol;\n\n if (protocol && protocol.charAt(protocol.length - 1) !== ':') protocol += ':';\n\n var result = protocol + (url.slashes ? '//' : '');\n\n if (url.username) {\n result += url.username;\n if (url.password) result += ':'+ url.password;\n result += '@';\n }\n\n result += url.host + url.pathname;\n\n query = 'object' === typeof url.query ? stringify(url.query) : url.query;\n if (query) result += '?' !== query.charAt(0) ? '?'+ query : query;\n\n if (url.hash) result += url.hash;\n\n return result;\n}\n\nUrl.prototype = { set: set, toString: toString };\n\n//\n// Expose the URL parser and some additional properties that might be useful for\n// others or testing.\n//\nUrl.extractProtocol = extractProtocol;\nUrl.location = lolcation;\nUrl.trimLeft = trimLeft;\nUrl.qs = qs;\n\nmodule.exports = Url;\n","import reduce from \"lodash/reduce\"\nimport * as NotOfType from \"./transformers/not-of-type\"\nimport * as ParameterOneOf from \"./transformers/parameter-oneof\"\n\nconst errorTransformers = [\n NotOfType,\n ParameterOneOf\n]\n\nexport default function transformErrors (errors, system) {\n let inputs = {\n jsSpec: system.specSelectors.specJson().toJS()\n }\n\n let transformedErrors = reduce(errorTransformers, (result, transformer) => {\n try {\n let newlyTransformedErrors = transformer.transform(result, inputs)\n return newlyTransformedErrors.filter(err => !!err) // filter removed errors\n } catch(e) {\n console.error(\"Transformer error:\", e)\n return result\n }\n }, errors)\n\n return transformedErrors\n .filter(err => !!err) // filter removed errors\n .map(err => {\n if(!err.get(\"line\") && err.get(\"path\")) {\n // TODO: re-resolve line number if we've transformed it away\n }\n return err\n })\n\n}\n","var global = require('./_global');\nvar hide = require('./_hide');\nvar has = require('./_has');\nvar SRC = require('./_uid')('src');\nvar $toString = require('./_function-to-string');\nvar TO_STRING = 'toString';\nvar TPL = ('' + $toString).split(TO_STRING);\n\nrequire('./_core').inspectSource = function (it) {\n return $toString.call(it);\n};\n\n(module.exports = function (O, key, val, safe) {\n var isFunction = typeof val == 'function';\n if (isFunction) has(val, 'name') || hide(val, 'name', key);\n if (O[key] === val) return;\n if (isFunction) has(val, SRC) || hide(val, SRC, O[key] ? '' + O[key] : TPL.join(String(key)));\n if (O === global) {\n O[key] = val;\n } else if (!safe) {\n delete O[key];\n hide(O, key, val);\n } else if (O[key]) {\n O[key] = val;\n } else {\n hide(O, key, val);\n }\n// add fake Function#toString for correct work wrapped methods / constructors with methods like LoDash isNative\n})(Function.prototype, TO_STRING, function toString() {\n return typeof this == 'function' && this[SRC] || $toString.call(this);\n});\n","module.exports = function (it) {\n return typeof it === 'object' ? it !== null : typeof it === 'function';\n};\n","module.exports = function (exec) {\n try {\n return !!exec();\n } catch (e) {\n return true;\n }\n};\n","// 7.1.13 ToObject(argument)\nvar defined = require('./_defined');\nmodule.exports = function (it) {\n return Object(defined(it));\n};\n","// 19.1.2.14 / 15.2.3.14 Object.keys(O)\nvar $keys = require('./_object-keys-internal');\nvar enumBugKeys = require('./_enum-bug-keys');\n\nmodule.exports = Object.keys || function keys(O) {\n return $keys(O, enumBugKeys);\n};\n","'use strict';\nvar $at = require('./_string-at')(true);\n\n// 21.1.3.27 String.prototype[@@iterator]()\nrequire('./_iter-define')(String, 'String', function (iterated) {\n this._t = String(iterated); // target\n this._i = 0; // next index\n// 21.1.5.2.1 %StringIteratorPrototype%.next()\n}, function () {\n var O = this._t;\n var index = this._i;\n var point;\n if (index >= O.length) return { value: undefined, done: true };\n point = $at(O, index);\n this._i += point.length;\n return { value: point, done: false };\n});\n","module.exports = {};\n","require('./es6.array.iterator');\nvar global = require('./_global');\nvar hide = require('./_hide');\nvar Iterators = require('./_iterators');\nvar TO_STRING_TAG = require('./_wks')('toStringTag');\n\nvar DOMIterables = ('CSSRuleList,CSSStyleDeclaration,CSSValueList,ClientRectList,DOMRectList,DOMStringList,' +\n 'DOMTokenList,DataTransferItemList,FileList,HTMLAllCollection,HTMLCollection,HTMLFormElement,HTMLSelectElement,' +\n 'MediaList,MimeTypeArray,NamedNodeMap,NodeList,PaintRequestList,Plugin,PluginArray,SVGLengthList,SVGNumberList,' +\n 'SVGPathSegList,SVGPointList,SVGStringList,SVGTransformList,SourceBufferList,StyleSheetList,TextTrackCueList,' +\n 'TextTrackList,TouchList').split(',');\n\nfor (var i = 0; i < DOMIterables.length; i++) {\n var NAME = DOMIterables[i];\n var Collection = global[NAME];\n var proto = Collection && Collection.prototype;\n if (proto && !proto[TO_STRING_TAG]) hide(proto, TO_STRING_TAG, NAME);\n Iterators[NAME] = Iterators.Array;\n}\n","/**\n * Copyright (c) 2013-present, Facebook, Inc.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n *\n */\n\n'use strict';\n\nvar _assign = require('object-assign');\n\nvar ReactBaseClasses = require('./ReactBaseClasses');\nvar ReactChildren = require('./ReactChildren');\nvar ReactDOMFactories = require('./ReactDOMFactories');\nvar ReactElement = require('./ReactElement');\nvar ReactPropTypes = require('./ReactPropTypes');\nvar ReactVersion = require('./ReactVersion');\n\nvar createReactClass = require('./createClass');\nvar onlyChild = require('./onlyChild');\n\nvar createElement = ReactElement.createElement;\nvar createFactory = ReactElement.createFactory;\nvar cloneElement = ReactElement.cloneElement;\n\nif (process.env.NODE_ENV !== 'production') {\n var lowPriorityWarning = require('./lowPriorityWarning');\n var canDefineProperty = require('./canDefineProperty');\n var ReactElementValidator = require('./ReactElementValidator');\n var didWarnPropTypesDeprecated = false;\n createElement = ReactElementValidator.createElement;\n createFactory = ReactElementValidator.createFactory;\n cloneElement = ReactElementValidator.cloneElement;\n}\n\nvar __spread = _assign;\nvar createMixin = function (mixin) {\n return mixin;\n};\n\nif (process.env.NODE_ENV !== 'production') {\n var warnedForSpread = false;\n var warnedForCreateMixin = false;\n __spread = function () {\n lowPriorityWarning(warnedForSpread, 'React.__spread is deprecated and should not be used. Use ' + 'Object.assign directly or another helper function with similar ' + 'semantics. You may be seeing this warning due to your compiler. ' + 'See https://fb.me/react-spread-deprecation for more details.');\n warnedForSpread = true;\n return _assign.apply(null, arguments);\n };\n\n createMixin = function (mixin) {\n lowPriorityWarning(warnedForCreateMixin, 'React.createMixin is deprecated and should not be used. ' + 'In React v16.0, it will be removed. ' + 'You can use this mixin directly instead. ' + 'See https://fb.me/createmixin-was-never-implemented for more info.');\n warnedForCreateMixin = true;\n return mixin;\n };\n}\n\nvar React = {\n // Modern\n\n Children: {\n map: ReactChildren.map,\n forEach: ReactChildren.forEach,\n count: ReactChildren.count,\n toArray: ReactChildren.toArray,\n only: onlyChild\n },\n\n Component: ReactBaseClasses.Component,\n PureComponent: ReactBaseClasses.PureComponent,\n\n createElement: createElement,\n cloneElement: cloneElement,\n isValidElement: ReactElement.isValidElement,\n\n // Classic\n\n PropTypes: ReactPropTypes,\n createClass: createReactClass,\n createFactory: createFactory,\n createMixin: createMixin,\n\n // This looks DOM specific but these are actually isomorphic helpers\n // since they are just generating DOM strings.\n DOM: ReactDOMFactories,\n\n version: ReactVersion,\n\n // Deprecated hook for JSX spread, don't use this for anything.\n __spread: __spread\n};\n\nif (process.env.NODE_ENV !== 'production') {\n var warnedForCreateClass = false;\n if (canDefineProperty) {\n Object.defineProperty(React, 'PropTypes', {\n get: function () {\n lowPriorityWarning(didWarnPropTypesDeprecated, 'Accessing PropTypes via the main React package is deprecated,' + ' and will be removed in React v16.0.' + ' Use the latest available v15.* prop-types package from npm instead.' + ' For info on usage, compatibility, migration and more, see ' + 'https://fb.me/prop-types-docs');\n didWarnPropTypesDeprecated = true;\n return ReactPropTypes;\n }\n });\n\n Object.defineProperty(React, 'createClass', {\n get: function () {\n lowPriorityWarning(warnedForCreateClass, 'Accessing createClass via the main React package is deprecated,' + ' and will be removed in React v16.0.' + \" Use a plain JavaScript class instead. If you're not yet \" + 'ready to migrate, create-react-class v15.* is available ' + 'on npm as a temporary, drop-in replacement. ' + 'For more info see https://fb.me/react-create-class');\n warnedForCreateClass = true;\n return createReactClass;\n }\n });\n }\n\n // React.DOM factories are deprecated. Wrap these methods so that\n // invocations of the React.DOM namespace and alert users to switch\n // to the `react-dom-factories` package.\n React.DOM = {};\n var warnedForFactories = false;\n Object.keys(ReactDOMFactories).forEach(function (factory) {\n React.DOM[factory] = function () {\n if (!warnedForFactories) {\n lowPriorityWarning(false, 'Accessing factories like React.DOM.%s has been deprecated ' + 'and will be removed in v16.0+. Use the ' + 'react-dom-factories package instead. ' + ' Version 1.0 provides a drop-in replacement.' + ' For more info, see https://fb.me/react-dom-factories', factory);\n warnedForFactories = true;\n }\n return ReactDOMFactories[factory].apply(ReactDOMFactories, arguments);\n };\n });\n}\n\nmodule.exports = React;","/**\n * Copyright (c) 2014-present, Facebook, Inc.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n *\n */\n\n'use strict';\n\nvar _assign = require('object-assign');\n\nvar ReactCurrentOwner = require('./ReactCurrentOwner');\n\nvar warning = require('fbjs/lib/warning');\nvar canDefineProperty = require('./canDefineProperty');\nvar hasOwnProperty = Object.prototype.hasOwnProperty;\n\nvar REACT_ELEMENT_TYPE = require('./ReactElementSymbol');\n\nvar RESERVED_PROPS = {\n key: true,\n ref: true,\n __self: true,\n __source: true\n};\n\nvar specialPropKeyWarningShown, specialPropRefWarningShown;\n\nfunction hasValidRef(config) {\n if (process.env.NODE_ENV !== 'production') {\n if (hasOwnProperty.call(config, 'ref')) {\n var getter = Object.getOwnPropertyDescriptor(config, 'ref').get;\n if (getter && getter.isReactWarning) {\n return false;\n }\n }\n }\n return config.ref !== undefined;\n}\n\nfunction hasValidKey(config) {\n if (process.env.NODE_ENV !== 'production') {\n if (hasOwnProperty.call(config, 'key')) {\n var getter = Object.getOwnPropertyDescriptor(config, 'key').get;\n if (getter && getter.isReactWarning) {\n return false;\n }\n }\n }\n return config.key !== undefined;\n}\n\nfunction defineKeyPropWarningGetter(props, displayName) {\n var warnAboutAccessingKey = function () {\n if (!specialPropKeyWarningShown) {\n specialPropKeyWarningShown = true;\n process.env.NODE_ENV !== 'production' ? warning(false, '%s: `key` is not a prop. Trying to access it will result ' + 'in `undefined` being returned. If you need to access the same ' + 'value within the child component, you should pass it as a different ' + 'prop. (https://fb.me/react-special-props)', displayName) : void 0;\n }\n };\n warnAboutAccessingKey.isReactWarning = true;\n Object.defineProperty(props, 'key', {\n get: warnAboutAccessingKey,\n configurable: true\n });\n}\n\nfunction defineRefPropWarningGetter(props, displayName) {\n var warnAboutAccessingRef = function () {\n if (!specialPropRefWarningShown) {\n specialPropRefWarningShown = true;\n process.env.NODE_ENV !== 'production' ? warning(false, '%s: `ref` is not a prop. Trying to access it will result ' + 'in `undefined` being returned. If you need to access the same ' + 'value within the child component, you should pass it as a different ' + 'prop. (https://fb.me/react-special-props)', displayName) : void 0;\n }\n };\n warnAboutAccessingRef.isReactWarning = true;\n Object.defineProperty(props, 'ref', {\n get: warnAboutAccessingRef,\n configurable: true\n });\n}\n\n/**\n * Factory method to create a new React element. This no longer adheres to\n * the class pattern, so do not use new to call it. Also, no instanceof check\n * will work. Instead test $$typeof field against Symbol.for('react.element') to check\n * if something is a React Element.\n *\n * @param {*} type\n * @param {*} key\n * @param {string|object} ref\n * @param {*} self A *temporary* helper to detect places where `this` is\n * different from the `owner` when React.createElement is called, so that we\n * can warn. We want to get rid of owner and replace string `ref`s with arrow\n * functions, and as long as `this` and owner are the same, there will be no\n * change in behavior.\n * @param {*} source An annotation object (added by a transpiler or otherwise)\n * indicating filename, line number, and/or other information.\n * @param {*} owner\n * @param {*} props\n * @internal\n */\nvar ReactElement = function (type, key, ref, self, source, owner, props) {\n var element = {\n // This tag allow us to uniquely identify this as a React Element\n $$typeof: REACT_ELEMENT_TYPE,\n\n // Built-in properties that belong on the element\n type: type,\n key: key,\n ref: ref,\n props: props,\n\n // Record the component responsible for creating this element.\n _owner: owner\n };\n\n if (process.env.NODE_ENV !== 'production') {\n // The validation flag is currently mutative. We put it on\n // an external backing store so that we can freeze the whole object.\n // This can be replaced with a WeakMap once they are implemented in\n // commonly used development environments.\n element._store = {};\n\n // To make comparing ReactElements easier for testing purposes, we make\n // the validation flag non-enumerable (where possible, which should\n // include every environment we run tests in), so the test framework\n // ignores it.\n if (canDefineProperty) {\n Object.defineProperty(element._store, 'validated', {\n configurable: false,\n enumerable: false,\n writable: true,\n value: false\n });\n // self and source are DEV only properties.\n Object.defineProperty(element, '_self', {\n configurable: false,\n enumerable: false,\n writable: false,\n value: self\n });\n // Two elements created in two different places should be considered\n // equal for testing purposes and therefore we hide it from enumeration.\n Object.defineProperty(element, '_source', {\n configurable: false,\n enumerable: false,\n writable: false,\n value: source\n });\n } else {\n element._store.validated = false;\n element._self = self;\n element._source = source;\n }\n if (Object.freeze) {\n Object.freeze(element.props);\n Object.freeze(element);\n }\n }\n\n return element;\n};\n\n/**\n * Create and return a new ReactElement of the given type.\n * See https://facebook.github.io/react/docs/top-level-api.html#react.createelement\n */\nReactElement.createElement = function (type, config, children) {\n var propName;\n\n // Reserved names are extracted\n var props = {};\n\n var key = null;\n var ref = null;\n var self = null;\n var source = null;\n\n if (config != null) {\n if (hasValidRef(config)) {\n ref = config.ref;\n }\n if (hasValidKey(config)) {\n key = '' + config.key;\n }\n\n self = config.__self === undefined ? null : config.__self;\n source = config.__source === undefined ? null : config.__source;\n // Remaining properties are added to a new props object\n for (propName in config) {\n if (hasOwnProperty.call(config, propName) && !RESERVED_PROPS.hasOwnProperty(propName)) {\n props[propName] = config[propName];\n }\n }\n }\n\n // Children can be more than one argument, and those are transferred onto\n // the newly allocated props object.\n var childrenLength = arguments.length - 2;\n if (childrenLength === 1) {\n props.children = children;\n } else if (childrenLength > 1) {\n var childArray = Array(childrenLength);\n for (var i = 0; i < childrenLength; i++) {\n childArray[i] = arguments[i + 2];\n }\n if (process.env.NODE_ENV !== 'production') {\n if (Object.freeze) {\n Object.freeze(childArray);\n }\n }\n props.children = childArray;\n }\n\n // Resolve default props\n if (type && type.defaultProps) {\n var defaultProps = type.defaultProps;\n for (propName in defaultProps) {\n if (props[propName] === undefined) {\n props[propName] = defaultProps[propName];\n }\n }\n }\n if (process.env.NODE_ENV !== 'production') {\n if (key || ref) {\n if (typeof props.$$typeof === 'undefined' || props.$$typeof !== REACT_ELEMENT_TYPE) {\n var displayName = typeof type === 'function' ? type.displayName || type.name || 'Unknown' : type;\n if (key) {\n defineKeyPropWarningGetter(props, displayName);\n }\n if (ref) {\n defineRefPropWarningGetter(props, displayName);\n }\n }\n }\n }\n return ReactElement(type, key, ref, self, source, ReactCurrentOwner.current, props);\n};\n\n/**\n * Return a function that produces ReactElements of a given type.\n * See https://facebook.github.io/react/docs/top-level-api.html#react.createfactory\n */\nReactElement.createFactory = function (type) {\n var factory = ReactElement.createElement.bind(null, type);\n // Expose the type on the factory and the prototype so that it can be\n // easily accessed on elements. E.g. `.type === Foo`.\n // This should not be named `constructor` since this may not be the function\n // that created the element, and it may not even be a constructor.\n // Legacy hook TODO: Warn if this is accessed\n factory.type = type;\n return factory;\n};\n\nReactElement.cloneAndReplaceKey = function (oldElement, newKey) {\n var newElement = ReactElement(oldElement.type, newKey, oldElement.ref, oldElement._self, oldElement._source, oldElement._owner, oldElement.props);\n\n return newElement;\n};\n\n/**\n * Clone and return a new ReactElement using element as the starting point.\n * See https://facebook.github.io/react/docs/top-level-api.html#react.cloneelement\n */\nReactElement.cloneElement = function (element, config, children) {\n var propName;\n\n // Original props are copied\n var props = _assign({}, element.props);\n\n // Reserved names are extracted\n var key = element.key;\n var ref = element.ref;\n // Self is preserved since the owner is preserved.\n var self = element._self;\n // Source is preserved since cloneElement is unlikely to be targeted by a\n // transpiler, and the original source is probably a better indicator of the\n // true owner.\n var source = element._source;\n\n // Owner will be preserved, unless ref is overridden\n var owner = element._owner;\n\n if (config != null) {\n if (hasValidRef(config)) {\n // Silently steal the ref from the parent.\n ref = config.ref;\n owner = ReactCurrentOwner.current;\n }\n if (hasValidKey(config)) {\n key = '' + config.key;\n }\n\n // Remaining properties override existing props\n var defaultProps;\n if (element.type && element.type.defaultProps) {\n defaultProps = element.type.defaultProps;\n }\n for (propName in config) {\n if (hasOwnProperty.call(config, propName) && !RESERVED_PROPS.hasOwnProperty(propName)) {\n if (config[propName] === undefined && defaultProps !== undefined) {\n // Resolve default props\n props[propName] = defaultProps[propName];\n } else {\n props[propName] = config[propName];\n }\n }\n }\n }\n\n // Children can be more than one argument, and those are transferred onto\n // the newly allocated props object.\n var childrenLength = arguments.length - 2;\n if (childrenLength === 1) {\n props.children = children;\n } else if (childrenLength > 1) {\n var childArray = Array(childrenLength);\n for (var i = 0; i < childrenLength; i++) {\n childArray[i] = arguments[i + 2];\n }\n props.children = childArray;\n }\n\n return ReactElement(element.type, key, ref, self, source, owner, props);\n};\n\n/**\n * Verifies the object is a ReactElement.\n * See https://facebook.github.io/react/docs/top-level-api.html#react.isvalidelement\n * @param {?object} object\n * @return {boolean} True if `object` is a valid component.\n * @final\n */\nReactElement.isValidElement = function (object) {\n return typeof object === 'object' && object !== null && object.$$typeof === REACT_ELEMENT_TYPE;\n};\n\nmodule.exports = ReactElement;","var root = require('./_root');\n\n/** Built-in value references. */\nvar Symbol = root.Symbol;\n\nmodule.exports = Symbol;\n","var isFunction = require('./isFunction'),\n isLength = require('./isLength');\n\n/**\n * Checks if `value` is array-like. A value is considered array-like if it's\n * not a function and has a `value.length` that's an integer greater than or\n * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is array-like, else `false`.\n * @example\n *\n * _.isArrayLike([1, 2, 3]);\n * // => true\n *\n * _.isArrayLike(document.body.children);\n * // => true\n *\n * _.isArrayLike('abc');\n * // => true\n *\n * _.isArrayLike(_.noop);\n * // => false\n */\nfunction isArrayLike(value) {\n return value != null && isLength(value.length) && !isFunction(value);\n}\n\nmodule.exports = isArrayLike;\n","var isArray = require('./isArray'),\n isKey = require('./_isKey'),\n stringToPath = require('./_stringToPath'),\n toString = require('./toString');\n\n/**\n * Casts `value` to a path array if it's not one.\n *\n * @private\n * @param {*} value The value to inspect.\n * @param {Object} [object] The object to query keys on.\n * @returns {Array} Returns the cast property path array.\n */\nfunction castPath(value, object) {\n if (isArray(value)) {\n return value;\n }\n return isKey(value, object) ? [value] : stringToPath(toString(value));\n}\n\nmodule.exports = castPath;\n","var isSymbol = require('./isSymbol');\n\n/** Used as references for various `Number` constants. */\nvar INFINITY = 1 / 0;\n\n/**\n * Converts `value` to a string key if it's not a string or symbol.\n *\n * @private\n * @param {*} value The value to inspect.\n * @returns {string|symbol} Returns the key.\n */\nfunction toKey(value) {\n if (typeof value == 'string' || isSymbol(value)) {\n return value;\n }\n var result = (value + '');\n return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;\n}\n\nmodule.exports = toKey;\n","\"use strict\";\n\nvar isValue = require(\"./is-value\");\n\nmodule.exports = function (value) {\n\tif (!isValue(value)) throw new TypeError(\"Cannot use null or undefined\");\n\treturn value;\n};\n","var Buffer = require('safe-buffer').Buffer\n\n// prototype class for hash functions\nfunction Hash (blockSize, finalSize) {\n this._block = Buffer.alloc(blockSize)\n this._finalSize = finalSize\n this._blockSize = blockSize\n this._len = 0\n}\n\nHash.prototype.update = function (data, enc) {\n if (typeof data === 'string') {\n enc = enc || 'utf8'\n data = Buffer.from(data, enc)\n }\n\n var block = this._block\n var blockSize = this._blockSize\n var length = data.length\n var accum = this._len\n\n for (var offset = 0; offset < length;) {\n var assigned = accum % blockSize\n var remainder = Math.min(length - offset, blockSize - assigned)\n\n for (var i = 0; i < remainder; i++) {\n block[assigned + i] = data[offset + i]\n }\n\n accum += remainder\n offset += remainder\n\n if ((accum % blockSize) === 0) {\n this._update(block)\n }\n }\n\n this._len += length\n return this\n}\n\nHash.prototype.digest = function (enc) {\n var rem = this._len % this._blockSize\n\n this._block[rem] = 0x80\n\n // zero (rem + 1) trailing bits, where (rem + 1) is the smallest\n // non-negative solution to the equation (length + 1 + (rem + 1)) === finalSize mod blockSize\n this._block.fill(0, rem + 1)\n\n if (rem >= this._finalSize) {\n this._update(this._block)\n this._block.fill(0)\n }\n\n var bits = this._len * 8\n\n // uint32\n if (bits <= 0xffffffff) {\n this._block.writeUInt32BE(bits, this._blockSize - 4)\n\n // uint64\n } else {\n var lowBits = (bits & 0xffffffff) >>> 0\n var highBits = (bits - lowBits) / 0x100000000\n\n this._block.writeUInt32BE(highBits, this._blockSize - 8)\n this._block.writeUInt32BE(lowBits, this._blockSize - 4)\n }\n\n this._update(this._block)\n var hash = this._hash()\n\n return enc ? hash.toString(enc) : hash\n}\n\nHash.prototype._update = function () {\n throw new Error('_update must be implemented by subclass')\n}\n\nmodule.exports = Hash\n","var ctx = require('./_ctx');\nvar call = require('./_iter-call');\nvar isArrayIter = require('./_is-array-iter');\nvar anObject = require('./_an-object');\nvar toLength = require('./_to-length');\nvar getIterFn = require('./core.get-iterator-method');\nvar BREAK = {};\nvar RETURN = {};\nvar exports = module.exports = function (iterable, entries, fn, that, ITERATOR) {\n var iterFn = ITERATOR ? function () { return iterable; } : getIterFn(iterable);\n var f = ctx(fn, that, entries ? 2 : 1);\n var index = 0;\n var length, step, iterator, result;\n if (typeof iterFn != 'function') throw TypeError(iterable + ' is not iterable!');\n // fast case for arrays with default iterator\n if (isArrayIter(iterFn)) for (length = toLength(iterable.length); length > index; index++) {\n result = entries ? f(anObject(step = iterable[index])[0], step[1]) : f(iterable[index]);\n if (result === BREAK || result === RETURN) return result;\n } else for (iterator = iterFn.call(iterable); !(step = iterator.next()).done;) {\n result = call(iterator, f, step.value, entries);\n if (result === BREAK || result === RETURN) return result;\n }\n};\nexports.BREAK = BREAK;\nexports.RETURN = RETURN;\n","'use strict';\n\n\nfunction isNothing(subject) {\n return (typeof subject === 'undefined') || (subject === null);\n}\n\n\nfunction isObject(subject) {\n return (typeof subject === 'object') && (subject !== null);\n}\n\n\nfunction toArray(sequence) {\n if (Array.isArray(sequence)) return sequence;\n else if (isNothing(sequence)) return [];\n\n return [ sequence ];\n}\n\n\nfunction extend(target, source) {\n var index, length, key, sourceKeys;\n\n if (source) {\n sourceKeys = Object.keys(source);\n\n for (index = 0, length = sourceKeys.length; index < length; index += 1) {\n key = sourceKeys[index];\n target[key] = source[key];\n }\n }\n\n return target;\n}\n\n\nfunction repeat(string, count) {\n var result = '', cycle;\n\n for (cycle = 0; cycle < count; cycle += 1) {\n result += string;\n }\n\n return result;\n}\n\n\nfunction isNegativeZero(number) {\n return (number === 0) && (Number.NEGATIVE_INFINITY === 1 / number);\n}\n\n\nmodule.exports.isNothing = isNothing;\nmodule.exports.isObject = isObject;\nmodule.exports.toArray = toArray;\nmodule.exports.repeat = repeat;\nmodule.exports.isNegativeZero = isNegativeZero;\nmodule.exports.extend = extend;\n","'use strict';\n\n/*eslint-disable max-len*/\n\nvar common = require('./common');\nvar YAMLException = require('./exception');\nvar Type = require('./type');\n\n\nfunction compileList(schema, name, result) {\n var exclude = [];\n\n schema.include.forEach(function (includedSchema) {\n result = compileList(includedSchema, name, result);\n });\n\n schema[name].forEach(function (currentType) {\n result.forEach(function (previousType, previousIndex) {\n if (previousType.tag === currentType.tag && previousType.kind === currentType.kind) {\n exclude.push(previousIndex);\n }\n });\n\n result.push(currentType);\n });\n\n return result.filter(function (type, index) {\n return exclude.indexOf(index) === -1;\n });\n}\n\n\nfunction compileMap(/* lists... */) {\n var result = {\n scalar: {},\n sequence: {},\n mapping: {},\n fallback: {}\n }, index, length;\n\n function collectType(type) {\n result[type.kind][type.tag] = result['fallback'][type.tag] = type;\n }\n\n for (index = 0, length = arguments.length; index < length; index += 1) {\n arguments[index].forEach(collectType);\n }\n return result;\n}\n\n\nfunction Schema(definition) {\n this.include = definition.include || [];\n this.implicit = definition.implicit || [];\n this.explicit = definition.explicit || [];\n\n this.implicit.forEach(function (type) {\n if (type.loadKind && type.loadKind !== 'scalar') {\n throw new YAMLException('There is a non-scalar type in the implicit list of a schema. Implicit resolving of such types is not supported.');\n }\n });\n\n this.compiledImplicit = compileList(this, 'implicit', []);\n this.compiledExplicit = compileList(this, 'explicit', []);\n this.compiledTypeMap = compileMap(this.compiledImplicit, this.compiledExplicit);\n}\n\n\nSchema.DEFAULT = null;\n\n\nSchema.create = function createSchema() {\n var schemas, types;\n\n switch (arguments.length) {\n case 1:\n schemas = Schema.DEFAULT;\n types = arguments[0];\n break;\n\n case 2:\n schemas = arguments[0];\n types = arguments[1];\n break;\n\n default:\n throw new YAMLException('Wrong number of arguments for Schema.create function');\n }\n\n schemas = common.toArray(schemas);\n types = common.toArray(types);\n\n if (!schemas.every(function (schema) { return schema instanceof Schema; })) {\n throw new YAMLException('Specified list of super schemas (or a single Schema object) contains a non-Schema object.');\n }\n\n if (!types.every(function (type) { return type instanceof Type; })) {\n throw new YAMLException('Specified list of YAML types (or a single Type object) contains a non-Type object.');\n }\n\n return new Schema({\n include: schemas,\n explicit: types\n });\n};\n\n\nmodule.exports = Schema;\n","/**\n * Copyright (c) 2013-present, Facebook, Inc.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n *\n */\n\n'use strict';\n\nvar _prodInvariant = require('./reactProdInvariant');\n\nvar invariant = require('fbjs/lib/invariant');\n\nfunction checkMask(value, bitmask) {\n return (value & bitmask) === bitmask;\n}\n\nvar DOMPropertyInjection = {\n /**\n * Mapping from normalized, camelcased property names to a configuration that\n * specifies how the associated DOM property should be accessed or rendered.\n */\n MUST_USE_PROPERTY: 0x1,\n HAS_BOOLEAN_VALUE: 0x4,\n HAS_NUMERIC_VALUE: 0x8,\n HAS_POSITIVE_NUMERIC_VALUE: 0x10 | 0x8,\n HAS_OVERLOADED_BOOLEAN_VALUE: 0x20,\n\n /**\n * Inject some specialized knowledge about the DOM. This takes a config object\n * with the following properties:\n *\n * isCustomAttribute: function that given an attribute name will return true\n * if it can be inserted into the DOM verbatim. Useful for data-* or aria-*\n * attributes where it's impossible to enumerate all of the possible\n * attribute names,\n *\n * Properties: object mapping DOM property name to one of the\n * DOMPropertyInjection constants or null. If your attribute isn't in here,\n * it won't get written to the DOM.\n *\n * DOMAttributeNames: object mapping React attribute name to the DOM\n * attribute name. Attribute names not specified use the **lowercase**\n * normalized name.\n *\n * DOMAttributeNamespaces: object mapping React attribute name to the DOM\n * attribute namespace URL. (Attribute names not specified use no namespace.)\n *\n * DOMPropertyNames: similar to DOMAttributeNames but for DOM properties.\n * Property names not specified use the normalized name.\n *\n * DOMMutationMethods: Properties that require special mutation methods. If\n * `value` is undefined, the mutation method should unset the property.\n *\n * @param {object} domPropertyConfig the config as described above.\n */\n injectDOMPropertyConfig: function (domPropertyConfig) {\n var Injection = DOMPropertyInjection;\n var Properties = domPropertyConfig.Properties || {};\n var DOMAttributeNamespaces = domPropertyConfig.DOMAttributeNamespaces || {};\n var DOMAttributeNames = domPropertyConfig.DOMAttributeNames || {};\n var DOMPropertyNames = domPropertyConfig.DOMPropertyNames || {};\n var DOMMutationMethods = domPropertyConfig.DOMMutationMethods || {};\n\n if (domPropertyConfig.isCustomAttribute) {\n DOMProperty._isCustomAttributeFunctions.push(domPropertyConfig.isCustomAttribute);\n }\n\n for (var propName in Properties) {\n !!DOMProperty.properties.hasOwnProperty(propName) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'injectDOMPropertyConfig(...): You\\'re trying to inject DOM property \\'%s\\' which has already been injected. You may be accidentally injecting the same DOM property config twice, or you may be injecting two configs that have conflicting property names.', propName) : _prodInvariant('48', propName) : void 0;\n\n var lowerCased = propName.toLowerCase();\n var propConfig = Properties[propName];\n\n var propertyInfo = {\n attributeName: lowerCased,\n attributeNamespace: null,\n propertyName: propName,\n mutationMethod: null,\n\n mustUseProperty: checkMask(propConfig, Injection.MUST_USE_PROPERTY),\n hasBooleanValue: checkMask(propConfig, Injection.HAS_BOOLEAN_VALUE),\n hasNumericValue: checkMask(propConfig, Injection.HAS_NUMERIC_VALUE),\n hasPositiveNumericValue: checkMask(propConfig, Injection.HAS_POSITIVE_NUMERIC_VALUE),\n hasOverloadedBooleanValue: checkMask(propConfig, Injection.HAS_OVERLOADED_BOOLEAN_VALUE)\n };\n !(propertyInfo.hasBooleanValue + propertyInfo.hasNumericValue + propertyInfo.hasOverloadedBooleanValue <= 1) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'DOMProperty: Value can be one of boolean, overloaded boolean, or numeric value, but not a combination: %s', propName) : _prodInvariant('50', propName) : void 0;\n\n if (process.env.NODE_ENV !== 'production') {\n DOMProperty.getPossibleStandardName[lowerCased] = propName;\n }\n\n if (DOMAttributeNames.hasOwnProperty(propName)) {\n var attributeName = DOMAttributeNames[propName];\n propertyInfo.attributeName = attributeName;\n if (process.env.NODE_ENV !== 'production') {\n DOMProperty.getPossibleStandardName[attributeName] = propName;\n }\n }\n\n if (DOMAttributeNamespaces.hasOwnProperty(propName)) {\n propertyInfo.attributeNamespace = DOMAttributeNamespaces[propName];\n }\n\n if (DOMPropertyNames.hasOwnProperty(propName)) {\n propertyInfo.propertyName = DOMPropertyNames[propName];\n }\n\n if (DOMMutationMethods.hasOwnProperty(propName)) {\n propertyInfo.mutationMethod = DOMMutationMethods[propName];\n }\n\n DOMProperty.properties[propName] = propertyInfo;\n }\n }\n};\n\n/* eslint-disable max-len */\nvar ATTRIBUTE_NAME_START_CHAR = ':A-Z_a-z\\\\u00C0-\\\\u00D6\\\\u00D8-\\\\u00F6\\\\u00F8-\\\\u02FF\\\\u0370-\\\\u037D\\\\u037F-\\\\u1FFF\\\\u200C-\\\\u200D\\\\u2070-\\\\u218F\\\\u2C00-\\\\u2FEF\\\\u3001-\\\\uD7FF\\\\uF900-\\\\uFDCF\\\\uFDF0-\\\\uFFFD';\n/* eslint-enable max-len */\n\n/**\n * DOMProperty exports lookup objects that can be used like functions:\n *\n * > DOMProperty.isValid['id']\n * true\n * > DOMProperty.isValid['foobar']\n * undefined\n *\n * Although this may be confusing, it performs better in general.\n *\n * @see http://jsperf.com/key-exists\n * @see http://jsperf.com/key-missing\n */\nvar DOMProperty = {\n ID_ATTRIBUTE_NAME: 'data-reactid',\n ROOT_ATTRIBUTE_NAME: 'data-reactroot',\n\n ATTRIBUTE_NAME_START_CHAR: ATTRIBUTE_NAME_START_CHAR,\n ATTRIBUTE_NAME_CHAR: ATTRIBUTE_NAME_START_CHAR + '\\\\-.0-9\\\\u00B7\\\\u0300-\\\\u036F\\\\u203F-\\\\u2040',\n\n /**\n * Map from property \"standard name\" to an object with info about how to set\n * the property in the DOM. Each object contains:\n *\n * attributeName:\n * Used when rendering markup or with `*Attribute()`.\n * attributeNamespace\n * propertyName:\n * Used on DOM node instances. (This includes properties that mutate due to\n * external factors.)\n * mutationMethod:\n * If non-null, used instead of the property or `setAttribute()` after\n * initial render.\n * mustUseProperty:\n * Whether the property must be accessed and mutated as an object property.\n * hasBooleanValue:\n * Whether the property should be removed when set to a falsey value.\n * hasNumericValue:\n * Whether the property must be numeric or parse as a numeric and should be\n * removed when set to a falsey value.\n * hasPositiveNumericValue:\n * Whether the property must be positive numeric or parse as a positive\n * numeric and should be removed when set to a falsey value.\n * hasOverloadedBooleanValue:\n * Whether the property can be used as a flag as well as with a value.\n * Removed when strictly equal to false; present without a value when\n * strictly equal to true; present with a value otherwise.\n */\n properties: {},\n\n /**\n * Mapping from lowercase property names to the properly cased version, used\n * to warn in the case of missing properties. Available only in __DEV__.\n *\n * autofocus is predefined, because adding it to the property whitelist\n * causes unintended side effects.\n *\n * @type {Object}\n */\n getPossibleStandardName: process.env.NODE_ENV !== 'production' ? { autofocus: 'autoFocus' } : null,\n\n /**\n * All of the isCustomAttribute() functions that have been injected.\n */\n _isCustomAttributeFunctions: [],\n\n /**\n * Checks whether a property name is a custom attribute.\n * @method\n */\n isCustomAttribute: function (attributeName) {\n for (var i = 0; i < DOMProperty._isCustomAttributeFunctions.length; i++) {\n var isCustomAttributeFn = DOMProperty._isCustomAttributeFunctions[i];\n if (isCustomAttributeFn(attributeName)) {\n return true;\n }\n }\n return false;\n },\n\n injection: DOMPropertyInjection\n};\n\nmodule.exports = DOMProperty;","/**\n * Copyright (c) 2013-present, Facebook, Inc.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n *\n */\n\n'use strict';\n\nvar ReactRef = require('./ReactRef');\nvar ReactInstrumentation = require('./ReactInstrumentation');\n\nvar warning = require('fbjs/lib/warning');\n\n/**\n * Helper to call ReactRef.attachRefs with this composite component, split out\n * to avoid allocations in the transaction mount-ready queue.\n */\nfunction attachRefs() {\n ReactRef.attachRefs(this, this._currentElement);\n}\n\nvar ReactReconciler = {\n /**\n * Initializes the component, renders markup, and registers event listeners.\n *\n * @param {ReactComponent} internalInstance\n * @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction\n * @param {?object} the containing host component instance\n * @param {?object} info about the host container\n * @return {?string} Rendered markup to be inserted into the DOM.\n * @final\n * @internal\n */\n mountComponent: function (internalInstance, transaction, hostParent, hostContainerInfo, context, parentDebugID) // 0 in production and for roots\n {\n if (process.env.NODE_ENV !== 'production') {\n if (internalInstance._debugID !== 0) {\n ReactInstrumentation.debugTool.onBeforeMountComponent(internalInstance._debugID, internalInstance._currentElement, parentDebugID);\n }\n }\n var markup = internalInstance.mountComponent(transaction, hostParent, hostContainerInfo, context, parentDebugID);\n if (internalInstance._currentElement && internalInstance._currentElement.ref != null) {\n transaction.getReactMountReady().enqueue(attachRefs, internalInstance);\n }\n if (process.env.NODE_ENV !== 'production') {\n if (internalInstance._debugID !== 0) {\n ReactInstrumentation.debugTool.onMountComponent(internalInstance._debugID);\n }\n }\n return markup;\n },\n\n /**\n * Returns a value that can be passed to\n * ReactComponentEnvironment.replaceNodeWithMarkup.\n */\n getHostNode: function (internalInstance) {\n return internalInstance.getHostNode();\n },\n\n /**\n * Releases any resources allocated by `mountComponent`.\n *\n * @final\n * @internal\n */\n unmountComponent: function (internalInstance, safely) {\n if (process.env.NODE_ENV !== 'production') {\n if (internalInstance._debugID !== 0) {\n ReactInstrumentation.debugTool.onBeforeUnmountComponent(internalInstance._debugID);\n }\n }\n ReactRef.detachRefs(internalInstance, internalInstance._currentElement);\n internalInstance.unmountComponent(safely);\n if (process.env.NODE_ENV !== 'production') {\n if (internalInstance._debugID !== 0) {\n ReactInstrumentation.debugTool.onUnmountComponent(internalInstance._debugID);\n }\n }\n },\n\n /**\n * Update a component using a new element.\n *\n * @param {ReactComponent} internalInstance\n * @param {ReactElement} nextElement\n * @param {ReactReconcileTransaction} transaction\n * @param {object} context\n * @internal\n */\n receiveComponent: function (internalInstance, nextElement, transaction, context) {\n var prevElement = internalInstance._currentElement;\n\n if (nextElement === prevElement && context === internalInstance._context) {\n // Since elements are immutable after the owner is rendered,\n // we can do a cheap identity compare here to determine if this is a\n // superfluous reconcile. It's possible for state to be mutable but such\n // change should trigger an update of the owner which would recreate\n // the element. We explicitly check for the existence of an owner since\n // it's possible for an element created outside a composite to be\n // deeply mutated and reused.\n\n // TODO: Bailing out early is just a perf optimization right?\n // TODO: Removing the return statement should affect correctness?\n return;\n }\n\n if (process.env.NODE_ENV !== 'production') {\n if (internalInstance._debugID !== 0) {\n ReactInstrumentation.debugTool.onBeforeUpdateComponent(internalInstance._debugID, nextElement);\n }\n }\n\n var refsChanged = ReactRef.shouldUpdateRefs(prevElement, nextElement);\n\n if (refsChanged) {\n ReactRef.detachRefs(internalInstance, prevElement);\n }\n\n internalInstance.receiveComponent(nextElement, transaction, context);\n\n if (refsChanged && internalInstance._currentElement && internalInstance._currentElement.ref != null) {\n transaction.getReactMountReady().enqueue(attachRefs, internalInstance);\n }\n\n if (process.env.NODE_ENV !== 'production') {\n if (internalInstance._debugID !== 0) {\n ReactInstrumentation.debugTool.onUpdateComponent(internalInstance._debugID);\n }\n }\n },\n\n /**\n * Flush any dirty changes in a component.\n *\n * @param {ReactComponent} internalInstance\n * @param {ReactReconcileTransaction} transaction\n * @internal\n */\n performUpdateIfNecessary: function (internalInstance, transaction, updateBatchNumber) {\n if (internalInstance._updateBatchNumber !== updateBatchNumber) {\n // The component's enqueued batch number should always be the current\n // batch or the following one.\n process.env.NODE_ENV !== 'production' ? warning(internalInstance._updateBatchNumber == null || internalInstance._updateBatchNumber === updateBatchNumber + 1, 'performUpdateIfNecessary: Unexpected batch number (current %s, ' + 'pending %s)', updateBatchNumber, internalInstance._updateBatchNumber) : void 0;\n return;\n }\n if (process.env.NODE_ENV !== 'production') {\n if (internalInstance._debugID !== 0) {\n ReactInstrumentation.debugTool.onBeforeUpdateComponent(internalInstance._debugID, internalInstance._currentElement);\n }\n }\n internalInstance.performUpdateIfNecessary(transaction);\n if (process.env.NODE_ENV !== 'production') {\n if (internalInstance._debugID !== 0) {\n ReactInstrumentation.debugTool.onUpdateComponent(internalInstance._debugID);\n }\n }\n }\n};\n\nmodule.exports = ReactReconciler;","/**\n * Copyright (c) 2015-present, Facebook, Inc.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n *\n */\n\n'use strict';\n\nvar DOMNamespaces = require('./DOMNamespaces');\nvar setInnerHTML = require('./setInnerHTML');\n\nvar createMicrosoftUnsafeLocalFunction = require('./createMicrosoftUnsafeLocalFunction');\nvar setTextContent = require('./setTextContent');\n\nvar ELEMENT_NODE_TYPE = 1;\nvar DOCUMENT_FRAGMENT_NODE_TYPE = 11;\n\n/**\n * In IE (8-11) and Edge, appending nodes with no children is dramatically\n * faster than appending a full subtree, so we essentially queue up the\n * .appendChild calls here and apply them so each node is added to its parent\n * before any children are added.\n *\n * In other browsers, doing so is slower or neutral compared to the other order\n * (in Firefox, twice as slow) so we only do this inversion in IE.\n *\n * See https://github.com/spicyj/innerhtml-vs-createelement-vs-clonenode.\n */\nvar enableLazy = typeof document !== 'undefined' && typeof document.documentMode === 'number' || typeof navigator !== 'undefined' && typeof navigator.userAgent === 'string' && /\\bEdge\\/\\d/.test(navigator.userAgent);\n\nfunction insertTreeChildren(tree) {\n if (!enableLazy) {\n return;\n }\n var node = tree.node;\n var children = tree.children;\n if (children.length) {\n for (var i = 0; i < children.length; i++) {\n insertTreeBefore(node, children[i], null);\n }\n } else if (tree.html != null) {\n setInnerHTML(node, tree.html);\n } else if (tree.text != null) {\n setTextContent(node, tree.text);\n }\n}\n\nvar insertTreeBefore = createMicrosoftUnsafeLocalFunction(function (parentNode, tree, referenceNode) {\n // DocumentFragments aren't actually part of the DOM after insertion so\n // appending children won't update the DOM. We need to ensure the fragment\n // is properly populated first, breaking out of our lazy approach for just\n // this level. Also, some plugins (like Flash Player) will read\n // nodes immediately upon insertion into the DOM, so \n // must also be populated prior to insertion into the DOM.\n if (tree.node.nodeType === DOCUMENT_FRAGMENT_NODE_TYPE || tree.node.nodeType === ELEMENT_NODE_TYPE && tree.node.nodeName.toLowerCase() === 'object' && (tree.node.namespaceURI == null || tree.node.namespaceURI === DOMNamespaces.html)) {\n insertTreeChildren(tree);\n parentNode.insertBefore(tree.node, referenceNode);\n } else {\n parentNode.insertBefore(tree.node, referenceNode);\n insertTreeChildren(tree);\n }\n});\n\nfunction replaceChildWithTree(oldNode, newTree) {\n oldNode.parentNode.replaceChild(newTree.node, oldNode);\n insertTreeChildren(newTree);\n}\n\nfunction queueChild(parentTree, childTree) {\n if (enableLazy) {\n parentTree.children.push(childTree);\n } else {\n parentTree.node.appendChild(childTree.node);\n }\n}\n\nfunction queueHTML(tree, html) {\n if (enableLazy) {\n tree.html = html;\n } else {\n setInnerHTML(tree.node, html);\n }\n}\n\nfunction queueText(tree, text) {\n if (enableLazy) {\n tree.text = text;\n } else {\n setTextContent(tree.node, text);\n }\n}\n\nfunction toString() {\n return this.node.nodeName;\n}\n\nfunction DOMLazyTree(node) {\n return {\n node: node,\n children: [],\n html: null,\n text: null,\n toString: toString\n };\n}\n\nDOMLazyTree.insertTreeBefore = insertTreeBefore;\nDOMLazyTree.replaceChildWithTree = replaceChildWithTree;\nDOMLazyTree.queueChild = queueChild;\nDOMLazyTree.queueHTML = queueHTML;\nDOMLazyTree.queueText = queueText;\n\nmodule.exports = DOMLazyTree;","var assignValue = require('./_assignValue'),\n baseAssignValue = require('./_baseAssignValue');\n\n/**\n * Copies properties of `source` to `object`.\n *\n * @private\n * @param {Object} source The object to copy properties from.\n * @param {Array} props The property identifiers to copy.\n * @param {Object} [object={}] The object to copy properties to.\n * @param {Function} [customizer] The function to customize copied values.\n * @returns {Object} Returns `object`.\n */\nfunction copyObject(source, props, object, customizer) {\n var isNew = !object;\n object || (object = {});\n\n var index = -1,\n length = props.length;\n\n while (++index < length) {\n var key = props[index];\n\n var newValue = customizer\n ? customizer(object[key], source[key], key, object, source)\n : undefined;\n\n if (newValue === undefined) {\n newValue = source[key];\n }\n if (isNew) {\n baseAssignValue(object, key, newValue);\n } else {\n assignValue(object, key, newValue);\n }\n }\n return object;\n}\n\nmodule.exports = copyObject;\n","module.exports = require(\"core-js/library/fn/symbol/iterator\");","module.exports = require(\"core-js/library/fn/symbol\");","module.exports = require(\"core-js/library/fn/get-iterator\");","module.exports = require(\"core-js/library/fn/array/from\");","var baseGetTag = require('./_baseGetTag'),\n isObject = require('./isObject');\n\n/** `Object#toString` result references. */\nvar asyncTag = '[object AsyncFunction]',\n funcTag = '[object Function]',\n genTag = '[object GeneratorFunction]',\n proxyTag = '[object Proxy]';\n\n/**\n * Checks if `value` is classified as a `Function` object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a function, else `false`.\n * @example\n *\n * _.isFunction(_);\n * // => true\n *\n * _.isFunction(/abc/);\n * // => false\n */\nfunction isFunction(value) {\n if (!isObject(value)) {\n return false;\n }\n // The use of `Object#toString` avoids issues with the `typeof` operator\n // in Safari 9 which returns 'object' for typed arrays and other constructors.\n var tag = baseGetTag(value);\n return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag;\n}\n\nmodule.exports = isFunction;\n","'use strict';\n\n// Make a value ready for JSON.stringify() / process.send()\nmodule.exports = function (value) {\n\tif (typeof value === 'object') {\n\t\treturn destroyCircular(value, []);\n\t}\n\n\t// People sometimes throw things besides Error objects, so...\n\n\tif (typeof value === 'function') {\n\t\t// JSON.stringify discards functions. We do to, unless a function is thrown directly.\n\t\treturn '[Function: ' + (value.name || 'anonymous') + ']';\n\t}\n\n\treturn value;\n};\n\n// https://www.npmjs.com/package/destroy-circular\nfunction destroyCircular(from, seen) {\n\tvar to;\n\tif (Array.isArray(from)) {\n\t\tto = [];\n\t} else {\n\t\tto = {};\n\t}\n\n\tseen.push(from);\n\n\tObject.keys(from).forEach(function (key) {\n\t\tvar value = from[key];\n\n\t\tif (typeof value === 'function') {\n\t\t\treturn;\n\t\t}\n\n\t\tif (!value || typeof value !== 'object') {\n\t\t\tto[key] = value;\n\t\t\treturn;\n\t\t}\n\n\t\tif (seen.indexOf(from[key]) === -1) {\n\t\t\tto[key] = destroyCircular(from[key], seen.slice(0));\n\t\t\treturn;\n\t\t}\n\n\t\tto[key] = '[Circular]';\n\t});\n\n\tif (typeof from.name === 'string') {\n\t\tto.name = from.name;\n\t}\n\n\tif (typeof from.message === 'string') {\n\t\tto.message = from.message;\n\t}\n\n\tif (typeof from.stack === 'string') {\n\t\tto.stack = from.stack;\n\t}\n\n\treturn to;\n}\n","import { objectify, isFunc, normalizeArray, deeplyStripKey } from \"core/utils\"\nimport XML from \"@kyleshockey/xml\"\nimport memoizee from \"memoizee\"\nimport deepAssign from \"@kyleshockey/object-assign-deep\"\n\nconst primitives = {\n \"string\": () => \"string\",\n \"string_email\": () => \"user@example.com\",\n \"string_date-time\": () => new Date().toISOString(),\n \"string_date\": () => new Date().toISOString().substring(0, 10),\n \"string_uuid\": () => \"3fa85f64-5717-4562-b3fc-2c963f66afa6\",\n \"string_hostname\": () => \"example.com\",\n \"string_ipv4\": () => \"198.51.100.42\",\n \"string_ipv6\": () => \"2001:0db8:5b96:0000:0000:426f:8e17:642a\",\n \"number\": () => 0,\n \"number_float\": () => 0.0,\n \"integer\": () => 0,\n \"boolean\": (schema) => typeof schema.default === \"boolean\" ? schema.default : true\n}\n\nconst primitive = (schema) => {\n schema = objectify(schema)\n let { type, format } = schema\n\n let fn = primitives[`${type}_${format}`] || primitives[type]\n\n if(isFunc(fn))\n return fn(schema)\n\n return \"Unknown Type: \" + schema.type\n}\n\n\nexport const sampleFromSchema = (schema, config={}) => {\n let { type, example, properties, additionalProperties, items } = objectify(schema)\n let { includeReadOnly, includeWriteOnly } = config\n\n\n if(example !== undefined) {\n return deeplyStripKey(example, \"$$ref\", (val) => {\n // do a couple of quick sanity tests to ensure the value\n // looks like a $$ref that swagger-client generates.\n return typeof val === \"string\" && val.indexOf(\"#\") > -1\n })\n }\n\n if(!type) {\n if(properties) {\n type = \"object\"\n } else if(items) {\n type = \"array\"\n } else {\n return\n }\n }\n\n if(type === \"object\") {\n let props = objectify(properties)\n let obj = {}\n for (var name in props) {\n if ( props[name] && props[name].deprecated ) {\n continue\n }\n if ( props[name] && props[name].readOnly && !includeReadOnly ) {\n continue\n }\n if ( props[name] && props[name].writeOnly && !includeWriteOnly ) {\n continue\n }\n obj[name] = sampleFromSchema(props[name], config)\n }\n\n if ( additionalProperties === true ) {\n obj.additionalProp1 = {}\n } else if ( additionalProperties ) {\n let additionalProps = objectify(additionalProperties)\n let additionalPropVal = sampleFromSchema(additionalProps, config)\n\n for (let i = 1; i < 4; i++) {\n obj[\"additionalProp\" + i] = additionalPropVal\n }\n }\n return obj\n }\n\n if(type === \"array\") {\n if(Array.isArray(items.anyOf)) {\n return items.anyOf.map(i => sampleFromSchema(i, config))\n }\n\n if(Array.isArray(items.oneOf)) {\n return items.oneOf.map(i => sampleFromSchema(i, config))\n }\n\n return [ sampleFromSchema(items, config) ]\n }\n\n if(schema[\"enum\"]) {\n if(schema[\"default\"])\n return schema[\"default\"]\n return normalizeArray(schema[\"enum\"])[0]\n }\n\n if (type === \"file\") {\n return\n }\n\n return primitive(schema)\n}\n\nexport const inferSchema = (thing) => {\n if(thing.schema)\n thing = thing.schema\n\n if(thing.properties) {\n thing.type = \"object\"\n }\n\n return thing // Hopefully this will have something schema like in it... `type` for example\n}\n\n\nexport const sampleXmlFromSchema = (schema, config={}) => {\n let objectifySchema = deepAssign({}, objectify(schema))\n let { type, properties, additionalProperties, items, example } = objectifySchema\n let { includeReadOnly, includeWriteOnly } = config\n let defaultValue = objectifySchema.default\n let res = {}\n let _attr = {}\n let { xml } = schema\n let { name, prefix, namespace } = xml\n let enumValue = objectifySchema.enum\n let displayName, value\n\n if(!type) {\n if(properties || additionalProperties) {\n type = \"object\"\n } else if(items) {\n type = \"array\"\n } else {\n return\n }\n }\n\n name = name || \"notagname\"\n // add prefix to name if exists\n displayName = (prefix ? prefix + \":\" : \"\") + name\n if ( namespace ) {\n //add prefix to namespace if exists\n let namespacePrefix = prefix ? ( \"xmlns:\" + prefix ) : \"xmlns\"\n _attr[namespacePrefix] = namespace\n }\n\n if (type === \"array\") {\n if (items) {\n items.xml = items.xml || xml || {}\n items.xml.name = items.xml.name || xml.name\n\n if (xml.wrapped) {\n res[displayName] = []\n if (Array.isArray(example)) {\n example.forEach((v)=>{\n items.example = v\n res[displayName].push(sampleXmlFromSchema(items, config))\n })\n } else if (Array.isArray(defaultValue)) {\n defaultValue.forEach((v)=>{\n items.default = v\n res[displayName].push(sampleXmlFromSchema(items, config))\n })\n } else {\n res[displayName] = [sampleXmlFromSchema(items, config)]\n }\n\n if (_attr) {\n res[displayName].push({_attr: _attr})\n }\n return res\n }\n\n let _res = []\n\n if (Array.isArray(example)) {\n example.forEach((v)=>{\n items.example = v\n _res.push(sampleXmlFromSchema(items, config))\n })\n return _res\n } else if (Array.isArray(defaultValue)) {\n defaultValue.forEach((v)=>{\n items.default = v\n _res.push(sampleXmlFromSchema(items, config))\n })\n return _res\n }\n\n return sampleXmlFromSchema(items, config)\n }\n }\n\n if (type === \"object\") {\n let props = objectify(properties)\n res[displayName] = []\n example = example || {}\n\n for (let propName in props) {\n if (!props.hasOwnProperty(propName)) {\n continue\n }\n if ( props[propName].readOnly && !includeReadOnly ) {\n continue\n }\n if ( props[propName].writeOnly && !includeWriteOnly ) {\n continue\n }\n\n props[propName].xml = props[propName].xml || {}\n\n if (props[propName].xml.attribute) {\n let enumAttrVal = Array.isArray(props[propName].enum) && props[propName].enum[0]\n let attrExample = props[propName].example\n let attrDefault = props[propName].default\n _attr[props[propName].xml.name || propName] = attrExample!== undefined && attrExample\n || example[propName] !== undefined && example[propName] || attrDefault !== undefined && attrDefault\n || enumAttrVal || primitive(props[propName])\n } else {\n props[propName].xml.name = props[propName].xml.name || propName\n if(props[propName].example === undefined && example[propName] !== undefined) {\n props[propName].example = example[propName]\n }\n let t = sampleXmlFromSchema(props[propName])\n if (Array.isArray(t)) {\n res[displayName] = res[displayName].concat(t)\n } else {\n res[displayName].push(t)\n }\n\n }\n }\n\n if (additionalProperties === true) {\n res[displayName].push({additionalProp: \"Anything can be here\"})\n } else if (additionalProperties) {\n res[displayName].push({additionalProp: primitive(additionalProperties)})\n }\n\n if (_attr) {\n res[displayName].push({_attr: _attr})\n }\n return res\n }\n\n if (example !== undefined) {\n value = example\n } else if (defaultValue !== undefined) {\n //display example if exists\n value = defaultValue\n } else if (Array.isArray(enumValue)) {\n //display enum first value\n value = enumValue[0]\n } else {\n //set default value\n value = primitive(schema)\n }\n\n res[displayName] = _attr ? [{_attr: _attr}, value] : value\n\n return res\n}\n\nexport function createXMLExample(schema, config) {\n let json = sampleXmlFromSchema(schema, config)\n if (!json) { return }\n\n return XML(json, { declaration: true, indent: \"\\t\" })\n}\n\nexport const memoizedCreateXMLExample = memoizee(createXMLExample)\n\nexport const memoizedSampleFromSchema = memoizee(sampleFromSchema)\n","export const UPDATE_CONFIGS = \"configs_update\"\nexport const TOGGLE_CONFIGS = \"configs_toggle\"\n\n// Update the configs, with a merge ( not deep )\nexport function update(configName, configValue) {\n return {\n type: UPDATE_CONFIGS,\n payload: {\n [configName]: configValue\n },\n }\n}\n\n// Toggle's the config, by name\nexport function toggle(configName) {\n return {\n type: TOGGLE_CONFIGS,\n payload: configName,\n }\n}\n\n\n// Hook\nexport const loaded = () => () => {}\n","/**\n * @prettier\n */\n\nimport Im from \"immutable\"\n\nconst swagger2SchemaKeys = Im.Set.of(\n \"type\",\n \"format\",\n \"items\",\n \"default\",\n \"maximum\",\n \"exclusiveMaximum\",\n \"minimum\",\n \"exclusiveMinimum\",\n \"maxLength\",\n \"minLength\",\n \"pattern\",\n \"maxItems\",\n \"minItems\",\n \"uniqueItems\",\n \"enum\",\n \"multipleOf\"\n)\n\n/**\n * @typedef {Object} ParameterSchemaDescriptor\n * @property {Immutable.Map} schema - the parameter schema\n * @property {string|null} parameterContentMediaType - the effective media type, for `content`-based OpenAPI 3.0 Parameters, or `null` otherwise\n */\n\n/**\n * Get the effective schema value for a parameter, or an empty Immutable.Map if\n * no suitable schema can be found.\n *\n * Supports OpenAPI 3.0 `Parameter.content` priority -- since a Parameter Object\n * cannot have both `schema` and `content`, this function ignores `schema` when\n * `content` is present.\n *\n * @param {Immutable.Map} parameter The parameter to identify a schema for\n * @param {object} config\n * @param {boolean} config.isOAS3 Whether the parameter is from an OpenAPI 2.0\n * or OpenAPI 3.0 definition\n * @return {ParameterSchemaDescriptor} Information about the parameter schema\n */\nexport default function getParameterSchema(parameter, { isOAS3 } = {}) {\n // Return empty Map if `parameter` isn't a Map\n if (!Im.Map.isMap(parameter)) {\n return {\n schema: Im.Map(),\n parameterContentMediaType: null,\n }\n }\n\n if (!isOAS3) {\n // Swagger 2.0\n if (parameter.get(\"in\") === \"body\") {\n return {\n schema: parameter.get(\"schema\", Im.Map()),\n parameterContentMediaType: null,\n }\n } else {\n return {\n schema: parameter.filter((v, k) => swagger2SchemaKeys.includes(k)),\n parameterContentMediaType: null,\n }\n }\n }\n\n // If we've reached here, the parameter is OpenAPI 3.0\n\n if (parameter.get(\"content\")) {\n const parameterContentMediaTypes = parameter\n .get(\"content\", Im.Map({}))\n .keySeq()\n\n const parameterContentMediaType = parameterContentMediaTypes.first()\n\n return {\n schema: parameter.getIn(\n [\"content\", parameterContentMediaType, \"schema\"],\n Im.Map()\n ),\n parameterContentMediaType,\n }\n }\n\n return {\n schema: parameter.get(\"schema\", Im.Map()),\n parameterContentMediaType: null,\n }\n}\n","module.exports = require(\"regenerator-runtime\");\n","import freeGlobal from './_freeGlobal.js';\n\n/** Detect free variable `self`. */\nvar freeSelf = typeof self == 'object' && self && self.Object === Object && self;\n\n/** Used as a reference to the global object. */\nvar root = freeGlobal || freeSelf || Function('return this')();\n\nexport default root;\n","import root from './_root.js';\n\n/** Built-in value references. */\nvar Symbol = root.Symbol;\n\nexport default Symbol;\n","import Symbol from './_Symbol.js';\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Used to resolve the\n * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)\n * of values.\n */\nvar nativeObjectToString = objectProto.toString;\n\n/** Built-in value references. */\nvar symToStringTag = Symbol ? Symbol.toStringTag : undefined;\n\n/**\n * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values.\n *\n * @private\n * @param {*} value The value to query.\n * @returns {string} Returns the raw `toStringTag`.\n */\nfunction getRawTag(value) {\n var isOwn = hasOwnProperty.call(value, symToStringTag),\n tag = value[symToStringTag];\n\n try {\n value[symToStringTag] = undefined;\n var unmasked = true;\n } catch (e) {}\n\n var result = nativeObjectToString.call(value);\n if (unmasked) {\n if (isOwn) {\n value[symToStringTag] = tag;\n } else {\n delete value[symToStringTag];\n }\n }\n return result;\n}\n\nexport default getRawTag;\n","/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/**\n * Used to resolve the\n * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)\n * of values.\n */\nvar nativeObjectToString = objectProto.toString;\n\n/**\n * Converts `value` to a string using `Object.prototype.toString`.\n *\n * @private\n * @param {*} value The value to convert.\n * @returns {string} Returns the converted string.\n */\nfunction objectToString(value) {\n return nativeObjectToString.call(value);\n}\n\nexport default objectToString;\n","import Symbol from './_Symbol.js';\nimport getRawTag from './_getRawTag.js';\nimport objectToString from './_objectToString.js';\n\n/** `Object#toString` result references. */\nvar nullTag = '[object Null]',\n undefinedTag = '[object Undefined]';\n\n/** Built-in value references. */\nvar symToStringTag = Symbol ? Symbol.toStringTag : undefined;\n\n/**\n * The base implementation of `getTag` without fallbacks for buggy environments.\n *\n * @private\n * @param {*} value The value to query.\n * @returns {string} Returns the `toStringTag`.\n */\nfunction baseGetTag(value) {\n if (value == null) {\n return value === undefined ? undefinedTag : nullTag;\n }\n return (symToStringTag && symToStringTag in Object(value))\n ? getRawTag(value)\n : objectToString(value);\n}\n\nexport default baseGetTag;\n","/**\n * Creates a unary function that invokes `func` with its argument transformed.\n *\n * @private\n * @param {Function} func The function to wrap.\n * @param {Function} transform The argument transform.\n * @returns {Function} Returns the new function.\n */\nfunction overArg(func, transform) {\n return function(arg) {\n return func(transform(arg));\n };\n}\n\nexport default overArg;\n","import overArg from './_overArg.js';\n\n/** Built-in value references. */\nvar getPrototype = overArg(Object.getPrototypeOf, Object);\n\nexport default getPrototype;\n","/**\n * Checks if `value` is object-like. A value is object-like if it's not `null`\n * and has a `typeof` result of \"object\".\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is object-like, else `false`.\n * @example\n *\n * _.isObjectLike({});\n * // => true\n *\n * _.isObjectLike([1, 2, 3]);\n * // => true\n *\n * _.isObjectLike(_.noop);\n * // => false\n *\n * _.isObjectLike(null);\n * // => false\n */\nfunction isObjectLike(value) {\n return value != null && typeof value == 'object';\n}\n\nexport default isObjectLike;\n","import baseGetTag from './_baseGetTag.js';\nimport getPrototype from './_getPrototype.js';\nimport isObjectLike from './isObjectLike.js';\n\n/** `Object#toString` result references. */\nvar objectTag = '[object Object]';\n\n/** Used for built-in method references. */\nvar funcProto = Function.prototype,\n objectProto = Object.prototype;\n\n/** Used to resolve the decompiled source of functions. */\nvar funcToString = funcProto.toString;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/** Used to infer the `Object` constructor. */\nvar objectCtorString = funcToString.call(Object);\n\n/**\n * Checks if `value` is a plain object, that is, an object created by the\n * `Object` constructor or one with a `[[Prototype]]` of `null`.\n *\n * @static\n * @memberOf _\n * @since 0.8.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a plain object, else `false`.\n * @example\n *\n * function Foo() {\n * this.a = 1;\n * }\n *\n * _.isPlainObject(new Foo);\n * // => false\n *\n * _.isPlainObject([1, 2, 3]);\n * // => false\n *\n * _.isPlainObject({ 'x': 0, 'y': 0 });\n * // => true\n *\n * _.isPlainObject(Object.create(null));\n * // => true\n */\nfunction isPlainObject(value) {\n if (!isObjectLike(value) || baseGetTag(value) != objectTag) {\n return false;\n }\n var proto = getPrototype(value);\n if (proto === null) {\n return true;\n }\n var Ctor = hasOwnProperty.call(proto, 'constructor') && proto.constructor;\n return typeof Ctor == 'function' && Ctor instanceof Ctor &&\n funcToString.call(Ctor) == objectCtorString;\n}\n\nexport default isPlainObject;\n","import isPlainObject from 'lodash-es/isPlainObject';\nimport $$observable from 'symbol-observable';\n\n/**\n * These are private action types reserved by Redux.\n * For any unknown actions, you must return the current state.\n * If the current state is undefined, you must return the initial state.\n * Do not reference these action types directly in your code.\n */\nexport var ActionTypes = {\n INIT: '@@redux/INIT'\n\n /**\n * Creates a Redux store that holds the state tree.\n * The only way to change the data in the store is to call `dispatch()` on it.\n *\n * There should only be a single store in your app. To specify how different\n * parts of the state tree respond to actions, you may combine several reducers\n * into a single reducer function by using `combineReducers`.\n *\n * @param {Function} reducer A function that returns the next state tree, given\n * the current state tree and the action to handle.\n *\n * @param {any} [preloadedState] The initial state. You may optionally specify it\n * to hydrate the state from the server in universal apps, or to restore a\n * previously serialized user session.\n * If you use `combineReducers` to produce the root reducer function, this must be\n * an object with the same shape as `combineReducers` keys.\n *\n * @param {Function} [enhancer] The store enhancer. You may optionally specify it\n * to enhance the store with third-party capabilities such as middleware,\n * time travel, persistence, etc. The only store enhancer that ships with Redux\n * is `applyMiddleware()`.\n *\n * @returns {Store} A Redux store that lets you read the state, dispatch actions\n * and subscribe to changes.\n */\n};export default function createStore(reducer, preloadedState, enhancer) {\n var _ref2;\n\n if (typeof preloadedState === 'function' && typeof enhancer === 'undefined') {\n enhancer = preloadedState;\n preloadedState = undefined;\n }\n\n if (typeof enhancer !== 'undefined') {\n if (typeof enhancer !== 'function') {\n throw new Error('Expected the enhancer to be a function.');\n }\n\n return enhancer(createStore)(reducer, preloadedState);\n }\n\n if (typeof reducer !== 'function') {\n throw new Error('Expected the reducer to be a function.');\n }\n\n var currentReducer = reducer;\n var currentState = preloadedState;\n var currentListeners = [];\n var nextListeners = currentListeners;\n var isDispatching = false;\n\n function ensureCanMutateNextListeners() {\n if (nextListeners === currentListeners) {\n nextListeners = currentListeners.slice();\n }\n }\n\n /**\n * Reads the state tree managed by the store.\n *\n * @returns {any} The current state tree of your application.\n */\n function getState() {\n return currentState;\n }\n\n /**\n * Adds a change listener. It will be called any time an action is dispatched,\n * and some part of the state tree may potentially have changed. You may then\n * call `getState()` to read the current state tree inside the callback.\n *\n * You may call `dispatch()` from a change listener, with the following\n * caveats:\n *\n * 1. The subscriptions are snapshotted just before every `dispatch()` call.\n * If you subscribe or unsubscribe while the listeners are being invoked, this\n * will not have any effect on the `dispatch()` that is currently in progress.\n * However, the next `dispatch()` call, whether nested or not, will use a more\n * recent snapshot of the subscription list.\n *\n * 2. The listener should not expect to see all state changes, as the state\n * might have been updated multiple times during a nested `dispatch()` before\n * the listener is called. It is, however, guaranteed that all subscribers\n * registered before the `dispatch()` started will be called with the latest\n * state by the time it exits.\n *\n * @param {Function} listener A callback to be invoked on every dispatch.\n * @returns {Function} A function to remove this change listener.\n */\n function subscribe(listener) {\n if (typeof listener !== 'function') {\n throw new Error('Expected listener to be a function.');\n }\n\n var isSubscribed = true;\n\n ensureCanMutateNextListeners();\n nextListeners.push(listener);\n\n return function unsubscribe() {\n if (!isSubscribed) {\n return;\n }\n\n isSubscribed = false;\n\n ensureCanMutateNextListeners();\n var index = nextListeners.indexOf(listener);\n nextListeners.splice(index, 1);\n };\n }\n\n /**\n * Dispatches an action. It is the only way to trigger a state change.\n *\n * The `reducer` function, used to create the store, will be called with the\n * current state tree and the given `action`. Its return value will\n * be considered the **next** state of the tree, and the change listeners\n * will be notified.\n *\n * The base implementation only supports plain object actions. If you want to\n * dispatch a Promise, an Observable, a thunk, or something else, you need to\n * wrap your store creating function into the corresponding middleware. For\n * example, see the documentation for the `redux-thunk` package. Even the\n * middleware will eventually dispatch plain object actions using this method.\n *\n * @param {Object} action A plain object representing “what changed”. It is\n * a good idea to keep actions serializable so you can record and replay user\n * sessions, or use the time travelling `redux-devtools`. An action must have\n * a `type` property which may not be `undefined`. It is a good idea to use\n * string constants for action types.\n *\n * @returns {Object} For convenience, the same action object you dispatched.\n *\n * Note that, if you use a custom middleware, it may wrap `dispatch()` to\n * return something else (for example, a Promise you can await).\n */\n function dispatch(action) {\n if (!isPlainObject(action)) {\n throw new Error('Actions must be plain objects. ' + 'Use custom middleware for async actions.');\n }\n\n if (typeof action.type === 'undefined') {\n throw new Error('Actions may not have an undefined \"type\" property. ' + 'Have you misspelled a constant?');\n }\n\n if (isDispatching) {\n throw new Error('Reducers may not dispatch actions.');\n }\n\n try {\n isDispatching = true;\n currentState = currentReducer(currentState, action);\n } finally {\n isDispatching = false;\n }\n\n var listeners = currentListeners = nextListeners;\n for (var i = 0; i < listeners.length; i++) {\n var listener = listeners[i];\n listener();\n }\n\n return action;\n }\n\n /**\n * Replaces the reducer currently used by the store to calculate the state.\n *\n * You might need this if your app implements code splitting and you want to\n * load some of the reducers dynamically. You might also need this if you\n * implement a hot reloading mechanism for Redux.\n *\n * @param {Function} nextReducer The reducer for the store to use instead.\n * @returns {void}\n */\n function replaceReducer(nextReducer) {\n if (typeof nextReducer !== 'function') {\n throw new Error('Expected the nextReducer to be a function.');\n }\n\n currentReducer = nextReducer;\n dispatch({ type: ActionTypes.INIT });\n }\n\n /**\n * Interoperability point for observable/reactive libraries.\n * @returns {observable} A minimal observable of state changes.\n * For more information, see the observable proposal:\n * https://github.com/tc39/proposal-observable\n */\n function observable() {\n var _ref;\n\n var outerSubscribe = subscribe;\n return _ref = {\n /**\n * The minimal observable subscription method.\n * @param {Object} observer Any object that can be used as an observer.\n * The observer object should have a `next` method.\n * @returns {subscription} An object with an `unsubscribe` method that can\n * be used to unsubscribe the observable from the store, and prevent further\n * emission of values from the observable.\n */\n subscribe: function subscribe(observer) {\n if (typeof observer !== 'object') {\n throw new TypeError('Expected the observer to be an object.');\n }\n\n function observeState() {\n if (observer.next) {\n observer.next(getState());\n }\n }\n\n observeState();\n var unsubscribe = outerSubscribe(observeState);\n return { unsubscribe: unsubscribe };\n }\n }, _ref[$$observable] = function () {\n return this;\n }, _ref;\n }\n\n // When a store is created, an \"INIT\" action is dispatched so that every\n // reducer returns their initial state. This effectively populates\n // the initial state tree.\n dispatch({ type: ActionTypes.INIT });\n\n return _ref2 = {\n dispatch: dispatch,\n subscribe: subscribe,\n getState: getState,\n replaceReducer: replaceReducer\n }, _ref2[$$observable] = observable, _ref2;\n}","import { ActionTypes } from './createStore';\nimport isPlainObject from 'lodash-es/isPlainObject';\nimport warning from './utils/warning';\n\nfunction getUndefinedStateErrorMessage(key, action) {\n var actionType = action && action.type;\n var actionName = actionType && '\"' + actionType.toString() + '\"' || 'an action';\n\n return 'Given action ' + actionName + ', reducer \"' + key + '\" returned undefined. ' + 'To ignore an action, you must explicitly return the previous state. ' + 'If you want this reducer to hold no value, you can return null instead of undefined.';\n}\n\nfunction getUnexpectedStateShapeWarningMessage(inputState, reducers, action, unexpectedKeyCache) {\n var reducerKeys = Object.keys(reducers);\n var argumentName = action && action.type === ActionTypes.INIT ? 'preloadedState argument passed to createStore' : 'previous state received by the reducer';\n\n if (reducerKeys.length === 0) {\n return 'Store does not have a valid reducer. Make sure the argument passed ' + 'to combineReducers is an object whose values are reducers.';\n }\n\n if (!isPlainObject(inputState)) {\n return 'The ' + argumentName + ' has unexpected type of \"' + {}.toString.call(inputState).match(/\\s([a-z|A-Z]+)/)[1] + '\". Expected argument to be an object with the following ' + ('keys: \"' + reducerKeys.join('\", \"') + '\"');\n }\n\n var unexpectedKeys = Object.keys(inputState).filter(function (key) {\n return !reducers.hasOwnProperty(key) && !unexpectedKeyCache[key];\n });\n\n unexpectedKeys.forEach(function (key) {\n unexpectedKeyCache[key] = true;\n });\n\n if (unexpectedKeys.length > 0) {\n return 'Unexpected ' + (unexpectedKeys.length > 1 ? 'keys' : 'key') + ' ' + ('\"' + unexpectedKeys.join('\", \"') + '\" found in ' + argumentName + '. ') + 'Expected to find one of the known reducer keys instead: ' + ('\"' + reducerKeys.join('\", \"') + '\". Unexpected keys will be ignored.');\n }\n}\n\nfunction assertReducerShape(reducers) {\n Object.keys(reducers).forEach(function (key) {\n var reducer = reducers[key];\n var initialState = reducer(undefined, { type: ActionTypes.INIT });\n\n if (typeof initialState === 'undefined') {\n throw new Error('Reducer \"' + key + '\" returned undefined during initialization. ' + 'If the state passed to the reducer is undefined, you must ' + 'explicitly return the initial state. The initial state may ' + 'not be undefined. If you don\\'t want to set a value for this reducer, ' + 'you can use null instead of undefined.');\n }\n\n var type = '@@redux/PROBE_UNKNOWN_ACTION_' + Math.random().toString(36).substring(7).split('').join('.');\n if (typeof reducer(undefined, { type: type }) === 'undefined') {\n throw new Error('Reducer \"' + key + '\" returned undefined when probed with a random type. ' + ('Don\\'t try to handle ' + ActionTypes.INIT + ' or other actions in \"redux/*\" ') + 'namespace. They are considered private. Instead, you must return the ' + 'current state for any unknown actions, unless it is undefined, ' + 'in which case you must return the initial state, regardless of the ' + 'action type. The initial state may not be undefined, but can be null.');\n }\n });\n}\n\n/**\n * Turns an object whose values are different reducer functions, into a single\n * reducer function. It will call every child reducer, and gather their results\n * into a single state object, whose keys correspond to the keys of the passed\n * reducer functions.\n *\n * @param {Object} reducers An object whose values correspond to different\n * reducer functions that need to be combined into one. One handy way to obtain\n * it is to use ES6 `import * as reducers` syntax. The reducers may never return\n * undefined for any action. Instead, they should return their initial state\n * if the state passed to them was undefined, and the current state for any\n * unrecognized action.\n *\n * @returns {Function} A reducer function that invokes every reducer inside the\n * passed object, and builds a state object with the same shape.\n */\nexport default function combineReducers(reducers) {\n var reducerKeys = Object.keys(reducers);\n var finalReducers = {};\n for (var i = 0; i < reducerKeys.length; i++) {\n var key = reducerKeys[i];\n\n if (process.env.NODE_ENV !== 'production') {\n if (typeof reducers[key] === 'undefined') {\n warning('No reducer provided for key \"' + key + '\"');\n }\n }\n\n if (typeof reducers[key] === 'function') {\n finalReducers[key] = reducers[key];\n }\n }\n var finalReducerKeys = Object.keys(finalReducers);\n\n var unexpectedKeyCache = void 0;\n if (process.env.NODE_ENV !== 'production') {\n unexpectedKeyCache = {};\n }\n\n var shapeAssertionError = void 0;\n try {\n assertReducerShape(finalReducers);\n } catch (e) {\n shapeAssertionError = e;\n }\n\n return function combination() {\n var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n var action = arguments[1];\n\n if (shapeAssertionError) {\n throw shapeAssertionError;\n }\n\n if (process.env.NODE_ENV !== 'production') {\n var warningMessage = getUnexpectedStateShapeWarningMessage(state, finalReducers, action, unexpectedKeyCache);\n if (warningMessage) {\n warning(warningMessage);\n }\n }\n\n var hasChanged = false;\n var nextState = {};\n for (var _i = 0; _i < finalReducerKeys.length; _i++) {\n var _key = finalReducerKeys[_i];\n var reducer = finalReducers[_key];\n var previousStateForKey = state[_key];\n var nextStateForKey = reducer(previousStateForKey, action);\n if (typeof nextStateForKey === 'undefined') {\n var errorMessage = getUndefinedStateErrorMessage(_key, action);\n throw new Error(errorMessage);\n }\n nextState[_key] = nextStateForKey;\n hasChanged = hasChanged || nextStateForKey !== previousStateForKey;\n }\n return hasChanged ? nextState : state;\n };\n}","function bindActionCreator(actionCreator, dispatch) {\n return function () {\n return dispatch(actionCreator.apply(undefined, arguments));\n };\n}\n\n/**\n * Turns an object whose values are action creators, into an object with the\n * same keys, but with every function wrapped into a `dispatch` call so they\n * may be invoked directly. This is just a convenience method, as you can call\n * `store.dispatch(MyActionCreators.doSomething())` yourself just fine.\n *\n * For convenience, you can also pass a single function as the first argument,\n * and get a function in return.\n *\n * @param {Function|Object} actionCreators An object whose values are action\n * creator functions. One handy way to obtain it is to use ES6 `import * as`\n * syntax. You may also pass a single function.\n *\n * @param {Function} dispatch The `dispatch` function available on your Redux\n * store.\n *\n * @returns {Function|Object} The object mimicking the original object, but with\n * every action creator wrapped into the `dispatch` call. If you passed a\n * function as `actionCreators`, the return value will also be a single\n * function.\n */\nexport default function bindActionCreators(actionCreators, dispatch) {\n if (typeof actionCreators === 'function') {\n return bindActionCreator(actionCreators, dispatch);\n }\n\n if (typeof actionCreators !== 'object' || actionCreators === null) {\n throw new Error('bindActionCreators expected an object or a function, instead received ' + (actionCreators === null ? 'null' : typeof actionCreators) + '. ' + 'Did you write \"import ActionCreators from\" instead of \"import * as ActionCreators from\"?');\n }\n\n var keys = Object.keys(actionCreators);\n var boundActionCreators = {};\n for (var i = 0; i < keys.length; i++) {\n var key = keys[i];\n var actionCreator = actionCreators[key];\n if (typeof actionCreator === 'function') {\n boundActionCreators[key] = bindActionCreator(actionCreator, dispatch);\n }\n }\n return boundActionCreators;\n}","/**\n * Composes single-argument functions from right to left. The rightmost\n * function can take multiple arguments as it provides the signature for\n * the resulting composite function.\n *\n * @param {...Function} funcs The functions to compose.\n * @returns {Function} A function obtained by composing the argument functions\n * from right to left. For example, compose(f, g, h) is identical to doing\n * (...args) => f(g(h(...args))).\n */\n\nexport default function compose() {\n for (var _len = arguments.length, funcs = Array(_len), _key = 0; _key < _len; _key++) {\n funcs[_key] = arguments[_key];\n }\n\n if (funcs.length === 0) {\n return function (arg) {\n return arg;\n };\n }\n\n if (funcs.length === 1) {\n return funcs[0];\n }\n\n return funcs.reduce(function (a, b) {\n return function () {\n return a(b.apply(undefined, arguments));\n };\n });\n}","var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };\n\nimport compose from './compose';\n\n/**\n * Creates a store enhancer that applies middleware to the dispatch method\n * of the Redux store. This is handy for a variety of tasks, such as expressing\n * asynchronous actions in a concise manner, or logging every action payload.\n *\n * See `redux-thunk` package as an example of the Redux middleware.\n *\n * Because middleware is potentially asynchronous, this should be the first\n * store enhancer in the composition chain.\n *\n * Note that each middleware will be given the `dispatch` and `getState` functions\n * as named arguments.\n *\n * @param {...Function} middlewares The middleware chain to be applied.\n * @returns {Function} A store enhancer applying the middleware.\n */\nexport default function applyMiddleware() {\n for (var _len = arguments.length, middlewares = Array(_len), _key = 0; _key < _len; _key++) {\n middlewares[_key] = arguments[_key];\n }\n\n return function (createStore) {\n return function (reducer, preloadedState, enhancer) {\n var store = createStore(reducer, preloadedState, enhancer);\n var _dispatch = store.dispatch;\n var chain = [];\n\n var middlewareAPI = {\n getState: store.getState,\n dispatch: function dispatch(action) {\n return _dispatch(action);\n }\n };\n chain = middlewares.map(function (middleware) {\n return middleware(middlewareAPI);\n });\n _dispatch = compose.apply(undefined, chain)(store.dispatch);\n\n return _extends({}, store, {\n dispatch: _dispatch\n });\n };\n };\n}","var toString = {}.toString;\n\nmodule.exports = function (it) {\n return toString.call(it).slice(8, -1);\n};\n","// Thank's IE8 for his funny defineProperty\nmodule.exports = !require('./_fails')(function () {\n return Object.defineProperty({}, 'a', { get: function () { return 7; } }).a != 7;\n});\n","// 7.1.4 ToInteger\nvar ceil = Math.ceil;\nvar floor = Math.floor;\nmodule.exports = function (it) {\n return isNaN(it = +it) ? 0 : (it > 0 ? floor : ceil)(it);\n};\n","module.exports = {};\n","var toString = {}.toString;\n\nmodule.exports = function (it) {\n return toString.call(it).slice(8, -1);\n};\n","module.exports = true;\n","module.exports = function (bitmap, value) {\n return {\n enumerable: !(bitmap & 1),\n configurable: !(bitmap & 2),\n writable: !(bitmap & 4),\n value: value\n };\n};\n","// 19.1.2.2 / 15.2.3.5 Object.create(O [, Properties])\nvar anObject = require('./_an-object');\nvar dPs = require('./_object-dps');\nvar enumBugKeys = require('./_enum-bug-keys');\nvar IE_PROTO = require('./_shared-key')('IE_PROTO');\nvar Empty = function () { /* empty */ };\nvar PROTOTYPE = 'prototype';\n\n// Create object with fake `null` prototype: use iframe Object with cleared prototype\nvar createDict = function () {\n // Thrash, waste and sodomy: IE GC bug\n var iframe = require('./_dom-create')('iframe');\n var i = enumBugKeys.length;\n var lt = '<';\n var gt = '>';\n var iframeDocument;\n iframe.style.display = 'none';\n require('./_html').appendChild(iframe);\n iframe.src = 'javascript:'; // eslint-disable-line no-script-url\n // createDict = iframe.contentWindow.Object;\n // html.removeChild(iframe);\n iframeDocument = iframe.contentWindow.document;\n iframeDocument.open();\n iframeDocument.write(lt + 'script' + gt + 'document.F=Object' + lt + '/script' + gt);\n iframeDocument.close();\n createDict = iframeDocument.F;\n while (i--) delete createDict[PROTOTYPE][enumBugKeys[i]];\n return createDict();\n};\n\nmodule.exports = Object.create || function create(O, Properties) {\n var result;\n if (O !== null) {\n Empty[PROTOTYPE] = anObject(O);\n result = new Empty();\n Empty[PROTOTYPE] = null;\n // add \"__proto__\" for Object.getPrototypeOf polyfill\n result[IE_PROTO] = O;\n } else result = createDict();\n return Properties === undefined ? result : dPs(result, Properties);\n};\n","var def = require('./_object-dp').f;\nvar has = require('./_has');\nvar TAG = require('./_wks')('toStringTag');\n\nmodule.exports = function (it, tag, stat) {\n if (it && !has(it = stat ? it : it.prototype, TAG)) def(it, TAG, { configurable: true, value: tag });\n};\n","var META = require('./_uid')('meta');\nvar isObject = require('./_is-object');\nvar has = require('./_has');\nvar setDesc = require('./_object-dp').f;\nvar id = 0;\nvar isExtensible = Object.isExtensible || function () {\n return true;\n};\nvar FREEZE = !require('./_fails')(function () {\n return isExtensible(Object.preventExtensions({}));\n});\nvar setMeta = function (it) {\n setDesc(it, META, { value: {\n i: 'O' + ++id, // object ID\n w: {} // weak collections IDs\n } });\n};\nvar fastKey = function (it, create) {\n // return primitive with prefix\n if (!isObject(it)) return typeof it == 'symbol' ? it : (typeof it == 'string' ? 'S' : 'P') + it;\n if (!has(it, META)) {\n // can't set metadata to uncaught frozen object\n if (!isExtensible(it)) return 'F';\n // not necessary to add metadata\n if (!create) return 'E';\n // add missing metadata\n setMeta(it);\n // return object ID\n } return it[META].i;\n};\nvar getWeak = function (it, create) {\n if (!has(it, META)) {\n // can't set metadata to uncaught frozen object\n if (!isExtensible(it)) return true;\n // not necessary to add metadata\n if (!create) return false;\n // add missing metadata\n setMeta(it);\n // return hash weak collections IDs\n } return it[META].w;\n};\n// add metadata on freeze-family methods calling\nvar onFreeze = function (it) {\n if (FREEZE && meta.NEED && isExtensible(it) && !has(it, META)) setMeta(it);\n return it;\n};\nvar meta = module.exports = {\n KEY: META,\n NEED: false,\n fastKey: fastKey,\n getWeak: getWeak,\n onFreeze: onFreeze\n};\n","exports.f = {}.propertyIsEnumerable;\n","var pIE = require('./_object-pie');\nvar createDesc = require('./_property-desc');\nvar toIObject = require('./_to-iobject');\nvar toPrimitive = require('./_to-primitive');\nvar has = require('./_has');\nvar IE8_DOM_DEFINE = require('./_ie8-dom-define');\nvar gOPD = Object.getOwnPropertyDescriptor;\n\nexports.f = require('./_descriptors') ? gOPD : function getOwnPropertyDescriptor(O, P) {\n O = toIObject(O);\n P = toPrimitive(P, true);\n if (IE8_DOM_DEFINE) try {\n return gOPD(O, P);\n } catch (e) { /* empty */ }\n if (has(O, P)) return createDesc(!pIE.f.call(O, P), O[P]);\n};\n","/**\n * Copyright (c) 2013-present, Facebook, Inc.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n *\n * \n */\n'use strict';\n\n/**\n * WARNING: DO NOT manually require this module.\n * This is a replacement for `invariant(...)` used by the error code system\n * and will _only_ be required by the corresponding babel pass.\n * It always throws.\n */\n\nfunction reactProdInvariant(code) {\n var argCount = arguments.length - 1;\n\n var message = 'Minified React error #' + code + '; visit ' + 'http://facebook.github.io/react/docs/error-decoder.html?invariant=' + code;\n\n for (var argIdx = 0; argIdx < argCount; argIdx++) {\n message += '&args[]=' + encodeURIComponent(arguments[argIdx + 1]);\n }\n\n message += ' for the full message or use the non-minified dev environment' + ' for full errors and additional helpful warnings.';\n\n var error = new Error(message);\n error.name = 'Invariant Violation';\n error.framesToPop = 1; // we don't care about reactProdInvariant's own frame\n\n throw error;\n}\n\nmodule.exports = reactProdInvariant;","// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n// NOTE: These type checking functions intentionally don't use `instanceof`\n// because it is fragile and can be easily faked with `Object.create()`.\n\nfunction isArray(arg) {\n if (Array.isArray) {\n return Array.isArray(arg);\n }\n return objectToString(arg) === '[object Array]';\n}\nexports.isArray = isArray;\n\nfunction isBoolean(arg) {\n return typeof arg === 'boolean';\n}\nexports.isBoolean = isBoolean;\n\nfunction isNull(arg) {\n return arg === null;\n}\nexports.isNull = isNull;\n\nfunction isNullOrUndefined(arg) {\n return arg == null;\n}\nexports.isNullOrUndefined = isNullOrUndefined;\n\nfunction isNumber(arg) {\n return typeof arg === 'number';\n}\nexports.isNumber = isNumber;\n\nfunction isString(arg) {\n return typeof arg === 'string';\n}\nexports.isString = isString;\n\nfunction isSymbol(arg) {\n return typeof arg === 'symbol';\n}\nexports.isSymbol = isSymbol;\n\nfunction isUndefined(arg) {\n return arg === void 0;\n}\nexports.isUndefined = isUndefined;\n\nfunction isRegExp(re) {\n return objectToString(re) === '[object RegExp]';\n}\nexports.isRegExp = isRegExp;\n\nfunction isObject(arg) {\n return typeof arg === 'object' && arg !== null;\n}\nexports.isObject = isObject;\n\nfunction isDate(d) {\n return objectToString(d) === '[object Date]';\n}\nexports.isDate = isDate;\n\nfunction isError(e) {\n return (objectToString(e) === '[object Error]' || e instanceof Error);\n}\nexports.isError = isError;\n\nfunction isFunction(arg) {\n return typeof arg === 'function';\n}\nexports.isFunction = isFunction;\n\nfunction isPrimitive(arg) {\n return arg === null ||\n typeof arg === 'boolean' ||\n typeof arg === 'number' ||\n typeof arg === 'string' ||\n typeof arg === 'symbol' || // ES6 symbol\n typeof arg === 'undefined';\n}\nexports.isPrimitive = isPrimitive;\n\nexports.isBuffer = Buffer.isBuffer;\n\nfunction objectToString(o) {\n return Object.prototype.toString.call(o);\n}\n","// YAML error class. http://stackoverflow.com/questions/8458984\n//\n'use strict';\n\nfunction YAMLException(reason, mark) {\n // Super constructor\n Error.call(this);\n\n this.name = 'YAMLException';\n this.reason = reason;\n this.mark = mark;\n this.message = (this.reason || '(unknown reason)') + (this.mark ? ' ' + this.mark.toString() : '');\n\n // Include stack trace in error object\n if (Error.captureStackTrace) {\n // Chrome and NodeJS\n Error.captureStackTrace(this, this.constructor);\n } else {\n // FF, IE 10+ and Safari 6+. Fallback for others\n this.stack = (new Error()).stack || '';\n }\n}\n\n\n// Inherit from Error\nYAMLException.prototype = Object.create(Error.prototype);\nYAMLException.prototype.constructor = YAMLException;\n\n\nYAMLException.prototype.toString = function toString(compact) {\n var result = this.name + ': ';\n\n result += this.reason || '(unknown reason)';\n\n if (!compact && this.mark) {\n result += ' ' + this.mark.toString();\n }\n\n return result;\n};\n\n\nmodule.exports = YAMLException;\n","// JS-YAML's default schema for `safeLoad` function.\n// It is not described in the YAML specification.\n//\n// This schema is based on standard YAML's Core schema and includes most of\n// extra types described at YAML tag repository. (http://yaml.org/type/)\n\n\n'use strict';\n\n\nvar Schema = require('../schema');\n\n\nmodule.exports = new Schema({\n include: [\n require('./core')\n ],\n implicit: [\n require('../type/timestamp'),\n require('../type/merge')\n ],\n explicit: [\n require('../type/binary'),\n require('../type/omap'),\n require('../type/pairs'),\n require('../type/set')\n ]\n});\n","/**\n * Copyright (c) 2013-present, Facebook, Inc.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n *\n */\n\n'use strict';\n\nvar EventPluginHub = require('./EventPluginHub');\nvar EventPluginUtils = require('./EventPluginUtils');\n\nvar accumulateInto = require('./accumulateInto');\nvar forEachAccumulated = require('./forEachAccumulated');\nvar warning = require('fbjs/lib/warning');\n\nvar getListener = EventPluginHub.getListener;\n\n/**\n * Some event types have a notion of different registration names for different\n * \"phases\" of propagation. This finds listeners by a given phase.\n */\nfunction listenerAtPhase(inst, event, propagationPhase) {\n var registrationName = event.dispatchConfig.phasedRegistrationNames[propagationPhase];\n return getListener(inst, registrationName);\n}\n\n/**\n * Tags a `SyntheticEvent` with dispatched listeners. Creating this function\n * here, allows us to not have to bind or create functions for each event.\n * Mutating the event's members allows us to not have to create a wrapping\n * \"dispatch\" object that pairs the event with the listener.\n */\nfunction accumulateDirectionalDispatches(inst, phase, event) {\n if (process.env.NODE_ENV !== 'production') {\n process.env.NODE_ENV !== 'production' ? warning(inst, 'Dispatching inst must not be null') : void 0;\n }\n var listener = listenerAtPhase(inst, event, phase);\n if (listener) {\n event._dispatchListeners = accumulateInto(event._dispatchListeners, listener);\n event._dispatchInstances = accumulateInto(event._dispatchInstances, inst);\n }\n}\n\n/**\n * Collect dispatches (must be entirely collected before dispatching - see unit\n * tests). Lazily allocate the array to conserve memory. We must loop through\n * each event and perform the traversal for each one. We cannot perform a\n * single traversal for the entire collection of events because each event may\n * have a different target.\n */\nfunction accumulateTwoPhaseDispatchesSingle(event) {\n if (event && event.dispatchConfig.phasedRegistrationNames) {\n EventPluginUtils.traverseTwoPhase(event._targetInst, accumulateDirectionalDispatches, event);\n }\n}\n\n/**\n * Same as `accumulateTwoPhaseDispatchesSingle`, but skips over the targetID.\n */\nfunction accumulateTwoPhaseDispatchesSingleSkipTarget(event) {\n if (event && event.dispatchConfig.phasedRegistrationNames) {\n var targetInst = event._targetInst;\n var parentInst = targetInst ? EventPluginUtils.getParentInstance(targetInst) : null;\n EventPluginUtils.traverseTwoPhase(parentInst, accumulateDirectionalDispatches, event);\n }\n}\n\n/**\n * Accumulates without regard to direction, does not look for phased\n * registration names. Same as `accumulateDirectDispatchesSingle` but without\n * requiring that the `dispatchMarker` be the same as the dispatched ID.\n */\nfunction accumulateDispatches(inst, ignoredDirection, event) {\n if (event && event.dispatchConfig.registrationName) {\n var registrationName = event.dispatchConfig.registrationName;\n var listener = getListener(inst, registrationName);\n if (listener) {\n event._dispatchListeners = accumulateInto(event._dispatchListeners, listener);\n event._dispatchInstances = accumulateInto(event._dispatchInstances, inst);\n }\n }\n}\n\n/**\n * Accumulates dispatches on an `SyntheticEvent`, but only for the\n * `dispatchMarker`.\n * @param {SyntheticEvent} event\n */\nfunction accumulateDirectDispatchesSingle(event) {\n if (event && event.dispatchConfig.registrationName) {\n accumulateDispatches(event._targetInst, null, event);\n }\n}\n\nfunction accumulateTwoPhaseDispatches(events) {\n forEachAccumulated(events, accumulateTwoPhaseDispatchesSingle);\n}\n\nfunction accumulateTwoPhaseDispatchesSkipTarget(events) {\n forEachAccumulated(events, accumulateTwoPhaseDispatchesSingleSkipTarget);\n}\n\nfunction accumulateEnterLeaveDispatches(leave, enter, from, to) {\n EventPluginUtils.traverseEnterLeave(from, to, accumulateDispatches, leave, enter);\n}\n\nfunction accumulateDirectDispatches(events) {\n forEachAccumulated(events, accumulateDirectDispatchesSingle);\n}\n\n/**\n * A small set of propagation patterns, each of which will accept a small amount\n * of information, and generate a set of \"dispatch ready event objects\" - which\n * are sets of events that have already been annotated with a set of dispatched\n * listener functions/ids. The API is designed this way to discourage these\n * propagation strategies from actually executing the dispatches, since we\n * always want to collect the entire set of dispatches before executing event a\n * single one.\n *\n * @constructor EventPropagators\n */\nvar EventPropagators = {\n accumulateTwoPhaseDispatches: accumulateTwoPhaseDispatches,\n accumulateTwoPhaseDispatchesSkipTarget: accumulateTwoPhaseDispatchesSkipTarget,\n accumulateDirectDispatches: accumulateDirectDispatches,\n accumulateEnterLeaveDispatches: accumulateEnterLeaveDispatches\n};\n\nmodule.exports = EventPropagators;","/**\n * Copyright (c) 2013-present, Facebook, Inc.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n *\n */\n\n'use strict';\n\nvar _prodInvariant = require('./reactProdInvariant');\n\nvar EventPluginRegistry = require('./EventPluginRegistry');\nvar EventPluginUtils = require('./EventPluginUtils');\nvar ReactErrorUtils = require('./ReactErrorUtils');\n\nvar accumulateInto = require('./accumulateInto');\nvar forEachAccumulated = require('./forEachAccumulated');\nvar invariant = require('fbjs/lib/invariant');\n\n/**\n * Internal store for event listeners\n */\nvar listenerBank = {};\n\n/**\n * Internal queue of events that have accumulated their dispatches and are\n * waiting to have their dispatches executed.\n */\nvar eventQueue = null;\n\n/**\n * Dispatches an event and releases it back into the pool, unless persistent.\n *\n * @param {?object} event Synthetic event to be dispatched.\n * @param {boolean} simulated If the event is simulated (changes exn behavior)\n * @private\n */\nvar executeDispatchesAndRelease = function (event, simulated) {\n if (event) {\n EventPluginUtils.executeDispatchesInOrder(event, simulated);\n\n if (!event.isPersistent()) {\n event.constructor.release(event);\n }\n }\n};\nvar executeDispatchesAndReleaseSimulated = function (e) {\n return executeDispatchesAndRelease(e, true);\n};\nvar executeDispatchesAndReleaseTopLevel = function (e) {\n return executeDispatchesAndRelease(e, false);\n};\n\nvar getDictionaryKey = function (inst) {\n // Prevents V8 performance issue:\n // https://github.com/facebook/react/pull/7232\n return '.' + inst._rootNodeID;\n};\n\nfunction isInteractive(tag) {\n return tag === 'button' || tag === 'input' || tag === 'select' || tag === 'textarea';\n}\n\nfunction shouldPreventMouseEvent(name, type, props) {\n switch (name) {\n case 'onClick':\n case 'onClickCapture':\n case 'onDoubleClick':\n case 'onDoubleClickCapture':\n case 'onMouseDown':\n case 'onMouseDownCapture':\n case 'onMouseMove':\n case 'onMouseMoveCapture':\n case 'onMouseUp':\n case 'onMouseUpCapture':\n return !!(props.disabled && isInteractive(type));\n default:\n return false;\n }\n}\n\n/**\n * This is a unified interface for event plugins to be installed and configured.\n *\n * Event plugins can implement the following properties:\n *\n * `extractEvents` {function(string, DOMEventTarget, string, object): *}\n * Required. When a top-level event is fired, this method is expected to\n * extract synthetic events that will in turn be queued and dispatched.\n *\n * `eventTypes` {object}\n * Optional, plugins that fire events must publish a mapping of registration\n * names that are used to register listeners. Values of this mapping must\n * be objects that contain `registrationName` or `phasedRegistrationNames`.\n *\n * `executeDispatch` {function(object, function, string)}\n * Optional, allows plugins to override how an event gets dispatched. By\n * default, the listener is simply invoked.\n *\n * Each plugin that is injected into `EventsPluginHub` is immediately operable.\n *\n * @public\n */\nvar EventPluginHub = {\n /**\n * Methods for injecting dependencies.\n */\n injection: {\n /**\n * @param {array} InjectedEventPluginOrder\n * @public\n */\n injectEventPluginOrder: EventPluginRegistry.injectEventPluginOrder,\n\n /**\n * @param {object} injectedNamesToPlugins Map from names to plugin modules.\n */\n injectEventPluginsByName: EventPluginRegistry.injectEventPluginsByName\n },\n\n /**\n * Stores `listener` at `listenerBank[registrationName][key]`. Is idempotent.\n *\n * @param {object} inst The instance, which is the source of events.\n * @param {string} registrationName Name of listener (e.g. `onClick`).\n * @param {function} listener The callback to store.\n */\n putListener: function (inst, registrationName, listener) {\n !(typeof listener === 'function') ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Expected %s listener to be a function, instead got type %s', registrationName, typeof listener) : _prodInvariant('94', registrationName, typeof listener) : void 0;\n\n var key = getDictionaryKey(inst);\n var bankForRegistrationName = listenerBank[registrationName] || (listenerBank[registrationName] = {});\n bankForRegistrationName[key] = listener;\n\n var PluginModule = EventPluginRegistry.registrationNameModules[registrationName];\n if (PluginModule && PluginModule.didPutListener) {\n PluginModule.didPutListener(inst, registrationName, listener);\n }\n },\n\n /**\n * @param {object} inst The instance, which is the source of events.\n * @param {string} registrationName Name of listener (e.g. `onClick`).\n * @return {?function} The stored callback.\n */\n getListener: function (inst, registrationName) {\n // TODO: shouldPreventMouseEvent is DOM-specific and definitely should not\n // live here; needs to be moved to a better place soon\n var bankForRegistrationName = listenerBank[registrationName];\n if (shouldPreventMouseEvent(registrationName, inst._currentElement.type, inst._currentElement.props)) {\n return null;\n }\n var key = getDictionaryKey(inst);\n return bankForRegistrationName && bankForRegistrationName[key];\n },\n\n /**\n * Deletes a listener from the registration bank.\n *\n * @param {object} inst The instance, which is the source of events.\n * @param {string} registrationName Name of listener (e.g. `onClick`).\n */\n deleteListener: function (inst, registrationName) {\n var PluginModule = EventPluginRegistry.registrationNameModules[registrationName];\n if (PluginModule && PluginModule.willDeleteListener) {\n PluginModule.willDeleteListener(inst, registrationName);\n }\n\n var bankForRegistrationName = listenerBank[registrationName];\n // TODO: This should never be null -- when is it?\n if (bankForRegistrationName) {\n var key = getDictionaryKey(inst);\n delete bankForRegistrationName[key];\n }\n },\n\n /**\n * Deletes all listeners for the DOM element with the supplied ID.\n *\n * @param {object} inst The instance, which is the source of events.\n */\n deleteAllListeners: function (inst) {\n var key = getDictionaryKey(inst);\n for (var registrationName in listenerBank) {\n if (!listenerBank.hasOwnProperty(registrationName)) {\n continue;\n }\n\n if (!listenerBank[registrationName][key]) {\n continue;\n }\n\n var PluginModule = EventPluginRegistry.registrationNameModules[registrationName];\n if (PluginModule && PluginModule.willDeleteListener) {\n PluginModule.willDeleteListener(inst, registrationName);\n }\n\n delete listenerBank[registrationName][key];\n }\n },\n\n /**\n * Allows registered plugins an opportunity to extract events from top-level\n * native browser events.\n *\n * @return {*} An accumulation of synthetic events.\n * @internal\n */\n extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget) {\n var events;\n var plugins = EventPluginRegistry.plugins;\n for (var i = 0; i < plugins.length; i++) {\n // Not every plugin in the ordering may be loaded at runtime.\n var possiblePlugin = plugins[i];\n if (possiblePlugin) {\n var extractedEvents = possiblePlugin.extractEvents(topLevelType, targetInst, nativeEvent, nativeEventTarget);\n if (extractedEvents) {\n events = accumulateInto(events, extractedEvents);\n }\n }\n }\n return events;\n },\n\n /**\n * Enqueues a synthetic event that should be dispatched when\n * `processEventQueue` is invoked.\n *\n * @param {*} events An accumulation of synthetic events.\n * @internal\n */\n enqueueEvents: function (events) {\n if (events) {\n eventQueue = accumulateInto(eventQueue, events);\n }\n },\n\n /**\n * Dispatches all synthetic events on the event queue.\n *\n * @internal\n */\n processEventQueue: function (simulated) {\n // Set `eventQueue` to null before processing it so that we can tell if more\n // events get enqueued while processing.\n var processingEventQueue = eventQueue;\n eventQueue = null;\n if (simulated) {\n forEachAccumulated(processingEventQueue, executeDispatchesAndReleaseSimulated);\n } else {\n forEachAccumulated(processingEventQueue, executeDispatchesAndReleaseTopLevel);\n }\n !!eventQueue ? process.env.NODE_ENV !== 'production' ? invariant(false, 'processEventQueue(): Additional events were enqueued while processing an event queue. Support for this has not yet been implemented.') : _prodInvariant('95') : void 0;\n // This would be a good time to rethrow if any of the event handlers threw.\n ReactErrorUtils.rethrowCaughtError();\n },\n\n /**\n * These are needed for tests only. Do not use!\n */\n __purge: function () {\n listenerBank = {};\n },\n\n __getListenerBank: function () {\n return listenerBank;\n }\n};\n\nmodule.exports = EventPluginHub;","/**\n * Copyright (c) 2013-present, Facebook, Inc.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n *\n */\n\n'use strict';\n\nvar SyntheticEvent = require('./SyntheticEvent');\n\nvar getEventTarget = require('./getEventTarget');\n\n/**\n * @interface UIEvent\n * @see http://www.w3.org/TR/DOM-Level-3-Events/\n */\nvar UIEventInterface = {\n view: function (event) {\n if (event.view) {\n return event.view;\n }\n\n var target = getEventTarget(event);\n if (target.window === target) {\n // target is a window object\n return target;\n }\n\n var doc = target.ownerDocument;\n // TODO: Figure out why `ownerDocument` is sometimes undefined in IE8.\n if (doc) {\n return doc.defaultView || doc.parentWindow;\n } else {\n return window;\n }\n },\n detail: function (event) {\n return event.detail || 0;\n }\n};\n\n/**\n * @param {object} dispatchConfig Configuration used to dispatch this event.\n * @param {string} dispatchMarker Marker identifying the event target.\n * @param {object} nativeEvent Native browser event.\n * @extends {SyntheticEvent}\n */\nfunction SyntheticUIEvent(dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget) {\n return SyntheticEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget);\n}\n\nSyntheticEvent.augmentClass(SyntheticUIEvent, UIEventInterface);\n\nmodule.exports = SyntheticUIEvent;","/**\n * Copyright (c) 2013-present, Facebook, Inc.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n *\n */\n\n'use strict';\n\n/**\n * `ReactInstanceMap` maintains a mapping from a public facing stateful\n * instance (key) and the internal representation (value). This allows public\n * methods to accept the user facing instance as an argument and map them back\n * to internal methods.\n */\n\n// TODO: Replace this with ES6: var ReactInstanceMap = new Map();\n\nvar ReactInstanceMap = {\n /**\n * This API should be called `delete` but we'd have to make sure to always\n * transform these to strings for IE support. When this transform is fully\n * supported we can rename it.\n */\n remove: function (key) {\n key._reactInternalInstance = undefined;\n },\n\n get: function (key) {\n return key._reactInternalInstance;\n },\n\n has: function (key) {\n return key._reactInternalInstance !== undefined;\n },\n\n set: function (key, value) {\n key._reactInternalInstance = value;\n }\n};\n\nmodule.exports = ReactInstanceMap;","var isObject = require('./_is-object');\nmodule.exports = function (it, TYPE) {\n if (!isObject(it) || it._t !== TYPE) throw TypeError('Incompatible receiver, ' + TYPE + ' required!');\n return it;\n};\n","'use strict';\n\n/*\n * OBJECT ASSIGN DEEP\n * Allows deep cloning of plain objects that contain primitives, nested plain objects, or nested plain arrays.\n */\n\n/*\n * A unified way of returning a string that describes the type of the given variable.\n */\n\nvar _typeof = typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; };\n\nfunction getTypeOf(input) {\n\n\tif (input === null) {\n\t\treturn 'null';\n\t} else if (typeof input === 'undefined') {\n\t\treturn 'undefined';\n\t} else if ((typeof input === 'undefined' ? 'undefined' : _typeof(input)) === 'object') {\n\t\treturn Array.isArray(input) ? 'array' : 'object';\n\t}\n\n\treturn typeof input === 'undefined' ? 'undefined' : _typeof(input);\n}\n\n/*\n * Branching logic which calls the correct function to clone the given value base on its type.\n */\nfunction cloneValue(value) {\n\n\t// The value is an object so lets clone it.\n\tif (getTypeOf(value) === 'object') {\n\t\treturn quickCloneObject(value);\n\t}\n\n\t// The value is an array so lets clone it.\n\telse if (getTypeOf(value) === 'array') {\n\t\t\treturn quickCloneArray(value);\n\t\t}\n\n\t// Any other value can just be copied.\n\treturn value;\n}\n\n/*\n * Enumerates the given array and returns a new array, with each of its values cloned (i.e. references broken).\n */\nfunction quickCloneArray(input) {\n\treturn input.map(cloneValue);\n}\n\n/*\n * Enumerates the properties of the given object (ignoring the prototype chain) and returns a new object, with each of\n * its values cloned (i.e. references broken).\n */\nfunction quickCloneObject(input) {\n\n\tvar output = {};\n\n\tfor (var key in input) {\n\t\tif (!input.hasOwnProperty(key)) {\n\t\t\tcontinue;\n\t\t}\n\n\t\toutput[key] = cloneValue(input[key]);\n\t}\n\n\treturn output;\n}\n\n/*\n * Does the actual deep merging.\n */\nfunction executeDeepMerge(target) {\n\tvar _objects = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];\n\n\tvar _options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};\n\n\tvar options = {\n\t\tarrayBehaviour: _options.arrayBehaviour || 'replace' // Can be \"merge\" or \"replace\".\n\t};\n\n\t// Ensure we have actual objects for each.\n\tvar objects = _objects.map(function (object) {\n\t\treturn object || {};\n\t});\n\tvar output = target || {};\n\n\t// Enumerate the objects and their keys.\n\tfor (var oindex = 0; oindex < objects.length; oindex++) {\n\t\tvar object = objects[oindex];\n\t\tvar keys = Object.keys(object);\n\n\t\tfor (var kindex = 0; kindex < keys.length; kindex++) {\n\t\t\tvar key = keys[kindex];\n\t\t\tvar value = object[key];\n\t\t\tvar type = getTypeOf(value);\n\t\t\tvar existingValueType = getTypeOf(output[key]);\n\n\t\t\tif (type === 'object') {\n\t\t\t\tif (existingValueType !== 'undefined') {\n\t\t\t\t\tvar existingValue = existingValueType === 'object' ? output[key] : {};\n\t\t\t\t\toutput[key] = executeDeepMerge({}, [existingValue, quickCloneObject(value)], options);\n\t\t\t\t} else {\n\t\t\t\t\toutput[key] = quickCloneObject(value);\n\t\t\t\t}\n\t\t\t} else if (type === 'array') {\n\t\t\t\tif (existingValueType === 'array') {\n\t\t\t\t\tvar newValue = quickCloneArray(value);\n\t\t\t\t\toutput[key] = options.arrayBehaviour === 'merge' ? output[key].concat(newValue) : newValue;\n\t\t\t\t} else {\n\t\t\t\t\toutput[key] = quickCloneArray(value);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\toutput[key] = value;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn output;\n}\n\n/*\n * Merge all the supplied objects into the target object, breaking all references, including those of nested objects\n * and arrays, and even objects nested inside arrays. The first parameter is not mutated unlike Object.assign().\n * Properties in later objects will always overwrite.\n */\nmodule.exports = function objectAssignDeep(target) {\n\tfor (var _len = arguments.length, objects = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {\n\t\tobjects[_key - 1] = arguments[_key];\n\t}\n\n\treturn executeDeepMerge(target, objects);\n};\n\n/*\n * Same as objectAssignDeep() except it doesn't mutate the target object and returns an entirely new object.\n */\nmodule.exports.noMutate = function objectAssignDeepInto() {\n\tfor (var _len2 = arguments.length, objects = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {\n\t\tobjects[_key2] = arguments[_key2];\n\t}\n\n\treturn executeDeepMerge({}, objects);\n};\n\n/*\n * Allows an options object to be passed in to customise the behaviour of the function.\n */\nmodule.exports.withOptions = function objectAssignDeepInto(target, objects, options) {\n\treturn executeDeepMerge(target, objects, options);\n};","'use strict';\n\n\nvar yaml = require('./lib/js-yaml.js');\n\n\nmodule.exports = yaml;\n","import YAML from \"js-yaml\"\n\nexport const parseYamlConfig = (yaml, system) => {\n try {\n return YAML.safeLoad(yaml)\n } catch(e) {\n if (system) {\n system.errActions.newThrownErr( new Error(e) )\n }\n return {}\n }\n}\n","import React, { Component } from \"react\"\nimport ReactDOM from \"react-dom\"\nimport { connect, Provider } from \"react-redux\"\nimport omit from \"lodash/omit\"\n\nconst SystemWrapper = (getSystem, ComponentToWrap ) => class extends Component {\n render() {\n return \n }\n}\n\nconst RootWrapper = (reduxStore, ComponentToWrap) => class extends Component {\n render() {\n return (\n \n \n \n )\n }\n}\n\nconst makeContainer = (getSystem, component, reduxStore) => {\n const mapStateToProps = function(state, ownProps) {\n const propsForContainerComponent = Object.assign({}, ownProps, getSystem())\n const ori = component.prototype.mapStateToProps || (state => { return {state} })\n return ori(state, propsForContainerComponent)\n }\n\n let wrappedWithSystem = SystemWrapper(getSystem, component, reduxStore)\n let connected = connect( mapStateToProps )(wrappedWithSystem)\n if(reduxStore)\n return RootWrapper(reduxStore, connected)\n return connected\n}\n\nconst handleProps = (getSystem, mapping, props, oldProps) => {\n for (let prop in mapping) {\n let fn = mapping[prop]\n if(typeof fn === \"function\")\n fn(props[prop], oldProps[prop], getSystem())\n }\n}\n\nexport const makeMappedContainer = (getSystem, getStore, memGetComponent, getComponents, componentName, mapping) => {\n\n return class extends Component {\n\n constructor(props, context) {\n super(props, context)\n handleProps(getSystem, mapping, props, {})\n }\n\n componentWillReceiveProps(nextProps) {\n handleProps(getSystem, mapping, nextProps, this.props)\n }\n\n render() {\n let cleanProps = omit(this.props, mapping ? Object.keys(mapping) : [])\n let Comp = memGetComponent(componentName, \"root\")\n return \n }\n\n }\n\n}\n\nexport const render = (getSystem, getStore, getComponent, getComponents, domNode) => {\n let App = (getComponent(getSystem, getStore, getComponents, \"App\", \"root\"))\n ReactDOM.render(( ), domNode)\n}\n\n// Render try/catch wrapper\nconst createClass = component => class extends Component {\n render() {\n return component(this.props)\n }\n}\n\nconst Fallback = ({ name }) =>
😱 Could not render { name === \"t\" ? \"this component\" : name }, see the console.
\n\nconst wrapRender = (component) => {\n const isStateless = component => !(component.prototype && component.prototype.isReactComponent)\n\n const target = isStateless(component) ? createClass(component) : component\n\n const ori = target.prototype.render\n\n target.prototype.render = function render(...args) {\n try {\n return ori.apply(this, args)\n } catch (error) {\n console.error(error) // eslint-disable-line no-console\n return \n }\n }\n\n return target\n}\n\nexport const getComponent = (getSystem, getStore, getComponents, componentName, container, config = {}) => {\n\n if(typeof componentName !== \"string\")\n throw new TypeError(\"Need a string, to fetch a component. Was given a \" + typeof componentName)\n\n // getComponent has a config object as a third, optional parameter\n // using the config object requires the presence of the second parameter, container\n // e.g. getComponent(\"JsonSchema_string_whatever\", false, { failSilently: true })\n let component = getComponents(componentName)\n\n if(!component) {\n if (!config.failSilently) {\n getSystem().log.warn(\"Could not find component:\", componentName)\n }\n return null\n }\n\n if(!container)\n return wrapRender(component)\n\n if(container === \"root\")\n return makeContainer(getSystem, component, getStore())\n\n // container == truthy\n return makeContainer(getSystem, wrapRender(component))\n}\n","export const setHash = (value) => {\n if(value) {\n return history.pushState(null, null, `#${value}`)\n } else {\n return window.location.hash = \"\"\n }\n}\n","// getting tag from 19.1.3.6 Object.prototype.toString()\nvar cof = require('./_cof');\nvar TAG = require('./_wks')('toStringTag');\n// ES3 wrong here\nvar ARG = cof(function () { return arguments; }()) == 'Arguments';\n\n// fallback for IE11 Script Access Denied error\nvar tryGet = function (it, key) {\n try {\n return it[key];\n } catch (e) { /* empty */ }\n};\n\nmodule.exports = function (it) {\n var O, T, B;\n return it === undefined ? 'Undefined' : it === null ? 'Null'\n // @@toStringTag case\n : typeof (T = tryGet(O = Object(it), TAG)) == 'string' ? T\n // builtinTag case\n : ARG ? cof(O)\n // ES3 arguments fallback\n : (B = cof(O)) == 'Object' && typeof O.callee == 'function' ? 'Arguments' : B;\n};\n","var anObject = require('./_an-object');\nvar IE8_DOM_DEFINE = require('./_ie8-dom-define');\nvar toPrimitive = require('./_to-primitive');\nvar dP = Object.defineProperty;\n\nexports.f = require('./_descriptors') ? Object.defineProperty : function defineProperty(O, P, Attributes) {\n anObject(O);\n P = toPrimitive(P, true);\n anObject(Attributes);\n if (IE8_DOM_DEFINE) try {\n return dP(O, P, Attributes);\n } catch (e) { /* empty */ }\n if ('get' in Attributes || 'set' in Attributes) throw TypeError('Accessors not supported!');\n if ('value' in Attributes) O[P] = Attributes.value;\n return O;\n};\n","var hasOwnProperty = {}.hasOwnProperty;\nmodule.exports = function (it, key) {\n return hasOwnProperty.call(it, key);\n};\n","// optional / simple context binding\nvar aFunction = require('./_a-function');\nmodule.exports = function (fn, that, length) {\n aFunction(fn);\n if (that === undefined) return fn;\n switch (length) {\n case 1: return function (a) {\n return fn.call(that, a);\n };\n case 2: return function (a, b) {\n return fn.call(that, a, b);\n };\n case 3: return function (a, b, c) {\n return fn.call(that, a, b, c);\n };\n }\n return function (/* ...args */) {\n return fn.apply(that, arguments);\n };\n};\n","module.exports = function (it) {\n if (typeof it != 'function') throw TypeError(it + ' is not a function!');\n return it;\n};\n","// to indexed object, toObject with fallback for non-array-like ES3 strings\nvar IObject = require('./_iobject');\nvar defined = require('./_defined');\nmodule.exports = function (it) {\n return IObject(defined(it));\n};\n","'use strict';\n\nvar classof = require('./_classof');\nvar builtinExec = RegExp.prototype.exec;\n\n // `RegExpExec` abstract operation\n// https://tc39.github.io/ecma262/#sec-regexpexec\nmodule.exports = function (R, S) {\n var exec = R.exec;\n if (typeof exec === 'function') {\n var result = exec.call(R, S);\n if (typeof result !== 'object') {\n throw new TypeError('RegExp exec method returned something other than an Object or null');\n }\n return result;\n }\n if (classof(R) !== 'RegExp') {\n throw new TypeError('RegExp#exec called on incompatible receiver');\n }\n return builtinExec.call(R, S);\n};\n","'use strict';\nrequire('./es6.regexp.exec');\nvar redefine = require('./_redefine');\nvar hide = require('./_hide');\nvar fails = require('./_fails');\nvar defined = require('./_defined');\nvar wks = require('./_wks');\nvar regexpExec = require('./_regexp-exec');\n\nvar SPECIES = wks('species');\n\nvar REPLACE_SUPPORTS_NAMED_GROUPS = !fails(function () {\n // #replace needs built-in support for named groups.\n // #match works fine because it just return the exec results, even if it has\n // a \"grops\" property.\n var re = /./;\n re.exec = function () {\n var result = [];\n result.groups = { a: '7' };\n return result;\n };\n return ''.replace(re, '$') !== '7';\n});\n\nvar SPLIT_WORKS_WITH_OVERWRITTEN_EXEC = (function () {\n // Chrome 51 has a buggy \"split\" implementation when RegExp#exec !== nativeExec\n var re = /(?:)/;\n var originalExec = re.exec;\n re.exec = function () { return originalExec.apply(this, arguments); };\n var result = 'ab'.split(re);\n return result.length === 2 && result[0] === 'a' && result[1] === 'b';\n})();\n\nmodule.exports = function (KEY, length, exec) {\n var SYMBOL = wks(KEY);\n\n var DELEGATES_TO_SYMBOL = !fails(function () {\n // String methods call symbol-named RegEp methods\n var O = {};\n O[SYMBOL] = function () { return 7; };\n return ''[KEY](O) != 7;\n });\n\n var DELEGATES_TO_EXEC = DELEGATES_TO_SYMBOL ? !fails(function () {\n // Symbol-named RegExp methods call .exec\n var execCalled = false;\n var re = /a/;\n re.exec = function () { execCalled = true; return null; };\n if (KEY === 'split') {\n // RegExp[@@split] doesn't call the regex's exec method, but first creates\n // a new one. We need to return the patched regex when creating the new one.\n re.constructor = {};\n re.constructor[SPECIES] = function () { return re; };\n }\n re[SYMBOL]('');\n return !execCalled;\n }) : undefined;\n\n if (\n !DELEGATES_TO_SYMBOL ||\n !DELEGATES_TO_EXEC ||\n (KEY === 'replace' && !REPLACE_SUPPORTS_NAMED_GROUPS) ||\n (KEY === 'split' && !SPLIT_WORKS_WITH_OVERWRITTEN_EXEC)\n ) {\n var nativeRegExpMethod = /./[SYMBOL];\n var fns = exec(\n defined,\n SYMBOL,\n ''[KEY],\n function maybeCallNative(nativeMethod, regexp, str, arg2, forceStringMethod) {\n if (regexp.exec === regexpExec) {\n if (DELEGATES_TO_SYMBOL && !forceStringMethod) {\n // The native String method already delegates to @@method (this\n // polyfilled function), leasing to infinite recursion.\n // We avoid it by directly calling the native @@method method.\n return { done: true, value: nativeRegExpMethod.call(regexp, str, arg2) };\n }\n return { done: true, value: nativeMethod.call(str, regexp, arg2) };\n }\n return { done: false };\n }\n );\n var strfn = fns[0];\n var rxfn = fns[1];\n\n redefine(String.prototype, KEY, strfn);\n hide(RegExp.prototype, SYMBOL, length == 2\n // 21.2.5.8 RegExp.prototype[@@replace](string, replaceValue)\n // 21.2.5.11 RegExp.prototype[@@split](string, limit)\n ? function (string, arg) { return rxfn.call(string, this, arg); }\n // 21.2.5.6 RegExp.prototype[@@match](string)\n // 21.2.5.9 RegExp.prototype[@@search](string)\n : function (string) { return rxfn.call(string, this); }\n );\n }\n};\n","// 7.1.15 ToLength\nvar toInteger = require('./_to-integer');\nvar min = Math.min;\nmodule.exports = function (it) {\n return it > 0 ? min(toInteger(it), 0x1fffffffffffff) : 0; // pow(2, 53) - 1 == 9007199254740991\n};\n","var id = 0;\nvar px = Math.random();\nmodule.exports = function (key) {\n return 'Symbol('.concat(key === undefined ? '' : key, ')_', (++id + px).toString(36));\n};\n","exports.f = Object.getOwnPropertySymbols;\n","/**\n * Copyright (c) 2013-present, Facebook, Inc.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n *\n */\n\n'use strict';\n\nvar emptyObject = {};\n\nif (process.env.NODE_ENV !== 'production') {\n Object.freeze(emptyObject);\n}\n\nmodule.exports = emptyObject;","// getting tag from 19.1.3.6 Object.prototype.toString()\nvar cof = require('./_cof');\nvar TAG = require('./_wks')('toStringTag');\n// ES3 wrong here\nvar ARG = cof(function () { return arguments; }()) == 'Arguments';\n\n// fallback for IE11 Script Access Denied error\nvar tryGet = function (it, key) {\n try {\n return it[key];\n } catch (e) { /* empty */ }\n};\n\nmodule.exports = function (it) {\n var O, T, B;\n return it === undefined ? 'Undefined' : it === null ? 'Null'\n // @@toStringTag case\n : typeof (T = tryGet(O = Object(it), TAG)) == 'string' ? T\n // builtinTag case\n : ARG ? cof(O)\n // ES3 arguments fallback\n : (B = cof(O)) == 'Object' && typeof O.callee == 'function' ? 'Arguments' : B;\n};\n","var baseGetTag = require('./_baseGetTag'),\n isObjectLike = require('./isObjectLike');\n\n/** `Object#toString` result references. */\nvar symbolTag = '[object Symbol]';\n\n/**\n * Checks if `value` is classified as a `Symbol` primitive or object.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a symbol, else `false`.\n * @example\n *\n * _.isSymbol(Symbol.iterator);\n * // => true\n *\n * _.isSymbol('abc');\n * // => false\n */\nfunction isSymbol(value) {\n return typeof value == 'symbol' ||\n (isObjectLike(value) && baseGetTag(value) == symbolTag);\n}\n\nmodule.exports = isSymbol;\n","var getNative = require('./_getNative');\n\n/* Built-in method references that are verified to be native. */\nvar nativeCreate = getNative(Object, 'create');\n\nmodule.exports = nativeCreate;\n","var listCacheClear = require('./_listCacheClear'),\n listCacheDelete = require('./_listCacheDelete'),\n listCacheGet = require('./_listCacheGet'),\n listCacheHas = require('./_listCacheHas'),\n listCacheSet = require('./_listCacheSet');\n\n/**\n * Creates an list cache object.\n *\n * @private\n * @constructor\n * @param {Array} [entries] The key-value pairs to cache.\n */\nfunction ListCache(entries) {\n var index = -1,\n length = entries == null ? 0 : entries.length;\n\n this.clear();\n while (++index < length) {\n var entry = entries[index];\n this.set(entry[0], entry[1]);\n }\n}\n\n// Add methods to `ListCache`.\nListCache.prototype.clear = listCacheClear;\nListCache.prototype['delete'] = listCacheDelete;\nListCache.prototype.get = listCacheGet;\nListCache.prototype.has = listCacheHas;\nListCache.prototype.set = listCacheSet;\n\nmodule.exports = ListCache;\n","var eq = require('./eq');\n\n/**\n * Gets the index at which the `key` is found in `array` of key-value pairs.\n *\n * @private\n * @param {Array} array The array to inspect.\n * @param {*} key The key to search for.\n * @returns {number} Returns the index of the matched value, else `-1`.\n */\nfunction assocIndexOf(array, key) {\n var length = array.length;\n while (length--) {\n if (eq(array[length][0], key)) {\n return length;\n }\n }\n return -1;\n}\n\nmodule.exports = assocIndexOf;\n","var isKeyable = require('./_isKeyable');\n\n/**\n * Gets the data for `map`.\n *\n * @private\n * @param {Object} map The map to query.\n * @param {string} key The reference key.\n * @returns {*} Returns the map data.\n */\nfunction getMapData(map, key) {\n var data = map.__data__;\n return isKeyable(key)\n ? data[typeof key == 'string' ? 'string' : 'hash']\n : data.map;\n}\n\nmodule.exports = getMapData;\n","var baseMatches = require('./_baseMatches'),\n baseMatchesProperty = require('./_baseMatchesProperty'),\n identity = require('./identity'),\n isArray = require('./isArray'),\n property = require('./property');\n\n/**\n * The base implementation of `_.iteratee`.\n *\n * @private\n * @param {*} [value=_.identity] The value to convert to an iteratee.\n * @returns {Function} Returns the iteratee.\n */\nfunction baseIteratee(value) {\n // Don't store the `typeof` result in a variable to avoid a JIT bug in Safari 9.\n // See https://bugs.webkit.org/show_bug.cgi?id=156034 for more details.\n if (typeof value == 'function') {\n return value;\n }\n if (value == null) {\n return identity;\n }\n if (typeof value == 'object') {\n return isArray(value)\n ? baseMatchesProperty(value[0], value[1])\n : baseMatches(value);\n }\n return property(value);\n}\n\nmodule.exports = baseIteratee;\n","module.exports = function(module) {\n\tif (!module.webpackPolyfill) {\n\t\tmodule.deprecate = function() {};\n\t\tmodule.paths = [];\n\t\t// module.parent = undefined by default\n\t\tif (!module.children) module.children = [];\n\t\tObject.defineProperty(module, \"loaded\", {\n\t\t\tenumerable: true,\n\t\t\tget: function() {\n\t\t\t\treturn module.l;\n\t\t\t}\n\t\t});\n\t\tObject.defineProperty(module, \"id\", {\n\t\t\tenumerable: true,\n\t\t\tget: function() {\n\t\t\t\treturn module.i;\n\t\t\t}\n\t\t});\n\t\tmodule.webpackPolyfill = 1;\n\t}\n\treturn module;\n};\n","/** Used as references for various `Number` constants. */\nvar MAX_SAFE_INTEGER = 9007199254740991;\n\n/** Used to detect unsigned integer values. */\nvar reIsUint = /^(?:0|[1-9]\\d*)$/;\n\n/**\n * Checks if `value` is a valid array-like index.\n *\n * @private\n * @param {*} value The value to check.\n * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.\n * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.\n */\nfunction isIndex(value, length) {\n var type = typeof value;\n length = length == null ? MAX_SAFE_INTEGER : length;\n\n return !!length &&\n (type == 'number' ||\n (type != 'symbol' && reIsUint.test(value))) &&\n (value > -1 && value % 1 == 0 && value < length);\n}\n\nmodule.exports = isIndex;\n","/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/**\n * Checks if `value` is likely a prototype object.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a prototype, else `false`.\n */\nfunction isPrototype(value) {\n var Ctor = value && value.constructor,\n proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto;\n\n return value === proto;\n}\n\nmodule.exports = isPrototype;\n","var DataView = require('./_DataView'),\n Map = require('./_Map'),\n Promise = require('./_Promise'),\n Set = require('./_Set'),\n WeakMap = require('./_WeakMap'),\n baseGetTag = require('./_baseGetTag'),\n toSource = require('./_toSource');\n\n/** `Object#toString` result references. */\nvar mapTag = '[object Map]',\n objectTag = '[object Object]',\n promiseTag = '[object Promise]',\n setTag = '[object Set]',\n weakMapTag = '[object WeakMap]';\n\nvar dataViewTag = '[object DataView]';\n\n/** Used to detect maps, sets, and weakmaps. */\nvar dataViewCtorString = toSource(DataView),\n mapCtorString = toSource(Map),\n promiseCtorString = toSource(Promise),\n setCtorString = toSource(Set),\n weakMapCtorString = toSource(WeakMap);\n\n/**\n * Gets the `toStringTag` of `value`.\n *\n * @private\n * @param {*} value The value to query.\n * @returns {string} Returns the `toStringTag`.\n */\nvar getTag = baseGetTag;\n\n// Fallback for data views, maps, sets, and weak maps in IE 11 and promises in Node.js < 6.\nif ((DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag) ||\n (Map && getTag(new Map) != mapTag) ||\n (Promise && getTag(Promise.resolve()) != promiseTag) ||\n (Set && getTag(new Set) != setTag) ||\n (WeakMap && getTag(new WeakMap) != weakMapTag)) {\n getTag = function(value) {\n var result = baseGetTag(value),\n Ctor = result == objectTag ? value.constructor : undefined,\n ctorString = Ctor ? toSource(Ctor) : '';\n\n if (ctorString) {\n switch (ctorString) {\n case dataViewCtorString: return dataViewTag;\n case mapCtorString: return mapTag;\n case promiseCtorString: return promiseTag;\n case setCtorString: return setTag;\n case weakMapCtorString: return weakMapTag;\n }\n }\n return result;\n };\n}\n\nmodule.exports = getTag;\n","var castPath = require('./_castPath'),\n toKey = require('./_toKey');\n\n/**\n * The base implementation of `_.get` without support for default values.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {Array|string} path The path of the property to get.\n * @returns {*} Returns the resolved value.\n */\nfunction baseGet(object, path) {\n path = castPath(path, object);\n\n var index = 0,\n length = path.length;\n\n while (object != null && index < length) {\n object = object[toKey(path[index++])];\n }\n return (index && index == length) ? object : undefined;\n}\n\nmodule.exports = baseGet;\n","'use strict';\n\nif (!process.version ||\n process.version.indexOf('v0.') === 0 ||\n process.version.indexOf('v1.') === 0 && process.version.indexOf('v1.8.') !== 0) {\n module.exports = { nextTick: nextTick };\n} else {\n module.exports = process\n}\n\nfunction nextTick(fn, arg1, arg2, arg3) {\n if (typeof fn !== 'function') {\n throw new TypeError('\"callback\" argument must be a function');\n }\n var len = arguments.length;\n var args, i;\n switch (len) {\n case 0:\n case 1:\n return process.nextTick(fn);\n case 2:\n return process.nextTick(function afterTickOne() {\n fn.call(null, arg1);\n });\n case 3:\n return process.nextTick(function afterTickTwo() {\n fn.call(null, arg1, arg2);\n });\n case 4:\n return process.nextTick(function afterTickThree() {\n fn.call(null, arg1, arg2, arg3);\n });\n default:\n args = new Array(len - 1);\n i = 0;\n while (i < args.length) {\n args[i++] = arguments[i];\n }\n return process.nextTick(function afterTick() {\n fn.apply(null, args);\n });\n }\n}\n\n","\"use strict\";\n\nmodule.exports = require(\"./_iterate\")(\"forEach\");\n","'use strict';\n\nvar assign = require('es5-ext/object/assign')\n , normalizeOpts = require('es5-ext/object/normalize-options')\n , isCallable = require('es5-ext/object/is-callable')\n , contains = require('es5-ext/string/#/contains')\n\n , d;\n\nd = module.exports = function (dscr, value/*, options*/) {\n\tvar c, e, w, options, desc;\n\tif ((arguments.length < 2) || (typeof dscr !== 'string')) {\n\t\toptions = value;\n\t\tvalue = dscr;\n\t\tdscr = null;\n\t} else {\n\t\toptions = arguments[2];\n\t}\n\tif (dscr == null) {\n\t\tc = w = true;\n\t\te = false;\n\t} else {\n\t\tc = contains.call(dscr, 'c');\n\t\te = contains.call(dscr, 'e');\n\t\tw = contains.call(dscr, 'w');\n\t}\n\n\tdesc = { value: value, configurable: c, enumerable: e, writable: w };\n\treturn !options ? desc : assign(normalizeOpts(options), desc);\n};\n\nd.gs = function (dscr, get, set/*, options*/) {\n\tvar c, e, options, desc;\n\tif (typeof dscr !== 'string') {\n\t\toptions = set;\n\t\tset = get;\n\t\tget = dscr;\n\t\tdscr = null;\n\t} else {\n\t\toptions = arguments[3];\n\t}\n\tif (get == null) {\n\t\tget = undefined;\n\t} else if (!isCallable(get)) {\n\t\toptions = get;\n\t\tget = set = undefined;\n\t} else if (set == null) {\n\t\tset = undefined;\n\t} else if (!isCallable(set)) {\n\t\toptions = set;\n\t\tset = undefined;\n\t}\n\tif (dscr == null) {\n\t\tc = true;\n\t\te = false;\n\t} else {\n\t\tc = contains.call(dscr, 'c');\n\t\te = contains.call(dscr, 'e');\n\t}\n\n\tdesc = { get: get, set: set, configurable: c, enumerable: e };\n\treturn !options ? desc : assign(normalizeOpts(options), desc);\n};\n","module.exports = function (it, Constructor, name, forbiddenField) {\n if (!(it instanceof Constructor) || (forbiddenField !== undefined && forbiddenField in it)) {\n throw TypeError(name + ': incorrect invocation!');\n } return it;\n};\n","var hide = require('./_hide');\nmodule.exports = function (target, src, safe) {\n for (var key in src) {\n if (safe && target[key]) target[key] = src[key];\n else hide(target, key, src[key]);\n } return target;\n};\n","// JS-YAML's default schema for `load` function.\n// It is not described in the YAML specification.\n//\n// This schema is based on JS-YAML's default safe schema and includes\n// JavaScript-specific types: !!js/undefined, !!js/regexp and !!js/function.\n//\n// Also this schema is used as default base schema at `Schema.create` function.\n\n\n'use strict';\n\n\nvar Schema = require('../schema');\n\n\nmodule.exports = Schema.DEFAULT = new Schema({\n include: [\n require('./default_safe')\n ],\n explicit: [\n require('../type/js/undefined'),\n require('../type/js/regexp'),\n require('../type/js/function')\n ]\n});\n","var baseAssignValue = require('./_baseAssignValue'),\n eq = require('./eq');\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Assigns `value` to `key` of `object` if the existing value is not equivalent\n * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)\n * for equality comparisons.\n *\n * @private\n * @param {Object} object The object to modify.\n * @param {string} key The key of the property to assign.\n * @param {*} value The value to assign.\n */\nfunction assignValue(object, key, value) {\n var objValue = object[key];\n if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) ||\n (value === undefined && !(key in object))) {\n baseAssignValue(object, key, value);\n }\n}\n\nmodule.exports = assignValue;\n","/**\n * Copyright (c) 2013-present, Facebook, Inc.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n *\n * \n */\n\n'use strict';\n\nvar _prodInvariant = require('./reactProdInvariant');\n\nvar invariant = require('fbjs/lib/invariant');\n\nvar OBSERVED_ERROR = {};\n\n/**\n * `Transaction` creates a black box that is able to wrap any method such that\n * certain invariants are maintained before and after the method is invoked\n * (Even if an exception is thrown while invoking the wrapped method). Whoever\n * instantiates a transaction can provide enforcers of the invariants at\n * creation time. The `Transaction` class itself will supply one additional\n * automatic invariant for you - the invariant that any transaction instance\n * should not be run while it is already being run. You would typically create a\n * single instance of a `Transaction` for reuse multiple times, that potentially\n * is used to wrap several different methods. Wrappers are extremely simple -\n * they only require implementing two methods.\n *\n *
\n *                       wrappers (injected at creation time)\n *                                      +        +\n *                                      |        |\n *                    +-----------------|--------|--------------+\n *                    |                 v        |              |\n *                    |      +---------------+   |              |\n *                    |   +--|    wrapper1   |---|----+         |\n *                    |   |  +---------------+   v    |         |\n *                    |   |          +-------------+  |         |\n *                    |   |     +----|   wrapper2  |--------+   |\n *                    |   |     |    +-------------+  |     |   |\n *                    |   |     |                     |     |   |\n *                    |   v     v                     v     v   | wrapper\n *                    | +---+ +---+   +---------+   +---+ +---+ | invariants\n * perform(anyMethod) | |   | |   |   |         |   |   | |   | | maintained\n * +----------------->|-|---|-|---|-->|anyMethod|---|---|-|---|-|-------->\n *                    | |   | |   |   |         |   |   | |   | |\n *                    | |   | |   |   |         |   |   | |   | |\n *                    | |   | |   |   |         |   |   | |   | |\n *                    | +---+ +---+   +---------+   +---+ +---+ |\n *                    |  initialize                    close    |\n *                    +-----------------------------------------+\n * 
\n *\n * Use cases:\n * - Preserving the input selection ranges before/after reconciliation.\n * Restoring selection even in the event of an unexpected error.\n * - Deactivating events while rearranging the DOM, preventing blurs/focuses,\n * while guaranteeing that afterwards, the event system is reactivated.\n * - Flushing a queue of collected DOM mutations to the main UI thread after a\n * reconciliation takes place in a worker thread.\n * - Invoking any collected `componentDidUpdate` callbacks after rendering new\n * content.\n * - (Future use case): Wrapping particular flushes of the `ReactWorker` queue\n * to preserve the `scrollTop` (an automatic scroll aware DOM).\n * - (Future use case): Layout calculations before and after DOM updates.\n *\n * Transactional plugin API:\n * - A module that has an `initialize` method that returns any precomputation.\n * - and a `close` method that accepts the precomputation. `close` is invoked\n * when the wrapped process is completed, or has failed.\n *\n * @param {Array} transactionWrapper Wrapper modules\n * that implement `initialize` and `close`.\n * @return {Transaction} Single transaction for reuse in thread.\n *\n * @class Transaction\n */\nvar TransactionImpl = {\n /**\n * Sets up this instance so that it is prepared for collecting metrics. Does\n * so such that this setup method may be used on an instance that is already\n * initialized, in a way that does not consume additional memory upon reuse.\n * That can be useful if you decide to make your subclass of this mixin a\n * \"PooledClass\".\n */\n reinitializeTransaction: function () {\n this.transactionWrappers = this.getTransactionWrappers();\n if (this.wrapperInitData) {\n this.wrapperInitData.length = 0;\n } else {\n this.wrapperInitData = [];\n }\n this._isInTransaction = false;\n },\n\n _isInTransaction: false,\n\n /**\n * @abstract\n * @return {Array} Array of transaction wrappers.\n */\n getTransactionWrappers: null,\n\n isInTransaction: function () {\n return !!this._isInTransaction;\n },\n\n /* eslint-disable space-before-function-paren */\n\n /**\n * Executes the function within a safety window. Use this for the top level\n * methods that result in large amounts of computation/mutations that would\n * need to be safety checked. The optional arguments helps prevent the need\n * to bind in many cases.\n *\n * @param {function} method Member of scope to call.\n * @param {Object} scope Scope to invoke from.\n * @param {Object?=} a Argument to pass to the method.\n * @param {Object?=} b Argument to pass to the method.\n * @param {Object?=} c Argument to pass to the method.\n * @param {Object?=} d Argument to pass to the method.\n * @param {Object?=} e Argument to pass to the method.\n * @param {Object?=} f Argument to pass to the method.\n *\n * @return {*} Return value from `method`.\n */\n perform: function (method, scope, a, b, c, d, e, f) {\n /* eslint-enable space-before-function-paren */\n !!this.isInTransaction() ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Transaction.perform(...): Cannot initialize a transaction when there is already an outstanding transaction.') : _prodInvariant('27') : void 0;\n var errorThrown;\n var ret;\n try {\n this._isInTransaction = true;\n // Catching errors makes debugging more difficult, so we start with\n // errorThrown set to true before setting it to false after calling\n // close -- if it's still set to true in the finally block, it means\n // one of these calls threw.\n errorThrown = true;\n this.initializeAll(0);\n ret = method.call(scope, a, b, c, d, e, f);\n errorThrown = false;\n } finally {\n try {\n if (errorThrown) {\n // If `method` throws, prefer to show that stack trace over any thrown\n // by invoking `closeAll`.\n try {\n this.closeAll(0);\n } catch (err) {}\n } else {\n // Since `method` didn't throw, we don't want to silence the exception\n // here.\n this.closeAll(0);\n }\n } finally {\n this._isInTransaction = false;\n }\n }\n return ret;\n },\n\n initializeAll: function (startIndex) {\n var transactionWrappers = this.transactionWrappers;\n for (var i = startIndex; i < transactionWrappers.length; i++) {\n var wrapper = transactionWrappers[i];\n try {\n // Catching errors makes debugging more difficult, so we start with the\n // OBSERVED_ERROR state before overwriting it with the real return value\n // of initialize -- if it's still set to OBSERVED_ERROR in the finally\n // block, it means wrapper.initialize threw.\n this.wrapperInitData[i] = OBSERVED_ERROR;\n this.wrapperInitData[i] = wrapper.initialize ? wrapper.initialize.call(this) : null;\n } finally {\n if (this.wrapperInitData[i] === OBSERVED_ERROR) {\n // The initializer for wrapper i threw an error; initialize the\n // remaining wrappers but silence any exceptions from them to ensure\n // that the first error is the one to bubble up.\n try {\n this.initializeAll(i + 1);\n } catch (err) {}\n }\n }\n }\n },\n\n /**\n * Invokes each of `this.transactionWrappers.close[i]` functions, passing into\n * them the respective return values of `this.transactionWrappers.init[i]`\n * (`close`rs that correspond to initializers that failed will not be\n * invoked).\n */\n closeAll: function (startIndex) {\n !this.isInTransaction() ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Transaction.closeAll(): Cannot close transaction when none are open.') : _prodInvariant('28') : void 0;\n var transactionWrappers = this.transactionWrappers;\n for (var i = startIndex; i < transactionWrappers.length; i++) {\n var wrapper = transactionWrappers[i];\n var initData = this.wrapperInitData[i];\n var errorThrown;\n try {\n // Catching errors makes debugging more difficult, so we start with\n // errorThrown set to true before setting it to false after calling\n // close -- if it's still set to true in the finally block, it means\n // wrapper.close threw.\n errorThrown = true;\n if (initData !== OBSERVED_ERROR && wrapper.close) {\n wrapper.close.call(this, initData);\n }\n errorThrown = false;\n } finally {\n if (errorThrown) {\n // The closer for wrapper i threw an error; close the remaining\n // wrappers but silence any exceptions from them to ensure that the\n // first error is the one to bubble up.\n try {\n this.closeAll(i + 1);\n } catch (e) {}\n }\n }\n }\n this.wrapperInitData.length = 0;\n }\n};\n\nmodule.exports = TransactionImpl;","/**\n * Copyright (c) 2013-present, Facebook, Inc.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n *\n */\n\n'use strict';\n\nvar SyntheticUIEvent = require('./SyntheticUIEvent');\nvar ViewportMetrics = require('./ViewportMetrics');\n\nvar getEventModifierState = require('./getEventModifierState');\n\n/**\n * @interface MouseEvent\n * @see http://www.w3.org/TR/DOM-Level-3-Events/\n */\nvar MouseEventInterface = {\n screenX: null,\n screenY: null,\n clientX: null,\n clientY: null,\n ctrlKey: null,\n shiftKey: null,\n altKey: null,\n metaKey: null,\n getModifierState: getEventModifierState,\n button: function (event) {\n // Webkit, Firefox, IE9+\n // which: 1 2 3\n // button: 0 1 2 (standard)\n var button = event.button;\n if ('which' in event) {\n return button;\n }\n // IE<9\n // which: undefined\n // button: 0 0 0\n // button: 1 4 2 (onmouseup)\n return button === 2 ? 2 : button === 4 ? 1 : 0;\n },\n buttons: null,\n relatedTarget: function (event) {\n return event.relatedTarget || (event.fromElement === event.srcElement ? event.toElement : event.fromElement);\n },\n // \"Proprietary\" Interface.\n pageX: function (event) {\n return 'pageX' in event ? event.pageX : event.clientX + ViewportMetrics.currentScrollLeft;\n },\n pageY: function (event) {\n return 'pageY' in event ? event.pageY : event.clientY + ViewportMetrics.currentScrollTop;\n }\n};\n\n/**\n * @param {object} dispatchConfig Configuration used to dispatch this event.\n * @param {string} dispatchMarker Marker identifying the event target.\n * @param {object} nativeEvent Native browser event.\n * @extends {SyntheticUIEvent}\n */\nfunction SyntheticMouseEvent(dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget) {\n return SyntheticUIEvent.call(this, dispatchConfig, dispatchMarker, nativeEvent, nativeEventTarget);\n}\n\nSyntheticUIEvent.augmentClass(SyntheticMouseEvent, MouseEventInterface);\n\nmodule.exports = SyntheticMouseEvent;","/**\n * Copyright (c) 2013-present, Facebook, Inc.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n *\n */\n\n'use strict';\n\nvar ExecutionEnvironment = require('fbjs/lib/ExecutionEnvironment');\nvar DOMNamespaces = require('./DOMNamespaces');\n\nvar WHITESPACE_TEST = /^[ \\r\\n\\t\\f]/;\nvar NONVISIBLE_TEST = /<(!--|link|noscript|meta|script|style)[ \\r\\n\\t\\f\\/>]/;\n\nvar createMicrosoftUnsafeLocalFunction = require('./createMicrosoftUnsafeLocalFunction');\n\n// SVG temp container for IE lacking innerHTML\nvar reusableSVGContainer;\n\n/**\n * Set the innerHTML property of a node, ensuring that whitespace is preserved\n * even in IE8.\n *\n * @param {DOMElement} node\n * @param {string} html\n * @internal\n */\nvar setInnerHTML = createMicrosoftUnsafeLocalFunction(function (node, html) {\n // IE does not have innerHTML for SVG nodes, so instead we inject the\n // new markup in a temp node and then move the child nodes across into\n // the target node\n if (node.namespaceURI === DOMNamespaces.svg && !('innerHTML' in node)) {\n reusableSVGContainer = reusableSVGContainer || document.createElement('div');\n reusableSVGContainer.innerHTML = '' + html + '';\n var svgNode = reusableSVGContainer.firstChild;\n while (svgNode.firstChild) {\n node.appendChild(svgNode.firstChild);\n }\n } else {\n node.innerHTML = html;\n }\n});\n\nif (ExecutionEnvironment.canUseDOM) {\n // IE8: When updating a just created node with innerHTML only leading\n // whitespace is removed. When updating an existing node with innerHTML\n // whitespace in root TextNodes is also collapsed.\n // @see quirksmode.org/bugreports/archives/2004/11/innerhtml_and_t.html\n\n // Feature detection; only IE8 is known to behave improperly like this.\n var testElement = document.createElement('div');\n testElement.innerHTML = ' ';\n if (testElement.innerHTML === '') {\n setInnerHTML = function (node, html) {\n // Magic theory: IE8 supposedly differentiates between added and updated\n // nodes when processing innerHTML, innerHTML on updated nodes suffers\n // from worse whitespace behavior. Re-adding a node like this triggers\n // the initial and more favorable whitespace behavior.\n // TODO: What to do on a detached node?\n if (node.parentNode) {\n node.parentNode.replaceChild(node, node);\n }\n\n // We also implement a workaround for non-visible tags disappearing into\n // thin air on IE8, this only happens if there is no visible text\n // in-front of the non-visible tags. Piggyback on the whitespace fix\n // and simply check if any non-visible tags appear in the source.\n if (WHITESPACE_TEST.test(html) || html[0] === '<' && NONVISIBLE_TEST.test(html)) {\n // Recover leading whitespace by temporarily prepending any character.\n // \\uFEFF has the potential advantage of being zero-width/invisible.\n // UglifyJS drops U+FEFF chars when parsing, so use String.fromCharCode\n // in hopes that this is preserved even if \"\\uFEFF\" is transformed to\n // the actual Unicode character (by Babel, for example).\n // https://github.com/mishoo/UglifyJS2/blob/v2.4.20/lib/parse.js#L216\n node.innerHTML = String.fromCharCode(0xfeff) + html;\n\n // deleteData leaves an empty `TextNode` which offsets the index of all\n // children. Definitely want to avoid this.\n var textNode = node.firstChild;\n if (textNode.data.length === 1) {\n node.removeChild(textNode);\n } else {\n textNode.deleteData(0, 1);\n }\n } else {\n node.innerHTML = html;\n }\n };\n }\n testElement = null;\n}\n\nmodule.exports = setInnerHTML;","/**\n * Copyright (c) 2016-present, Facebook, Inc.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n *\n * Based on the escape-html library, which is used under the MIT License below:\n *\n * Copyright (c) 2012-2013 TJ Holowaychuk\n * Copyright (c) 2015 Andreas Lubbe\n * Copyright (c) 2015 Tiancheng \"Timothy\" Gu\n *\n * Permission is hereby granted, free of charge, to any person obtaining\n * a copy of this software and associated documentation files (the\n * 'Software'), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish,\n * distribute, sublicense, and/or sell copies of the Software, and to\n * permit persons to whom the Software is furnished to do so, subject to\n * the following conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n *\n */\n\n'use strict';\n\n// code copied and modified from escape-html\n/**\n * Module variables.\n * @private\n */\n\nvar matchHtmlRegExp = /[\"'&<>]/;\n\n/**\n * Escape special characters in the given string of html.\n *\n * @param {string} string The string to escape for inserting into HTML\n * @return {string}\n * @public\n */\n\nfunction escapeHtml(string) {\n var str = '' + string;\n var match = matchHtmlRegExp.exec(str);\n\n if (!match) {\n return str;\n }\n\n var escape;\n var html = '';\n var index = 0;\n var lastIndex = 0;\n\n for (index = match.index; index < str.length; index++) {\n switch (str.charCodeAt(index)) {\n case 34:\n // \"\n escape = '"';\n break;\n case 38:\n // &\n escape = '&';\n break;\n case 39:\n // '\n escape = '''; // modified from escape-html; used to be '''\n break;\n case 60:\n // <\n escape = '<';\n break;\n case 62:\n // >\n escape = '>';\n break;\n default:\n continue;\n }\n\n if (lastIndex !== index) {\n html += str.substring(lastIndex, index);\n }\n\n lastIndex = index + 1;\n html += escape;\n }\n\n return lastIndex !== index ? html + str.substring(lastIndex, index) : html;\n}\n// end code copied and modified from escape-html\n\n/**\n * Escapes text to prevent scripting attacks.\n *\n * @param {*} text Text value to escape.\n * @return {string} An escaped string.\n */\nfunction escapeTextContentForBrowser(text) {\n if (typeof text === 'boolean' || typeof text === 'number') {\n // this shortcircuit helps perf for types that we know will never have\n // special characters, especially given that this function is used often\n // for numeric dom ids.\n return '' + text;\n }\n return escapeHtml(text);\n}\n\nmodule.exports = escapeTextContentForBrowser;","/**\n * Copyright (c) 2013-present, Facebook, Inc.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n *\n */\n\n'use strict';\n\nvar _assign = require('object-assign');\n\nvar EventPluginRegistry = require('./EventPluginRegistry');\nvar ReactEventEmitterMixin = require('./ReactEventEmitterMixin');\nvar ViewportMetrics = require('./ViewportMetrics');\n\nvar getVendorPrefixedEventName = require('./getVendorPrefixedEventName');\nvar isEventSupported = require('./isEventSupported');\n\n/**\n * Summary of `ReactBrowserEventEmitter` event handling:\n *\n * - Top-level delegation is used to trap most native browser events. This\n * may only occur in the main thread and is the responsibility of\n * ReactEventListener, which is injected and can therefore support pluggable\n * event sources. This is the only work that occurs in the main thread.\n *\n * - We normalize and de-duplicate events to account for browser quirks. This\n * may be done in the worker thread.\n *\n * - Forward these native events (with the associated top-level type used to\n * trap it) to `EventPluginHub`, which in turn will ask plugins if they want\n * to extract any synthetic events.\n *\n * - The `EventPluginHub` will then process each event by annotating them with\n * \"dispatches\", a sequence of listeners and IDs that care about that event.\n *\n * - The `EventPluginHub` then dispatches the events.\n *\n * Overview of React and the event system:\n *\n * +------------+ .\n * | DOM | .\n * +------------+ .\n * | .\n * v .\n * +------------+ .\n * | ReactEvent | .\n * | Listener | .\n * +------------+ . +-----------+\n * | . +--------+|SimpleEvent|\n * | . | |Plugin |\n * +-----|------+ . v +-----------+\n * | | | . +--------------+ +------------+\n * | +-----------.--->|EventPluginHub| | Event |\n * | | . | | +-----------+ | Propagators|\n * | ReactEvent | . | | |TapEvent | |------------|\n * | Emitter | . | |<---+|Plugin | |other plugin|\n * | | . | | +-----------+ | utilities |\n * | +-----------.--->| | +------------+\n * | | | . +--------------+\n * +-----|------+ . ^ +-----------+\n * | . | |Enter/Leave|\n * + . +-------+|Plugin |\n * +-------------+ . +-----------+\n * | application | .\n * |-------------| .\n * | | .\n * | | .\n * +-------------+ .\n * .\n * React Core . General Purpose Event Plugin System\n */\n\nvar hasEventPageXY;\nvar alreadyListeningTo = {};\nvar isMonitoringScrollValue = false;\nvar reactTopListenersCounter = 0;\n\n// For events like 'submit' which don't consistently bubble (which we trap at a\n// lower node than `document`), binding at `document` would cause duplicate\n// events so we don't include them here\nvar topEventMapping = {\n topAbort: 'abort',\n topAnimationEnd: getVendorPrefixedEventName('animationend') || 'animationend',\n topAnimationIteration: getVendorPrefixedEventName('animationiteration') || 'animationiteration',\n topAnimationStart: getVendorPrefixedEventName('animationstart') || 'animationstart',\n topBlur: 'blur',\n topCanPlay: 'canplay',\n topCanPlayThrough: 'canplaythrough',\n topChange: 'change',\n topClick: 'click',\n topCompositionEnd: 'compositionend',\n topCompositionStart: 'compositionstart',\n topCompositionUpdate: 'compositionupdate',\n topContextMenu: 'contextmenu',\n topCopy: 'copy',\n topCut: 'cut',\n topDoubleClick: 'dblclick',\n topDrag: 'drag',\n topDragEnd: 'dragend',\n topDragEnter: 'dragenter',\n topDragExit: 'dragexit',\n topDragLeave: 'dragleave',\n topDragOver: 'dragover',\n topDragStart: 'dragstart',\n topDrop: 'drop',\n topDurationChange: 'durationchange',\n topEmptied: 'emptied',\n topEncrypted: 'encrypted',\n topEnded: 'ended',\n topError: 'error',\n topFocus: 'focus',\n topInput: 'input',\n topKeyDown: 'keydown',\n topKeyPress: 'keypress',\n topKeyUp: 'keyup',\n topLoadedData: 'loadeddata',\n topLoadedMetadata: 'loadedmetadata',\n topLoadStart: 'loadstart',\n topMouseDown: 'mousedown',\n topMouseMove: 'mousemove',\n topMouseOut: 'mouseout',\n topMouseOver: 'mouseover',\n topMouseUp: 'mouseup',\n topPaste: 'paste',\n topPause: 'pause',\n topPlay: 'play',\n topPlaying: 'playing',\n topProgress: 'progress',\n topRateChange: 'ratechange',\n topScroll: 'scroll',\n topSeeked: 'seeked',\n topSeeking: 'seeking',\n topSelectionChange: 'selectionchange',\n topStalled: 'stalled',\n topSuspend: 'suspend',\n topTextInput: 'textInput',\n topTimeUpdate: 'timeupdate',\n topTouchCancel: 'touchcancel',\n topTouchEnd: 'touchend',\n topTouchMove: 'touchmove',\n topTouchStart: 'touchstart',\n topTransitionEnd: getVendorPrefixedEventName('transitionend') || 'transitionend',\n topVolumeChange: 'volumechange',\n topWaiting: 'waiting',\n topWheel: 'wheel'\n};\n\n/**\n * To ensure no conflicts with other potential React instances on the page\n */\nvar topListenersIDKey = '_reactListenersID' + String(Math.random()).slice(2);\n\nfunction getListeningForDocument(mountAt) {\n // In IE8, `mountAt` is a host object and doesn't have `hasOwnProperty`\n // directly.\n if (!Object.prototype.hasOwnProperty.call(mountAt, topListenersIDKey)) {\n mountAt[topListenersIDKey] = reactTopListenersCounter++;\n alreadyListeningTo[mountAt[topListenersIDKey]] = {};\n }\n return alreadyListeningTo[mountAt[topListenersIDKey]];\n}\n\n/**\n * `ReactBrowserEventEmitter` is used to attach top-level event listeners. For\n * example:\n *\n * EventPluginHub.putListener('myID', 'onClick', myFunction);\n *\n * This would allocate a \"registration\" of `('onClick', myFunction)` on 'myID'.\n *\n * @internal\n */\nvar ReactBrowserEventEmitter = _assign({}, ReactEventEmitterMixin, {\n /**\n * Injectable event backend\n */\n ReactEventListener: null,\n\n injection: {\n /**\n * @param {object} ReactEventListener\n */\n injectReactEventListener: function (ReactEventListener) {\n ReactEventListener.setHandleTopLevel(ReactBrowserEventEmitter.handleTopLevel);\n ReactBrowserEventEmitter.ReactEventListener = ReactEventListener;\n }\n },\n\n /**\n * Sets whether or not any created callbacks should be enabled.\n *\n * @param {boolean} enabled True if callbacks should be enabled.\n */\n setEnabled: function (enabled) {\n if (ReactBrowserEventEmitter.ReactEventListener) {\n ReactBrowserEventEmitter.ReactEventListener.setEnabled(enabled);\n }\n },\n\n /**\n * @return {boolean} True if callbacks are enabled.\n */\n isEnabled: function () {\n return !!(ReactBrowserEventEmitter.ReactEventListener && ReactBrowserEventEmitter.ReactEventListener.isEnabled());\n },\n\n /**\n * We listen for bubbled touch events on the document object.\n *\n * Firefox v8.01 (and possibly others) exhibited strange behavior when\n * mounting `onmousemove` events at some node that was not the document\n * element. The symptoms were that if your mouse is not moving over something\n * contained within that mount point (for example on the background) the\n * top-level listeners for `onmousemove` won't be called. However, if you\n * register the `mousemove` on the document object, then it will of course\n * catch all `mousemove`s. This along with iOS quirks, justifies restricting\n * top-level listeners to the document object only, at least for these\n * movement types of events and possibly all events.\n *\n * @see http://www.quirksmode.org/blog/archives/2010/09/click_event_del.html\n *\n * Also, `keyup`/`keypress`/`keydown` do not bubble to the window on IE, but\n * they bubble to document.\n *\n * @param {string} registrationName Name of listener (e.g. `onClick`).\n * @param {object} contentDocumentHandle Document which owns the container\n */\n listenTo: function (registrationName, contentDocumentHandle) {\n var mountAt = contentDocumentHandle;\n var isListening = getListeningForDocument(mountAt);\n var dependencies = EventPluginRegistry.registrationNameDependencies[registrationName];\n\n for (var i = 0; i < dependencies.length; i++) {\n var dependency = dependencies[i];\n if (!(isListening.hasOwnProperty(dependency) && isListening[dependency])) {\n if (dependency === 'topWheel') {\n if (isEventSupported('wheel')) {\n ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent('topWheel', 'wheel', mountAt);\n } else if (isEventSupported('mousewheel')) {\n ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent('topWheel', 'mousewheel', mountAt);\n } else {\n // Firefox needs to capture a different mouse scroll event.\n // @see http://www.quirksmode.org/dom/events/tests/scroll.html\n ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent('topWheel', 'DOMMouseScroll', mountAt);\n }\n } else if (dependency === 'topScroll') {\n if (isEventSupported('scroll', true)) {\n ReactBrowserEventEmitter.ReactEventListener.trapCapturedEvent('topScroll', 'scroll', mountAt);\n } else {\n ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent('topScroll', 'scroll', ReactBrowserEventEmitter.ReactEventListener.WINDOW_HANDLE);\n }\n } else if (dependency === 'topFocus' || dependency === 'topBlur') {\n if (isEventSupported('focus', true)) {\n ReactBrowserEventEmitter.ReactEventListener.trapCapturedEvent('topFocus', 'focus', mountAt);\n ReactBrowserEventEmitter.ReactEventListener.trapCapturedEvent('topBlur', 'blur', mountAt);\n } else if (isEventSupported('focusin')) {\n // IE has `focusin` and `focusout` events which bubble.\n // @see http://www.quirksmode.org/blog/archives/2008/04/delegating_the.html\n ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent('topFocus', 'focusin', mountAt);\n ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent('topBlur', 'focusout', mountAt);\n }\n\n // to make sure blur and focus event listeners are only attached once\n isListening.topBlur = true;\n isListening.topFocus = true;\n } else if (topEventMapping.hasOwnProperty(dependency)) {\n ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent(dependency, topEventMapping[dependency], mountAt);\n }\n\n isListening[dependency] = true;\n }\n }\n },\n\n trapBubbledEvent: function (topLevelType, handlerBaseName, handle) {\n return ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent(topLevelType, handlerBaseName, handle);\n },\n\n trapCapturedEvent: function (topLevelType, handlerBaseName, handle) {\n return ReactBrowserEventEmitter.ReactEventListener.trapCapturedEvent(topLevelType, handlerBaseName, handle);\n },\n\n /**\n * Protect against document.createEvent() returning null\n * Some popup blocker extensions appear to do this:\n * https://github.com/facebook/react/issues/6887\n */\n supportsEventPageXY: function () {\n if (!document.createEvent) {\n return false;\n }\n var ev = document.createEvent('MouseEvent');\n return ev != null && 'pageX' in ev;\n },\n\n /**\n * Listens to window scroll and resize events. We cache scroll values so that\n * application code can access them without triggering reflows.\n *\n * ViewportMetrics is only used by SyntheticMouse/TouchEvent and only when\n * pageX/pageY isn't supported (legacy browsers).\n *\n * NOTE: Scroll events do not bubble.\n *\n * @see http://www.quirksmode.org/dom/events/scroll.html\n */\n ensureScrollValueMonitoring: function () {\n if (hasEventPageXY === undefined) {\n hasEventPageXY = ReactBrowserEventEmitter.supportsEventPageXY();\n }\n if (!hasEventPageXY && !isMonitoringScrollValue) {\n var refresh = ViewportMetrics.refreshScrollValues;\n ReactBrowserEventEmitter.ReactEventListener.monitorScrollValue(refresh);\n isMonitoringScrollValue = true;\n }\n }\n});\n\nmodule.exports = ReactBrowserEventEmitter;","module.exports = require(\"core-js/library/fn/promise\");","var _Promise = require(\"../core-js/promise\");\n\nfunction asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {\n try {\n var info = gen[key](arg);\n var value = info.value;\n } catch (error) {\n reject(error);\n return;\n }\n\n if (info.done) {\n resolve(value);\n } else {\n _Promise.resolve(value).then(_next, _throw);\n }\n}\n\nfunction _asyncToGenerator(fn) {\n return function () {\n var self = this,\n args = arguments;\n return new _Promise(function (resolve, reject) {\n var gen = fn.apply(self, args);\n\n function _next(value) {\n asyncGeneratorStep(gen, resolve, reject, _next, _throw, \"next\", value);\n }\n\n function _throw(err) {\n asyncGeneratorStep(gen, resolve, reject, _next, _throw, \"throw\", err);\n }\n\n _next(undefined);\n });\n };\n}\n\nmodule.exports = _asyncToGenerator;","import React from \"react\"\nimport URL from \"url-parse\"\n\nimport PropTypes from \"prop-types\"\nimport { sanitizeUrl } from \"core/utils\"\nimport win from \"core/window\"\n\nexport default class OnlineValidatorBadge extends React.Component {\n static propTypes = {\n getComponent: PropTypes.func.isRequired,\n getConfigs: PropTypes.func.isRequired,\n specSelectors: PropTypes.object.isRequired\n }\n\n constructor(props, context) {\n super(props, context)\n let { getConfigs } = props\n let { validatorUrl } = getConfigs()\n this.state = {\n url: this.getDefinitionUrl(),\n validatorUrl: validatorUrl === undefined ? \"https://validator.swagger.io/validator\" : validatorUrl\n }\n }\n\n getDefinitionUrl = () => {\n // TODO: test this behavior by stubbing `window.location` in an Enzyme/JSDom env\n let { specSelectors } = this.props\n\n const urlObject = new URL(specSelectors.url(), win.location)\n return urlObject.toString()\n }\n\n componentWillReceiveProps(nextProps) {\n let { getConfigs } = nextProps\n let { validatorUrl } = getConfigs()\n\n this.setState({\n url: this.getDefinitionUrl(),\n validatorUrl: validatorUrl === undefined ? \"https://validator.swagger.io/validator\" : validatorUrl\n })\n }\n\n render() {\n let { getConfigs } = this.props\n let { spec } = getConfigs()\n\n let sanitizedValidatorUrl = sanitizeUrl(this.state.validatorUrl)\n\n if ( typeof spec === \"object\" && Object.keys(spec).length) return null\n\n if (!this.state.url || !this.state.validatorUrl || this.state.url.indexOf(\"localhost\") >= 0\n || this.state.url.indexOf(\"127.0.0.1\") >= 0) {\n return null\n }\n\n return (\n
\n \n \n )\n }\n}\n\n\nclass ValidatorImage extends React.Component {\n static propTypes = {\n src: PropTypes.string,\n alt: PropTypes.string\n }\n\n constructor(props) {\n super(props)\n this.state = {\n loaded: false,\n error: false\n }\n }\n\n componentDidMount() {\n const img = new Image()\n img.onload = () => {\n this.setState({\n loaded: true\n })\n }\n img.onerror = () => {\n this.setState({\n error: true\n })\n }\n img.src = this.props.src\n }\n\n componentWillReceiveProps(nextProps) {\n if (nextProps.src !== this.props.src) {\n const img = new Image()\n img.onload = () => {\n this.setState({\n loaded: true\n })\n }\n img.onerror = () => {\n this.setState({\n error: true\n })\n }\n img.src = nextProps.src\n }\n }\n\n render() {\n if (this.state.error) {\n return {\"Error\"}\n } else if (!this.state.loaded) {\n return null\n }\n return {this.props.alt}\n }\n}\n","var textarea;\n\nfunction decodeEntity(name) {\n textarea = textarea || document.createElement('textarea');\n textarea.innerHTML = '&' + name + ';';\n return textarea.value;\n}\n\n/**\n * Utility functions\n */\n\nfunction typeOf(obj) {\n return Object.prototype.toString.call(obj);\n}\n\nfunction isString(obj) {\n return typeOf(obj) === '[object String]';\n}\n\nvar hasOwn = Object.prototype.hasOwnProperty;\n\nfunction has(object, key) {\n return object\n ? hasOwn.call(object, key)\n : false;\n}\n\n// Extend objects\n//\nfunction assign(obj /*from1, from2, from3, ...*/) {\n var sources = [].slice.call(arguments, 1);\n\n sources.forEach(function (source) {\n if (!source) { return; }\n\n if (typeof source !== 'object') {\n throw new TypeError(source + 'must be object');\n }\n\n Object.keys(source).forEach(function (key) {\n obj[key] = source[key];\n });\n });\n\n return obj;\n}\n\n////////////////////////////////////////////////////////////////////////////////\n\nvar UNESCAPE_MD_RE = /\\\\([\\\\!\"#$%&'()*+,.\\/:;<=>?@[\\]^_`{|}~-])/g;\n\nfunction unescapeMd(str) {\n if (str.indexOf('\\\\') < 0) { return str; }\n return str.replace(UNESCAPE_MD_RE, '$1');\n}\n\n////////////////////////////////////////////////////////////////////////////////\n\nfunction isValidEntityCode(c) {\n /*eslint no-bitwise:0*/\n // broken sequence\n if (c >= 0xD800 && c <= 0xDFFF) { return false; }\n // never used\n if (c >= 0xFDD0 && c <= 0xFDEF) { return false; }\n if ((c & 0xFFFF) === 0xFFFF || (c & 0xFFFF) === 0xFFFE) { return false; }\n // control codes\n if (c >= 0x00 && c <= 0x08) { return false; }\n if (c === 0x0B) { return false; }\n if (c >= 0x0E && c <= 0x1F) { return false; }\n if (c >= 0x7F && c <= 0x9F) { return false; }\n // out of range\n if (c > 0x10FFFF) { return false; }\n return true;\n}\n\nfunction fromCodePoint(c) {\n /*eslint no-bitwise:0*/\n if (c > 0xffff) {\n c -= 0x10000;\n var surrogate1 = 0xd800 + (c >> 10),\n surrogate2 = 0xdc00 + (c & 0x3ff);\n\n return String.fromCharCode(surrogate1, surrogate2);\n }\n return String.fromCharCode(c);\n}\n\nvar NAMED_ENTITY_RE = /&([a-z#][a-z0-9]{1,31});/gi;\nvar DIGITAL_ENTITY_TEST_RE = /^#((?:x[a-f0-9]{1,8}|[0-9]{1,8}))/i;\n\nfunction replaceEntityPattern(match, name) {\n var code = 0;\n var decoded = decodeEntity(name);\n\n if (name !== decoded) {\n return decoded;\n } else if (name.charCodeAt(0) === 0x23/* # */ && DIGITAL_ENTITY_TEST_RE.test(name)) {\n code = name[1].toLowerCase() === 'x' ?\n parseInt(name.slice(2), 16)\n :\n parseInt(name.slice(1), 10);\n if (isValidEntityCode(code)) {\n return fromCodePoint(code);\n }\n }\n return match;\n}\n\nfunction replaceEntities(str) {\n if (str.indexOf('&') < 0) { return str; }\n\n return str.replace(NAMED_ENTITY_RE, replaceEntityPattern);\n}\n\n////////////////////////////////////////////////////////////////////////////////\n\nvar HTML_ESCAPE_TEST_RE = /[&<>\"]/;\nvar HTML_ESCAPE_REPLACE_RE = /[&<>\"]/g;\nvar HTML_REPLACEMENTS = {\n '&': '&',\n '<': '<',\n '>': '>',\n '\"': '"'\n};\n\nfunction replaceUnsafeChar(ch) {\n return HTML_REPLACEMENTS[ch];\n}\n\nfunction escapeHtml(str) {\n if (HTML_ESCAPE_TEST_RE.test(str)) {\n return str.replace(HTML_ESCAPE_REPLACE_RE, replaceUnsafeChar);\n }\n return str;\n}\n\nvar utils = /*#__PURE__*/Object.freeze({\n isString: isString,\n has: has,\n assign: assign,\n unescapeMd: unescapeMd,\n isValidEntityCode: isValidEntityCode,\n fromCodePoint: fromCodePoint,\n replaceEntities: replaceEntities,\n escapeHtml: escapeHtml\n});\n\n/**\n * Renderer rules cache\n */\n\nvar rules = {};\n\n/**\n * Blockquotes\n */\n\nrules.blockquote_open = function(/* tokens, idx, options, env */) {\n return '
\\n';\n};\n\nrules.blockquote_close = function(tokens, idx /*, options, env */) {\n return '
' + getBreak(tokens, idx);\n};\n\n/**\n * Code\n */\n\nrules.code = function(tokens, idx /*, options, env */) {\n if (tokens[idx].block) {\n return '
' + escapeHtml(tokens[idx].content) + '
' + getBreak(tokens, idx);\n }\n return '' + escapeHtml(tokens[idx].content) + '';\n};\n\n/**\n * Fenced code blocks\n */\n\nrules.fence = function(tokens, idx, options, env, instance) {\n var token = tokens[idx];\n var langClass = '';\n var langPrefix = options.langPrefix;\n var langName = '', fences, fenceName;\n var highlighted;\n\n if (token.params) {\n\n //\n // ```foo bar\n //\n // Try custom renderer \"foo\" first. That will simplify overwrite\n // for diagrams, latex, and any other fenced block with custom look\n //\n\n fences = token.params.split(/\\s+/g);\n fenceName = fences.join(' ');\n\n if (has(instance.rules.fence_custom, fences[0])) {\n return instance.rules.fence_custom[fences[0]](tokens, idx, options, env, instance);\n }\n\n langName = escapeHtml(replaceEntities(unescapeMd(fenceName)));\n langClass = ' class=\"' + langPrefix + langName + '\"';\n }\n\n if (options.highlight) {\n highlighted = options.highlight.apply(options.highlight, [ token.content ].concat(fences))\n || escapeHtml(token.content);\n } else {\n highlighted = escapeHtml(token.content);\n }\n\n return '
'\n        + highlighted\n        + '
'\n + getBreak(tokens, idx);\n};\n\nrules.fence_custom = {};\n\n/**\n * Headings\n */\n\nrules.heading_open = function(tokens, idx /*, options, env */) {\n return '';\n};\nrules.heading_close = function(tokens, idx /*, options, env */) {\n return '\\n';\n};\n\n/**\n * Horizontal rules\n */\n\nrules.hr = function(tokens, idx, options /*, env */) {\n return (options.xhtmlOut ? '
' : '
') + getBreak(tokens, idx);\n};\n\n/**\n * Bullets\n */\n\nrules.bullet_list_open = function(/* tokens, idx, options, env */) {\n return '
    \\n';\n};\nrules.bullet_list_close = function(tokens, idx /*, options, env */) {\n return '
' + getBreak(tokens, idx);\n};\n\n/**\n * List items\n */\n\nrules.list_item_open = function(/* tokens, idx, options, env */) {\n return '
  • ';\n};\nrules.list_item_close = function(/* tokens, idx, options, env */) {\n return '
  • \\n';\n};\n\n/**\n * Ordered list items\n */\n\nrules.ordered_list_open = function(tokens, idx /*, options, env */) {\n var token = tokens[idx];\n var order = token.order > 1 ? ' start=\"' + token.order + '\"' : '';\n return '\\n';\n};\nrules.ordered_list_close = function(tokens, idx /*, options, env */) {\n return '' + getBreak(tokens, idx);\n};\n\n/**\n * Paragraphs\n */\n\nrules.paragraph_open = function(tokens, idx /*, options, env */) {\n return tokens[idx].tight ? '' : '

    ';\n};\nrules.paragraph_close = function(tokens, idx /*, options, env */) {\n var addBreak = !(tokens[idx].tight && idx && tokens[idx - 1].type === 'inline' && !tokens[idx - 1].content);\n return (tokens[idx].tight ? '' : '

    ') + (addBreak ? getBreak(tokens, idx) : '');\n};\n\n/**\n * Links\n */\n\nrules.link_open = function(tokens, idx, options /* env */) {\n var title = tokens[idx].title ? (' title=\"' + escapeHtml(replaceEntities(tokens[idx].title)) + '\"') : '';\n var target = options.linkTarget ? (' target=\"' + options.linkTarget + '\"') : '';\n return '';\n};\nrules.link_close = function(/* tokens, idx, options, env */) {\n return '';\n};\n\n/**\n * Images\n */\n\nrules.image = function(tokens, idx, options /*, env */) {\n var src = ' src=\"' + escapeHtml(tokens[idx].src) + '\"';\n var title = tokens[idx].title ? (' title=\"' + escapeHtml(replaceEntities(tokens[idx].title)) + '\"') : '';\n var alt = ' alt=\"' + (tokens[idx].alt ? escapeHtml(replaceEntities(unescapeMd(tokens[idx].alt))) : '') + '\"';\n var suffix = options.xhtmlOut ? ' /' : '';\n return '';\n};\n\n/**\n * Tables\n */\n\nrules.table_open = function(/* tokens, idx, options, env */) {\n return '\\n';\n};\nrules.table_close = function(/* tokens, idx, options, env */) {\n return '
    \\n';\n};\nrules.thead_open = function(/* tokens, idx, options, env */) {\n return '\\n';\n};\nrules.thead_close = function(/* tokens, idx, options, env */) {\n return '\\n';\n};\nrules.tbody_open = function(/* tokens, idx, options, env */) {\n return '\\n';\n};\nrules.tbody_close = function(/* tokens, idx, options, env */) {\n return '\\n';\n};\nrules.tr_open = function(/* tokens, idx, options, env */) {\n return '';\n};\nrules.tr_close = function(/* tokens, idx, options, env */) {\n return '\\n';\n};\nrules.th_open = function(tokens, idx /*, options, env */) {\n var token = tokens[idx];\n return '';\n};\nrules.th_close = function(/* tokens, idx, options, env */) {\n return '';\n};\nrules.td_open = function(tokens, idx /*, options, env */) {\n var token = tokens[idx];\n return '';\n};\nrules.td_close = function(/* tokens, idx, options, env */) {\n return '';\n};\n\n/**\n * Bold\n */\n\nrules.strong_open = function(/* tokens, idx, options, env */) {\n return '';\n};\nrules.strong_close = function(/* tokens, idx, options, env */) {\n return '';\n};\n\n/**\n * Italicize\n */\n\nrules.em_open = function(/* tokens, idx, options, env */) {\n return '';\n};\nrules.em_close = function(/* tokens, idx, options, env */) {\n return '';\n};\n\n/**\n * Strikethrough\n */\n\nrules.del_open = function(/* tokens, idx, options, env */) {\n return '';\n};\nrules.del_close = function(/* tokens, idx, options, env */) {\n return '';\n};\n\n/**\n * Insert\n */\n\nrules.ins_open = function(/* tokens, idx, options, env */) {\n return '';\n};\nrules.ins_close = function(/* tokens, idx, options, env */) {\n return '';\n};\n\n/**\n * Highlight\n */\n\nrules.mark_open = function(/* tokens, idx, options, env */) {\n return '';\n};\nrules.mark_close = function(/* tokens, idx, options, env */) {\n return '';\n};\n\n/**\n * Super- and sub-script\n */\n\nrules.sub = function(tokens, idx /*, options, env */) {\n return '' + escapeHtml(tokens[idx].content) + '';\n};\nrules.sup = function(tokens, idx /*, options, env */) {\n return '' + escapeHtml(tokens[idx].content) + '';\n};\n\n/**\n * Breaks\n */\n\nrules.hardbreak = function(tokens, idx, options /*, env */) {\n return options.xhtmlOut ? '
    \\n' : '
    \\n';\n};\nrules.softbreak = function(tokens, idx, options /*, env */) {\n return options.breaks ? (options.xhtmlOut ? '
    \\n' : '
    \\n') : '\\n';\n};\n\n/**\n * Text\n */\n\nrules.text = function(tokens, idx /*, options, env */) {\n return escapeHtml(tokens[idx].content);\n};\n\n/**\n * Content\n */\n\nrules.htmlblock = function(tokens, idx /*, options, env */) {\n return tokens[idx].content;\n};\nrules.htmltag = function(tokens, idx /*, options, env */) {\n return tokens[idx].content;\n};\n\n/**\n * Abbreviations, initialism\n */\n\nrules.abbr_open = function(tokens, idx /*, options, env */) {\n return '';\n};\nrules.abbr_close = function(/* tokens, idx, options, env */) {\n return '';\n};\n\n/**\n * Footnotes\n */\n\nrules.footnote_ref = function(tokens, idx) {\n var n = Number(tokens[idx].id + 1).toString();\n var id = 'fnref' + n;\n if (tokens[idx].subId > 0) {\n id += ':' + tokens[idx].subId;\n }\n return '[' + n + ']';\n};\nrules.footnote_block_open = function(tokens, idx, options) {\n var hr = options.xhtmlOut\n ? '
    \\n'\n : '
    \\n';\n return hr + '
    \\n
      \\n';\n};\nrules.footnote_block_close = function() {\n return '
    \\n
    \\n';\n};\nrules.footnote_open = function(tokens, idx) {\n var id = Number(tokens[idx].id + 1).toString();\n return '
  • ';\n};\nrules.footnote_close = function() {\n return '
  • \\n';\n};\nrules.footnote_anchor = function(tokens, idx) {\n var n = Number(tokens[idx].id + 1).toString();\n var id = 'fnref' + n;\n if (tokens[idx].subId > 0) {\n id += ':' + tokens[idx].subId;\n }\n return ' ';\n};\n\n/**\n * Definition lists\n */\n\nrules.dl_open = function() {\n return '
    \\n';\n};\nrules.dt_open = function() {\n return '
    ';\n};\nrules.dd_open = function() {\n return '
    ';\n};\nrules.dl_close = function() {\n return '
    \\n';\n};\nrules.dt_close = function() {\n return '\\n';\n};\nrules.dd_close = function() {\n return '\\n';\n};\n\n/**\n * Helper functions\n */\n\nfunction nextToken(tokens, idx) {\n if (++idx >= tokens.length - 2) {\n return idx;\n }\n if ((tokens[idx].type === 'paragraph_open' && tokens[idx].tight) &&\n (tokens[idx + 1].type === 'inline' && tokens[idx + 1].content.length === 0) &&\n (tokens[idx + 2].type === 'paragraph_close' && tokens[idx + 2].tight)) {\n return nextToken(tokens, idx + 2);\n }\n return idx;\n}\n\n/**\n * Check to see if `\\n` is needed before the next token.\n *\n * @param {Array} `tokens`\n * @param {Number} `idx`\n * @return {String} Empty string or newline\n * @api private\n */\n\nvar getBreak = rules.getBreak = function getBreak(tokens, idx) {\n idx = nextToken(tokens, idx);\n if (idx < tokens.length && tokens[idx].type === 'list_item_close') {\n return '';\n }\n return '\\n';\n};\n\n/**\n * Renderer class. Renders HTML and exposes `rules` to allow\n * local modifications.\n */\n\nfunction Renderer() {\n this.rules = assign({}, rules);\n\n // exported helper, for custom rules only\n this.getBreak = rules.getBreak;\n}\n\n/**\n * Render a string of inline HTML with the given `tokens` and\n * `options`.\n *\n * @param {Array} `tokens`\n * @param {Object} `options`\n * @param {Object} `env`\n * @return {String}\n * @api public\n */\n\nRenderer.prototype.renderInline = function (tokens, options, env) {\n var _rules = this.rules;\n var len = tokens.length, i = 0;\n var result = '';\n\n while (len--) {\n result += _rules[tokens[i].type](tokens, i++, options, env, this);\n }\n\n return result;\n};\n\n/**\n * Render a string of HTML with the given `tokens` and\n * `options`.\n *\n * @param {Array} `tokens`\n * @param {Object} `options`\n * @param {Object} `env`\n * @return {String}\n * @api public\n */\n\nRenderer.prototype.render = function (tokens, options, env) {\n var _rules = this.rules;\n var len = tokens.length, i = -1;\n var result = '';\n\n while (++i < len) {\n if (tokens[i].type === 'inline') {\n result += this.renderInline(tokens[i].children, options, env);\n } else {\n result += _rules[tokens[i].type](tokens, i, options, env, this);\n }\n }\n return result;\n};\n\n/**\n * Ruler is a helper class for building responsibility chains from\n * parse rules. It allows:\n *\n * - easy stack rules chains\n * - getting main chain and named chains content (as arrays of functions)\n *\n * Helper methods, should not be used directly.\n * @api private\n */\n\nfunction Ruler() {\n // List of added rules. Each element is:\n //\n // { name: XXX,\n // enabled: Boolean,\n // fn: Function(),\n // alt: [ name2, name3 ] }\n //\n this.__rules__ = [];\n\n // Cached rule chains.\n //\n // First level - chain name, '' for default.\n // Second level - digital anchor for fast filtering by charcodes.\n //\n this.__cache__ = null;\n}\n\n/**\n * Find the index of a rule by `name`.\n *\n * @param {String} `name`\n * @return {Number} Index of the given `name`\n * @api private\n */\n\nRuler.prototype.__find__ = function (name) {\n var len = this.__rules__.length;\n var i = -1;\n\n while (len--) {\n if (this.__rules__[++i].name === name) {\n return i;\n }\n }\n return -1;\n};\n\n/**\n * Build the rules lookup cache\n *\n * @api private\n */\n\nRuler.prototype.__compile__ = function () {\n var self = this;\n var chains = [ '' ];\n\n // collect unique names\n self.__rules__.forEach(function (rule) {\n if (!rule.enabled) {\n return;\n }\n\n rule.alt.forEach(function (altName) {\n if (chains.indexOf(altName) < 0) {\n chains.push(altName);\n }\n });\n });\n\n self.__cache__ = {};\n\n chains.forEach(function (chain) {\n self.__cache__[chain] = [];\n self.__rules__.forEach(function (rule) {\n if (!rule.enabled) {\n return;\n }\n\n if (chain && rule.alt.indexOf(chain) < 0) {\n return;\n }\n self.__cache__[chain].push(rule.fn);\n });\n });\n};\n\n/**\n * Ruler public methods\n * ------------------------------------------------\n */\n\n/**\n * Replace rule function\n *\n * @param {String} `name` Rule name\n * @param {Function `fn`\n * @param {Object} `options`\n * @api private\n */\n\nRuler.prototype.at = function (name, fn, options) {\n var idx = this.__find__(name);\n var opt = options || {};\n\n if (idx === -1) {\n throw new Error('Parser rule not found: ' + name);\n }\n\n this.__rules__[idx].fn = fn;\n this.__rules__[idx].alt = opt.alt || [];\n this.__cache__ = null;\n};\n\n/**\n * Add a rule to the chain before given the `ruleName`.\n *\n * @param {String} `beforeName`\n * @param {String} `ruleName`\n * @param {Function} `fn`\n * @param {Object} `options`\n * @api private\n */\n\nRuler.prototype.before = function (beforeName, ruleName, fn, options) {\n var idx = this.__find__(beforeName);\n var opt = options || {};\n\n if (idx === -1) {\n throw new Error('Parser rule not found: ' + beforeName);\n }\n\n this.__rules__.splice(idx, 0, {\n name: ruleName,\n enabled: true,\n fn: fn,\n alt: opt.alt || []\n });\n\n this.__cache__ = null;\n};\n\n/**\n * Add a rule to the chain after the given `ruleName`.\n *\n * @param {String} `afterName`\n * @param {String} `ruleName`\n * @param {Function} `fn`\n * @param {Object} `options`\n * @api private\n */\n\nRuler.prototype.after = function (afterName, ruleName, fn, options) {\n var idx = this.__find__(afterName);\n var opt = options || {};\n\n if (idx === -1) {\n throw new Error('Parser rule not found: ' + afterName);\n }\n\n this.__rules__.splice(idx + 1, 0, {\n name: ruleName,\n enabled: true,\n fn: fn,\n alt: opt.alt || []\n });\n\n this.__cache__ = null;\n};\n\n/**\n * Add a rule to the end of chain.\n *\n * @param {String} `ruleName`\n * @param {Function} `fn`\n * @param {Object} `options`\n * @return {String}\n */\n\nRuler.prototype.push = function (ruleName, fn, options) {\n var opt = options || {};\n\n this.__rules__.push({\n name: ruleName,\n enabled: true,\n fn: fn,\n alt: opt.alt || []\n });\n\n this.__cache__ = null;\n};\n\n/**\n * Enable a rule or list of rules.\n *\n * @param {String|Array} `list` Name or array of rule names to enable\n * @param {Boolean} `strict` If `true`, all non listed rules will be disabled.\n * @api private\n */\n\nRuler.prototype.enable = function (list, strict) {\n list = !Array.isArray(list)\n ? [ list ]\n : list;\n\n // In strict mode disable all existing rules first\n if (strict) {\n this.__rules__.forEach(function (rule) {\n rule.enabled = false;\n });\n }\n\n // Search by name and enable\n list.forEach(function (name) {\n var idx = this.__find__(name);\n if (idx < 0) {\n throw new Error('Rules manager: invalid rule name ' + name);\n }\n this.__rules__[idx].enabled = true;\n }, this);\n\n this.__cache__ = null;\n};\n\n\n/**\n * Disable a rule or list of rules.\n *\n * @param {String|Array} `list` Name or array of rule names to disable\n * @api private\n */\n\nRuler.prototype.disable = function (list) {\n list = !Array.isArray(list)\n ? [ list ]\n : list;\n\n // Search by name and disable\n list.forEach(function (name) {\n var idx = this.__find__(name);\n if (idx < 0) {\n throw new Error('Rules manager: invalid rule name ' + name);\n }\n this.__rules__[idx].enabled = false;\n }, this);\n\n this.__cache__ = null;\n};\n\n/**\n * Get a rules list as an array of functions.\n *\n * @param {String} `chainName`\n * @return {Object}\n * @api private\n */\n\nRuler.prototype.getRules = function (chainName) {\n if (this.__cache__ === null) {\n this.__compile__();\n }\n return this.__cache__[chainName] || [];\n};\n\nfunction block(state) {\n\n if (state.inlineMode) {\n state.tokens.push({\n type: 'inline',\n content: state.src.replace(/\\n/g, ' ').trim(),\n level: 0,\n lines: [ 0, 1 ],\n children: []\n });\n\n } else {\n state.block.parse(state.src, state.options, state.env, state.tokens);\n }\n}\n\n// Inline parser state\n\nfunction StateInline(src, parserInline, options, env, outTokens) {\n this.src = src;\n this.env = env;\n this.options = options;\n this.parser = parserInline;\n this.tokens = outTokens;\n this.pos = 0;\n this.posMax = this.src.length;\n this.level = 0;\n this.pending = '';\n this.pendingLevel = 0;\n\n this.cache = []; // Stores { start: end } pairs. Useful for backtrack\n // optimization of pairs parse (emphasis, strikes).\n\n // Link parser state vars\n\n this.isInLabel = false; // Set true when seek link label - we should disable\n // \"paired\" rules (emphasis, strikes) to not skip\n // tailing `]`\n\n this.linkLevel = 0; // Increment for each nesting link. Used to prevent\n // nesting in definitions\n\n this.linkContent = ''; // Temporary storage for link url\n\n this.labelUnmatchedScopes = 0; // Track unpaired `[` for link labels\n // (backtrack optimization)\n}\n\n// Flush pending text\n//\nStateInline.prototype.pushPending = function () {\n this.tokens.push({\n type: 'text',\n content: this.pending,\n level: this.pendingLevel\n });\n this.pending = '';\n};\n\n// Push new token to \"stream\".\n// If pending text exists - flush it as text token\n//\nStateInline.prototype.push = function (token) {\n if (this.pending) {\n this.pushPending();\n }\n\n this.tokens.push(token);\n this.pendingLevel = this.level;\n};\n\n// Store value to cache.\n// !!! Implementation has parser-specific optimizations\n// !!! keys MUST be integer, >= 0; values MUST be integer, > 0\n//\nStateInline.prototype.cacheSet = function (key, val) {\n for (var i = this.cache.length; i <= key; i++) {\n this.cache.push(0);\n }\n\n this.cache[key] = val;\n};\n\n// Get cache value\n//\nStateInline.prototype.cacheGet = function (key) {\n return key < this.cache.length ? this.cache[key] : 0;\n};\n\n/**\n * Parse link labels\n *\n * This function assumes that first character (`[`) already matches;\n * returns the end of the label.\n *\n * @param {Object} state\n * @param {Number} start\n * @api private\n */\n\nfunction parseLinkLabel(state, start) {\n var level, found, marker,\n labelEnd = -1,\n max = state.posMax,\n oldPos = state.pos,\n oldFlag = state.isInLabel;\n\n if (state.isInLabel) { return -1; }\n\n if (state.labelUnmatchedScopes) {\n state.labelUnmatchedScopes--;\n return -1;\n }\n\n state.pos = start + 1;\n state.isInLabel = true;\n level = 1;\n\n while (state.pos < max) {\n marker = state.src.charCodeAt(state.pos);\n if (marker === 0x5B /* [ */) {\n level++;\n } else if (marker === 0x5D /* ] */) {\n level--;\n if (level === 0) {\n found = true;\n break;\n }\n }\n\n state.parser.skipToken(state);\n }\n\n if (found) {\n labelEnd = state.pos;\n state.labelUnmatchedScopes = 0;\n } else {\n state.labelUnmatchedScopes = level - 1;\n }\n\n // restore old state\n state.pos = oldPos;\n state.isInLabel = oldFlag;\n\n return labelEnd;\n}\n\n// Parse abbreviation definitions, i.e. `*[abbr]: description`\n\n\nfunction parseAbbr(str, parserInline, options, env) {\n var state, labelEnd, pos, max, label, title;\n\n if (str.charCodeAt(0) !== 0x2A/* * */) { return -1; }\n if (str.charCodeAt(1) !== 0x5B/* [ */) { return -1; }\n\n if (str.indexOf(']:') === -1) { return -1; }\n\n state = new StateInline(str, parserInline, options, env, []);\n labelEnd = parseLinkLabel(state, 1);\n\n if (labelEnd < 0 || str.charCodeAt(labelEnd + 1) !== 0x3A/* : */) { return -1; }\n\n max = state.posMax;\n\n // abbr title is always one line, so looking for ending \"\\n\" here\n for (pos = labelEnd + 2; pos < max; pos++) {\n if (state.src.charCodeAt(pos) === 0x0A) { break; }\n }\n\n label = str.slice(2, labelEnd);\n title = str.slice(labelEnd + 2, pos).trim();\n if (title.length === 0) { return -1; }\n if (!env.abbreviations) { env.abbreviations = {}; }\n // prepend ':' to avoid conflict with Object.prototype members\n if (typeof env.abbreviations[':' + label] === 'undefined') {\n env.abbreviations[':' + label] = title;\n }\n\n return pos;\n}\n\nfunction abbr(state) {\n var tokens = state.tokens, i, l, content, pos;\n\n if (state.inlineMode) {\n return;\n }\n\n // Parse inlines\n for (i = 1, l = tokens.length - 1; i < l; i++) {\n if (tokens[i - 1].type === 'paragraph_open' &&\n tokens[i].type === 'inline' &&\n tokens[i + 1].type === 'paragraph_close') {\n\n content = tokens[i].content;\n while (content.length) {\n pos = parseAbbr(content, state.inline, state.options, state.env);\n if (pos < 0) { break; }\n content = content.slice(pos).trim();\n }\n\n tokens[i].content = content;\n if (!content.length) {\n tokens[i - 1].tight = true;\n tokens[i + 1].tight = true;\n }\n }\n }\n}\n\nfunction normalizeLink(url) {\n var normalized = replaceEntities(url);\n // We shouldn't care about the result of malformed URIs,\n // and should not throw an exception.\n try {\n normalized = decodeURI(normalized);\n } catch (err) {}\n return encodeURI(normalized);\n}\n\n/**\n * Parse link destination\n *\n * - on success it returns a string and updates state.pos;\n * - on failure it returns null\n *\n * @param {Object} state\n * @param {Number} pos\n * @api private\n */\n\nfunction parseLinkDestination(state, pos) {\n var code, level, link,\n start = pos,\n max = state.posMax;\n\n if (state.src.charCodeAt(pos) === 0x3C /* < */) {\n pos++;\n while (pos < max) {\n code = state.src.charCodeAt(pos);\n if (code === 0x0A /* \\n */) { return false; }\n if (code === 0x3E /* > */) {\n link = normalizeLink(unescapeMd(state.src.slice(start + 1, pos)));\n if (!state.parser.validateLink(link)) { return false; }\n state.pos = pos + 1;\n state.linkContent = link;\n return true;\n }\n if (code === 0x5C /* \\ */ && pos + 1 < max) {\n pos += 2;\n continue;\n }\n\n pos++;\n }\n\n // no closing '>'\n return false;\n }\n\n // this should be ... } else { ... branch\n\n level = 0;\n while (pos < max) {\n code = state.src.charCodeAt(pos);\n\n if (code === 0x20) { break; }\n\n // ascii control chars\n if (code < 0x20 || code === 0x7F) { break; }\n\n if (code === 0x5C /* \\ */ && pos + 1 < max) {\n pos += 2;\n continue;\n }\n\n if (code === 0x28 /* ( */) {\n level++;\n if (level > 1) { break; }\n }\n\n if (code === 0x29 /* ) */) {\n level--;\n if (level < 0) { break; }\n }\n\n pos++;\n }\n\n if (start === pos) { return false; }\n\n link = unescapeMd(state.src.slice(start, pos));\n if (!state.parser.validateLink(link)) { return false; }\n\n state.linkContent = link;\n state.pos = pos;\n return true;\n}\n\n/**\n * Parse link title\n *\n * - on success it returns a string and updates state.pos;\n * - on failure it returns null\n *\n * @param {Object} state\n * @param {Number} pos\n * @api private\n */\n\nfunction parseLinkTitle(state, pos) {\n var code,\n start = pos,\n max = state.posMax,\n marker = state.src.charCodeAt(pos);\n\n if (marker !== 0x22 /* \" */ && marker !== 0x27 /* ' */ && marker !== 0x28 /* ( */) { return false; }\n\n pos++;\n\n // if opening marker is \"(\", switch it to closing marker \")\"\n if (marker === 0x28) { marker = 0x29; }\n\n while (pos < max) {\n code = state.src.charCodeAt(pos);\n if (code === marker) {\n state.pos = pos + 1;\n state.linkContent = unescapeMd(state.src.slice(start + 1, pos));\n return true;\n }\n if (code === 0x5C /* \\ */ && pos + 1 < max) {\n pos += 2;\n continue;\n }\n\n pos++;\n }\n\n return false;\n}\n\nfunction normalizeReference(str) {\n // use .toUpperCase() instead of .toLowerCase()\n // here to avoid a conflict with Object.prototype\n // members (most notably, `__proto__`)\n return str.trim().replace(/\\s+/g, ' ').toUpperCase();\n}\n\nfunction parseReference(str, parser, options, env) {\n var state, labelEnd, pos, max, code, start, href, title, label;\n\n if (str.charCodeAt(0) !== 0x5B/* [ */) { return -1; }\n\n if (str.indexOf(']:') === -1) { return -1; }\n\n state = new StateInline(str, parser, options, env, []);\n labelEnd = parseLinkLabel(state, 0);\n\n if (labelEnd < 0 || str.charCodeAt(labelEnd + 1) !== 0x3A/* : */) { return -1; }\n\n max = state.posMax;\n\n // [label]: destination 'title'\n // ^^^ skip optional whitespace here\n for (pos = labelEnd + 2; pos < max; pos++) {\n code = state.src.charCodeAt(pos);\n if (code !== 0x20 && code !== 0x0A) { break; }\n }\n\n // [label]: destination 'title'\n // ^^^^^^^^^^^ parse this\n if (!parseLinkDestination(state, pos)) { return -1; }\n href = state.linkContent;\n pos = state.pos;\n\n // [label]: destination 'title'\n // ^^^ skipping those spaces\n start = pos;\n for (pos = pos + 1; pos < max; pos++) {\n code = state.src.charCodeAt(pos);\n if (code !== 0x20 && code !== 0x0A) { break; }\n }\n\n // [label]: destination 'title'\n // ^^^^^^^ parse this\n if (pos < max && start !== pos && parseLinkTitle(state, pos)) {\n title = state.linkContent;\n pos = state.pos;\n } else {\n title = '';\n pos = start;\n }\n\n // ensure that the end of the line is empty\n while (pos < max && state.src.charCodeAt(pos) === 0x20/* space */) { pos++; }\n if (pos < max && state.src.charCodeAt(pos) !== 0x0A) { return -1; }\n\n label = normalizeReference(str.slice(1, labelEnd));\n if (typeof env.references[label] === 'undefined') {\n env.references[label] = { title: title, href: href };\n }\n\n return pos;\n}\n\n\nfunction references(state) {\n var tokens = state.tokens, i, l, content, pos;\n\n state.env.references = state.env.references || {};\n\n if (state.inlineMode) {\n return;\n }\n\n // Scan definitions in paragraph inlines\n for (i = 1, l = tokens.length - 1; i < l; i++) {\n if (tokens[i].type === 'inline' &&\n tokens[i - 1].type === 'paragraph_open' &&\n tokens[i + 1].type === 'paragraph_close') {\n\n content = tokens[i].content;\n while (content.length) {\n pos = parseReference(content, state.inline, state.options, state.env);\n if (pos < 0) { break; }\n content = content.slice(pos).trim();\n }\n\n tokens[i].content = content;\n if (!content.length) {\n tokens[i - 1].tight = true;\n tokens[i + 1].tight = true;\n }\n }\n }\n}\n\nfunction inline(state) {\n var tokens = state.tokens, tok, i, l;\n\n // Parse inlines\n for (i = 0, l = tokens.length; i < l; i++) {\n tok = tokens[i];\n if (tok.type === 'inline') {\n state.inline.parse(tok.content, state.options, state.env, tok.children);\n }\n }\n}\n\nfunction footnote_block(state) {\n var i, l, j, t, lastParagraph, list, tokens, current, currentLabel,\n level = 0,\n insideRef = false,\n refTokens = {};\n\n if (!state.env.footnotes) { return; }\n\n state.tokens = state.tokens.filter(function(tok) {\n if (tok.type === 'footnote_reference_open') {\n insideRef = true;\n current = [];\n currentLabel = tok.label;\n return false;\n }\n if (tok.type === 'footnote_reference_close') {\n insideRef = false;\n // prepend ':' to avoid conflict with Object.prototype members\n refTokens[':' + currentLabel] = current;\n return false;\n }\n if (insideRef) { current.push(tok); }\n return !insideRef;\n });\n\n if (!state.env.footnotes.list) { return; }\n list = state.env.footnotes.list;\n\n state.tokens.push({\n type: 'footnote_block_open',\n level: level++\n });\n for (i = 0, l = list.length; i < l; i++) {\n state.tokens.push({\n type: 'footnote_open',\n id: i,\n level: level++\n });\n\n if (list[i].tokens) {\n tokens = [];\n tokens.push({\n type: 'paragraph_open',\n tight: false,\n level: level++\n });\n tokens.push({\n type: 'inline',\n content: '',\n level: level,\n children: list[i].tokens\n });\n tokens.push({\n type: 'paragraph_close',\n tight: false,\n level: --level\n });\n } else if (list[i].label) {\n tokens = refTokens[':' + list[i].label];\n }\n\n state.tokens = state.tokens.concat(tokens);\n if (state.tokens[state.tokens.length - 1].type === 'paragraph_close') {\n lastParagraph = state.tokens.pop();\n } else {\n lastParagraph = null;\n }\n\n t = list[i].count > 0 ? list[i].count : 1;\n for (j = 0; j < t; j++) {\n state.tokens.push({\n type: 'footnote_anchor',\n id: i,\n subId: j,\n level: level\n });\n }\n\n if (lastParagraph) {\n state.tokens.push(lastParagraph);\n }\n\n state.tokens.push({\n type: 'footnote_close',\n level: --level\n });\n }\n state.tokens.push({\n type: 'footnote_block_close',\n level: --level\n });\n}\n\n// Enclose abbreviations in tags\n//\n\nvar PUNCT_CHARS = ' \\n()[]\\'\".,!?-';\n\n\n// from Google closure library\n// http://closure-library.googlecode.com/git-history/docs/local_closure_goog_string_string.js.source.html#line1021\nfunction regEscape(s) {\n return s.replace(/([-()\\[\\]{}+?*.$\\^|,:#= 0; i--) {\n token = tokens[i];\n if (token.type !== 'text') { continue; }\n\n pos = 0;\n text = token.content;\n reg.lastIndex = 0;\n level = token.level;\n nodes = [];\n\n while ((m = reg.exec(text))) {\n if (reg.lastIndex > pos) {\n nodes.push({\n type: 'text',\n content: text.slice(pos, m.index + m[1].length),\n level: level\n });\n }\n\n nodes.push({\n type: 'abbr_open',\n title: state.env.abbreviations[':' + m[2]],\n level: level++\n });\n nodes.push({\n type: 'text',\n content: m[2],\n level: level\n });\n nodes.push({\n type: 'abbr_close',\n level: --level\n });\n pos = reg.lastIndex - m[3].length;\n }\n\n if (!nodes.length) { continue; }\n\n if (pos < text.length) {\n nodes.push({\n type: 'text',\n content: text.slice(pos),\n level: level\n });\n }\n\n // replace current node\n blockTokens[j].children = tokens = [].concat(tokens.slice(0, i), nodes, tokens.slice(i + 1));\n }\n }\n}\n\n// Simple typographical replacements\n//\n// TODO:\n// - fractionals 1/2, 1/4, 3/4 -> ½, ¼, ¾\n// - miltiplication 2 x 4 -> 2 × 4\n\nvar RARE_RE = /\\+-|\\.\\.|\\?\\?\\?\\?|!!!!|,,|--/;\n\nvar SCOPED_ABBR_RE = /\\((c|tm|r|p)\\)/ig;\nvar SCOPED_ABBR = {\n 'c': '©',\n 'r': '®',\n 'p': '§',\n 'tm': '™'\n};\n\nfunction replaceScopedAbbr(str) {\n if (str.indexOf('(') < 0) { return str; }\n\n return str.replace(SCOPED_ABBR_RE, function(match, name) {\n return SCOPED_ABBR[name.toLowerCase()];\n });\n}\n\n\nfunction replace(state) {\n var i, token, text, inlineTokens, blkIdx;\n\n if (!state.options.typographer) { return; }\n\n for (blkIdx = state.tokens.length - 1; blkIdx >= 0; blkIdx--) {\n\n if (state.tokens[blkIdx].type !== 'inline') { continue; }\n\n inlineTokens = state.tokens[blkIdx].children;\n\n for (i = inlineTokens.length - 1; i >= 0; i--) {\n token = inlineTokens[i];\n if (token.type === 'text') {\n text = token.content;\n\n text = replaceScopedAbbr(text);\n\n if (RARE_RE.test(text)) {\n text = text\n .replace(/\\+-/g, '±')\n // .., ..., ....... -> …\n // but ?..... & !..... -> ?.. & !..\n .replace(/\\.{2,}/g, '…').replace(/([?!])…/g, '$1..')\n .replace(/([?!]){4,}/g, '$1$1$1').replace(/,{2,}/g, ',')\n // em-dash\n .replace(/(^|[^-])---([^-]|$)/mg, '$1\\u2014$2')\n // en-dash\n .replace(/(^|\\s)--(\\s|$)/mg, '$1\\u2013$2')\n .replace(/(^|[^-\\s])--([^-\\s]|$)/mg, '$1\\u2013$2');\n }\n\n token.content = text;\n }\n }\n }\n}\n\n// Convert straight quotation marks to typographic ones\n//\n\nvar QUOTE_TEST_RE = /['\"]/;\nvar QUOTE_RE = /['\"]/g;\nvar PUNCT_RE = /[-\\s()\\[\\]]/;\nvar APOSTROPHE = '’';\n\n// This function returns true if the character at `pos`\n// could be inside a word.\nfunction isLetter(str, pos) {\n if (pos < 0 || pos >= str.length) { return false; }\n return !PUNCT_RE.test(str[pos]);\n}\n\n\nfunction replaceAt(str, index, ch) {\n return str.substr(0, index) + ch + str.substr(index + 1);\n}\n\n\nfunction smartquotes(state) {\n /*eslint max-depth:0*/\n var i, token, text, t, pos, max, thisLevel, lastSpace, nextSpace, item,\n canOpen, canClose, j, isSingle, blkIdx, tokens,\n stack;\n\n if (!state.options.typographer) { return; }\n\n stack = [];\n\n for (blkIdx = state.tokens.length - 1; blkIdx >= 0; blkIdx--) {\n\n if (state.tokens[blkIdx].type !== 'inline') { continue; }\n\n tokens = state.tokens[blkIdx].children;\n stack.length = 0;\n\n for (i = 0; i < tokens.length; i++) {\n token = tokens[i];\n\n if (token.type !== 'text' || QUOTE_TEST_RE.test(token.text)) { continue; }\n\n thisLevel = tokens[i].level;\n\n for (j = stack.length - 1; j >= 0; j--) {\n if (stack[j].level <= thisLevel) { break; }\n }\n stack.length = j + 1;\n\n text = token.content;\n pos = 0;\n max = text.length;\n\n /*eslint no-labels:0,block-scoped-var:0*/\n OUTER:\n while (pos < max) {\n QUOTE_RE.lastIndex = pos;\n t = QUOTE_RE.exec(text);\n if (!t) { break; }\n\n lastSpace = !isLetter(text, t.index - 1);\n pos = t.index + 1;\n isSingle = (t[0] === \"'\");\n nextSpace = !isLetter(text, pos);\n\n if (!nextSpace && !lastSpace) {\n // middle of word\n if (isSingle) {\n token.content = replaceAt(token.content, t.index, APOSTROPHE);\n }\n continue;\n }\n\n canOpen = !nextSpace;\n canClose = !lastSpace;\n\n if (canClose) {\n // this could be a closing quote, rewind the stack to get a match\n for (j = stack.length - 1; j >= 0; j--) {\n item = stack[j];\n if (stack[j].level < thisLevel) { break; }\n if (item.single === isSingle && stack[j].level === thisLevel) {\n item = stack[j];\n if (isSingle) {\n tokens[item.token].content = replaceAt(tokens[item.token].content, item.pos, state.options.quotes[2]);\n token.content = replaceAt(token.content, t.index, state.options.quotes[3]);\n } else {\n tokens[item.token].content = replaceAt(tokens[item.token].content, item.pos, state.options.quotes[0]);\n token.content = replaceAt(token.content, t.index, state.options.quotes[1]);\n }\n stack.length = j;\n continue OUTER;\n }\n }\n }\n\n if (canOpen) {\n stack.push({\n token: i,\n pos: t.index,\n single: isSingle,\n level: thisLevel\n });\n } else if (canClose && isSingle) {\n token.content = replaceAt(token.content, t.index, APOSTROPHE);\n }\n }\n }\n }\n}\n\n/**\n * Core parser `rules`\n */\n\nvar _rules = [\n [ 'block', block ],\n [ 'abbr', abbr ],\n [ 'references', references ],\n [ 'inline', inline ],\n [ 'footnote_tail', footnote_block ],\n [ 'abbr2', abbr2 ],\n [ 'replacements', replace ],\n [ 'smartquotes', smartquotes ],\n];\n\n/**\n * Class for top level (`core`) parser rules\n *\n * @api private\n */\n\nfunction Core() {\n this.options = {};\n this.ruler = new Ruler();\n for (var i = 0; i < _rules.length; i++) {\n this.ruler.push(_rules[i][0], _rules[i][1]);\n }\n}\n\n/**\n * Process rules with the given `state`\n *\n * @param {Object} `state`\n * @api private\n */\n\nCore.prototype.process = function (state) {\n var i, l, rules;\n rules = this.ruler.getRules('');\n for (i = 0, l = rules.length; i < l; i++) {\n rules[i](state);\n }\n};\n\n// Parser state class\n\nfunction StateBlock(src, parser, options, env, tokens) {\n var ch, s, start, pos, len, indent, indent_found;\n\n this.src = src;\n\n // Shortcuts to simplify nested calls\n this.parser = parser;\n\n this.options = options;\n\n this.env = env;\n\n //\n // Internal state vartiables\n //\n\n this.tokens = tokens;\n\n this.bMarks = []; // line begin offsets for fast jumps\n this.eMarks = []; // line end offsets for fast jumps\n this.tShift = []; // indent for each line\n\n // block parser variables\n this.blkIndent = 0; // required block content indent\n // (for example, if we are in list)\n this.line = 0; // line index in src\n this.lineMax = 0; // lines count\n this.tight = false; // loose/tight mode for lists\n this.parentType = 'root'; // if `list`, block parser stops on two newlines\n this.ddIndent = -1; // indent of the current dd block (-1 if there isn't any)\n\n this.level = 0;\n\n // renderer\n this.result = '';\n\n // Create caches\n // Generate markers.\n s = this.src;\n indent = 0;\n indent_found = false;\n\n for (start = pos = indent = 0, len = s.length; pos < len; pos++) {\n ch = s.charCodeAt(pos);\n\n if (!indent_found) {\n if (ch === 0x20/* space */) {\n indent++;\n continue;\n } else {\n indent_found = true;\n }\n }\n\n if (ch === 0x0A || pos === len - 1) {\n if (ch !== 0x0A) { pos++; }\n this.bMarks.push(start);\n this.eMarks.push(pos);\n this.tShift.push(indent);\n\n indent_found = false;\n indent = 0;\n start = pos + 1;\n }\n }\n\n // Push fake entry to simplify cache bounds checks\n this.bMarks.push(s.length);\n this.eMarks.push(s.length);\n this.tShift.push(0);\n\n this.lineMax = this.bMarks.length - 1; // don't count last fake line\n}\n\nStateBlock.prototype.isEmpty = function isEmpty(line) {\n return this.bMarks[line] + this.tShift[line] >= this.eMarks[line];\n};\n\nStateBlock.prototype.skipEmptyLines = function skipEmptyLines(from) {\n for (var max = this.lineMax; from < max; from++) {\n if (this.bMarks[from] + this.tShift[from] < this.eMarks[from]) {\n break;\n }\n }\n return from;\n};\n\n// Skip spaces from given position.\nStateBlock.prototype.skipSpaces = function skipSpaces(pos) {\n for (var max = this.src.length; pos < max; pos++) {\n if (this.src.charCodeAt(pos) !== 0x20/* space */) { break; }\n }\n return pos;\n};\n\n// Skip char codes from given position\nStateBlock.prototype.skipChars = function skipChars(pos, code) {\n for (var max = this.src.length; pos < max; pos++) {\n if (this.src.charCodeAt(pos) !== code) { break; }\n }\n return pos;\n};\n\n// Skip char codes reverse from given position - 1\nStateBlock.prototype.skipCharsBack = function skipCharsBack(pos, code, min) {\n if (pos <= min) { return pos; }\n\n while (pos > min) {\n if (code !== this.src.charCodeAt(--pos)) { return pos + 1; }\n }\n return pos;\n};\n\n// cut lines range from source.\nStateBlock.prototype.getLines = function getLines(begin, end, indent, keepLastLF) {\n var i, first, last, queue, shift,\n line = begin;\n\n if (begin >= end) {\n return '';\n }\n\n // Opt: don't use push queue for single line;\n if (line + 1 === end) {\n first = this.bMarks[line] + Math.min(this.tShift[line], indent);\n last = keepLastLF ? this.eMarks[line] + 1 : this.eMarks[line];\n return this.src.slice(first, last);\n }\n\n queue = new Array(end - begin);\n\n for (i = 0; line < end; line++, i++) {\n shift = this.tShift[line];\n if (shift > indent) { shift = indent; }\n if (shift < 0) { shift = 0; }\n\n first = this.bMarks[line] + shift;\n\n if (line + 1 < end || keepLastLF) {\n // No need for bounds check because we have fake entry on tail.\n last = this.eMarks[line] + 1;\n } else {\n last = this.eMarks[line];\n }\n\n queue[i] = this.src.slice(first, last);\n }\n\n return queue.join('');\n};\n\n// Code block (4 spaces padded)\n\nfunction code(state, startLine, endLine/*, silent*/) {\n var nextLine, last;\n\n if (state.tShift[startLine] - state.blkIndent < 4) { return false; }\n\n last = nextLine = startLine + 1;\n\n while (nextLine < endLine) {\n if (state.isEmpty(nextLine)) {\n nextLine++;\n continue;\n }\n if (state.tShift[nextLine] - state.blkIndent >= 4) {\n nextLine++;\n last = nextLine;\n continue;\n }\n break;\n }\n\n state.line = nextLine;\n state.tokens.push({\n type: 'code',\n content: state.getLines(startLine, last, 4 + state.blkIndent, true),\n block: true,\n lines: [ startLine, state.line ],\n level: state.level\n });\n\n return true;\n}\n\n// fences (``` lang, ~~~ lang)\n\nfunction fences(state, startLine, endLine, silent) {\n var marker, len, params, nextLine, mem,\n haveEndMarker = false,\n pos = state.bMarks[startLine] + state.tShift[startLine],\n max = state.eMarks[startLine];\n\n if (pos + 3 > max) { return false; }\n\n marker = state.src.charCodeAt(pos);\n\n if (marker !== 0x7E/* ~ */ && marker !== 0x60 /* ` */) {\n return false;\n }\n\n // scan marker length\n mem = pos;\n pos = state.skipChars(pos, marker);\n\n len = pos - mem;\n\n if (len < 3) { return false; }\n\n params = state.src.slice(pos, max).trim();\n\n if (params.indexOf('`') >= 0) { return false; }\n\n // Since start is found, we can report success here in validation mode\n if (silent) { return true; }\n\n // search end of block\n nextLine = startLine;\n\n for (;;) {\n nextLine++;\n if (nextLine >= endLine) {\n // unclosed block should be autoclosed by end of document.\n // also block seems to be autoclosed by end of parent\n break;\n }\n\n pos = mem = state.bMarks[nextLine] + state.tShift[nextLine];\n max = state.eMarks[nextLine];\n\n if (pos < max && state.tShift[nextLine] < state.blkIndent) {\n // non-empty line with negative indent should stop the list:\n // - ```\n // test\n break;\n }\n\n if (state.src.charCodeAt(pos) !== marker) { continue; }\n\n if (state.tShift[nextLine] - state.blkIndent >= 4) {\n // closing fence should be indented less than 4 spaces\n continue;\n }\n\n pos = state.skipChars(pos, marker);\n\n // closing code fence must be at least as long as the opening one\n if (pos - mem < len) { continue; }\n\n // make sure tail has spaces only\n pos = state.skipSpaces(pos);\n\n if (pos < max) { continue; }\n\n haveEndMarker = true;\n // found!\n break;\n }\n\n // If a fence has heading spaces, they should be removed from its inner block\n len = state.tShift[startLine];\n\n state.line = nextLine + (haveEndMarker ? 1 : 0);\n state.tokens.push({\n type: 'fence',\n params: params,\n content: state.getLines(startLine + 1, nextLine, len, true),\n lines: [ startLine, state.line ],\n level: state.level\n });\n\n return true;\n}\n\n// Block quotes\n\nfunction blockquote(state, startLine, endLine, silent) {\n var nextLine, lastLineEmpty, oldTShift, oldBMarks, oldIndent, oldParentType, lines,\n terminatorRules,\n i, l, terminate,\n pos = state.bMarks[startLine] + state.tShift[startLine],\n max = state.eMarks[startLine];\n\n if (pos > max) { return false; }\n\n // check the block quote marker\n if (state.src.charCodeAt(pos++) !== 0x3E/* > */) { return false; }\n\n if (state.level >= state.options.maxNesting) { return false; }\n\n // we know that it's going to be a valid blockquote,\n // so no point trying to find the end of it in silent mode\n if (silent) { return true; }\n\n // skip one optional space after '>'\n if (state.src.charCodeAt(pos) === 0x20) { pos++; }\n\n oldIndent = state.blkIndent;\n state.blkIndent = 0;\n\n oldBMarks = [ state.bMarks[startLine] ];\n state.bMarks[startLine] = pos;\n\n // check if we have an empty blockquote\n pos = pos < max ? state.skipSpaces(pos) : pos;\n lastLineEmpty = pos >= max;\n\n oldTShift = [ state.tShift[startLine] ];\n state.tShift[startLine] = pos - state.bMarks[startLine];\n\n terminatorRules = state.parser.ruler.getRules('blockquote');\n\n // Search the end of the block\n //\n // Block ends with either:\n // 1. an empty line outside:\n // ```\n // > test\n //\n // ```\n // 2. an empty line inside:\n // ```\n // >\n // test\n // ```\n // 3. another tag\n // ```\n // > test\n // - - -\n // ```\n for (nextLine = startLine + 1; nextLine < endLine; nextLine++) {\n pos = state.bMarks[nextLine] + state.tShift[nextLine];\n max = state.eMarks[nextLine];\n\n if (pos >= max) {\n // Case 1: line is not inside the blockquote, and this line is empty.\n break;\n }\n\n if (state.src.charCodeAt(pos++) === 0x3E/* > */) {\n // This line is inside the blockquote.\n\n // skip one optional space after '>'\n if (state.src.charCodeAt(pos) === 0x20) { pos++; }\n\n oldBMarks.push(state.bMarks[nextLine]);\n state.bMarks[nextLine] = pos;\n\n pos = pos < max ? state.skipSpaces(pos) : pos;\n lastLineEmpty = pos >= max;\n\n oldTShift.push(state.tShift[nextLine]);\n state.tShift[nextLine] = pos - state.bMarks[nextLine];\n continue;\n }\n\n // Case 2: line is not inside the blockquote, and the last line was empty.\n if (lastLineEmpty) { break; }\n\n // Case 3: another tag found.\n terminate = false;\n for (i = 0, l = terminatorRules.length; i < l; i++) {\n if (terminatorRules[i](state, nextLine, endLine, true)) {\n terminate = true;\n break;\n }\n }\n if (terminate) { break; }\n\n oldBMarks.push(state.bMarks[nextLine]);\n oldTShift.push(state.tShift[nextLine]);\n\n // A negative number means that this is a paragraph continuation;\n //\n // Any negative number will do the job here, but it's better for it\n // to be large enough to make any bugs obvious.\n state.tShift[nextLine] = -1337;\n }\n\n oldParentType = state.parentType;\n state.parentType = 'blockquote';\n state.tokens.push({\n type: 'blockquote_open',\n lines: lines = [ startLine, 0 ],\n level: state.level++\n });\n state.parser.tokenize(state, startLine, nextLine);\n state.tokens.push({\n type: 'blockquote_close',\n level: --state.level\n });\n state.parentType = oldParentType;\n lines[1] = state.line;\n\n // Restore original tShift; this might not be necessary since the parser\n // has already been here, but just to make sure we can do that.\n for (i = 0; i < oldTShift.length; i++) {\n state.bMarks[i + startLine] = oldBMarks[i];\n state.tShift[i + startLine] = oldTShift[i];\n }\n state.blkIndent = oldIndent;\n\n return true;\n}\n\n// Horizontal rule\n\nfunction hr(state, startLine, endLine, silent) {\n var marker, cnt, ch,\n pos = state.bMarks[startLine],\n max = state.eMarks[startLine];\n\n pos += state.tShift[startLine];\n\n if (pos > max) { return false; }\n\n marker = state.src.charCodeAt(pos++);\n\n // Check hr marker\n if (marker !== 0x2A/* * */ &&\n marker !== 0x2D/* - */ &&\n marker !== 0x5F/* _ */) {\n return false;\n }\n\n // markers can be mixed with spaces, but there should be at least 3 one\n\n cnt = 1;\n while (pos < max) {\n ch = state.src.charCodeAt(pos++);\n if (ch !== marker && ch !== 0x20/* space */) { return false; }\n if (ch === marker) { cnt++; }\n }\n\n if (cnt < 3) { return false; }\n\n if (silent) { return true; }\n\n state.line = startLine + 1;\n state.tokens.push({\n type: 'hr',\n lines: [ startLine, state.line ],\n level: state.level\n });\n\n return true;\n}\n\n// Lists\n\n// Search `[-+*][\\n ]`, returns next pos arter marker on success\n// or -1 on fail.\nfunction skipBulletListMarker(state, startLine) {\n var marker, pos, max;\n\n pos = state.bMarks[startLine] + state.tShift[startLine];\n max = state.eMarks[startLine];\n\n if (pos >= max) { return -1; }\n\n marker = state.src.charCodeAt(pos++);\n // Check bullet\n if (marker !== 0x2A/* * */ &&\n marker !== 0x2D/* - */ &&\n marker !== 0x2B/* + */) {\n return -1;\n }\n\n if (pos < max && state.src.charCodeAt(pos) !== 0x20) {\n // \" 1.test \" - is not a list item\n return -1;\n }\n\n return pos;\n}\n\n// Search `\\d+[.)][\\n ]`, returns next pos arter marker on success\n// or -1 on fail.\nfunction skipOrderedListMarker(state, startLine) {\n var ch,\n pos = state.bMarks[startLine] + state.tShift[startLine],\n max = state.eMarks[startLine];\n\n if (pos + 1 >= max) { return -1; }\n\n ch = state.src.charCodeAt(pos++);\n\n if (ch < 0x30/* 0 */ || ch > 0x39/* 9 */) { return -1; }\n\n for (;;) {\n // EOL -> fail\n if (pos >= max) { return -1; }\n\n ch = state.src.charCodeAt(pos++);\n\n if (ch >= 0x30/* 0 */ && ch <= 0x39/* 9 */) {\n continue;\n }\n\n // found valid marker\n if (ch === 0x29/* ) */ || ch === 0x2e/* . */) {\n break;\n }\n\n return -1;\n }\n\n\n if (pos < max && state.src.charCodeAt(pos) !== 0x20/* space */) {\n // \" 1.test \" - is not a list item\n return -1;\n }\n return pos;\n}\n\nfunction markTightParagraphs(state, idx) {\n var i, l,\n level = state.level + 2;\n\n for (i = idx + 2, l = state.tokens.length - 2; i < l; i++) {\n if (state.tokens[i].level === level && state.tokens[i].type === 'paragraph_open') {\n state.tokens[i + 2].tight = true;\n state.tokens[i].tight = true;\n i += 2;\n }\n }\n}\n\n\nfunction list(state, startLine, endLine, silent) {\n var nextLine,\n indent,\n oldTShift,\n oldIndent,\n oldTight,\n oldParentType,\n start,\n posAfterMarker,\n max,\n indentAfterMarker,\n markerValue,\n markerCharCode,\n isOrdered,\n contentStart,\n listTokIdx,\n prevEmptyEnd,\n listLines,\n itemLines,\n tight = true,\n terminatorRules,\n i, l, terminate;\n\n // Detect list type and position after marker\n if ((posAfterMarker = skipOrderedListMarker(state, startLine)) >= 0) {\n isOrdered = true;\n } else if ((posAfterMarker = skipBulletListMarker(state, startLine)) >= 0) {\n isOrdered = false;\n } else {\n return false;\n }\n\n if (state.level >= state.options.maxNesting) { return false; }\n\n // We should terminate list on style change. Remember first one to compare.\n markerCharCode = state.src.charCodeAt(posAfterMarker - 1);\n\n // For validation mode we can terminate immediately\n if (silent) { return true; }\n\n // Start list\n listTokIdx = state.tokens.length;\n\n if (isOrdered) {\n start = state.bMarks[startLine] + state.tShift[startLine];\n markerValue = Number(state.src.substr(start, posAfterMarker - start - 1));\n\n state.tokens.push({\n type: 'ordered_list_open',\n order: markerValue,\n lines: listLines = [ startLine, 0 ],\n level: state.level++\n });\n\n } else {\n state.tokens.push({\n type: 'bullet_list_open',\n lines: listLines = [ startLine, 0 ],\n level: state.level++\n });\n }\n\n //\n // Iterate list items\n //\n\n nextLine = startLine;\n prevEmptyEnd = false;\n terminatorRules = state.parser.ruler.getRules('list');\n\n while (nextLine < endLine) {\n contentStart = state.skipSpaces(posAfterMarker);\n max = state.eMarks[nextLine];\n\n if (contentStart >= max) {\n // trimming space in \"- \\n 3\" case, indent is 1 here\n indentAfterMarker = 1;\n } else {\n indentAfterMarker = contentStart - posAfterMarker;\n }\n\n // If we have more than 4 spaces, the indent is 1\n // (the rest is just indented code block)\n if (indentAfterMarker > 4) { indentAfterMarker = 1; }\n\n // If indent is less than 1, assume that it's one, example:\n // \"-\\n test\"\n if (indentAfterMarker < 1) { indentAfterMarker = 1; }\n\n // \" - test\"\n // ^^^^^ - calculating total length of this thing\n indent = (posAfterMarker - state.bMarks[nextLine]) + indentAfterMarker;\n\n // Run subparser & write tokens\n state.tokens.push({\n type: 'list_item_open',\n lines: itemLines = [ startLine, 0 ],\n level: state.level++\n });\n\n oldIndent = state.blkIndent;\n oldTight = state.tight;\n oldTShift = state.tShift[startLine];\n oldParentType = state.parentType;\n state.tShift[startLine] = contentStart - state.bMarks[startLine];\n state.blkIndent = indent;\n state.tight = true;\n state.parentType = 'list';\n\n state.parser.tokenize(state, startLine, endLine, true);\n\n // If any of list item is tight, mark list as tight\n if (!state.tight || prevEmptyEnd) {\n tight = false;\n }\n // Item become loose if finish with empty line,\n // but we should filter last element, because it means list finish\n prevEmptyEnd = (state.line - startLine) > 1 && state.isEmpty(state.line - 1);\n\n state.blkIndent = oldIndent;\n state.tShift[startLine] = oldTShift;\n state.tight = oldTight;\n state.parentType = oldParentType;\n\n state.tokens.push({\n type: 'list_item_close',\n level: --state.level\n });\n\n nextLine = startLine = state.line;\n itemLines[1] = nextLine;\n contentStart = state.bMarks[startLine];\n\n if (nextLine >= endLine) { break; }\n\n if (state.isEmpty(nextLine)) {\n break;\n }\n\n //\n // Try to check if list is terminated or continued.\n //\n if (state.tShift[nextLine] < state.blkIndent) { break; }\n\n // fail if terminating block found\n terminate = false;\n for (i = 0, l = terminatorRules.length; i < l; i++) {\n if (terminatorRules[i](state, nextLine, endLine, true)) {\n terminate = true;\n break;\n }\n }\n if (terminate) { break; }\n\n // fail if list has another type\n if (isOrdered) {\n posAfterMarker = skipOrderedListMarker(state, nextLine);\n if (posAfterMarker < 0) { break; }\n } else {\n posAfterMarker = skipBulletListMarker(state, nextLine);\n if (posAfterMarker < 0) { break; }\n }\n\n if (markerCharCode !== state.src.charCodeAt(posAfterMarker - 1)) { break; }\n }\n\n // Finilize list\n state.tokens.push({\n type: isOrdered ? 'ordered_list_close' : 'bullet_list_close',\n level: --state.level\n });\n listLines[1] = nextLine;\n\n state.line = nextLine;\n\n // mark paragraphs tight if needed\n if (tight) {\n markTightParagraphs(state, listTokIdx);\n }\n\n return true;\n}\n\n// Process footnote reference list\n\nfunction footnote(state, startLine, endLine, silent) {\n var oldBMark, oldTShift, oldParentType, pos, label,\n start = state.bMarks[startLine] + state.tShift[startLine],\n max = state.eMarks[startLine];\n\n // line should be at least 5 chars - \"[^x]:\"\n if (start + 4 > max) { return false; }\n\n if (state.src.charCodeAt(start) !== 0x5B/* [ */) { return false; }\n if (state.src.charCodeAt(start + 1) !== 0x5E/* ^ */) { return false; }\n if (state.level >= state.options.maxNesting) { return false; }\n\n for (pos = start + 2; pos < max; pos++) {\n if (state.src.charCodeAt(pos) === 0x20) { return false; }\n if (state.src.charCodeAt(pos) === 0x5D /* ] */) {\n break;\n }\n }\n\n if (pos === start + 2) { return false; } // no empty footnote labels\n if (pos + 1 >= max || state.src.charCodeAt(++pos) !== 0x3A /* : */) { return false; }\n if (silent) { return true; }\n pos++;\n\n if (!state.env.footnotes) { state.env.footnotes = {}; }\n if (!state.env.footnotes.refs) { state.env.footnotes.refs = {}; }\n label = state.src.slice(start + 2, pos - 2);\n state.env.footnotes.refs[':' + label] = -1;\n\n state.tokens.push({\n type: 'footnote_reference_open',\n label: label,\n level: state.level++\n });\n\n oldBMark = state.bMarks[startLine];\n oldTShift = state.tShift[startLine];\n oldParentType = state.parentType;\n state.tShift[startLine] = state.skipSpaces(pos) - pos;\n state.bMarks[startLine] = pos;\n state.blkIndent += 4;\n state.parentType = 'footnote';\n\n if (state.tShift[startLine] < state.blkIndent) {\n state.tShift[startLine] += state.blkIndent;\n state.bMarks[startLine] -= state.blkIndent;\n }\n\n state.parser.tokenize(state, startLine, endLine, true);\n\n state.parentType = oldParentType;\n state.blkIndent -= 4;\n state.tShift[startLine] = oldTShift;\n state.bMarks[startLine] = oldBMark;\n\n state.tokens.push({\n type: 'footnote_reference_close',\n level: --state.level\n });\n\n return true;\n}\n\n// heading (#, ##, ...)\n\nfunction heading(state, startLine, endLine, silent) {\n var ch, level, tmp,\n pos = state.bMarks[startLine] + state.tShift[startLine],\n max = state.eMarks[startLine];\n\n if (pos >= max) { return false; }\n\n ch = state.src.charCodeAt(pos);\n\n if (ch !== 0x23/* # */ || pos >= max) { return false; }\n\n // count heading level\n level = 1;\n ch = state.src.charCodeAt(++pos);\n while (ch === 0x23/* # */ && pos < max && level <= 6) {\n level++;\n ch = state.src.charCodeAt(++pos);\n }\n\n if (level > 6 || (pos < max && ch !== 0x20/* space */)) { return false; }\n\n if (silent) { return true; }\n\n // Let's cut tails like ' ### ' from the end of string\n\n max = state.skipCharsBack(max, 0x20, pos); // space\n tmp = state.skipCharsBack(max, 0x23, pos); // #\n if (tmp > pos && state.src.charCodeAt(tmp - 1) === 0x20/* space */) {\n max = tmp;\n }\n\n state.line = startLine + 1;\n\n state.tokens.push({ type: 'heading_open',\n hLevel: level,\n lines: [ startLine, state.line ],\n level: state.level\n });\n\n // only if header is not empty\n if (pos < max) {\n state.tokens.push({\n type: 'inline',\n content: state.src.slice(pos, max).trim(),\n level: state.level + 1,\n lines: [ startLine, state.line ],\n children: []\n });\n }\n state.tokens.push({ type: 'heading_close', hLevel: level, level: state.level });\n\n return true;\n}\n\n// lheading (---, ===)\n\nfunction lheading(state, startLine, endLine/*, silent*/) {\n var marker, pos, max,\n next = startLine + 1;\n\n if (next >= endLine) { return false; }\n if (state.tShift[next] < state.blkIndent) { return false; }\n\n // Scan next line\n\n if (state.tShift[next] - state.blkIndent > 3) { return false; }\n\n pos = state.bMarks[next] + state.tShift[next];\n max = state.eMarks[next];\n\n if (pos >= max) { return false; }\n\n marker = state.src.charCodeAt(pos);\n\n if (marker !== 0x2D/* - */ && marker !== 0x3D/* = */) { return false; }\n\n pos = state.skipChars(pos, marker);\n\n pos = state.skipSpaces(pos);\n\n if (pos < max) { return false; }\n\n pos = state.bMarks[startLine] + state.tShift[startLine];\n\n state.line = next + 1;\n state.tokens.push({\n type: 'heading_open',\n hLevel: marker === 0x3D/* = */ ? 1 : 2,\n lines: [ startLine, state.line ],\n level: state.level\n });\n state.tokens.push({\n type: 'inline',\n content: state.src.slice(pos, state.eMarks[startLine]).trim(),\n level: state.level + 1,\n lines: [ startLine, state.line - 1 ],\n children: []\n });\n state.tokens.push({\n type: 'heading_close',\n hLevel: marker === 0x3D/* = */ ? 1 : 2,\n level: state.level\n });\n\n return true;\n}\n\n// List of valid html blocks names, accorting to commonmark spec\n// http://jgm.github.io/CommonMark/spec.html#html-blocks\n\nvar html_blocks = {};\n\n[\n 'article',\n 'aside',\n 'button',\n 'blockquote',\n 'body',\n 'canvas',\n 'caption',\n 'col',\n 'colgroup',\n 'dd',\n 'div',\n 'dl',\n 'dt',\n 'embed',\n 'fieldset',\n 'figcaption',\n 'figure',\n 'footer',\n 'form',\n 'h1',\n 'h2',\n 'h3',\n 'h4',\n 'h5',\n 'h6',\n 'header',\n 'hgroup',\n 'hr',\n 'iframe',\n 'li',\n 'map',\n 'object',\n 'ol',\n 'output',\n 'p',\n 'pre',\n 'progress',\n 'script',\n 'section',\n 'style',\n 'table',\n 'tbody',\n 'td',\n 'textarea',\n 'tfoot',\n 'th',\n 'tr',\n 'thead',\n 'ul',\n 'video'\n].forEach(function (name) { html_blocks[name] = true; });\n\n// HTML block\n\n\nvar HTML_TAG_OPEN_RE = /^<([a-zA-Z]{1,15})[\\s\\/>]/;\nvar HTML_TAG_CLOSE_RE = /^<\\/([a-zA-Z]{1,15})[\\s>]/;\n\nfunction isLetter$1(ch) {\n /*eslint no-bitwise:0*/\n var lc = ch | 0x20; // to lower case\n return (lc >= 0x61/* a */) && (lc <= 0x7a/* z */);\n}\n\nfunction htmlblock(state, startLine, endLine, silent) {\n var ch, match, nextLine,\n pos = state.bMarks[startLine],\n max = state.eMarks[startLine],\n shift = state.tShift[startLine];\n\n pos += shift;\n\n if (!state.options.html) { return false; }\n\n if (shift > 3 || pos + 2 >= max) { return false; }\n\n if (state.src.charCodeAt(pos) !== 0x3C/* < */) { return false; }\n\n ch = state.src.charCodeAt(pos + 1);\n\n if (ch === 0x21/* ! */ || ch === 0x3F/* ? */) {\n // Directive start / comment start / processing instruction start\n if (silent) { return true; }\n\n } else if (ch === 0x2F/* / */ || isLetter$1(ch)) {\n\n // Probably start or end of tag\n if (ch === 0x2F/* \\ */) {\n // closing tag\n match = state.src.slice(pos, max).match(HTML_TAG_CLOSE_RE);\n if (!match) { return false; }\n } else {\n // opening tag\n match = state.src.slice(pos, max).match(HTML_TAG_OPEN_RE);\n if (!match) { return false; }\n }\n // Make sure tag name is valid\n if (html_blocks[match[1].toLowerCase()] !== true) { return false; }\n if (silent) { return true; }\n\n } else {\n return false;\n }\n\n // If we are here - we detected HTML block.\n // Let's roll down till empty line (block end).\n nextLine = startLine + 1;\n while (nextLine < state.lineMax && !state.isEmpty(nextLine)) {\n nextLine++;\n }\n\n state.line = nextLine;\n state.tokens.push({\n type: 'htmlblock',\n level: state.level,\n lines: [ startLine, state.line ],\n content: state.getLines(startLine, nextLine, 0, true)\n });\n\n return true;\n}\n\n// GFM table, non-standard\n\nfunction getLine(state, line) {\n var pos = state.bMarks[line] + state.blkIndent,\n max = state.eMarks[line];\n\n return state.src.substr(pos, max - pos);\n}\n\nfunction table(state, startLine, endLine, silent) {\n var ch, lineText, pos, i, nextLine, rows, cell,\n aligns, t, tableLines, tbodyLines;\n\n // should have at least three lines\n if (startLine + 2 > endLine) { return false; }\n\n nextLine = startLine + 1;\n\n if (state.tShift[nextLine] < state.blkIndent) { return false; }\n\n // first character of the second line should be '|' or '-'\n\n pos = state.bMarks[nextLine] + state.tShift[nextLine];\n if (pos >= state.eMarks[nextLine]) { return false; }\n\n ch = state.src.charCodeAt(pos);\n if (ch !== 0x7C/* | */ && ch !== 0x2D/* - */ && ch !== 0x3A/* : */) { return false; }\n\n lineText = getLine(state, startLine + 1);\n if (!/^[-:| ]+$/.test(lineText)) { return false; }\n\n rows = lineText.split('|');\n if (rows <= 2) { return false; }\n aligns = [];\n for (i = 0; i < rows.length; i++) {\n t = rows[i].trim();\n if (!t) {\n // allow empty columns before and after table, but not in between columns;\n // e.g. allow ` |---| `, disallow ` ---||--- `\n if (i === 0 || i === rows.length - 1) {\n continue;\n } else {\n return false;\n }\n }\n\n if (!/^:?-+:?$/.test(t)) { return false; }\n if (t.charCodeAt(t.length - 1) === 0x3A/* : */) {\n aligns.push(t.charCodeAt(0) === 0x3A/* : */ ? 'center' : 'right');\n } else if (t.charCodeAt(0) === 0x3A/* : */) {\n aligns.push('left');\n } else {\n aligns.push('');\n }\n }\n\n lineText = getLine(state, startLine).trim();\n if (lineText.indexOf('|') === -1) { return false; }\n rows = lineText.replace(/^\\||\\|$/g, '').split('|');\n if (aligns.length !== rows.length) { return false; }\n if (silent) { return true; }\n\n state.tokens.push({\n type: 'table_open',\n lines: tableLines = [ startLine, 0 ],\n level: state.level++\n });\n state.tokens.push({\n type: 'thead_open',\n lines: [ startLine, startLine + 1 ],\n level: state.level++\n });\n\n state.tokens.push({\n type: 'tr_open',\n lines: [ startLine, startLine + 1 ],\n level: state.level++\n });\n for (i = 0; i < rows.length; i++) {\n state.tokens.push({\n type: 'th_open',\n align: aligns[i],\n lines: [ startLine, startLine + 1 ],\n level: state.level++\n });\n state.tokens.push({\n type: 'inline',\n content: rows[i].trim(),\n lines: [ startLine, startLine + 1 ],\n level: state.level,\n children: []\n });\n state.tokens.push({ type: 'th_close', level: --state.level });\n }\n state.tokens.push({ type: 'tr_close', level: --state.level });\n state.tokens.push({ type: 'thead_close', level: --state.level });\n\n state.tokens.push({\n type: 'tbody_open',\n lines: tbodyLines = [ startLine + 2, 0 ],\n level: state.level++\n });\n\n for (nextLine = startLine + 2; nextLine < endLine; nextLine++) {\n if (state.tShift[nextLine] < state.blkIndent) { break; }\n\n lineText = getLine(state, nextLine).trim();\n if (lineText.indexOf('|') === -1) { break; }\n rows = lineText.replace(/^\\||\\|$/g, '').split('|');\n\n state.tokens.push({ type: 'tr_open', level: state.level++ });\n for (i = 0; i < rows.length; i++) {\n state.tokens.push({ type: 'td_open', align: aligns[i], level: state.level++ });\n // 0x7c === '|'\n cell = rows[i].substring(\n rows[i].charCodeAt(0) === 0x7c ? 1 : 0,\n rows[i].charCodeAt(rows[i].length - 1) === 0x7c ? rows[i].length - 1 : rows[i].length\n ).trim();\n state.tokens.push({\n type: 'inline',\n content: cell,\n level: state.level,\n children: []\n });\n state.tokens.push({ type: 'td_close', level: --state.level });\n }\n state.tokens.push({ type: 'tr_close', level: --state.level });\n }\n state.tokens.push({ type: 'tbody_close', level: --state.level });\n state.tokens.push({ type: 'table_close', level: --state.level });\n\n tableLines[1] = tbodyLines[1] = nextLine;\n state.line = nextLine;\n return true;\n}\n\n// Definition lists\n\n// Search `[:~][\\n ]`, returns next pos after marker on success\n// or -1 on fail.\nfunction skipMarker(state, line) {\n var pos, marker,\n start = state.bMarks[line] + state.tShift[line],\n max = state.eMarks[line];\n\n if (start >= max) { return -1; }\n\n // Check bullet\n marker = state.src.charCodeAt(start++);\n if (marker !== 0x7E/* ~ */ && marker !== 0x3A/* : */) { return -1; }\n\n pos = state.skipSpaces(start);\n\n // require space after \":\"\n if (start === pos) { return -1; }\n\n // no empty definitions, e.g. \" : \"\n if (pos >= max) { return -1; }\n\n return pos;\n}\n\nfunction markTightParagraphs$1(state, idx) {\n var i, l,\n level = state.level + 2;\n\n for (i = idx + 2, l = state.tokens.length - 2; i < l; i++) {\n if (state.tokens[i].level === level && state.tokens[i].type === 'paragraph_open') {\n state.tokens[i + 2].tight = true;\n state.tokens[i].tight = true;\n i += 2;\n }\n }\n}\n\nfunction deflist(state, startLine, endLine, silent) {\n var contentStart,\n ddLine,\n dtLine,\n itemLines,\n listLines,\n listTokIdx,\n nextLine,\n oldIndent,\n oldDDIndent,\n oldParentType,\n oldTShift,\n oldTight,\n prevEmptyEnd,\n tight;\n\n if (silent) {\n // quirk: validation mode validates a dd block only, not a whole deflist\n if (state.ddIndent < 0) { return false; }\n return skipMarker(state, startLine) >= 0;\n }\n\n nextLine = startLine + 1;\n if (state.isEmpty(nextLine)) {\n if (++nextLine > endLine) { return false; }\n }\n\n if (state.tShift[nextLine] < state.blkIndent) { return false; }\n contentStart = skipMarker(state, nextLine);\n if (contentStart < 0) { return false; }\n\n if (state.level >= state.options.maxNesting) { return false; }\n\n // Start list\n listTokIdx = state.tokens.length;\n\n state.tokens.push({\n type: 'dl_open',\n lines: listLines = [ startLine, 0 ],\n level: state.level++\n });\n\n //\n // Iterate list items\n //\n\n dtLine = startLine;\n ddLine = nextLine;\n\n // One definition list can contain multiple DTs,\n // and one DT can be followed by multiple DDs.\n //\n // Thus, there is two loops here, and label is\n // needed to break out of the second one\n //\n /*eslint no-labels:0,block-scoped-var:0*/\n OUTER:\n for (;;) {\n tight = true;\n prevEmptyEnd = false;\n\n state.tokens.push({\n type: 'dt_open',\n lines: [ dtLine, dtLine ],\n level: state.level++\n });\n state.tokens.push({\n type: 'inline',\n content: state.getLines(dtLine, dtLine + 1, state.blkIndent, false).trim(),\n level: state.level + 1,\n lines: [ dtLine, dtLine ],\n children: []\n });\n state.tokens.push({\n type: 'dt_close',\n level: --state.level\n });\n\n for (;;) {\n state.tokens.push({\n type: 'dd_open',\n lines: itemLines = [ nextLine, 0 ],\n level: state.level++\n });\n\n oldTight = state.tight;\n oldDDIndent = state.ddIndent;\n oldIndent = state.blkIndent;\n oldTShift = state.tShift[ddLine];\n oldParentType = state.parentType;\n state.blkIndent = state.ddIndent = state.tShift[ddLine] + 2;\n state.tShift[ddLine] = contentStart - state.bMarks[ddLine];\n state.tight = true;\n state.parentType = 'deflist';\n\n state.parser.tokenize(state, ddLine, endLine, true);\n\n // If any of list item is tight, mark list as tight\n if (!state.tight || prevEmptyEnd) {\n tight = false;\n }\n // Item become loose if finish with empty line,\n // but we should filter last element, because it means list finish\n prevEmptyEnd = (state.line - ddLine) > 1 && state.isEmpty(state.line - 1);\n\n state.tShift[ddLine] = oldTShift;\n state.tight = oldTight;\n state.parentType = oldParentType;\n state.blkIndent = oldIndent;\n state.ddIndent = oldDDIndent;\n\n state.tokens.push({\n type: 'dd_close',\n level: --state.level\n });\n\n itemLines[1] = nextLine = state.line;\n\n if (nextLine >= endLine) { break OUTER; }\n\n if (state.tShift[nextLine] < state.blkIndent) { break OUTER; }\n contentStart = skipMarker(state, nextLine);\n if (contentStart < 0) { break; }\n\n ddLine = nextLine;\n\n // go to the next loop iteration:\n // insert DD tag and repeat checking\n }\n\n if (nextLine >= endLine) { break; }\n dtLine = nextLine;\n\n if (state.isEmpty(dtLine)) { break; }\n if (state.tShift[dtLine] < state.blkIndent) { break; }\n\n ddLine = dtLine + 1;\n if (ddLine >= endLine) { break; }\n if (state.isEmpty(ddLine)) { ddLine++; }\n if (ddLine >= endLine) { break; }\n\n if (state.tShift[ddLine] < state.blkIndent) { break; }\n contentStart = skipMarker(state, ddLine);\n if (contentStart < 0) { break; }\n\n // go to the next loop iteration:\n // insert DT and DD tags and repeat checking\n }\n\n // Finilize list\n state.tokens.push({\n type: 'dl_close',\n level: --state.level\n });\n listLines[1] = nextLine;\n\n state.line = nextLine;\n\n // mark paragraphs tight if needed\n if (tight) {\n markTightParagraphs$1(state, listTokIdx);\n }\n\n return true;\n}\n\n// Paragraph\n\nfunction paragraph(state, startLine/*, endLine*/) {\n var endLine, content, terminate, i, l,\n nextLine = startLine + 1,\n terminatorRules;\n\n endLine = state.lineMax;\n\n // jump line-by-line until empty one or EOF\n if (nextLine < endLine && !state.isEmpty(nextLine)) {\n terminatorRules = state.parser.ruler.getRules('paragraph');\n\n for (; nextLine < endLine && !state.isEmpty(nextLine); nextLine++) {\n // this would be a code block normally, but after paragraph\n // it's considered a lazy continuation regardless of what's there\n if (state.tShift[nextLine] - state.blkIndent > 3) { continue; }\n\n // Some tags can terminate paragraph without empty line.\n terminate = false;\n for (i = 0, l = terminatorRules.length; i < l; i++) {\n if (terminatorRules[i](state, nextLine, endLine, true)) {\n terminate = true;\n break;\n }\n }\n if (terminate) { break; }\n }\n }\n\n content = state.getLines(startLine, nextLine, state.blkIndent, false).trim();\n\n state.line = nextLine;\n if (content.length) {\n state.tokens.push({\n type: 'paragraph_open',\n tight: false,\n lines: [ startLine, state.line ],\n level: state.level\n });\n state.tokens.push({\n type: 'inline',\n content: content,\n level: state.level + 1,\n lines: [ startLine, state.line ],\n children: []\n });\n state.tokens.push({\n type: 'paragraph_close',\n tight: false,\n level: state.level\n });\n }\n\n return true;\n}\n\n/**\n * Parser rules\n */\n\nvar _rules$1 = [\n [ 'code', code ],\n [ 'fences', fences, [ 'paragraph', 'blockquote', 'list' ] ],\n [ 'blockquote', blockquote, [ 'paragraph', 'blockquote', 'list' ] ],\n [ 'hr', hr, [ 'paragraph', 'blockquote', 'list' ] ],\n [ 'list', list, [ 'paragraph', 'blockquote' ] ],\n [ 'footnote', footnote, [ 'paragraph' ] ],\n [ 'heading', heading, [ 'paragraph', 'blockquote' ] ],\n [ 'lheading', lheading ],\n [ 'htmlblock', htmlblock, [ 'paragraph', 'blockquote' ] ],\n [ 'table', table, [ 'paragraph' ] ],\n [ 'deflist', deflist, [ 'paragraph' ] ],\n [ 'paragraph', paragraph ]\n];\n\n/**\n * Block Parser class\n *\n * @api private\n */\n\nfunction ParserBlock() {\n this.ruler = new Ruler();\n for (var i = 0; i < _rules$1.length; i++) {\n this.ruler.push(_rules$1[i][0], _rules$1[i][1], {\n alt: (_rules$1[i][2] || []).slice()\n });\n }\n}\n\n/**\n * Generate tokens for the given input range.\n *\n * @param {Object} `state` Has properties like `src`, `parser`, `options` etc\n * @param {Number} `startLine`\n * @param {Number} `endLine`\n * @api private\n */\n\nParserBlock.prototype.tokenize = function (state, startLine, endLine) {\n var rules = this.ruler.getRules('');\n var len = rules.length;\n var line = startLine;\n var hasEmptyLines = false;\n var ok, i;\n\n while (line < endLine) {\n state.line = line = state.skipEmptyLines(line);\n if (line >= endLine) {\n break;\n }\n\n // Termination condition for nested calls.\n // Nested calls currently used for blockquotes & lists\n if (state.tShift[line] < state.blkIndent) {\n break;\n }\n\n // Try all possible rules.\n // On success, rule should:\n //\n // - update `state.line`\n // - update `state.tokens`\n // - return true\n\n for (i = 0; i < len; i++) {\n ok = rules[i](state, line, endLine, false);\n if (ok) {\n break;\n }\n }\n\n // set state.tight iff we had an empty line before current tag\n // i.e. latest empty line should not count\n state.tight = !hasEmptyLines;\n\n // paragraph might \"eat\" one newline after it in nested lists\n if (state.isEmpty(state.line - 1)) {\n hasEmptyLines = true;\n }\n\n line = state.line;\n\n if (line < endLine && state.isEmpty(line)) {\n hasEmptyLines = true;\n line++;\n\n // two empty lines should stop the parser in list mode\n if (line < endLine && state.parentType === 'list' && state.isEmpty(line)) { break; }\n state.line = line;\n }\n }\n};\n\nvar TABS_SCAN_RE = /[\\n\\t]/g;\nvar NEWLINES_RE = /\\r[\\n\\u0085]|[\\u2424\\u2028\\u0085]/g;\nvar SPACES_RE = /\\u00a0/g;\n\n/**\n * Tokenize the given `str`.\n *\n * @param {String} `str` Source string\n * @param {Object} `options`\n * @param {Object} `env`\n * @param {Array} `outTokens`\n * @api private\n */\n\nParserBlock.prototype.parse = function (str, options, env, outTokens) {\n var state, lineStart = 0, lastTabPos = 0;\n if (!str) { return []; }\n\n // Normalize spaces\n str = str.replace(SPACES_RE, ' ');\n\n // Normalize newlines\n str = str.replace(NEWLINES_RE, '\\n');\n\n // Replace tabs with proper number of spaces (1..4)\n if (str.indexOf('\\t') >= 0) {\n str = str.replace(TABS_SCAN_RE, function (match, offset) {\n var result;\n if (str.charCodeAt(offset) === 0x0A) {\n lineStart = offset + 1;\n lastTabPos = 0;\n return match;\n }\n result = ' '.slice((offset - lineStart - lastTabPos) % 4);\n lastTabPos = offset - lineStart + 1;\n return result;\n });\n }\n\n state = new StateBlock(str, this, options, env, outTokens);\n this.tokenize(state, state.line, state.lineMax);\n};\n\n// Skip text characters for text token, place those to pending buffer\n// and increment current pos\n\n// Rule to skip pure text\n// '{}$%@~+=:' reserved for extentions\n\nfunction isTerminatorChar(ch) {\n switch (ch) {\n case 0x0A/* \\n */:\n case 0x5C/* \\ */:\n case 0x60/* ` */:\n case 0x2A/* * */:\n case 0x5F/* _ */:\n case 0x5E/* ^ */:\n case 0x5B/* [ */:\n case 0x5D/* ] */:\n case 0x21/* ! */:\n case 0x26/* & */:\n case 0x3C/* < */:\n case 0x3E/* > */:\n case 0x7B/* { */:\n case 0x7D/* } */:\n case 0x24/* $ */:\n case 0x25/* % */:\n case 0x40/* @ */:\n case 0x7E/* ~ */:\n case 0x2B/* + */:\n case 0x3D/* = */:\n case 0x3A/* : */:\n return true;\n default:\n return false;\n }\n}\n\nfunction text(state, silent) {\n var pos = state.pos;\n\n while (pos < state.posMax && !isTerminatorChar(state.src.charCodeAt(pos))) {\n pos++;\n }\n\n if (pos === state.pos) { return false; }\n\n if (!silent) { state.pending += state.src.slice(state.pos, pos); }\n\n state.pos = pos;\n\n return true;\n}\n\n// Proceess '\\n'\n\nfunction newline(state, silent) {\n var pmax, max, pos = state.pos;\n\n if (state.src.charCodeAt(pos) !== 0x0A/* \\n */) { return false; }\n\n pmax = state.pending.length - 1;\n max = state.posMax;\n\n // ' \\n' -> hardbreak\n // Lookup in pending chars is bad practice! Don't copy to other rules!\n // Pending string is stored in concat mode, indexed lookups will cause\n // convertion to flat mode.\n if (!silent) {\n if (pmax >= 0 && state.pending.charCodeAt(pmax) === 0x20) {\n if (pmax >= 1 && state.pending.charCodeAt(pmax - 1) === 0x20) {\n // Strip out all trailing spaces on this line.\n for (var i = pmax - 2; i >= 0; i--) {\n if (state.pending.charCodeAt(i) !== 0x20) {\n state.pending = state.pending.substring(0, i + 1);\n break;\n }\n }\n state.push({\n type: 'hardbreak',\n level: state.level\n });\n } else {\n state.pending = state.pending.slice(0, -1);\n state.push({\n type: 'softbreak',\n level: state.level\n });\n }\n\n } else {\n state.push({\n type: 'softbreak',\n level: state.level\n });\n }\n }\n\n pos++;\n\n // skip heading spaces for next line\n while (pos < max && state.src.charCodeAt(pos) === 0x20) { pos++; }\n\n state.pos = pos;\n return true;\n}\n\n// Proceess escaped chars and hardbreaks\n\nvar ESCAPED = [];\n\nfor (var i = 0; i < 256; i++) { ESCAPED.push(0); }\n\n'\\\\!\"#$%&\\'()*+,./:;<=>?@[]^_`{|}~-'\n .split('').forEach(function(ch) { ESCAPED[ch.charCodeAt(0)] = 1; });\n\n\nfunction escape(state, silent) {\n var ch, pos = state.pos, max = state.posMax;\n\n if (state.src.charCodeAt(pos) !== 0x5C/* \\ */) { return false; }\n\n pos++;\n\n if (pos < max) {\n ch = state.src.charCodeAt(pos);\n\n if (ch < 256 && ESCAPED[ch] !== 0) {\n if (!silent) { state.pending += state.src[pos]; }\n state.pos += 2;\n return true;\n }\n\n if (ch === 0x0A) {\n if (!silent) {\n state.push({\n type: 'hardbreak',\n level: state.level\n });\n }\n\n pos++;\n // skip leading whitespaces from next line\n while (pos < max && state.src.charCodeAt(pos) === 0x20) { pos++; }\n\n state.pos = pos;\n return true;\n }\n }\n\n if (!silent) { state.pending += '\\\\'; }\n state.pos++;\n return true;\n}\n\n// Parse backticks\n\nfunction backticks(state, silent) {\n var start, max, marker, matchStart, matchEnd,\n pos = state.pos,\n ch = state.src.charCodeAt(pos);\n\n if (ch !== 0x60/* ` */) { return false; }\n\n start = pos;\n pos++;\n max = state.posMax;\n\n while (pos < max && state.src.charCodeAt(pos) === 0x60/* ` */) { pos++; }\n\n marker = state.src.slice(start, pos);\n\n matchStart = matchEnd = pos;\n\n while ((matchStart = state.src.indexOf('`', matchEnd)) !== -1) {\n matchEnd = matchStart + 1;\n\n while (matchEnd < max && state.src.charCodeAt(matchEnd) === 0x60/* ` */) { matchEnd++; }\n\n if (matchEnd - matchStart === marker.length) {\n if (!silent) {\n state.push({\n type: 'code',\n content: state.src.slice(pos, matchStart)\n .replace(/[ \\n]+/g, ' ')\n .trim(),\n block: false,\n level: state.level\n });\n }\n state.pos = matchEnd;\n return true;\n }\n }\n\n if (!silent) { state.pending += marker; }\n state.pos += marker.length;\n return true;\n}\n\n// Process ~~deleted text~~\n\nfunction del(state, silent) {\n var found,\n pos,\n stack,\n max = state.posMax,\n start = state.pos,\n lastChar,\n nextChar;\n\n if (state.src.charCodeAt(start) !== 0x7E/* ~ */) { return false; }\n if (silent) { return false; } // don't run any pairs in validation mode\n if (start + 4 >= max) { return false; }\n if (state.src.charCodeAt(start + 1) !== 0x7E/* ~ */) { return false; }\n if (state.level >= state.options.maxNesting) { return false; }\n\n lastChar = start > 0 ? state.src.charCodeAt(start - 1) : -1;\n nextChar = state.src.charCodeAt(start + 2);\n\n if (lastChar === 0x7E/* ~ */) { return false; }\n if (nextChar === 0x7E/* ~ */) { return false; }\n if (nextChar === 0x20 || nextChar === 0x0A) { return false; }\n\n pos = start + 2;\n while (pos < max && state.src.charCodeAt(pos) === 0x7E/* ~ */) { pos++; }\n if (pos > start + 3) {\n // sequence of 4+ markers taking as literal, same as in a emphasis\n state.pos += pos - start;\n if (!silent) { state.pending += state.src.slice(start, pos); }\n return true;\n }\n\n state.pos = start + 2;\n stack = 1;\n\n while (state.pos + 1 < max) {\n if (state.src.charCodeAt(state.pos) === 0x7E/* ~ */) {\n if (state.src.charCodeAt(state.pos + 1) === 0x7E/* ~ */) {\n lastChar = state.src.charCodeAt(state.pos - 1);\n nextChar = state.pos + 2 < max ? state.src.charCodeAt(state.pos + 2) : -1;\n if (nextChar !== 0x7E/* ~ */ && lastChar !== 0x7E/* ~ */) {\n if (lastChar !== 0x20 && lastChar !== 0x0A) {\n // closing '~~'\n stack--;\n } else if (nextChar !== 0x20 && nextChar !== 0x0A) {\n // opening '~~'\n stack++;\n } // else {\n // // standalone ' ~~ ' indented with spaces\n // }\n if (stack <= 0) {\n found = true;\n break;\n }\n }\n }\n }\n\n state.parser.skipToken(state);\n }\n\n if (!found) {\n // parser failed to find ending tag, so it's not valid emphasis\n state.pos = start;\n return false;\n }\n\n // found!\n state.posMax = state.pos;\n state.pos = start + 2;\n\n if (!silent) {\n state.push({ type: 'del_open', level: state.level++ });\n state.parser.tokenize(state);\n state.push({ type: 'del_close', level: --state.level });\n }\n\n state.pos = state.posMax + 2;\n state.posMax = max;\n return true;\n}\n\n// Process ++inserted text++\n\nfunction ins(state, silent) {\n var found,\n pos,\n stack,\n max = state.posMax,\n start = state.pos,\n lastChar,\n nextChar;\n\n if (state.src.charCodeAt(start) !== 0x2B/* + */) { return false; }\n if (silent) { return false; } // don't run any pairs in validation mode\n if (start + 4 >= max) { return false; }\n if (state.src.charCodeAt(start + 1) !== 0x2B/* + */) { return false; }\n if (state.level >= state.options.maxNesting) { return false; }\n\n lastChar = start > 0 ? state.src.charCodeAt(start - 1) : -1;\n nextChar = state.src.charCodeAt(start + 2);\n\n if (lastChar === 0x2B/* + */) { return false; }\n if (nextChar === 0x2B/* + */) { return false; }\n if (nextChar === 0x20 || nextChar === 0x0A) { return false; }\n\n pos = start + 2;\n while (pos < max && state.src.charCodeAt(pos) === 0x2B/* + */) { pos++; }\n if (pos !== start + 2) {\n // sequence of 3+ markers taking as literal, same as in a emphasis\n state.pos += pos - start;\n if (!silent) { state.pending += state.src.slice(start, pos); }\n return true;\n }\n\n state.pos = start + 2;\n stack = 1;\n\n while (state.pos + 1 < max) {\n if (state.src.charCodeAt(state.pos) === 0x2B/* + */) {\n if (state.src.charCodeAt(state.pos + 1) === 0x2B/* + */) {\n lastChar = state.src.charCodeAt(state.pos - 1);\n nextChar = state.pos + 2 < max ? state.src.charCodeAt(state.pos + 2) : -1;\n if (nextChar !== 0x2B/* + */ && lastChar !== 0x2B/* + */) {\n if (lastChar !== 0x20 && lastChar !== 0x0A) {\n // closing '++'\n stack--;\n } else if (nextChar !== 0x20 && nextChar !== 0x0A) {\n // opening '++'\n stack++;\n } // else {\n // // standalone ' ++ ' indented with spaces\n // }\n if (stack <= 0) {\n found = true;\n break;\n }\n }\n }\n }\n\n state.parser.skipToken(state);\n }\n\n if (!found) {\n // parser failed to find ending tag, so it's not valid emphasis\n state.pos = start;\n return false;\n }\n\n // found!\n state.posMax = state.pos;\n state.pos = start + 2;\n\n if (!silent) {\n state.push({ type: 'ins_open', level: state.level++ });\n state.parser.tokenize(state);\n state.push({ type: 'ins_close', level: --state.level });\n }\n\n state.pos = state.posMax + 2;\n state.posMax = max;\n return true;\n}\n\n// Process ==highlighted text==\n\nfunction mark(state, silent) {\n var found,\n pos,\n stack,\n max = state.posMax,\n start = state.pos,\n lastChar,\n nextChar;\n\n if (state.src.charCodeAt(start) !== 0x3D/* = */) { return false; }\n if (silent) { return false; } // don't run any pairs in validation mode\n if (start + 4 >= max) { return false; }\n if (state.src.charCodeAt(start + 1) !== 0x3D/* = */) { return false; }\n if (state.level >= state.options.maxNesting) { return false; }\n\n lastChar = start > 0 ? state.src.charCodeAt(start - 1) : -1;\n nextChar = state.src.charCodeAt(start + 2);\n\n if (lastChar === 0x3D/* = */) { return false; }\n if (nextChar === 0x3D/* = */) { return false; }\n if (nextChar === 0x20 || nextChar === 0x0A) { return false; }\n\n pos = start + 2;\n while (pos < max && state.src.charCodeAt(pos) === 0x3D/* = */) { pos++; }\n if (pos !== start + 2) {\n // sequence of 3+ markers taking as literal, same as in a emphasis\n state.pos += pos - start;\n if (!silent) { state.pending += state.src.slice(start, pos); }\n return true;\n }\n\n state.pos = start + 2;\n stack = 1;\n\n while (state.pos + 1 < max) {\n if (state.src.charCodeAt(state.pos) === 0x3D/* = */) {\n if (state.src.charCodeAt(state.pos + 1) === 0x3D/* = */) {\n lastChar = state.src.charCodeAt(state.pos - 1);\n nextChar = state.pos + 2 < max ? state.src.charCodeAt(state.pos + 2) : -1;\n if (nextChar !== 0x3D/* = */ && lastChar !== 0x3D/* = */) {\n if (lastChar !== 0x20 && lastChar !== 0x0A) {\n // closing '=='\n stack--;\n } else if (nextChar !== 0x20 && nextChar !== 0x0A) {\n // opening '=='\n stack++;\n } // else {\n // // standalone ' == ' indented with spaces\n // }\n if (stack <= 0) {\n found = true;\n break;\n }\n }\n }\n }\n\n state.parser.skipToken(state);\n }\n\n if (!found) {\n // parser failed to find ending tag, so it's not valid emphasis\n state.pos = start;\n return false;\n }\n\n // found!\n state.posMax = state.pos;\n state.pos = start + 2;\n\n if (!silent) {\n state.push({ type: 'mark_open', level: state.level++ });\n state.parser.tokenize(state);\n state.push({ type: 'mark_close', level: --state.level });\n }\n\n state.pos = state.posMax + 2;\n state.posMax = max;\n return true;\n}\n\n// Process *this* and _that_\n\nfunction isAlphaNum(code) {\n return (code >= 0x30 /* 0 */ && code <= 0x39 /* 9 */) ||\n (code >= 0x41 /* A */ && code <= 0x5A /* Z */) ||\n (code >= 0x61 /* a */ && code <= 0x7A /* z */);\n}\n\n// parse sequence of emphasis markers,\n// \"start\" should point at a valid marker\nfunction scanDelims(state, start) {\n var pos = start, lastChar, nextChar, count,\n can_open = true,\n can_close = true,\n max = state.posMax,\n marker = state.src.charCodeAt(start);\n\n lastChar = start > 0 ? state.src.charCodeAt(start - 1) : -1;\n\n while (pos < max && state.src.charCodeAt(pos) === marker) { pos++; }\n if (pos >= max) { can_open = false; }\n count = pos - start;\n\n if (count >= 4) {\n // sequence of four or more unescaped markers can't start/end an emphasis\n can_open = can_close = false;\n } else {\n nextChar = pos < max ? state.src.charCodeAt(pos) : -1;\n\n // check whitespace conditions\n if (nextChar === 0x20 || nextChar === 0x0A) { can_open = false; }\n if (lastChar === 0x20 || lastChar === 0x0A) { can_close = false; }\n\n if (marker === 0x5F /* _ */) {\n // check if we aren't inside the word\n if (isAlphaNum(lastChar)) { can_open = false; }\n if (isAlphaNum(nextChar)) { can_close = false; }\n }\n }\n\n return {\n can_open: can_open,\n can_close: can_close,\n delims: count\n };\n}\n\nfunction emphasis(state, silent) {\n var startCount,\n count,\n found,\n oldCount,\n newCount,\n stack,\n res,\n max = state.posMax,\n start = state.pos,\n marker = state.src.charCodeAt(start);\n\n if (marker !== 0x5F/* _ */ && marker !== 0x2A /* * */) { return false; }\n if (silent) { return false; } // don't run any pairs in validation mode\n\n res = scanDelims(state, start);\n startCount = res.delims;\n if (!res.can_open) {\n state.pos += startCount;\n if (!silent) { state.pending += state.src.slice(start, state.pos); }\n return true;\n }\n\n if (state.level >= state.options.maxNesting) { return false; }\n\n state.pos = start + startCount;\n stack = [ startCount ];\n\n while (state.pos < max) {\n if (state.src.charCodeAt(state.pos) === marker) {\n res = scanDelims(state, state.pos);\n count = res.delims;\n if (res.can_close) {\n oldCount = stack.pop();\n newCount = count;\n\n while (oldCount !== newCount) {\n if (newCount < oldCount) {\n stack.push(oldCount - newCount);\n break;\n }\n\n // assert(newCount > oldCount)\n newCount -= oldCount;\n\n if (stack.length === 0) { break; }\n state.pos += oldCount;\n oldCount = stack.pop();\n }\n\n if (stack.length === 0) {\n startCount = oldCount;\n found = true;\n break;\n }\n state.pos += count;\n continue;\n }\n\n if (res.can_open) { stack.push(count); }\n state.pos += count;\n continue;\n }\n\n state.parser.skipToken(state);\n }\n\n if (!found) {\n // parser failed to find ending tag, so it's not valid emphasis\n state.pos = start;\n return false;\n }\n\n // found!\n state.posMax = state.pos;\n state.pos = start + startCount;\n\n if (!silent) {\n if (startCount === 2 || startCount === 3) {\n state.push({ type: 'strong_open', level: state.level++ });\n }\n if (startCount === 1 || startCount === 3) {\n state.push({ type: 'em_open', level: state.level++ });\n }\n\n state.parser.tokenize(state);\n\n if (startCount === 1 || startCount === 3) {\n state.push({ type: 'em_close', level: --state.level });\n }\n if (startCount === 2 || startCount === 3) {\n state.push({ type: 'strong_close', level: --state.level });\n }\n }\n\n state.pos = state.posMax + startCount;\n state.posMax = max;\n return true;\n}\n\n// Process ~subscript~\n\n// same as UNESCAPE_MD_RE plus a space\nvar UNESCAPE_RE = /\\\\([ \\\\!\"#$%&'()*+,.\\/:;<=>?@[\\]^_`{|}~-])/g;\n\nfunction sub(state, silent) {\n var found,\n content,\n max = state.posMax,\n start = state.pos;\n\n if (state.src.charCodeAt(start) !== 0x7E/* ~ */) { return false; }\n if (silent) { return false; } // don't run any pairs in validation mode\n if (start + 2 >= max) { return false; }\n if (state.level >= state.options.maxNesting) { return false; }\n\n state.pos = start + 1;\n\n while (state.pos < max) {\n if (state.src.charCodeAt(state.pos) === 0x7E/* ~ */) {\n found = true;\n break;\n }\n\n state.parser.skipToken(state);\n }\n\n if (!found || start + 1 === state.pos) {\n state.pos = start;\n return false;\n }\n\n content = state.src.slice(start + 1, state.pos);\n\n // don't allow unescaped spaces/newlines inside\n if (content.match(/(^|[^\\\\])(\\\\\\\\)*\\s/)) {\n state.pos = start;\n return false;\n }\n\n // found!\n state.posMax = state.pos;\n state.pos = start + 1;\n\n if (!silent) {\n state.push({\n type: 'sub',\n level: state.level,\n content: content.replace(UNESCAPE_RE, '$1')\n });\n }\n\n state.pos = state.posMax + 1;\n state.posMax = max;\n return true;\n}\n\n// Process ^superscript^\n\n// same as UNESCAPE_MD_RE plus a space\nvar UNESCAPE_RE$1 = /\\\\([ \\\\!\"#$%&'()*+,.\\/:;<=>?@[\\]^_`{|}~-])/g;\n\nfunction sup(state, silent) {\n var found,\n content,\n max = state.posMax,\n start = state.pos;\n\n if (state.src.charCodeAt(start) !== 0x5E/* ^ */) { return false; }\n if (silent) { return false; } // don't run any pairs in validation mode\n if (start + 2 >= max) { return false; }\n if (state.level >= state.options.maxNesting) { return false; }\n\n state.pos = start + 1;\n\n while (state.pos < max) {\n if (state.src.charCodeAt(state.pos) === 0x5E/* ^ */) {\n found = true;\n break;\n }\n\n state.parser.skipToken(state);\n }\n\n if (!found || start + 1 === state.pos) {\n state.pos = start;\n return false;\n }\n\n content = state.src.slice(start + 1, state.pos);\n\n // don't allow unescaped spaces/newlines inside\n if (content.match(/(^|[^\\\\])(\\\\\\\\)*\\s/)) {\n state.pos = start;\n return false;\n }\n\n // found!\n state.posMax = state.pos;\n state.pos = start + 1;\n\n if (!silent) {\n state.push({\n type: 'sup',\n level: state.level,\n content: content.replace(UNESCAPE_RE$1, '$1')\n });\n }\n\n state.pos = state.posMax + 1;\n state.posMax = max;\n return true;\n}\n\n// Process [links]( \"stuff\")\n\n\nfunction links(state, silent) {\n var labelStart,\n labelEnd,\n label,\n href,\n title,\n pos,\n ref,\n code,\n isImage = false,\n oldPos = state.pos,\n max = state.posMax,\n start = state.pos,\n marker = state.src.charCodeAt(start);\n\n if (marker === 0x21/* ! */) {\n isImage = true;\n marker = state.src.charCodeAt(++start);\n }\n\n if (marker !== 0x5B/* [ */) { return false; }\n if (state.level >= state.options.maxNesting) { return false; }\n\n labelStart = start + 1;\n labelEnd = parseLinkLabel(state, start);\n\n // parser failed to find ']', so it's not a valid link\n if (labelEnd < 0) { return false; }\n\n pos = labelEnd + 1;\n if (pos < max && state.src.charCodeAt(pos) === 0x28/* ( */) {\n //\n // Inline link\n //\n\n // [link]( \"title\" )\n // ^^ skipping these spaces\n pos++;\n for (; pos < max; pos++) {\n code = state.src.charCodeAt(pos);\n if (code !== 0x20 && code !== 0x0A) { break; }\n }\n if (pos >= max) { return false; }\n\n // [link]( \"title\" )\n // ^^^^^^ parsing link destination\n start = pos;\n if (parseLinkDestination(state, pos)) {\n href = state.linkContent;\n pos = state.pos;\n } else {\n href = '';\n }\n\n // [link]( \"title\" )\n // ^^ skipping these spaces\n start = pos;\n for (; pos < max; pos++) {\n code = state.src.charCodeAt(pos);\n if (code !== 0x20 && code !== 0x0A) { break; }\n }\n\n // [link]( \"title\" )\n // ^^^^^^^ parsing link title\n if (pos < max && start !== pos && parseLinkTitle(state, pos)) {\n title = state.linkContent;\n pos = state.pos;\n\n // [link]( \"title\" )\n // ^^ skipping these spaces\n for (; pos < max; pos++) {\n code = state.src.charCodeAt(pos);\n if (code !== 0x20 && code !== 0x0A) { break; }\n }\n } else {\n title = '';\n }\n\n if (pos >= max || state.src.charCodeAt(pos) !== 0x29/* ) */) {\n state.pos = oldPos;\n return false;\n }\n pos++;\n } else {\n //\n // Link reference\n //\n\n // do not allow nested reference links\n if (state.linkLevel > 0) { return false; }\n\n // [foo] [bar]\n // ^^ optional whitespace (can include newlines)\n for (; pos < max; pos++) {\n code = state.src.charCodeAt(pos);\n if (code !== 0x20 && code !== 0x0A) { break; }\n }\n\n if (pos < max && state.src.charCodeAt(pos) === 0x5B/* [ */) {\n start = pos + 1;\n pos = parseLinkLabel(state, pos);\n if (pos >= 0) {\n label = state.src.slice(start, pos++);\n } else {\n pos = start - 1;\n }\n }\n\n // covers label === '' and label === undefined\n // (collapsed reference link and shortcut reference link respectively)\n if (!label) {\n if (typeof label === 'undefined') {\n pos = labelEnd + 1;\n }\n label = state.src.slice(labelStart, labelEnd);\n }\n\n ref = state.env.references[normalizeReference(label)];\n if (!ref) {\n state.pos = oldPos;\n return false;\n }\n href = ref.href;\n title = ref.title;\n }\n\n //\n // We found the end of the link, and know for a fact it's a valid link;\n // so all that's left to do is to call tokenizer.\n //\n if (!silent) {\n state.pos = labelStart;\n state.posMax = labelEnd;\n\n if (isImage) {\n state.push({\n type: 'image',\n src: href,\n title: title,\n alt: state.src.substr(labelStart, labelEnd - labelStart),\n level: state.level\n });\n } else {\n state.push({\n type: 'link_open',\n href: href,\n title: title,\n level: state.level++\n });\n state.linkLevel++;\n state.parser.tokenize(state);\n state.linkLevel--;\n state.push({ type: 'link_close', level: --state.level });\n }\n }\n\n state.pos = pos;\n state.posMax = max;\n return true;\n}\n\n// Process inline footnotes (^[...])\n\n\nfunction footnote_inline(state, silent) {\n var labelStart,\n labelEnd,\n footnoteId,\n oldLength,\n max = state.posMax,\n start = state.pos;\n\n if (start + 2 >= max) { return false; }\n if (state.src.charCodeAt(start) !== 0x5E/* ^ */) { return false; }\n if (state.src.charCodeAt(start + 1) !== 0x5B/* [ */) { return false; }\n if (state.level >= state.options.maxNesting) { return false; }\n\n labelStart = start + 2;\n labelEnd = parseLinkLabel(state, start + 1);\n\n // parser failed to find ']', so it's not a valid note\n if (labelEnd < 0) { return false; }\n\n // We found the end of the link, and know for a fact it's a valid link;\n // so all that's left to do is to call tokenizer.\n //\n if (!silent) {\n if (!state.env.footnotes) { state.env.footnotes = {}; }\n if (!state.env.footnotes.list) { state.env.footnotes.list = []; }\n footnoteId = state.env.footnotes.list.length;\n\n state.pos = labelStart;\n state.posMax = labelEnd;\n\n state.push({\n type: 'footnote_ref',\n id: footnoteId,\n level: state.level\n });\n state.linkLevel++;\n oldLength = state.tokens.length;\n state.parser.tokenize(state);\n state.env.footnotes.list[footnoteId] = { tokens: state.tokens.splice(oldLength) };\n state.linkLevel--;\n }\n\n state.pos = labelEnd + 1;\n state.posMax = max;\n return true;\n}\n\n// Process footnote references ([^...])\n\nfunction footnote_ref(state, silent) {\n var label,\n pos,\n footnoteId,\n footnoteSubId,\n max = state.posMax,\n start = state.pos;\n\n // should be at least 4 chars - \"[^x]\"\n if (start + 3 > max) { return false; }\n\n if (!state.env.footnotes || !state.env.footnotes.refs) { return false; }\n if (state.src.charCodeAt(start) !== 0x5B/* [ */) { return false; }\n if (state.src.charCodeAt(start + 1) !== 0x5E/* ^ */) { return false; }\n if (state.level >= state.options.maxNesting) { return false; }\n\n for (pos = start + 2; pos < max; pos++) {\n if (state.src.charCodeAt(pos) === 0x20) { return false; }\n if (state.src.charCodeAt(pos) === 0x0A) { return false; }\n if (state.src.charCodeAt(pos) === 0x5D /* ] */) {\n break;\n }\n }\n\n if (pos === start + 2) { return false; } // no empty footnote labels\n if (pos >= max) { return false; }\n pos++;\n\n label = state.src.slice(start + 2, pos - 1);\n if (typeof state.env.footnotes.refs[':' + label] === 'undefined') { return false; }\n\n if (!silent) {\n if (!state.env.footnotes.list) { state.env.footnotes.list = []; }\n\n if (state.env.footnotes.refs[':' + label] < 0) {\n footnoteId = state.env.footnotes.list.length;\n state.env.footnotes.list[footnoteId] = { label: label, count: 0 };\n state.env.footnotes.refs[':' + label] = footnoteId;\n } else {\n footnoteId = state.env.footnotes.refs[':' + label];\n }\n\n footnoteSubId = state.env.footnotes.list[footnoteId].count;\n state.env.footnotes.list[footnoteId].count++;\n\n state.push({\n type: 'footnote_ref',\n id: footnoteId,\n subId: footnoteSubId,\n level: state.level\n });\n }\n\n state.pos = pos;\n state.posMax = max;\n return true;\n}\n\n// List of valid url schemas, accorting to commonmark spec\n// http://jgm.github.io/CommonMark/spec.html#autolinks\n\nvar url_schemas = [\n 'coap',\n 'doi',\n 'javascript',\n 'aaa',\n 'aaas',\n 'about',\n 'acap',\n 'cap',\n 'cid',\n 'crid',\n 'data',\n 'dav',\n 'dict',\n 'dns',\n 'file',\n 'ftp',\n 'geo',\n 'go',\n 'gopher',\n 'h323',\n 'http',\n 'https',\n 'iax',\n 'icap',\n 'im',\n 'imap',\n 'info',\n 'ipp',\n 'iris',\n 'iris.beep',\n 'iris.xpc',\n 'iris.xpcs',\n 'iris.lwz',\n 'ldap',\n 'mailto',\n 'mid',\n 'msrp',\n 'msrps',\n 'mtqp',\n 'mupdate',\n 'news',\n 'nfs',\n 'ni',\n 'nih',\n 'nntp',\n 'opaquelocktoken',\n 'pop',\n 'pres',\n 'rtsp',\n 'service',\n 'session',\n 'shttp',\n 'sieve',\n 'sip',\n 'sips',\n 'sms',\n 'snmp',\n 'soap.beep',\n 'soap.beeps',\n 'tag',\n 'tel',\n 'telnet',\n 'tftp',\n 'thismessage',\n 'tn3270',\n 'tip',\n 'tv',\n 'urn',\n 'vemmi',\n 'ws',\n 'wss',\n 'xcon',\n 'xcon-userid',\n 'xmlrpc.beep',\n 'xmlrpc.beeps',\n 'xmpp',\n 'z39.50r',\n 'z39.50s',\n 'adiumxtra',\n 'afp',\n 'afs',\n 'aim',\n 'apt',\n 'attachment',\n 'aw',\n 'beshare',\n 'bitcoin',\n 'bolo',\n 'callto',\n 'chrome',\n 'chrome-extension',\n 'com-eventbrite-attendee',\n 'content',\n 'cvs',\n 'dlna-playsingle',\n 'dlna-playcontainer',\n 'dtn',\n 'dvb',\n 'ed2k',\n 'facetime',\n 'feed',\n 'finger',\n 'fish',\n 'gg',\n 'git',\n 'gizmoproject',\n 'gtalk',\n 'hcp',\n 'icon',\n 'ipn',\n 'irc',\n 'irc6',\n 'ircs',\n 'itms',\n 'jar',\n 'jms',\n 'keyparc',\n 'lastfm',\n 'ldaps',\n 'magnet',\n 'maps',\n 'market',\n 'message',\n 'mms',\n 'ms-help',\n 'msnim',\n 'mumble',\n 'mvn',\n 'notes',\n 'oid',\n 'palm',\n 'paparazzi',\n 'platform',\n 'proxy',\n 'psyc',\n 'query',\n 'res',\n 'resource',\n 'rmi',\n 'rsync',\n 'rtmp',\n 'secondlife',\n 'sftp',\n 'sgn',\n 'skype',\n 'smb',\n 'soldat',\n 'spotify',\n 'ssh',\n 'steam',\n 'svn',\n 'teamspeak',\n 'things',\n 'udp',\n 'unreal',\n 'ut2004',\n 'ventrilo',\n 'view-source',\n 'webcal',\n 'wtai',\n 'wyciwyg',\n 'xfire',\n 'xri',\n 'ymsgr'\n];\n\n// Process autolinks ''\n\n\n/*eslint max-len:0*/\nvar EMAIL_RE = /^<([a-zA-Z0-9.!#$%&'*+\\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*)>/;\nvar AUTOLINK_RE = /^<([a-zA-Z.\\-]{1,25}):([^<>\\x00-\\x20]*)>/;\n\n\nfunction autolink(state, silent) {\n var tail, linkMatch, emailMatch, url, fullUrl, pos = state.pos;\n\n if (state.src.charCodeAt(pos) !== 0x3C/* < */) { return false; }\n\n tail = state.src.slice(pos);\n\n if (tail.indexOf('>') < 0) { return false; }\n\n linkMatch = tail.match(AUTOLINK_RE);\n\n if (linkMatch) {\n if (url_schemas.indexOf(linkMatch[1].toLowerCase()) < 0) { return false; }\n\n url = linkMatch[0].slice(1, -1);\n fullUrl = normalizeLink(url);\n if (!state.parser.validateLink(url)) { return false; }\n\n if (!silent) {\n state.push({\n type: 'link_open',\n href: fullUrl,\n level: state.level\n });\n state.push({\n type: 'text',\n content: url,\n level: state.level + 1\n });\n state.push({ type: 'link_close', level: state.level });\n }\n\n state.pos += linkMatch[0].length;\n return true;\n }\n\n emailMatch = tail.match(EMAIL_RE);\n\n if (emailMatch) {\n\n url = emailMatch[0].slice(1, -1);\n\n fullUrl = normalizeLink('mailto:' + url);\n if (!state.parser.validateLink(fullUrl)) { return false; }\n\n if (!silent) {\n state.push({\n type: 'link_open',\n href: fullUrl,\n level: state.level\n });\n state.push({\n type: 'text',\n content: url,\n level: state.level + 1\n });\n state.push({ type: 'link_close', level: state.level });\n }\n\n state.pos += emailMatch[0].length;\n return true;\n }\n\n return false;\n}\n\n// Regexps to match html elements\n\nfunction replace$1(regex, options) {\n regex = regex.source;\n options = options || '';\n\n return function self(name, val) {\n if (!name) {\n return new RegExp(regex, options);\n }\n val = val.source || val;\n regex = regex.replace(name, val);\n return self;\n };\n}\n\n\nvar attr_name = /[a-zA-Z_:][a-zA-Z0-9:._-]*/;\n\nvar unquoted = /[^\"'=<>`\\x00-\\x20]+/;\nvar single_quoted = /'[^']*'/;\nvar double_quoted = /\"[^\"]*\"/;\n\n/*eslint no-spaced-func:0*/\nvar attr_value = replace$1(/(?:unquoted|single_quoted|double_quoted)/)\n ('unquoted', unquoted)\n ('single_quoted', single_quoted)\n ('double_quoted', double_quoted)\n ();\n\nvar attribute = replace$1(/(?:\\s+attr_name(?:\\s*=\\s*attr_value)?)/)\n ('attr_name', attr_name)\n ('attr_value', attr_value)\n ();\n\nvar open_tag = replace$1(/<[A-Za-z][A-Za-z0-9]*attribute*\\s*\\/?>/)\n ('attribute', attribute)\n ();\n\nvar close_tag = /<\\/[A-Za-z][A-Za-z0-9]*\\s*>/;\nvar comment = /|/;\nvar processing = /<[?].*?[?]>/;\nvar declaration = /]*>/;\nvar cdata = //;\n\nvar HTML_TAG_RE = replace$1(/^(?:open_tag|close_tag|comment|processing|declaration|cdata)/)\n ('open_tag', open_tag)\n ('close_tag', close_tag)\n ('comment', comment)\n ('processing', processing)\n ('declaration', declaration)\n ('cdata', cdata)\n ();\n\n// Process html tags\n\n\nfunction isLetter$2(ch) {\n /*eslint no-bitwise:0*/\n var lc = ch | 0x20; // to lower case\n return (lc >= 0x61/* a */) && (lc <= 0x7a/* z */);\n}\n\n\nfunction htmltag(state, silent) {\n var ch, match, max, pos = state.pos;\n\n if (!state.options.html) { return false; }\n\n // Check start\n max = state.posMax;\n if (state.src.charCodeAt(pos) !== 0x3C/* < */ ||\n pos + 2 >= max) {\n return false;\n }\n\n // Quick fail on second char\n ch = state.src.charCodeAt(pos + 1);\n if (ch !== 0x21/* ! */ &&\n ch !== 0x3F/* ? */ &&\n ch !== 0x2F/* / */ &&\n !isLetter$2(ch)) {\n return false;\n }\n\n match = state.src.slice(pos).match(HTML_TAG_RE);\n if (!match) { return false; }\n\n if (!silent) {\n state.push({\n type: 'htmltag',\n content: state.src.slice(pos, pos + match[0].length),\n level: state.level\n });\n }\n state.pos += match[0].length;\n return true;\n}\n\n// Process html entity - {, ¯, ", ...\n\n\nvar DIGITAL_RE = /^&#((?:x[a-f0-9]{1,8}|[0-9]{1,8}));/i;\nvar NAMED_RE = /^&([a-z][a-z0-9]{1,31});/i;\n\n\nfunction entity(state, silent) {\n var ch, code, match, pos = state.pos, max = state.posMax;\n\n if (state.src.charCodeAt(pos) !== 0x26/* & */) { return false; }\n\n if (pos + 1 < max) {\n ch = state.src.charCodeAt(pos + 1);\n\n if (ch === 0x23 /* # */) {\n match = state.src.slice(pos).match(DIGITAL_RE);\n if (match) {\n if (!silent) {\n code = match[1][0].toLowerCase() === 'x' ? parseInt(match[1].slice(1), 16) : parseInt(match[1], 10);\n state.pending += isValidEntityCode(code) ? fromCodePoint(code) : fromCodePoint(0xFFFD);\n }\n state.pos += match[0].length;\n return true;\n }\n } else {\n match = state.src.slice(pos).match(NAMED_RE);\n if (match) {\n var decoded = decodeEntity(match[1]);\n if (match[1] !== decoded) {\n if (!silent) { state.pending += decoded; }\n state.pos += match[0].length;\n return true;\n }\n }\n }\n }\n\n if (!silent) { state.pending += '&'; }\n state.pos++;\n return true;\n}\n\n/**\n * Inline Parser `rules`\n */\n\nvar _rules$2 = [\n [ 'text', text ],\n [ 'newline', newline ],\n [ 'escape', escape ],\n [ 'backticks', backticks ],\n [ 'del', del ],\n [ 'ins', ins ],\n [ 'mark', mark ],\n [ 'emphasis', emphasis ],\n [ 'sub', sub ],\n [ 'sup', sup ],\n [ 'links', links ],\n [ 'footnote_inline', footnote_inline ],\n [ 'footnote_ref', footnote_ref ],\n [ 'autolink', autolink ],\n [ 'htmltag', htmltag ],\n [ 'entity', entity ]\n];\n\n/**\n * Inline Parser class. Note that link validation is stricter\n * in Remarkable than what is specified by CommonMark. If you\n * want to change this you can use a custom validator.\n *\n * @api private\n */\n\nfunction ParserInline() {\n this.ruler = new Ruler();\n for (var i = 0; i < _rules$2.length; i++) {\n this.ruler.push(_rules$2[i][0], _rules$2[i][1]);\n }\n\n // Can be overridden with a custom validator\n this.validateLink = validateLink;\n}\n\n/**\n * Skip a single token by running all rules in validation mode.\n * Returns `true` if any rule reports success.\n *\n * @param {Object} `state`\n * @api privage\n */\n\nParserInline.prototype.skipToken = function (state) {\n var rules = this.ruler.getRules('');\n var len = rules.length;\n var pos = state.pos;\n var i, cached_pos;\n\n if ((cached_pos = state.cacheGet(pos)) > 0) {\n state.pos = cached_pos;\n return;\n }\n\n for (i = 0; i < len; i++) {\n if (rules[i](state, true)) {\n state.cacheSet(pos, state.pos);\n return;\n }\n }\n\n state.pos++;\n state.cacheSet(pos, state.pos);\n};\n\n/**\n * Generate tokens for the given input range.\n *\n * @param {Object} `state`\n * @api private\n */\n\nParserInline.prototype.tokenize = function (state) {\n var rules = this.ruler.getRules('');\n var len = rules.length;\n var end = state.posMax;\n var ok, i;\n\n while (state.pos < end) {\n\n // Try all possible rules.\n // On success, the rule should:\n //\n // - update `state.pos`\n // - update `state.tokens`\n // - return true\n for (i = 0; i < len; i++) {\n ok = rules[i](state, false);\n\n if (ok) {\n break;\n }\n }\n\n if (ok) {\n if (state.pos >= end) { break; }\n continue;\n }\n\n state.pending += state.src[state.pos++];\n }\n\n if (state.pending) {\n state.pushPending();\n }\n};\n\n/**\n * Parse the given input string.\n *\n * @param {String} `str`\n * @param {Object} `options`\n * @param {Object} `env`\n * @param {Array} `outTokens`\n * @api private\n */\n\nParserInline.prototype.parse = function (str, options, env, outTokens) {\n var state = new StateInline(str, this, options, env, outTokens);\n this.tokenize(state);\n};\n\n/**\n * Validate the given `url` by checking for bad protocols.\n *\n * @param {String} `url`\n * @return {Boolean}\n */\n\nfunction validateLink(url) {\n var BAD_PROTOCOLS = [ 'vbscript', 'javascript', 'file', 'data' ];\n var str = url.trim().toLowerCase();\n // Care about digital entities \"javascript:alert(1)\"\n str = replaceEntities(str);\n if (str.indexOf(':') !== -1 && BAD_PROTOCOLS.indexOf(str.split(':')[0]) !== -1) {\n return false;\n }\n return true;\n}\n\n// Remarkable default options\n\nvar defaultConfig = {\n options: {\n html: false, // Enable HTML tags in source\n xhtmlOut: false, // Use '/' to close single tags (
    )\n breaks: false, // Convert '\\n' in paragraphs into
    \n langPrefix: 'language-', // CSS language prefix for fenced blocks\n linkTarget: '', // set target to open link in\n\n // Enable some language-neutral replacements + quotes beautification\n typographer: false,\n\n // Double + single quotes replacement pairs, when typographer enabled,\n // and smartquotes on. Set doubles to '«»' for Russian, '„“' for German.\n quotes: '“”‘’',\n\n // Highlighter function. Should return escaped HTML,\n // or '' if input not changed\n //\n // function (/*str, lang*/) { return ''; }\n //\n highlight: null,\n\n maxNesting: 20 // Internal protection, recursion limit\n },\n\n components: {\n\n core: {\n rules: [\n 'block',\n 'inline',\n 'references',\n 'replacements',\n 'smartquotes',\n 'references',\n 'abbr2',\n 'footnote_tail'\n ]\n },\n\n block: {\n rules: [\n 'blockquote',\n 'code',\n 'fences',\n 'footnote',\n 'heading',\n 'hr',\n 'htmlblock',\n 'lheading',\n 'list',\n 'paragraph',\n 'table'\n ]\n },\n\n inline: {\n rules: [\n 'autolink',\n 'backticks',\n 'del',\n 'emphasis',\n 'entity',\n 'escape',\n 'footnote_ref',\n 'htmltag',\n 'links',\n 'newline',\n 'text'\n ]\n }\n }\n};\n\n// Remarkable default options\n\nvar fullConfig = {\n options: {\n html: false, // Enable HTML tags in source\n xhtmlOut: false, // Use '/' to close single tags (
    )\n breaks: false, // Convert '\\n' in paragraphs into
    \n langPrefix: 'language-', // CSS language prefix for fenced blocks\n linkTarget: '', // set target to open link in\n\n // Enable some language-neutral replacements + quotes beautification\n typographer: false,\n\n // Double + single quotes replacement pairs, when typographer enabled,\n // and smartquotes on. Set doubles to '«»' for Russian, '„“' for German.\n quotes: '“”‘’',\n\n // Highlighter function. Should return escaped HTML,\n // or '' if input not changed\n //\n // function (/*str, lang*/) { return ''; }\n //\n highlight: null,\n\n maxNesting: 20 // Internal protection, recursion limit\n },\n\n components: {\n // Don't restrict core/block/inline rules\n core: {},\n block: {},\n inline: {}\n }\n};\n\n// Commonmark default options\n\nvar commonmarkConfig = {\n options: {\n html: true, // Enable HTML tags in source\n xhtmlOut: true, // Use '/' to close single tags (
    )\n breaks: false, // Convert '\\n' in paragraphs into
    \n langPrefix: 'language-', // CSS language prefix for fenced blocks\n linkTarget: '', // set target to open link in\n\n // Enable some language-neutral replacements + quotes beautification\n typographer: false,\n\n // Double + single quotes replacement pairs, when typographer enabled,\n // and smartquotes on. Set doubles to '«»' for Russian, '„“' for German.\n quotes: '“”‘’',\n\n // Highlighter function. Should return escaped HTML,\n // or '' if input not changed\n //\n // function (/*str, lang*/) { return ''; }\n //\n highlight: null,\n\n maxNesting: 20 // Internal protection, recursion limit\n },\n\n components: {\n\n core: {\n rules: [\n 'block',\n 'inline',\n 'references',\n 'abbr2'\n ]\n },\n\n block: {\n rules: [\n 'blockquote',\n 'code',\n 'fences',\n 'heading',\n 'hr',\n 'htmlblock',\n 'lheading',\n 'list',\n 'paragraph'\n ]\n },\n\n inline: {\n rules: [\n 'autolink',\n 'backticks',\n 'emphasis',\n 'entity',\n 'escape',\n 'htmltag',\n 'links',\n 'newline',\n 'text'\n ]\n }\n }\n};\n\n/**\n * Preset configs\n */\n\nvar config = {\n 'default': defaultConfig,\n 'full': fullConfig,\n 'commonmark': commonmarkConfig\n};\n\n/**\n * The `StateCore` class manages state.\n *\n * @param {Object} `instance` Remarkable instance\n * @param {String} `str` Markdown string\n * @param {Object} `env`\n */\n\nfunction StateCore(instance, str, env) {\n this.src = str;\n this.env = env;\n this.options = instance.options;\n this.tokens = [];\n this.inlineMode = false;\n\n this.inline = instance.inline;\n this.block = instance.block;\n this.renderer = instance.renderer;\n this.typographer = instance.typographer;\n}\n\n/**\n * The main `Remarkable` class. Create an instance of\n * `Remarkable` with a `preset` and/or `options`.\n *\n * @param {String} `preset` If no preset is given, `default` is used.\n * @param {Object} `options`\n */\n\nfunction Remarkable(preset, options) {\n if (typeof preset !== 'string') {\n options = preset;\n preset = 'default';\n }\n\n if (options && options.linkify != null) {\n console.warn(\n 'linkify option is removed. Use linkify plugin instead:\\n\\n' +\n 'import Remarkable from \\'remarkable\\';\\n' +\n 'import linkify from \\'remarkable/linkify\\';\\n' +\n 'new Remarkable().use(linkify)\\n'\n );\n }\n\n this.inline = new ParserInline();\n this.block = new ParserBlock();\n this.core = new Core();\n this.renderer = new Renderer();\n this.ruler = new Ruler();\n\n this.options = {};\n this.configure(config[preset]);\n this.set(options || {});\n}\n\n/**\n * Set options as an alternative to passing them\n * to the constructor.\n *\n * ```js\n * md.set({typographer: true});\n * ```\n * @param {Object} `options`\n * @api public\n */\n\nRemarkable.prototype.set = function (options) {\n assign(this.options, options);\n};\n\n/**\n * Batch loader for components rules states, and options\n *\n * @param {Object} `presets`\n */\n\nRemarkable.prototype.configure = function (presets) {\n var self = this;\n\n if (!presets) { throw new Error('Wrong `remarkable` preset, check name/content'); }\n if (presets.options) { self.set(presets.options); }\n if (presets.components) {\n Object.keys(presets.components).forEach(function (name) {\n if (presets.components[name].rules) {\n self[name].ruler.enable(presets.components[name].rules, true);\n }\n });\n }\n};\n\n/**\n * Use a plugin.\n *\n * ```js\n * var md = new Remarkable();\n *\n * md.use(plugin1)\n * .use(plugin2, opts)\n * .use(plugin3);\n * ```\n *\n * @param {Function} `plugin`\n * @param {Object} `options`\n * @return {Object} `Remarkable` for chaining\n */\n\nRemarkable.prototype.use = function (plugin, options) {\n plugin(this, options);\n return this;\n};\n\n\n/**\n * Parse the input `string` and return a tokens array.\n * Modifies `env` with definitions data.\n *\n * @param {String} `string`\n * @param {Object} `env`\n * @return {Array} Array of tokens\n */\n\nRemarkable.prototype.parse = function (str, env) {\n var state = new StateCore(this, str, env);\n this.core.process(state);\n return state.tokens;\n};\n\n/**\n * The main `.render()` method that does all the magic :)\n *\n * @param {String} `string`\n * @param {Object} `env`\n * @return {String} Rendered HTML.\n */\n\nRemarkable.prototype.render = function (str, env) {\n env = env || {};\n return this.renderer.render(this.parse(str, env), this.options, env);\n};\n\n/**\n * Parse the given content `string` as a single string.\n *\n * @param {String} `string`\n * @param {Object} `env`\n * @return {Array} Array of tokens\n */\n\nRemarkable.prototype.parseInline = function (str, env) {\n var state = new StateCore(this, str, env);\n state.inlineMode = true;\n this.core.process(state);\n return state.tokens;\n};\n\n/**\n * Render a single content `string`, without wrapping it\n * to paragraphs\n *\n * @param {String} `str`\n * @param {Object} `env`\n * @return {String}\n */\n\nRemarkable.prototype.renderInline = function (str, env) {\n env = env || {};\n return this.renderer.render(this.parseInline(str, env), this.options, env);\n};\n\nexport { Remarkable, utils };\n","/**\n * Assigns (shallow copies) the properties of `src` onto `dest`, if the\n * corresponding property on `dest` === `undefined`.\n *\n * @param {Object} dest The destination object.\n * @param {Object} src The source object.\n * @return {Object} The destination object (`dest`)\n */\nexport function defaults(dest, src) {\n for (var prop in src) {\n if (src.hasOwnProperty(prop) && dest[prop] === undefined) {\n dest[prop] = src[prop];\n }\n }\n return dest;\n}\n/**\n * Truncates the `str` at `len - ellipsisChars.length`, and adds the `ellipsisChars` to the\n * end of the string (by default, two periods: '..'). If the `str` length does not exceed\n * `len`, the string will be returned unchanged.\n *\n * @param {String} str The string to truncate and add an ellipsis to.\n * @param {Number} truncateLen The length to truncate the string at.\n * @param {String} [ellipsisChars=...] The ellipsis character(s) to add to the end of `str`\n * when truncated. Defaults to '...'\n */\nexport function ellipsis(str, truncateLen, ellipsisChars) {\n var ellipsisLength;\n if (str.length > truncateLen) {\n if (ellipsisChars == null) {\n ellipsisChars = '…';\n ellipsisLength = 3;\n }\n else {\n ellipsisLength = ellipsisChars.length;\n }\n str = str.substring(0, truncateLen - ellipsisLength) + ellipsisChars;\n }\n return str;\n}\n/**\n * Supports `Array.prototype.indexOf()` functionality for old IE (IE8 and below).\n *\n * @param {Array} arr The array to find an element of.\n * @param {*} element The element to find in the array, and return the index of.\n * @return {Number} The index of the `element`, or -1 if it was not found.\n */\nexport function indexOf(arr, element) {\n if (Array.prototype.indexOf) {\n return arr.indexOf(element);\n }\n else {\n for (var i = 0, len = arr.length; i < len; i++) {\n if (arr[i] === element)\n return i;\n }\n return -1;\n }\n}\n/**\n * Removes array elements based on a filtering function. Mutates the input\n * array.\n *\n * Using this instead of the ES5 Array.prototype.filter() function, to allow\n * Autolinker compatibility with IE8, and also to prevent creating many new\n * arrays in memory for filtering.\n *\n * @param {Array} arr The array to remove elements from. This array is\n * mutated.\n * @param {Function} fn A function which should return `true` to\n * remove an element.\n * @return {Array} The mutated input `arr`.\n */\nexport function remove(arr, fn) {\n for (var i = arr.length - 1; i >= 0; i--) {\n if (fn(arr[i]) === true) {\n arr.splice(i, 1);\n }\n }\n}\n/**\n * Performs the functionality of what modern browsers do when `String.prototype.split()` is called\n * with a regular expression that contains capturing parenthesis.\n *\n * For example:\n *\n * // Modern browsers:\n * \"a,b,c\".split( /(,)/ ); // --> [ 'a', ',', 'b', ',', 'c' ]\n *\n * // Old IE (including IE8):\n * \"a,b,c\".split( /(,)/ ); // --> [ 'a', 'b', 'c' ]\n *\n * This method emulates the functionality of modern browsers for the old IE case.\n *\n * @param {String} str The string to split.\n * @param {RegExp} splitRegex The regular expression to split the input `str` on. The splitting\n * character(s) will be spliced into the array, as in the \"modern browsers\" example in the\n * description of this method.\n * Note #1: the supplied regular expression **must** have the 'g' flag specified.\n * Note #2: for simplicity's sake, the regular expression does not need\n * to contain capturing parenthesis - it will be assumed that any match has them.\n * @return {String[]} The split array of strings, with the splitting character(s) included.\n */\nexport function splitAndCapture(str, splitRegex) {\n if (!splitRegex.global)\n throw new Error(\"`splitRegex` must have the 'g' flag set\");\n var result = [], lastIdx = 0, match;\n while (match = splitRegex.exec(str)) {\n result.push(str.substring(lastIdx, match.index));\n result.push(match[0]); // push the splitting char(s)\n lastIdx = match.index + match[0].length;\n }\n result.push(str.substring(lastIdx));\n return result;\n}\n/**\n * Function that should never be called but is used to check that every\n * enum value is handled using TypeScript's 'never' type.\n */\nexport function throwUnhandledCaseError(theValue) {\n throw new Error(\"Unhandled case for value: '\" + theValue + \"'\");\n}\n\n//# sourceMappingURL=utils.js.map\n","import { indexOf } from \"./utils\";\n/**\n * @class Autolinker.HtmlTag\n * @extends Object\n *\n * Represents an HTML tag, which can be used to easily build/modify HTML tags programmatically.\n *\n * Autolinker uses this abstraction to create HTML tags, and then write them out as strings. You may also use\n * this class in your code, especially within a {@link Autolinker#replaceFn replaceFn}.\n *\n * ## Examples\n *\n * Example instantiation:\n *\n * var tag = new Autolinker.HtmlTag( {\n * tagName : 'a',\n * attrs : { 'href': 'http://google.com', 'class': 'external-link' },\n * innerHtml : 'Google'\n * } );\n *\n * tag.toAnchorString(); // Google\n *\n * // Individual accessor methods\n * tag.getTagName(); // 'a'\n * tag.getAttr( 'href' ); // 'http://google.com'\n * tag.hasClass( 'external-link' ); // true\n *\n *\n * Using mutator methods (which may be used in combination with instantiation config properties):\n *\n * var tag = new Autolinker.HtmlTag();\n * tag.setTagName( 'a' );\n * tag.setAttr( 'href', 'http://google.com' );\n * tag.addClass( 'external-link' );\n * tag.setInnerHtml( 'Google' );\n *\n * tag.getTagName(); // 'a'\n * tag.getAttr( 'href' ); // 'http://google.com'\n * tag.hasClass( 'external-link' ); // true\n *\n * tag.toAnchorString(); // Google\n *\n *\n * ## Example use within a {@link Autolinker#replaceFn replaceFn}\n *\n * var html = Autolinker.link( \"Test google.com\", {\n * replaceFn : function( match ) {\n * var tag = match.buildTag(); // returns an {@link Autolinker.HtmlTag} instance, configured with the Match's href and anchor text\n * tag.setAttr( 'rel', 'nofollow' );\n *\n * return tag;\n * }\n * } );\n *\n * // generated html:\n * // Test google.com\n *\n *\n * ## Example use with a new tag for the replacement\n *\n * var html = Autolinker.link( \"Test google.com\", {\n * replaceFn : function( match ) {\n * var tag = new Autolinker.HtmlTag( {\n * tagName : 'button',\n * attrs : { 'title': 'Load URL: ' + match.getAnchorHref() },\n * innerHtml : 'Load URL: ' + match.getAnchorText()\n * } );\n *\n * return tag;\n * }\n * } );\n *\n * // generated html:\n * // Test \n */\nvar HtmlTag = /** @class */ (function () {\n /**\n * @method constructor\n * @param {Object} [cfg] The configuration properties for this class, in an Object (map)\n */\n function HtmlTag(cfg) {\n if (cfg === void 0) { cfg = {}; }\n /**\n * @cfg {String} tagName\n *\n * The tag name. Ex: 'a', 'button', etc.\n *\n * Not required at instantiation time, but should be set using {@link #setTagName} before {@link #toAnchorString}\n * is executed.\n */\n this.tagName = ''; // default value just to get the above doc comment in the ES5 output and documentation generator\n /**\n * @cfg {Object.} attrs\n *\n * An key/value Object (map) of attributes to create the tag with. The keys are the attribute names, and the\n * values are the attribute values.\n */\n this.attrs = {}; // default value just to get the above doc comment in the ES5 output and documentation generator\n /**\n * @cfg {String} innerHTML\n *\n * The inner HTML for the tag.\n */\n this.innerHTML = ''; // default value just to get the above doc comment in the ES5 output and documentation generator\n /**\n * @protected\n * @property {RegExp} whitespaceRegex\n *\n * Regular expression used to match whitespace in a string of CSS classes.\n */\n this.whitespaceRegex = /\\s+/; // default value just to get the above doc comment in the ES5 output and documentation generator\n this.tagName = cfg.tagName || '';\n this.attrs = cfg.attrs || {};\n this.innerHTML = cfg.innerHtml || cfg.innerHTML || ''; // accept either the camelCased form or the fully capitalized acronym as in the DOM\n }\n /**\n * Sets the tag name that will be used to generate the tag with.\n *\n * @param {String} tagName\n * @return {Autolinker.HtmlTag} This HtmlTag instance, so that method calls may be chained.\n */\n HtmlTag.prototype.setTagName = function (tagName) {\n this.tagName = tagName;\n return this;\n };\n /**\n * Retrieves the tag name.\n *\n * @return {String}\n */\n HtmlTag.prototype.getTagName = function () {\n return this.tagName || '';\n };\n /**\n * Sets an attribute on the HtmlTag.\n *\n * @param {String} attrName The attribute name to set.\n * @param {String} attrValue The attribute value to set.\n * @return {Autolinker.HtmlTag} This HtmlTag instance, so that method calls may be chained.\n */\n HtmlTag.prototype.setAttr = function (attrName, attrValue) {\n var tagAttrs = this.getAttrs();\n tagAttrs[attrName] = attrValue;\n return this;\n };\n /**\n * Retrieves an attribute from the HtmlTag. If the attribute does not exist, returns `undefined`.\n *\n * @param {String} attrName The attribute name to retrieve.\n * @return {String} The attribute's value, or `undefined` if it does not exist on the HtmlTag.\n */\n HtmlTag.prototype.getAttr = function (attrName) {\n return this.getAttrs()[attrName];\n };\n /**\n * Sets one or more attributes on the HtmlTag.\n *\n * @param {Object.} attrs A key/value Object (map) of the attributes to set.\n * @return {Autolinker.HtmlTag} This HtmlTag instance, so that method calls may be chained.\n */\n HtmlTag.prototype.setAttrs = function (attrs) {\n Object.assign(this.getAttrs(), attrs);\n return this;\n };\n /**\n * Retrieves the attributes Object (map) for the HtmlTag.\n *\n * @return {Object.} A key/value object of the attributes for the HtmlTag.\n */\n HtmlTag.prototype.getAttrs = function () {\n return this.attrs || (this.attrs = {});\n };\n /**\n * Sets the provided `cssClass`, overwriting any current CSS classes on the HtmlTag.\n *\n * @param {String} cssClass One or more space-separated CSS classes to set (overwrite).\n * @return {Autolinker.HtmlTag} This HtmlTag instance, so that method calls may be chained.\n */\n HtmlTag.prototype.setClass = function (cssClass) {\n return this.setAttr('class', cssClass);\n };\n /**\n * Convenience method to add one or more CSS classes to the HtmlTag. Will not add duplicate CSS classes.\n *\n * @param {String} cssClass One or more space-separated CSS classes to add.\n * @return {Autolinker.HtmlTag} This HtmlTag instance, so that method calls may be chained.\n */\n HtmlTag.prototype.addClass = function (cssClass) {\n var classAttr = this.getClass(), whitespaceRegex = this.whitespaceRegex, classes = (!classAttr) ? [] : classAttr.split(whitespaceRegex), newClasses = cssClass.split(whitespaceRegex), newClass;\n while (newClass = newClasses.shift()) {\n if (indexOf(classes, newClass) === -1) {\n classes.push(newClass);\n }\n }\n this.getAttrs()['class'] = classes.join(\" \");\n return this;\n };\n /**\n * Convenience method to remove one or more CSS classes from the HtmlTag.\n *\n * @param {String} cssClass One or more space-separated CSS classes to remove.\n * @return {Autolinker.HtmlTag} This HtmlTag instance, so that method calls may be chained.\n */\n HtmlTag.prototype.removeClass = function (cssClass) {\n var classAttr = this.getClass(), whitespaceRegex = this.whitespaceRegex, classes = (!classAttr) ? [] : classAttr.split(whitespaceRegex), removeClasses = cssClass.split(whitespaceRegex), removeClass;\n while (classes.length && (removeClass = removeClasses.shift())) {\n var idx = indexOf(classes, removeClass);\n if (idx !== -1) {\n classes.splice(idx, 1);\n }\n }\n this.getAttrs()['class'] = classes.join(\" \");\n return this;\n };\n /**\n * Convenience method to retrieve the CSS class(es) for the HtmlTag, which will each be separated by spaces when\n * there are multiple.\n *\n * @return {String}\n */\n HtmlTag.prototype.getClass = function () {\n return this.getAttrs()['class'] || \"\";\n };\n /**\n * Convenience method to check if the tag has a CSS class or not.\n *\n * @param {String} cssClass The CSS class to check for.\n * @return {Boolean} `true` if the HtmlTag has the CSS class, `false` otherwise.\n */\n HtmlTag.prototype.hasClass = function (cssClass) {\n return (' ' + this.getClass() + ' ').indexOf(' ' + cssClass + ' ') !== -1;\n };\n /**\n * Sets the inner HTML for the tag.\n *\n * @param {String} html The inner HTML to set.\n * @return {Autolinker.HtmlTag} This HtmlTag instance, so that method calls may be chained.\n */\n HtmlTag.prototype.setInnerHTML = function (html) {\n this.innerHTML = html;\n return this;\n };\n /**\n * Backwards compatibility method name.\n *\n * @param {String} html The inner HTML to set.\n * @return {Autolinker.HtmlTag} This HtmlTag instance, so that method calls may be chained.\n */\n HtmlTag.prototype.setInnerHtml = function (html) {\n return this.setInnerHTML(html);\n };\n /**\n * Retrieves the inner HTML for the tag.\n *\n * @return {String}\n */\n HtmlTag.prototype.getInnerHTML = function () {\n return this.innerHTML || \"\";\n };\n /**\n * Backward compatibility method name.\n *\n * @return {String}\n */\n HtmlTag.prototype.getInnerHtml = function () {\n return this.getInnerHTML();\n };\n /**\n * Override of superclass method used to generate the HTML string for the tag.\n *\n * @return {String}\n */\n HtmlTag.prototype.toAnchorString = function () {\n var tagName = this.getTagName(), attrsStr = this.buildAttrsStr();\n attrsStr = (attrsStr) ? ' ' + attrsStr : ''; // prepend a space if there are actually attributes\n return ['<', tagName, attrsStr, '>', this.getInnerHtml(), ''].join(\"\");\n };\n /**\n * Support method for {@link #toAnchorString}, returns the string space-separated key=\"value\" pairs, used to populate\n * the stringified HtmlTag.\n *\n * @protected\n * @return {String} Example return: `attr1=\"value1\" attr2=\"value2\"`\n */\n HtmlTag.prototype.buildAttrsStr = function () {\n if (!this.attrs)\n return \"\"; // no `attrs` Object (map) has been set, return empty string\n var attrs = this.getAttrs(), attrsArr = [];\n for (var prop in attrs) {\n if (attrs.hasOwnProperty(prop)) {\n attrsArr.push(prop + '=\"' + attrs[prop] + '\"');\n }\n }\n return attrsArr.join(\" \");\n };\n return HtmlTag;\n}());\nexport { HtmlTag };\n\n//# sourceMappingURL=html-tag.js.map\n","import { HtmlTag } from \"./html-tag\";\nimport { truncateSmart } from \"./truncate/truncate-smart\";\nimport { truncateMiddle } from \"./truncate/truncate-middle\";\nimport { truncateEnd } from \"./truncate/truncate-end\";\n/**\n * @protected\n * @class Autolinker.AnchorTagBuilder\n * @extends Object\n *\n * Builds anchor (<a>) tags for the Autolinker utility when a match is\n * found.\n *\n * Normally this class is instantiated, configured, and used internally by an\n * {@link Autolinker} instance, but may actually be used indirectly in a\n * {@link Autolinker#replaceFn replaceFn} to create {@link Autolinker.HtmlTag HtmlTag}\n * instances which may be modified before returning from the\n * {@link Autolinker#replaceFn replaceFn}. For example:\n *\n * var html = Autolinker.link( \"Test google.com\", {\n * replaceFn : function( match ) {\n * var tag = match.buildTag(); // returns an {@link Autolinker.HtmlTag} instance\n * tag.setAttr( 'rel', 'nofollow' );\n *\n * return tag;\n * }\n * } );\n *\n * // generated html:\n * // Test google.com\n */\nvar AnchorTagBuilder = /** @class */ (function () {\n /**\n * @method constructor\n * @param {Object} [cfg] The configuration options for the AnchorTagBuilder instance, specified in an Object (map).\n */\n function AnchorTagBuilder(cfg) {\n if (cfg === void 0) { cfg = {}; }\n /**\n * @cfg {Boolean} newWindow\n * @inheritdoc Autolinker#newWindow\n */\n this.newWindow = false; // default value just to get the above doc comment in the ES5 output and documentation generator\n /**\n * @cfg {Object} truncate\n * @inheritdoc Autolinker#truncate\n */\n this.truncate = {}; // default value just to get the above doc comment in the ES5 output and documentation generator\n /**\n * @cfg {String} className\n * @inheritdoc Autolinker#className\n */\n this.className = ''; // default value just to get the above doc comment in the ES5 output and documentation generator\n this.newWindow = cfg.newWindow || false;\n this.truncate = cfg.truncate || {};\n this.className = cfg.className || '';\n }\n /**\n * Generates the actual anchor (<a>) tag to use in place of the\n * matched text, via its `match` object.\n *\n * @param {Autolinker.match.Match} match The Match instance to generate an\n * anchor tag from.\n * @return {Autolinker.HtmlTag} The HtmlTag instance for the anchor tag.\n */\n AnchorTagBuilder.prototype.build = function (match) {\n return new HtmlTag({\n tagName: 'a',\n attrs: this.createAttrs(match),\n innerHtml: this.processAnchorText(match.getAnchorText())\n });\n };\n /**\n * Creates the Object (map) of the HTML attributes for the anchor (<a>)\n * tag being generated.\n *\n * @protected\n * @param {Autolinker.match.Match} match The Match instance to generate an\n * anchor tag from.\n * @return {Object} A key/value Object (map) of the anchor tag's attributes.\n */\n AnchorTagBuilder.prototype.createAttrs = function (match) {\n var attrs = {\n 'href': match.getAnchorHref() // we'll always have the `href` attribute\n };\n var cssClass = this.createCssClass(match);\n if (cssClass) {\n attrs['class'] = cssClass;\n }\n if (this.newWindow) {\n attrs['target'] = \"_blank\";\n attrs['rel'] = \"noopener noreferrer\"; // Issue #149. See https://mathiasbynens.github.io/rel-noopener/\n }\n if (this.truncate) {\n if (this.truncate.length && this.truncate.length < match.getAnchorText().length) {\n attrs['title'] = match.getAnchorHref();\n }\n }\n return attrs;\n };\n /**\n * Creates the CSS class that will be used for a given anchor tag, based on\n * the `matchType` and the {@link #className} config.\n *\n * Example returns:\n *\n * - \"\" // no {@link #className}\n * - \"myLink myLink-url\" // url match\n * - \"myLink myLink-email\" // email match\n * - \"myLink myLink-phone\" // phone match\n * - \"myLink myLink-hashtag\" // hashtag match\n * - \"myLink myLink-mention myLink-twitter\" // mention match with Twitter service\n *\n * @protected\n * @param {Autolinker.match.Match} match The Match instance to generate an\n * anchor tag from.\n * @return {String} The CSS class string for the link. Example return:\n * \"myLink myLink-url\". If no {@link #className} was configured, returns\n * an empty string.\n */\n AnchorTagBuilder.prototype.createCssClass = function (match) {\n var className = this.className;\n if (!className) {\n return \"\";\n }\n else {\n var returnClasses = [className], cssClassSuffixes = match.getCssClassSuffixes();\n for (var i = 0, len = cssClassSuffixes.length; i < len; i++) {\n returnClasses.push(className + '-' + cssClassSuffixes[i]);\n }\n return returnClasses.join(' ');\n }\n };\n /**\n * Processes the `anchorText` by truncating the text according to the\n * {@link #truncate} config.\n *\n * @private\n * @param {String} anchorText The anchor tag's text (i.e. what will be\n * displayed).\n * @return {String} The processed `anchorText`.\n */\n AnchorTagBuilder.prototype.processAnchorText = function (anchorText) {\n anchorText = this.doTruncate(anchorText);\n return anchorText;\n };\n /**\n * Performs the truncation of the `anchorText` based on the {@link #truncate}\n * option. If the `anchorText` is longer than the length specified by the\n * {@link #truncate} option, the truncation is performed based on the\n * `location` property. See {@link #truncate} for details.\n *\n * @private\n * @param {String} anchorText The anchor tag's text (i.e. what will be\n * displayed).\n * @return {String} The truncated anchor text.\n */\n AnchorTagBuilder.prototype.doTruncate = function (anchorText) {\n var truncate = this.truncate;\n if (!truncate || !truncate.length)\n return anchorText;\n var truncateLength = truncate.length, truncateLocation = truncate.location;\n if (truncateLocation === 'smart') {\n return truncateSmart(anchorText, truncateLength);\n }\n else if (truncateLocation === 'middle') {\n return truncateMiddle(anchorText, truncateLength);\n }\n else {\n return truncateEnd(anchorText, truncateLength);\n }\n };\n return AnchorTagBuilder;\n}());\nexport { AnchorTagBuilder };\n\n//# sourceMappingURL=anchor-tag-builder.js.map\n","/**\n * Date: 2015-10-05\n * Author: Kasper Søfren (https://github.com/kafoso)\n *\n * A truncation feature, where the ellipsis will be placed at a section within\n * the URL making it still somewhat human readable.\n *\n * @param {String} url\t\t\t\t\t\t A URL.\n * @param {Number} truncateLen\t\t The maximum length of the truncated output URL string.\n * @param {String} ellipsisChars\t The characters to place within the url, e.g. \"...\".\n * @return {String} The truncated URL.\n */\nexport function truncateSmart(url, truncateLen, ellipsisChars) {\n var ellipsisLengthBeforeParsing;\n var ellipsisLength;\n if (ellipsisChars == null) {\n ellipsisChars = '…';\n ellipsisLength = 3;\n ellipsisLengthBeforeParsing = 8;\n }\n else {\n ellipsisLength = ellipsisChars.length;\n ellipsisLengthBeforeParsing = ellipsisChars.length;\n }\n var parse_url = function (url) {\n var urlObj = {};\n var urlSub = url;\n var match = urlSub.match(/^([a-z]+):\\/\\//i);\n if (match) {\n urlObj.scheme = match[1];\n urlSub = urlSub.substr(match[0].length);\n }\n match = urlSub.match(/^(.*?)(?=(\\?|#|\\/|$))/i);\n if (match) {\n urlObj.host = match[1];\n urlSub = urlSub.substr(match[0].length);\n }\n match = urlSub.match(/^\\/(.*?)(?=(\\?|#|$))/i);\n if (match) {\n urlObj.path = match[1];\n urlSub = urlSub.substr(match[0].length);\n }\n match = urlSub.match(/^\\?(.*?)(?=(#|$))/i);\n if (match) {\n urlObj.query = match[1];\n urlSub = urlSub.substr(match[0].length);\n }\n match = urlSub.match(/^#(.*?)$/i);\n if (match) {\n urlObj.fragment = match[1];\n //urlSub = urlSub.substr(match[0].length); -- not used. Uncomment if adding another block.\n }\n return urlObj;\n };\n var buildUrl = function (urlObj) {\n var url = \"\";\n if (urlObj.scheme && urlObj.host) {\n url += urlObj.scheme + \"://\";\n }\n if (urlObj.host) {\n url += urlObj.host;\n }\n if (urlObj.path) {\n url += \"/\" + urlObj.path;\n }\n if (urlObj.query) {\n url += \"?\" + urlObj.query;\n }\n if (urlObj.fragment) {\n url += \"#\" + urlObj.fragment;\n }\n return url;\n };\n var buildSegment = function (segment, remainingAvailableLength) {\n var remainingAvailableLengthHalf = remainingAvailableLength / 2, startOffset = Math.ceil(remainingAvailableLengthHalf), endOffset = (-1) * Math.floor(remainingAvailableLengthHalf), end = \"\";\n if (endOffset < 0) {\n end = segment.substr(endOffset);\n }\n return segment.substr(0, startOffset) + ellipsisChars + end;\n };\n if (url.length <= truncateLen) {\n return url;\n }\n var availableLength = truncateLen - ellipsisLength;\n var urlObj = parse_url(url);\n // Clean up the URL\n if (urlObj.query) {\n var matchQuery = urlObj.query.match(/^(.*?)(?=(\\?|\\#))(.*?)$/i);\n if (matchQuery) {\n // Malformed URL; two or more \"?\". Removed any content behind the 2nd.\n urlObj.query = urlObj.query.substr(0, matchQuery[1].length);\n url = buildUrl(urlObj);\n }\n }\n if (url.length <= truncateLen) {\n return url;\n }\n if (urlObj.host) {\n urlObj.host = urlObj.host.replace(/^www\\./, \"\");\n url = buildUrl(urlObj);\n }\n if (url.length <= truncateLen) {\n return url;\n }\n // Process and build the URL\n var str = \"\";\n if (urlObj.host) {\n str += urlObj.host;\n }\n if (str.length >= availableLength) {\n if (urlObj.host.length == truncateLen) {\n return (urlObj.host.substr(0, (truncateLen - ellipsisLength)) + ellipsisChars).substr(0, availableLength + ellipsisLengthBeforeParsing);\n }\n return buildSegment(str, availableLength).substr(0, availableLength + ellipsisLengthBeforeParsing);\n }\n var pathAndQuery = \"\";\n if (urlObj.path) {\n pathAndQuery += \"/\" + urlObj.path;\n }\n if (urlObj.query) {\n pathAndQuery += \"?\" + urlObj.query;\n }\n if (pathAndQuery) {\n if ((str + pathAndQuery).length >= availableLength) {\n if ((str + pathAndQuery).length == truncateLen) {\n return (str + pathAndQuery).substr(0, truncateLen);\n }\n var remainingAvailableLength = availableLength - str.length;\n return (str + buildSegment(pathAndQuery, remainingAvailableLength)).substr(0, availableLength + ellipsisLengthBeforeParsing);\n }\n else {\n str += pathAndQuery;\n }\n }\n if (urlObj.fragment) {\n var fragment = \"#\" + urlObj.fragment;\n if ((str + fragment).length >= availableLength) {\n if ((str + fragment).length == truncateLen) {\n return (str + fragment).substr(0, truncateLen);\n }\n var remainingAvailableLength2 = availableLength - str.length;\n return (str + buildSegment(fragment, remainingAvailableLength2)).substr(0, availableLength + ellipsisLengthBeforeParsing);\n }\n else {\n str += fragment;\n }\n }\n if (urlObj.scheme && urlObj.host) {\n var scheme = urlObj.scheme + \"://\";\n if ((str + scheme).length < availableLength) {\n return (scheme + str).substr(0, truncateLen);\n }\n }\n if (str.length <= truncateLen) {\n return str;\n }\n var end = \"\";\n if (availableLength > 0) {\n end = str.substr((-1) * Math.floor(availableLength / 2));\n }\n return (str.substr(0, Math.ceil(availableLength / 2)) + ellipsisChars + end).substr(0, availableLength + ellipsisLengthBeforeParsing);\n}\n\n//# sourceMappingURL=truncate-smart.js.map\n","/**\n * Date: 2015-10-05\n * Author: Kasper Søfren (https://github.com/kafoso)\n *\n * A truncation feature, where the ellipsis will be placed in the dead-center of the URL.\n *\n * @param {String} url A URL.\n * @param {Number} truncateLen The maximum length of the truncated output URL string.\n * @param {String} ellipsisChars The characters to place within the url, e.g. \"..\".\n * @return {String} The truncated URL.\n */\nexport function truncateMiddle(url, truncateLen, ellipsisChars) {\n if (url.length <= truncateLen) {\n return url;\n }\n var ellipsisLengthBeforeParsing;\n var ellipsisLength;\n if (ellipsisChars == null) {\n ellipsisChars = '…';\n ellipsisLengthBeforeParsing = 8;\n ellipsisLength = 3;\n }\n else {\n ellipsisLengthBeforeParsing = ellipsisChars.length;\n ellipsisLength = ellipsisChars.length;\n }\n var availableLength = truncateLen - ellipsisLength;\n var end = \"\";\n if (availableLength > 0) {\n end = url.substr((-1) * Math.floor(availableLength / 2));\n }\n return (url.substr(0, Math.ceil(availableLength / 2)) + ellipsisChars + end).substr(0, availableLength + ellipsisLengthBeforeParsing);\n}\n\n//# sourceMappingURL=truncate-middle.js.map\n","import { ellipsis } from \"../utils\";\n/**\n * A truncation feature where the ellipsis will be placed at the end of the URL.\n *\n * @param {String} anchorText\n * @param {Number} truncateLen The maximum length of the truncated output URL string.\n * @param {String} ellipsisChars The characters to place within the url, e.g. \"..\".\n * @return {String} The truncated URL.\n */\nexport function truncateEnd(anchorText, truncateLen, ellipsisChars) {\n return ellipsis(anchorText, truncateLen, ellipsisChars);\n}\n\n//# sourceMappingURL=truncate-end.js.map\n","/**\n * @abstract\n * @class Autolinker.match.Match\n *\n * Represents a match found in an input string which should be Autolinked. A Match object is what is provided in a\n * {@link Autolinker#replaceFn replaceFn}, and may be used to query for details about the match.\n *\n * For example:\n *\n * var input = \"...\"; // string with URLs, Email Addresses, and Mentions (Twitter, Instagram, Soundcloud)\n *\n * var linkedText = Autolinker.link( input, {\n * replaceFn : function( match ) {\n * console.log( \"href = \", match.getAnchorHref() );\n * console.log( \"text = \", match.getAnchorText() );\n *\n * switch( match.getType() ) {\n * case 'url' :\n * console.log( \"url: \", match.getUrl() );\n *\n * case 'email' :\n * console.log( \"email: \", match.getEmail() );\n *\n * case 'mention' :\n * console.log( \"mention: \", match.getMention() );\n * }\n * }\n * } );\n *\n * See the {@link Autolinker} class for more details on using the {@link Autolinker#replaceFn replaceFn}.\n */\nvar Match = /** @class */ (function () {\n /**\n * @member Autolinker.match.Match\n * @method constructor\n * @param {Object} cfg The configuration properties for the Match\n * instance, specified in an Object (map).\n */\n function Match(cfg) {\n /**\n * @cfg {Autolinker.AnchorTagBuilder} tagBuilder (required)\n *\n * Reference to the AnchorTagBuilder instance to use to generate an anchor\n * tag for the Match.\n */\n this.__jsduckDummyDocProp = null; // property used just to get the above doc comment into the ES5 output and documentation generator\n /**\n * @cfg {String} matchedText (required)\n *\n * The original text that was matched by the {@link Autolinker.matcher.Matcher}.\n */\n this.matchedText = ''; // default value just to get the above doc comment in the ES5 output and documentation generator\n /**\n * @cfg {Number} offset (required)\n *\n * The offset of where the match was made in the input string.\n */\n this.offset = 0; // default value just to get the above doc comment in the ES5 output and documentation generator\n this.tagBuilder = cfg.tagBuilder;\n this.matchedText = cfg.matchedText;\n this.offset = cfg.offset;\n }\n /**\n * Returns the original text that was matched.\n *\n * @return {String}\n */\n Match.prototype.getMatchedText = function () {\n return this.matchedText;\n };\n /**\n * Sets the {@link #offset} of where the match was made in the input string.\n *\n * A {@link Autolinker.matcher.Matcher} will be fed only HTML text nodes,\n * and will therefore set an original offset that is relative to the HTML\n * text node itself. However, we want this offset to be relative to the full\n * HTML input string, and thus if using {@link Autolinker#parse} (rather\n * than calling a {@link Autolinker.matcher.Matcher} directly), then this\n * offset is corrected after the Matcher itself has done its job.\n *\n * @param {Number} offset\n */\n Match.prototype.setOffset = function (offset) {\n this.offset = offset;\n };\n /**\n * Returns the offset of where the match was made in the input string. This\n * is the 0-based index of the match.\n *\n * @return {Number}\n */\n Match.prototype.getOffset = function () {\n return this.offset;\n };\n /**\n * Returns the CSS class suffix(es) for this match.\n *\n * A CSS class suffix is appended to the {@link Autolinker#className} in\n * the {@link Autolinker.AnchorTagBuilder} when a match is translated into\n * an anchor tag.\n *\n * For example, if {@link Autolinker#className} was configured as 'myLink',\n * and this method returns `[ 'url' ]`, the final class name of the element\n * will become: 'myLink myLink-url'.\n *\n * The match may provide multiple CSS class suffixes to be appended to the\n * {@link Autolinker#className} in order to facilitate better styling\n * options for different match criteria. See {@link Autolinker.match.Mention}\n * for an example.\n *\n * By default, this method returns a single array with the match's\n * {@link #getType type} name, but may be overridden by subclasses.\n *\n * @return {String[]}\n */\n Match.prototype.getCssClassSuffixes = function () {\n return [this.getType()];\n };\n /**\n * Builds and returns an {@link Autolinker.HtmlTag} instance based on the\n * Match.\n *\n * This can be used to easily generate anchor tags from matches, and either\n * return their HTML string, or modify them before doing so.\n *\n * Example Usage:\n *\n * var tag = match.buildTag();\n * tag.addClass( 'cordova-link' );\n * tag.setAttr( 'target', '_system' );\n *\n * tag.toAnchorString(); // Google\n *\n * Example Usage in {@link Autolinker#replaceFn}:\n *\n * var html = Autolinker.link( \"Test google.com\", {\n * replaceFn : function( match ) {\n * var tag = match.buildTag(); // returns an {@link Autolinker.HtmlTag} instance\n * tag.setAttr( 'rel', 'nofollow' );\n *\n * return tag;\n * }\n * } );\n *\n * // generated html:\n * // Test google.com\n */\n Match.prototype.buildTag = function () {\n return this.tagBuilder.build(this);\n };\n return Match;\n}());\nexport { Match };\n\n//# sourceMappingURL=match.js.map\n","/*! *****************************************************************************\r\nCopyright (c) Microsoft Corporation. All rights reserved.\r\nLicensed under the Apache License, Version 2.0 (the \"License\"); you may not use\r\nthis file except in compliance with the License. You may obtain a copy of the\r\nLicense at http://www.apache.org/licenses/LICENSE-2.0\r\n\r\nTHIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\r\nKIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED\r\nWARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,\r\nMERCHANTABLITY OR NON-INFRINGEMENT.\r\n\r\nSee the Apache Version 2.0 License for specific language governing permissions\r\nand limitations under the License.\r\n***************************************************************************** */\r\n/* global Reflect, Promise */\r\n\r\nvar extendStatics = function(d, b) {\r\n extendStatics = Object.setPrototypeOf ||\r\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\r\n function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };\r\n return extendStatics(d, b);\r\n};\r\n\r\nexport function __extends(d, b) {\r\n extendStatics(d, b);\r\n function __() { this.constructor = d; }\r\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\r\n}\r\n\r\nexport var __assign = function() {\r\n __assign = Object.assign || function __assign(t) {\r\n for (var s, i = 1, n = arguments.length; i < n; i++) {\r\n s = arguments[i];\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];\r\n }\r\n return t;\r\n }\r\n return __assign.apply(this, arguments);\r\n}\r\n\r\nexport function __rest(s, e) {\r\n var t = {};\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\r\n t[p] = s[p];\r\n if (s != null && typeof Object.getOwnPropertySymbols === \"function\")\r\n for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {\r\n if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))\r\n t[p[i]] = s[p[i]];\r\n }\r\n return t;\r\n}\r\n\r\nexport function __decorate(decorators, target, key, desc) {\r\n var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;\r\n if (typeof Reflect === \"object\" && typeof Reflect.decorate === \"function\") r = Reflect.decorate(decorators, target, key, desc);\r\n else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;\r\n return c > 3 && r && Object.defineProperty(target, key, r), r;\r\n}\r\n\r\nexport function __param(paramIndex, decorator) {\r\n return function (target, key) { decorator(target, key, paramIndex); }\r\n}\r\n\r\nexport function __metadata(metadataKey, metadataValue) {\r\n if (typeof Reflect === \"object\" && typeof Reflect.metadata === \"function\") return Reflect.metadata(metadataKey, metadataValue);\r\n}\r\n\r\nexport function __awaiter(thisArg, _arguments, P, generator) {\r\n return new (P || (P = Promise))(function (resolve, reject) {\r\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\r\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\r\n function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }\r\n step((generator = generator.apply(thisArg, _arguments || [])).next());\r\n });\r\n}\r\n\r\nexport function __generator(thisArg, body) {\r\n var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;\r\n return g = { next: verb(0), \"throw\": verb(1), \"return\": verb(2) }, typeof Symbol === \"function\" && (g[Symbol.iterator] = function() { return this; }), g;\r\n function verb(n) { return function (v) { return step([n, v]); }; }\r\n function step(op) {\r\n if (f) throw new TypeError(\"Generator is already executing.\");\r\n while (_) try {\r\n if (f = 1, y && (t = op[0] & 2 ? y[\"return\"] : op[0] ? y[\"throw\"] || ((t = y[\"return\"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;\r\n if (y = 0, t) op = [op[0] & 2, t.value];\r\n switch (op[0]) {\r\n case 0: case 1: t = op; break;\r\n case 4: _.label++; return { value: op[1], done: false };\r\n case 5: _.label++; y = op[1]; op = [0]; continue;\r\n case 7: op = _.ops.pop(); _.trys.pop(); continue;\r\n default:\r\n if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\r\n if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\r\n if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\r\n if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\r\n if (t[2]) _.ops.pop();\r\n _.trys.pop(); continue;\r\n }\r\n op = body.call(thisArg, _);\r\n } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\r\n if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\r\n }\r\n}\r\n\r\nexport function __exportStar(m, exports) {\r\n for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];\r\n}\r\n\r\nexport function __values(o) {\r\n var m = typeof Symbol === \"function\" && o[Symbol.iterator], i = 0;\r\n if (m) return m.call(o);\r\n return {\r\n next: function () {\r\n if (o && i >= o.length) o = void 0;\r\n return { value: o && o[i++], done: !o };\r\n }\r\n };\r\n}\r\n\r\nexport function __read(o, n) {\r\n var m = typeof Symbol === \"function\" && o[Symbol.iterator];\r\n if (!m) return o;\r\n var i = m.call(o), r, ar = [], e;\r\n try {\r\n while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);\r\n }\r\n catch (error) { e = { error: error }; }\r\n finally {\r\n try {\r\n if (r && !r.done && (m = i[\"return\"])) m.call(i);\r\n }\r\n finally { if (e) throw e.error; }\r\n }\r\n return ar;\r\n}\r\n\r\nexport function __spread() {\r\n for (var ar = [], i = 0; i < arguments.length; i++)\r\n ar = ar.concat(__read(arguments[i]));\r\n return ar;\r\n}\r\n\r\nexport function __spreadArrays() {\r\n for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;\r\n for (var r = Array(s), k = 0, i = 0; i < il; i++)\r\n for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)\r\n r[k] = a[j];\r\n return r;\r\n};\r\n\r\nexport function __await(v) {\r\n return this instanceof __await ? (this.v = v, this) : new __await(v);\r\n}\r\n\r\nexport function __asyncGenerator(thisArg, _arguments, generator) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var g = generator.apply(thisArg, _arguments || []), i, q = [];\r\n return i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i;\r\n function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }\r\n function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }\r\n function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }\r\n function fulfill(value) { resume(\"next\", value); }\r\n function reject(value) { resume(\"throw\", value); }\r\n function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }\r\n}\r\n\r\nexport function __asyncDelegator(o) {\r\n var i, p;\r\n return i = {}, verb(\"next\"), verb(\"throw\", function (e) { throw e; }), verb(\"return\"), i[Symbol.iterator] = function () { return this; }, i;\r\n function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === \"return\" } : f ? f(v) : v; } : f; }\r\n}\r\n\r\nexport function __asyncValues(o) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var m = o[Symbol.asyncIterator], i;\r\n return m ? m.call(o) : (o = typeof __values === \"function\" ? __values(o) : o[Symbol.iterator](), i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i);\r\n function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }\r\n function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }\r\n}\r\n\r\nexport function __makeTemplateObject(cooked, raw) {\r\n if (Object.defineProperty) { Object.defineProperty(cooked, \"raw\", { value: raw }); } else { cooked.raw = raw; }\r\n return cooked;\r\n};\r\n\r\nexport function __importStar(mod) {\r\n if (mod && mod.__esModule) return mod;\r\n var result = {};\r\n if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];\r\n result.default = mod;\r\n return result;\r\n}\r\n\r\nexport function __importDefault(mod) {\r\n return (mod && mod.__esModule) ? mod : { default: mod };\r\n}\r\n","import * as tslib_1 from \"tslib\";\nimport { Match } from \"./match\";\n/**\n * @class Autolinker.match.Email\n * @extends Autolinker.match.Match\n *\n * Represents a Email match found in an input string which should be Autolinked.\n *\n * See this class's superclass ({@link Autolinker.match.Match}) for more details.\n */\nvar EmailMatch = /** @class */ (function (_super) {\n tslib_1.__extends(EmailMatch, _super);\n /**\n * @method constructor\n * @param {Object} cfg The configuration properties for the Match\n * instance, specified in an Object (map).\n */\n function EmailMatch(cfg) {\n var _this = _super.call(this, cfg) || this;\n /**\n * @cfg {String} email (required)\n *\n * The email address that was matched.\n */\n _this.email = ''; // default value just to get the above doc comment in the ES5 output and documentation generator\n _this.email = cfg.email;\n return _this;\n }\n /**\n * Returns a string name for the type of match that this class represents.\n * For the case of EmailMatch, returns 'email'.\n *\n * @return {String}\n */\n EmailMatch.prototype.getType = function () {\n return 'email';\n };\n /**\n * Returns the email address that was matched.\n *\n * @return {String}\n */\n EmailMatch.prototype.getEmail = function () {\n return this.email;\n };\n /**\n * Returns the anchor href that should be generated for the match.\n *\n * @return {String}\n */\n EmailMatch.prototype.getAnchorHref = function () {\n return 'mailto:' + this.email;\n };\n /**\n * Returns the anchor text that should be generated for the match.\n *\n * @return {String}\n */\n EmailMatch.prototype.getAnchorText = function () {\n return this.email;\n };\n return EmailMatch;\n}(Match));\nexport { EmailMatch };\n\n//# sourceMappingURL=email-match.js.map\n","import * as tslib_1 from \"tslib\";\nimport { Matcher } from \"./matcher\";\nimport { alphaNumericCharsStr, alphaNumericAndMarksCharsStr, getDomainNameStr } from \"../regex-lib\";\nimport { tldRegex } from \"./tld-regex\";\nimport { UrlMatch } from \"../match/url-match\";\nimport { UrlMatchValidator } from \"./url-match-validator\";\n// RegExp objects which are shared by all instances of UrlMatcher. These are\n// here to avoid re-instantiating the RegExp objects if `Autolinker.link()` is\n// called multiple times, thus instantiating UrlMatcher and its RegExp \n// objects each time (which is very expensive - see https://github.com/gregjacobs/Autolinker.js/issues/314). \n// See descriptions of the properties where they are used for details about them\nvar matcherRegex = (function () {\n var schemeRegex = /(?:[A-Za-z][-.+A-Za-z0-9]{0,63}:(?![A-Za-z][-.+A-Za-z0-9]{0,63}:\\/\\/)(?!\\d+\\/?)(?:\\/\\/)?)/, // match protocol, allow in format \"http://\" or \"mailto:\". However, do not match the first part of something like 'link:http://www.google.com' (i.e. don't match \"link:\"). Also, make sure we don't interpret 'google.com:8000' as if 'google.com' was a protocol here (i.e. ignore a trailing port number in this regex)\n wwwRegex = /(?:www\\.)/, // starting with 'www.'\n // Allow optional path, query string, and hash anchor, not ending in the following characters: \"?!:,.;\"\n // http://blog.codinghorror.com/the-problem-with-urls/\n urlSuffixRegex = new RegExp('[/?#](?:[' + alphaNumericAndMarksCharsStr + '\\\\-+&@#/%=~_()|\\'$*\\\\[\\\\]{}?!:,.;^\\u2713]*[' + alphaNumericAndMarksCharsStr + '\\\\-+&@#/%=~_()|\\'$*\\\\[\\\\]{}\\u2713])?');\n return new RegExp([\n '(?:',\n '(',\n schemeRegex.source,\n getDomainNameStr(2),\n ')',\n '|',\n '(',\n '(//)?',\n wwwRegex.source,\n getDomainNameStr(6),\n ')',\n '|',\n '(',\n '(//)?',\n getDomainNameStr(10) + '\\\\.',\n tldRegex.source,\n '(?![-' + alphaNumericCharsStr + '])',\n ')',\n ')',\n '(?::[0-9]+)?',\n '(?:' + urlSuffixRegex.source + ')?' // match for path, query string, and/or hash anchor - optional\n ].join(\"\"), 'gi');\n})();\nvar wordCharRegExp = new RegExp('[' + alphaNumericAndMarksCharsStr + ']');\n/**\n * @class Autolinker.matcher.Url\n * @extends Autolinker.matcher.Matcher\n *\n * Matcher to find URL matches in an input string.\n *\n * See this class's superclass ({@link Autolinker.matcher.Matcher}) for more details.\n */\nvar UrlMatcher = /** @class */ (function (_super) {\n tslib_1.__extends(UrlMatcher, _super);\n /**\n * @method constructor\n * @param {Object} cfg The configuration properties for the Match instance,\n * specified in an Object (map).\n */\n function UrlMatcher(cfg) {\n var _this = _super.call(this, cfg) || this;\n /**\n * @cfg {Object} stripPrefix (required)\n *\n * The Object form of {@link Autolinker#cfg-stripPrefix}.\n */\n _this.stripPrefix = { scheme: true, www: true }; // default value just to get the above doc comment in the ES5 output and documentation generator\n /**\n * @cfg {Boolean} stripTrailingSlash (required)\n * @inheritdoc Autolinker#stripTrailingSlash\n */\n _this.stripTrailingSlash = true; // default value just to get the above doc comment in the ES5 output and documentation generator\n /**\n * @cfg {Boolean} decodePercentEncoding (required)\n * @inheritdoc Autolinker#decodePercentEncoding\n */\n _this.decodePercentEncoding = true; // default value just to get the above doc comment in the ES5 output and documentation generator\n /**\n * @protected\n * @property {RegExp} matcherRegex\n *\n * The regular expression to match URLs with an optional scheme, port\n * number, path, query string, and hash anchor.\n *\n * Example matches:\n *\n * http://google.com\n * www.google.com\n * google.com/path/to/file?q1=1&q2=2#myAnchor\n *\n *\n * This regular expression will have the following capturing groups:\n *\n * 1. Group that matches a scheme-prefixed URL (i.e. 'http://google.com').\n * This is used to match scheme URLs with just a single word, such as\n * 'http://localhost', where we won't double check that the domain name\n * has at least one dot ('.') in it.\n * 2. Group that matches a 'www.' prefixed URL. This is only matched if the\n * 'www.' text was not prefixed by a scheme (i.e.: not prefixed by\n * 'http://', 'ftp:', etc.)\n * 3. A protocol-relative ('//') match for the case of a 'www.' prefixed\n * URL. Will be an empty string if it is not a protocol-relative match.\n * We need to know the character before the '//' in order to determine\n * if it is a valid match or the // was in a string we don't want to\n * auto-link.\n * 4. Group that matches a known TLD (top level domain), when a scheme\n * or 'www.'-prefixed domain is not matched.\n * 5. A protocol-relative ('//') match for the case of a known TLD prefixed\n * URL. Will be an empty string if it is not a protocol-relative match.\n * See #3 for more info.\n */\n _this.matcherRegex = matcherRegex;\n /**\n * A regular expression to use to check the character before a protocol-relative\n * URL match. We don't want to match a protocol-relative URL if it is part\n * of another word.\n *\n * For example, we want to match something like \"Go to: //google.com\",\n * but we don't want to match something like \"abc//google.com\"\n *\n * This regular expression is used to test the character before the '//'.\n *\n * @protected\n * @type {RegExp} wordCharRegExp\n */\n _this.wordCharRegExp = wordCharRegExp;\n _this.stripPrefix = cfg.stripPrefix;\n _this.stripTrailingSlash = cfg.stripTrailingSlash;\n _this.decodePercentEncoding = cfg.decodePercentEncoding;\n return _this;\n }\n /**\n * @inheritdoc\n */\n UrlMatcher.prototype.parseMatches = function (text) {\n var matcherRegex = this.matcherRegex, stripPrefix = this.stripPrefix, stripTrailingSlash = this.stripTrailingSlash, decodePercentEncoding = this.decodePercentEncoding, tagBuilder = this.tagBuilder, matches = [], match;\n var _loop_1 = function () {\n var matchStr = match[0], schemeUrlMatch = match[1], wwwUrlMatch = match[4], wwwProtocolRelativeMatch = match[5], \n //tldUrlMatch = match[ 8 ], -- not needed at the moment\n tldProtocolRelativeMatch = match[9], offset = match.index, protocolRelativeMatch = wwwProtocolRelativeMatch || tldProtocolRelativeMatch, prevChar = text.charAt(offset - 1);\n if (!UrlMatchValidator.isValid(matchStr, schemeUrlMatch)) {\n return \"continue\";\n }\n // If the match is preceded by an '@' character, then it is either\n // an email address or a username. Skip these types of matches.\n if (offset > 0 && prevChar === '@') {\n return \"continue\";\n }\n // If it's a protocol-relative '//' match, but the character before the '//'\n // was a word character (i.e. a letter/number), then we found the '//' in the\n // middle of another word (such as \"asdf//asdf.com\"). In this case, skip the\n // match.\n if (offset > 0 && protocolRelativeMatch && this_1.wordCharRegExp.test(prevChar)) {\n return \"continue\";\n }\n // If the URL ends with a question mark, don't include the question\n // mark as part of the URL. We'll assume the question mark was the\n // end of a sentence, such as: \"Going to google.com?\"\n if (/\\?$/.test(matchStr)) {\n matchStr = matchStr.substr(0, matchStr.length - 1);\n }\n // Handle a closing parenthesis or square bracket at the end of the \n // match, and exclude it if there is not a matching open parenthesis \n // or square bracket in the match itself.\n if (this_1.matchHasUnbalancedClosingParen(matchStr)) {\n matchStr = matchStr.substr(0, matchStr.length - 1); // remove the trailing \")\"\n }\n else {\n // Handle an invalid character after the TLD\n var pos = this_1.matchHasInvalidCharAfterTld(matchStr, schemeUrlMatch);\n if (pos > -1) {\n matchStr = matchStr.substr(0, pos); // remove the trailing invalid chars\n }\n }\n // The autolinker accepts many characters in a url's scheme (like `fake://test.com`).\n // However, in cases where a URL is missing whitespace before an obvious link,\n // (for example: `nowhitespacehttp://www.test.com`), we only want the match to start\n // at the http:// part. We will check if the match contains a common scheme and then \n // shift the match to start from there. \t\t\n var foundCommonScheme = ['http://', 'https://'].find(function (commonScheme) { return !!schemeUrlMatch && schemeUrlMatch.indexOf(commonScheme) !== -1; });\n if (foundCommonScheme) {\n // If we found an overmatched URL, we want to find the index\n // of where the match should start and shift the match to\n // start from the beginning of the common scheme\n var indexOfSchemeStart = matchStr.indexOf(foundCommonScheme);\n matchStr = matchStr.substr(indexOfSchemeStart);\n schemeUrlMatch = schemeUrlMatch.substr(indexOfSchemeStart);\n offset = offset + indexOfSchemeStart;\n }\n var urlMatchType = schemeUrlMatch ? 'scheme' : (wwwUrlMatch ? 'www' : 'tld'), protocolUrlMatch = !!schemeUrlMatch;\n matches.push(new UrlMatch({\n tagBuilder: tagBuilder,\n matchedText: matchStr,\n offset: offset,\n urlMatchType: urlMatchType,\n url: matchStr,\n protocolUrlMatch: protocolUrlMatch,\n protocolRelativeMatch: !!protocolRelativeMatch,\n stripPrefix: stripPrefix,\n stripTrailingSlash: stripTrailingSlash,\n decodePercentEncoding: decodePercentEncoding,\n }));\n };\n var this_1 = this;\n while ((match = matcherRegex.exec(text)) !== null) {\n _loop_1();\n }\n return matches;\n };\n /**\n * Determines if a match found has an unmatched closing parenthesis,\n * square bracket or curly bracket. If so, the symbol will be removed\n * from the match itself, and appended after the generated anchor tag.\n *\n * A match may have an extra closing parenthesis at the end of the match\n * because the regular expression must include parenthesis for URLs such as\n * \"wikipedia.com/something_(disambiguation)\", which should be auto-linked.\n *\n * However, an extra parenthesis *will* be included when the URL itself is\n * wrapped in parenthesis, such as in the case of:\n * \"(wikipedia.com/something_(disambiguation))\"\n * In this case, the last closing parenthesis should *not* be part of the\n * URL itself, and this method will return `true`.\n *\n * For square brackets in URLs such as in PHP arrays, the same behavior as\n * parenthesis discussed above should happen:\n * \"[http://www.example.com/foo.php?bar[]=1&bar[]=2&bar[]=3]\"\n * The closing square bracket should not be part of the URL itself, and this\n * method will return `true`.\n *\n * @protected\n * @param {String} matchStr The full match string from the {@link #matcherRegex}.\n * @return {Boolean} `true` if there is an unbalanced closing parenthesis or\n * square bracket at the end of the `matchStr`, `false` otherwise.\n */\n UrlMatcher.prototype.matchHasUnbalancedClosingParen = function (matchStr) {\n var endChar = matchStr.charAt(matchStr.length - 1);\n var startChar;\n if (endChar === ')') {\n startChar = '(';\n }\n else if (endChar === ']') {\n startChar = '[';\n }\n else if (endChar === '}') {\n startChar = '{';\n }\n else {\n return false; // not a close parenthesis or square bracket\n }\n // Find if there are the same number of open braces as close braces in\n // the URL string, minus the last character (which we have already \n // determined to be either ')', ']' or '}'\n var numOpenBraces = 0;\n for (var i = 0, len = matchStr.length - 1; i < len; i++) {\n var char = matchStr.charAt(i);\n if (char === startChar) {\n numOpenBraces++;\n }\n else if (char === endChar) {\n numOpenBraces = Math.max(numOpenBraces - 1, 0);\n }\n }\n // If the number of open braces matches the number of close braces in\n // the URL minus the last character, then the match has *unbalanced*\n // braces because of the last character. Example of unbalanced braces\n // from the regex match:\n // \"http://example.com?a[]=1]\"\n if (numOpenBraces === 0) {\n return true;\n }\n return false;\n };\n /**\n * Determine if there's an invalid character after the TLD in a URL. Valid\n * characters after TLD are ':/?#'. Exclude scheme matched URLs from this\n * check.\n *\n * @protected\n * @param {String} urlMatch The matched URL, if there was one. Will be an\n * empty string if the match is not a URL match.\n * @param {String} schemeUrlMatch The match URL string for a scheme\n * match. Ex: 'http://yahoo.com'. This is used to match something like\n * 'http://localhost', where we won't double check that the domain name\n * has at least one '.' in it.\n * @return {Number} the position where the invalid character was found. If\n * no such character was found, returns -1\n */\n UrlMatcher.prototype.matchHasInvalidCharAfterTld = function (urlMatch, schemeUrlMatch) {\n if (!urlMatch) {\n return -1;\n }\n var offset = 0;\n if (schemeUrlMatch) {\n offset = urlMatch.indexOf(':');\n urlMatch = urlMatch.slice(offset);\n }\n var re = new RegExp(\"^((.?\\/\\/)?[-.\" + alphaNumericAndMarksCharsStr + \"]*[-\" + alphaNumericAndMarksCharsStr + \"]\\\\.[-\" + alphaNumericAndMarksCharsStr + \"]+)\");\n var res = re.exec(urlMatch);\n if (res === null) {\n return -1;\n }\n offset += res[1].length;\n urlMatch = urlMatch.slice(res[1].length);\n if (/^[^-.A-Za-z0-9:\\/?#]/.test(urlMatch)) {\n return offset;\n }\n return -1;\n };\n return UrlMatcher;\n}(Matcher));\nexport { UrlMatcher };\n\n//# sourceMappingURL=url-matcher.js.map\n","import * as tslib_1 from \"tslib\";\nimport { Match } from \"./match\";\n/**\n * @class Autolinker.match.Hashtag\n * @extends Autolinker.match.Match\n *\n * Represents a Hashtag match found in an input string which should be\n * Autolinked.\n *\n * See this class's superclass ({@link Autolinker.match.Match}) for more\n * details.\n */\nvar HashtagMatch = /** @class */ (function (_super) {\n tslib_1.__extends(HashtagMatch, _super);\n /**\n * @method constructor\n * @param {Object} cfg The configuration properties for the Match\n * instance, specified in an Object (map).\n */\n function HashtagMatch(cfg) {\n var _this = _super.call(this, cfg) || this;\n /**\n * @cfg {String} serviceName\n *\n * The service to point hashtag matches to. See {@link Autolinker#hashtag}\n * for available values.\n */\n _this.serviceName = ''; // default value just to get the above doc comment in the ES5 output and documentation generator\n /**\n * @cfg {String} hashtag (required)\n *\n * The HashtagMatch that was matched, without the '#'.\n */\n _this.hashtag = ''; // default value just to get the above doc comment in the ES5 output and documentation generator\n _this.serviceName = cfg.serviceName;\n _this.hashtag = cfg.hashtag;\n return _this;\n }\n /**\n * Returns a string name for the type of match that this class represents.\n * For the case of HashtagMatch, returns 'hashtag'.\n *\n * @return {String}\n */\n HashtagMatch.prototype.getType = function () {\n return 'hashtag';\n };\n /**\n * Returns the configured {@link #serviceName} to point the HashtagMatch to.\n * Ex: 'facebook', 'twitter'.\n *\n * @return {String}\n */\n HashtagMatch.prototype.getServiceName = function () {\n return this.serviceName;\n };\n /**\n * Returns the matched hashtag, without the '#' character.\n *\n * @return {String}\n */\n HashtagMatch.prototype.getHashtag = function () {\n return this.hashtag;\n };\n /**\n * Returns the anchor href that should be generated for the match.\n *\n * @return {String}\n */\n HashtagMatch.prototype.getAnchorHref = function () {\n var serviceName = this.serviceName, hashtag = this.hashtag;\n switch (serviceName) {\n case 'twitter':\n return 'https://twitter.com/hashtag/' + hashtag;\n case 'facebook':\n return 'https://www.facebook.com/hashtag/' + hashtag;\n case 'instagram':\n return 'https://instagram.com/explore/tags/' + hashtag;\n default: // Shouldn't happen because Autolinker's constructor should block any invalid values, but just in case.\n throw new Error('Unknown service name to point hashtag to: ' + serviceName);\n }\n };\n /**\n * Returns the anchor text that should be generated for the match.\n *\n * @return {String}\n */\n HashtagMatch.prototype.getAnchorText = function () {\n return '#' + this.hashtag;\n };\n return HashtagMatch;\n}(Match));\nexport { HashtagMatch };\n\n//# sourceMappingURL=hashtag-match.js.map\n","import * as tslib_1 from \"tslib\";\nimport { Match } from \"./match\";\n/**\n * @class Autolinker.match.Mention\n * @extends Autolinker.match.Match\n *\n * Represents a Mention match found in an input string which should be Autolinked.\n *\n * See this class's superclass ({@link Autolinker.match.Match}) for more details.\n */\nvar MentionMatch = /** @class */ (function (_super) {\n tslib_1.__extends(MentionMatch, _super);\n /**\n * @method constructor\n * @param {Object} cfg The configuration properties for the Match\n * instance, specified in an Object (map).\n */\n function MentionMatch(cfg) {\n var _this = _super.call(this, cfg) || this;\n /**\n * @cfg {String} serviceName\n *\n * The service to point mention matches to. See {@link Autolinker#mention}\n * for available values.\n */\n _this.serviceName = 'twitter'; // default value just to get the above doc comment in the ES5 output and documentation generator\n /**\n * @cfg {String} mention (required)\n *\n * The Mention that was matched, without the '@' character.\n */\n _this.mention = ''; // default value just to get the above doc comment in the ES5 output and documentation generator\n _this.mention = cfg.mention;\n _this.serviceName = cfg.serviceName;\n return _this;\n }\n /**\n * Returns a string name for the type of match that this class represents.\n * For the case of MentionMatch, returns 'mention'.\n *\n * @return {String}\n */\n MentionMatch.prototype.getType = function () {\n return 'mention';\n };\n /**\n * Returns the mention, without the '@' character.\n *\n * @return {String}\n */\n MentionMatch.prototype.getMention = function () {\n return this.mention;\n };\n /**\n * Returns the configured {@link #serviceName} to point the mention to.\n * Ex: 'instagram', 'twitter', 'soundcloud'.\n *\n * @return {String}\n */\n MentionMatch.prototype.getServiceName = function () {\n return this.serviceName;\n };\n /**\n * Returns the anchor href that should be generated for the match.\n *\n * @return {String}\n */\n MentionMatch.prototype.getAnchorHref = function () {\n switch (this.serviceName) {\n case 'twitter':\n return 'https://twitter.com/' + this.mention;\n case 'instagram':\n return 'https://instagram.com/' + this.mention;\n case 'soundcloud':\n return 'https://soundcloud.com/' + this.mention;\n default: // Shouldn't happen because Autolinker's constructor should block any invalid values, but just in case.\n throw new Error('Unknown service name to point mention to: ' + this.serviceName);\n }\n };\n /**\n * Returns the anchor text that should be generated for the match.\n *\n * @return {String}\n */\n MentionMatch.prototype.getAnchorText = function () {\n return '@' + this.mention;\n };\n /**\n * Returns the CSS class suffixes that should be used on a tag built with\n * the match. See {@link Autolinker.match.Match#getCssClassSuffixes} for\n * details.\n *\n * @return {String[]}\n */\n MentionMatch.prototype.getCssClassSuffixes = function () {\n var cssClassSuffixes = _super.prototype.getCssClassSuffixes.call(this), serviceName = this.getServiceName();\n if (serviceName) {\n cssClassSuffixes.push(serviceName);\n }\n return cssClassSuffixes;\n };\n return MentionMatch;\n}(Match));\nexport { MentionMatch };\n\n//# sourceMappingURL=mention-match.js.map\n","import * as tslib_1 from \"tslib\";\nimport { Match } from \"./match\";\n/**\n * @class Autolinker.match.Phone\n * @extends Autolinker.match.Match\n *\n * Represents a Phone number match found in an input string which should be\n * Autolinked.\n *\n * See this class's superclass ({@link Autolinker.match.Match}) for more\n * details.\n */\nvar PhoneMatch = /** @class */ (function (_super) {\n tslib_1.__extends(PhoneMatch, _super);\n /**\n * @method constructor\n * @param {Object} cfg The configuration properties for the Match\n * instance, specified in an Object (map).\n */\n function PhoneMatch(cfg) {\n var _this = _super.call(this, cfg) || this;\n /**\n * @protected\n * @property {String} number (required)\n *\n * The phone number that was matched, without any delimiter characters.\n *\n * Note: This is a string to allow for prefixed 0's.\n */\n _this.number = ''; // default value just to get the above doc comment in the ES5 output and documentation generator\n /**\n * @protected\n * @property {Boolean} plusSign (required)\n *\n * `true` if the matched phone number started with a '+' sign. We'll include\n * it in the `tel:` URL if so, as this is needed for international numbers.\n *\n * Ex: '+1 (123) 456 7879'\n */\n _this.plusSign = false; // default value just to get the above doc comment in the ES5 output and documentation generator\n _this.number = cfg.number;\n _this.plusSign = cfg.plusSign;\n return _this;\n }\n /**\n * Returns a string name for the type of match that this class represents.\n * For the case of PhoneMatch, returns 'phone'.\n *\n * @return {String}\n */\n PhoneMatch.prototype.getType = function () {\n return 'phone';\n };\n /**\n * Returns the phone number that was matched as a string, without any\n * delimiter characters.\n *\n * Note: This is a string to allow for prefixed 0's.\n *\n * @return {String}\n */\n PhoneMatch.prototype.getPhoneNumber = function () {\n return this.number;\n };\n /**\n * Alias of {@link #getPhoneNumber}, returns the phone number that was\n * matched as a string, without any delimiter characters.\n *\n * Note: This is a string to allow for prefixed 0's.\n *\n * @return {String}\n */\n PhoneMatch.prototype.getNumber = function () {\n return this.getPhoneNumber();\n };\n /**\n * Returns the anchor href that should be generated for the match.\n *\n * @return {String}\n */\n PhoneMatch.prototype.getAnchorHref = function () {\n return 'tel:' + (this.plusSign ? '+' : '') + this.number;\n };\n /**\n * Returns the anchor text that should be generated for the match.\n *\n * @return {String}\n */\n PhoneMatch.prototype.getAnchorText = function () {\n return this.matchedText;\n };\n return PhoneMatch;\n}(Match));\nexport { PhoneMatch };\n\n//# sourceMappingURL=phone-match.js.map\n","import * as tslib_1 from \"tslib\";\nimport { Match } from \"./match\";\n/**\n * @class Autolinker.match.Url\n * @extends Autolinker.match.Match\n *\n * Represents a Url match found in an input string which should be Autolinked.\n *\n * See this class's superclass ({@link Autolinker.match.Match}) for more details.\n */\nvar UrlMatch = /** @class */ (function (_super) {\n tslib_1.__extends(UrlMatch, _super);\n /**\n * @method constructor\n * @param {Object} cfg The configuration properties for the Match\n * instance, specified in an Object (map).\n */\n function UrlMatch(cfg) {\n var _this = _super.call(this, cfg) || this;\n /**\n * @cfg {String} url (required)\n *\n * The url that was matched.\n */\n _this.url = ''; // default value just to get the above doc comment in the ES5 output and documentation generator\n /**\n * @cfg {\"scheme\"/\"www\"/\"tld\"} urlMatchType (required)\n *\n * The type of URL match that this class represents. This helps to determine\n * if the match was made in the original text with a prefixed scheme (ex:\n * 'http://www.google.com'), a prefixed 'www' (ex: 'www.google.com'), or\n * was matched by a known top-level domain (ex: 'google.com').\n */\n _this.urlMatchType = 'scheme'; // default value just to get the above doc comment in the ES5 output and documentation generator\n /**\n * @cfg {Boolean} protocolUrlMatch (required)\n *\n * `true` if the URL is a match which already has a protocol (i.e.\n * 'http://'), `false` if the match was from a 'www' or known TLD match.\n */\n _this.protocolUrlMatch = false; // default value just to get the above doc comment in the ES5 output and documentation generator\n /**\n * @cfg {Boolean} protocolRelativeMatch (required)\n *\n * `true` if the URL is a protocol-relative match. A protocol-relative match\n * is a URL that starts with '//', and will be either http:// or https://\n * based on the protocol that the site is loaded under.\n */\n _this.protocolRelativeMatch = false; // default value just to get the above doc comment in the ES5 output and documentation generator\n /**\n * @cfg {Object} stripPrefix (required)\n *\n * The Object form of {@link Autolinker#cfg-stripPrefix}.\n */\n _this.stripPrefix = { scheme: true, www: true }; // default value just to get the above doc comment in the ES5 output and documentation generator\n /**\n * @cfg {Boolean} stripTrailingSlash (required)\n * @inheritdoc Autolinker#cfg-stripTrailingSlash\n */\n _this.stripTrailingSlash = true; // default value just to get the above doc comment in the ES5 output and documentation generator\n /**\n * @cfg {Boolean} decodePercentEncoding (required)\n * @inheritdoc Autolinker#cfg-decodePercentEncoding\n */\n _this.decodePercentEncoding = true; // default value just to get the above doc comment in the ES5 output and documentation generator\n /**\n * @private\n * @property {RegExp} schemePrefixRegex\n *\n * A regular expression used to remove the 'http://' or 'https://' from\n * URLs.\n */\n _this.schemePrefixRegex = /^(https?:\\/\\/)?/i;\n /**\n * @private\n * @property {RegExp} wwwPrefixRegex\n *\n * A regular expression used to remove the 'www.' from URLs.\n */\n _this.wwwPrefixRegex = /^(https?:\\/\\/)?(www\\.)?/i;\n /**\n * @private\n * @property {RegExp} protocolRelativeRegex\n *\n * The regular expression used to remove the protocol-relative '//' from the {@link #url} string, for purposes\n * of {@link #getAnchorText}. A protocol-relative URL is, for example, \"//yahoo.com\"\n */\n _this.protocolRelativeRegex = /^\\/\\//;\n /**\n * @private\n * @property {Boolean} protocolPrepended\n *\n * Will be set to `true` if the 'http://' protocol has been prepended to the {@link #url} (because the\n * {@link #url} did not have a protocol)\n */\n _this.protocolPrepended = false;\n _this.urlMatchType = cfg.urlMatchType;\n _this.url = cfg.url;\n _this.protocolUrlMatch = cfg.protocolUrlMatch;\n _this.protocolRelativeMatch = cfg.protocolRelativeMatch;\n _this.stripPrefix = cfg.stripPrefix;\n _this.stripTrailingSlash = cfg.stripTrailingSlash;\n _this.decodePercentEncoding = cfg.decodePercentEncoding;\n return _this;\n }\n /**\n * Returns a string name for the type of match that this class represents.\n * For the case of UrlMatch, returns 'url'.\n *\n * @return {String}\n */\n UrlMatch.prototype.getType = function () {\n return 'url';\n };\n /**\n * Returns a string name for the type of URL match that this class\n * represents.\n *\n * This helps to determine if the match was made in the original text with a\n * prefixed scheme (ex: 'http://www.google.com'), a prefixed 'www' (ex:\n * 'www.google.com'), or was matched by a known top-level domain (ex:\n * 'google.com').\n *\n * @return {\"scheme\"/\"www\"/\"tld\"}\n */\n UrlMatch.prototype.getUrlMatchType = function () {\n return this.urlMatchType;\n };\n /**\n * Returns the url that was matched, assuming the protocol to be 'http://' if the original\n * match was missing a protocol.\n *\n * @return {String}\n */\n UrlMatch.prototype.getUrl = function () {\n var url = this.url;\n // if the url string doesn't begin with a protocol, assume 'http://'\n if (!this.protocolRelativeMatch && !this.protocolUrlMatch && !this.protocolPrepended) {\n url = this.url = 'http://' + url;\n this.protocolPrepended = true;\n }\n return url;\n };\n /**\n * Returns the anchor href that should be generated for the match.\n *\n * @return {String}\n */\n UrlMatch.prototype.getAnchorHref = function () {\n var url = this.getUrl();\n return url.replace(/&/g, '&'); // any &'s in the URL should be converted back to '&' if they were displayed as & in the source html\n };\n /**\n * Returns the anchor text that should be generated for the match.\n *\n * @return {String}\n */\n UrlMatch.prototype.getAnchorText = function () {\n var anchorText = this.getMatchedText();\n if (this.protocolRelativeMatch) {\n // Strip off any protocol-relative '//' from the anchor text\n anchorText = this.stripProtocolRelativePrefix(anchorText);\n }\n if (this.stripPrefix.scheme) {\n anchorText = this.stripSchemePrefix(anchorText);\n }\n if (this.stripPrefix.www) {\n anchorText = this.stripWwwPrefix(anchorText);\n }\n if (this.stripTrailingSlash) {\n anchorText = this.removeTrailingSlash(anchorText); // remove trailing slash, if there is one\n }\n if (this.decodePercentEncoding) {\n anchorText = this.removePercentEncoding(anchorText);\n }\n return anchorText;\n };\n // ---------------------------------------\n // Utility Functionality\n /**\n * Strips the scheme prefix (such as \"http://\" or \"https://\") from the given\n * `url`.\n *\n * @private\n * @param {String} url The text of the anchor that is being generated, for\n * which to strip off the url scheme.\n * @return {String} The `url`, with the scheme stripped.\n */\n UrlMatch.prototype.stripSchemePrefix = function (url) {\n return url.replace(this.schemePrefixRegex, '');\n };\n /**\n * Strips the 'www' prefix from the given `url`.\n *\n * @private\n * @param {String} url The text of the anchor that is being generated, for\n * which to strip off the 'www' if it exists.\n * @return {String} The `url`, with the 'www' stripped.\n */\n UrlMatch.prototype.stripWwwPrefix = function (url) {\n return url.replace(this.wwwPrefixRegex, '$1'); // leave any scheme ($1), it one exists\n };\n /**\n * Strips any protocol-relative '//' from the anchor text.\n *\n * @private\n * @param {String} text The text of the anchor that is being generated, for which to strip off the\n * protocol-relative prefix (such as stripping off \"//\")\n * @return {String} The `anchorText`, with the protocol-relative prefix stripped.\n */\n UrlMatch.prototype.stripProtocolRelativePrefix = function (text) {\n return text.replace(this.protocolRelativeRegex, '');\n };\n /**\n * Removes any trailing slash from the given `anchorText`, in preparation for the text to be displayed.\n *\n * @private\n * @param {String} anchorText The text of the anchor that is being generated, for which to remove any trailing\n * slash ('/') that may exist.\n * @return {String} The `anchorText`, with the trailing slash removed.\n */\n UrlMatch.prototype.removeTrailingSlash = function (anchorText) {\n if (anchorText.charAt(anchorText.length - 1) === '/') {\n anchorText = anchorText.slice(0, -1);\n }\n return anchorText;\n };\n /**\n * Decodes percent-encoded characters from the given `anchorText`, in\n * preparation for the text to be displayed.\n *\n * @private\n * @param {String} anchorText The text of the anchor that is being\n * generated, for which to decode any percent-encoded characters.\n * @return {String} The `anchorText`, with the percent-encoded characters\n * decoded.\n */\n UrlMatch.prototype.removePercentEncoding = function (anchorText) {\n // First, convert a few of the known % encodings to the corresponding\n // HTML entities that could accidentally be interpretted as special\n // HTML characters\n var preProcessedEntityAnchorText = anchorText\n .replace(/%22/gi, '"') // \" char\n .replace(/%26/gi, '&') // & char\n .replace(/%27/gi, ''') // ' char\n .replace(/%3C/gi, '<') // < char\n .replace(/%3E/gi, '>'); // > char\n try {\n // Now attempt to decode the rest of the anchor text\n return decodeURIComponent(preProcessedEntityAnchorText);\n }\n catch (e) { // Invalid % escape sequence in the anchor text\n return preProcessedEntityAnchorText;\n }\n };\n return UrlMatch;\n}(Match));\nexport { UrlMatch };\n\n//# sourceMappingURL=url-match.js.map\n","/**\n * @abstract\n * @class Autolinker.matcher.Matcher\n *\n * An abstract class and interface for individual matchers to find matches in\n * an input string with linkified versions of them.\n *\n * Note that Matchers do not take HTML into account - they must be fed the text\n * nodes of any HTML string, which is handled by {@link Autolinker#parse}.\n */\nvar Matcher = /** @class */ (function () {\n /**\n * @method constructor\n * @param {Object} cfg The configuration properties for the Matcher\n * instance, specified in an Object (map).\n */\n function Matcher(cfg) {\n /**\n * @cfg {Autolinker.AnchorTagBuilder} tagBuilder (required)\n *\n * Reference to the AnchorTagBuilder instance to use to generate HTML tags\n * for {@link Autolinker.match.Match Matches}.\n */\n this.__jsduckDummyDocProp = null; // property used just to get the above doc comment into the ES5 output and documentation generator\n this.tagBuilder = cfg.tagBuilder;\n }\n return Matcher;\n}());\nexport { Matcher };\n\n//# sourceMappingURL=matcher.js.map\n","/*\n * This file builds and stores a library of the common regular expressions used\n * by the Autolinker utility.\n *\n * Other regular expressions may exist ad-hoc, but these are generally the\n * regular expressions that are shared between source files.\n */\n/**\n * Regular expression to match upper and lowercase ASCII letters\n */\nexport var letterRe = /[A-Za-z]/;\n/**\n * Regular expression to match ASCII digits\n */\nexport var digitRe = /[\\d]/;\n/**\n * Regular expression to match everything *except* ASCII digits\n */\nexport var nonDigitRe = /[\\D]/;\n/**\n * Regular expression to match whitespace\n */\nexport var whitespaceRe = /\\s/;\n/**\n * Regular expression to match quote characters\n */\nexport var quoteRe = /['\"]/;\n/**\n * Regular expression to match the range of ASCII control characters (0-31), and\n * the backspace char (127)\n */\nexport var controlCharsRe = /[\\x00-\\x1F\\x7F]/;\n/**\n * The string form of a regular expression that would match all of the\n * alphabetic (\"letter\") chars in the unicode character set when placed in a\n * RegExp character class (`[]`). This includes all international alphabetic\n * characters.\n *\n * These would be the characters matched by unicode regex engines `\\p{L}`\n * escape (\"all letters\").\n *\n * Taken from the XRegExp library: http://xregexp.com/ (thanks @https://github.com/slevithan)\n * Specifically: http://xregexp.com/v/3.2.0/xregexp-all.js, the 'Letter'\n * regex's bmp\n *\n * VERY IMPORTANT: This set of characters is defined inside of a Regular\n * Expression literal rather than a string literal to prevent UglifyJS from\n * compressing the unicode escape sequences into their actual unicode\n * characters. If Uglify compresses these into the unicode characters\n * themselves, this results in the error \"Range out of order in character\n * class\" when these characters are used inside of a Regular Expression\n * character class (`[]`). See usages of this const. Alternatively, we can set\n * the UglifyJS option `ascii_only` to true for the build, but that doesn't\n * help others who are pulling in Autolinker into their own build and running\n * UglifyJS themselves.\n */\nexport var alphaCharsStr = /A-Za-z\\xAA\\xB5\\xBA\\xC0-\\xD6\\xD8-\\xF6\\xF8-\\u02C1\\u02C6-\\u02D1\\u02E0-\\u02E4\\u02EC\\u02EE\\u0370-\\u0374\\u0376\\u0377\\u037A-\\u037D\\u037F\\u0386\\u0388-\\u038A\\u038C\\u038E-\\u03A1\\u03A3-\\u03F5\\u03F7-\\u0481\\u048A-\\u052F\\u0531-\\u0556\\u0559\\u0561-\\u0587\\u05D0-\\u05EA\\u05F0-\\u05F2\\u0620-\\u064A\\u066E\\u066F\\u0671-\\u06D3\\u06D5\\u06E5\\u06E6\\u06EE\\u06EF\\u06FA-\\u06FC\\u06FF\\u0710\\u0712-\\u072F\\u074D-\\u07A5\\u07B1\\u07CA-\\u07EA\\u07F4\\u07F5\\u07FA\\u0800-\\u0815\\u081A\\u0824\\u0828\\u0840-\\u0858\\u08A0-\\u08B4\\u08B6-\\u08BD\\u0904-\\u0939\\u093D\\u0950\\u0958-\\u0961\\u0971-\\u0980\\u0985-\\u098C\\u098F\\u0990\\u0993-\\u09A8\\u09AA-\\u09B0\\u09B2\\u09B6-\\u09B9\\u09BD\\u09CE\\u09DC\\u09DD\\u09DF-\\u09E1\\u09F0\\u09F1\\u0A05-\\u0A0A\\u0A0F\\u0A10\\u0A13-\\u0A28\\u0A2A-\\u0A30\\u0A32\\u0A33\\u0A35\\u0A36\\u0A38\\u0A39\\u0A59-\\u0A5C\\u0A5E\\u0A72-\\u0A74\\u0A85-\\u0A8D\\u0A8F-\\u0A91\\u0A93-\\u0AA8\\u0AAA-\\u0AB0\\u0AB2\\u0AB3\\u0AB5-\\u0AB9\\u0ABD\\u0AD0\\u0AE0\\u0AE1\\u0AF9\\u0B05-\\u0B0C\\u0B0F\\u0B10\\u0B13-\\u0B28\\u0B2A-\\u0B30\\u0B32\\u0B33\\u0B35-\\u0B39\\u0B3D\\u0B5C\\u0B5D\\u0B5F-\\u0B61\\u0B71\\u0B83\\u0B85-\\u0B8A\\u0B8E-\\u0B90\\u0B92-\\u0B95\\u0B99\\u0B9A\\u0B9C\\u0B9E\\u0B9F\\u0BA3\\u0BA4\\u0BA8-\\u0BAA\\u0BAE-\\u0BB9\\u0BD0\\u0C05-\\u0C0C\\u0C0E-\\u0C10\\u0C12-\\u0C28\\u0C2A-\\u0C39\\u0C3D\\u0C58-\\u0C5A\\u0C60\\u0C61\\u0C80\\u0C85-\\u0C8C\\u0C8E-\\u0C90\\u0C92-\\u0CA8\\u0CAA-\\u0CB3\\u0CB5-\\u0CB9\\u0CBD\\u0CDE\\u0CE0\\u0CE1\\u0CF1\\u0CF2\\u0D05-\\u0D0C\\u0D0E-\\u0D10\\u0D12-\\u0D3A\\u0D3D\\u0D4E\\u0D54-\\u0D56\\u0D5F-\\u0D61\\u0D7A-\\u0D7F\\u0D85-\\u0D96\\u0D9A-\\u0DB1\\u0DB3-\\u0DBB\\u0DBD\\u0DC0-\\u0DC6\\u0E01-\\u0E30\\u0E32\\u0E33\\u0E40-\\u0E46\\u0E81\\u0E82\\u0E84\\u0E87\\u0E88\\u0E8A\\u0E8D\\u0E94-\\u0E97\\u0E99-\\u0E9F\\u0EA1-\\u0EA3\\u0EA5\\u0EA7\\u0EAA\\u0EAB\\u0EAD-\\u0EB0\\u0EB2\\u0EB3\\u0EBD\\u0EC0-\\u0EC4\\u0EC6\\u0EDC-\\u0EDF\\u0F00\\u0F40-\\u0F47\\u0F49-\\u0F6C\\u0F88-\\u0F8C\\u1000-\\u102A\\u103F\\u1050-\\u1055\\u105A-\\u105D\\u1061\\u1065\\u1066\\u106E-\\u1070\\u1075-\\u1081\\u108E\\u10A0-\\u10C5\\u10C7\\u10CD\\u10D0-\\u10FA\\u10FC-\\u1248\\u124A-\\u124D\\u1250-\\u1256\\u1258\\u125A-\\u125D\\u1260-\\u1288\\u128A-\\u128D\\u1290-\\u12B0\\u12B2-\\u12B5\\u12B8-\\u12BE\\u12C0\\u12C2-\\u12C5\\u12C8-\\u12D6\\u12D8-\\u1310\\u1312-\\u1315\\u1318-\\u135A\\u1380-\\u138F\\u13A0-\\u13F5\\u13F8-\\u13FD\\u1401-\\u166C\\u166F-\\u167F\\u1681-\\u169A\\u16A0-\\u16EA\\u16F1-\\u16F8\\u1700-\\u170C\\u170E-\\u1711\\u1720-\\u1731\\u1740-\\u1751\\u1760-\\u176C\\u176E-\\u1770\\u1780-\\u17B3\\u17D7\\u17DC\\u1820-\\u1877\\u1880-\\u1884\\u1887-\\u18A8\\u18AA\\u18B0-\\u18F5\\u1900-\\u191E\\u1950-\\u196D\\u1970-\\u1974\\u1980-\\u19AB\\u19B0-\\u19C9\\u1A00-\\u1A16\\u1A20-\\u1A54\\u1AA7\\u1B05-\\u1B33\\u1B45-\\u1B4B\\u1B83-\\u1BA0\\u1BAE\\u1BAF\\u1BBA-\\u1BE5\\u1C00-\\u1C23\\u1C4D-\\u1C4F\\u1C5A-\\u1C7D\\u1C80-\\u1C88\\u1CE9-\\u1CEC\\u1CEE-\\u1CF1\\u1CF5\\u1CF6\\u1D00-\\u1DBF\\u1E00-\\u1F15\\u1F18-\\u1F1D\\u1F20-\\u1F45\\u1F48-\\u1F4D\\u1F50-\\u1F57\\u1F59\\u1F5B\\u1F5D\\u1F5F-\\u1F7D\\u1F80-\\u1FB4\\u1FB6-\\u1FBC\\u1FBE\\u1FC2-\\u1FC4\\u1FC6-\\u1FCC\\u1FD0-\\u1FD3\\u1FD6-\\u1FDB\\u1FE0-\\u1FEC\\u1FF2-\\u1FF4\\u1FF6-\\u1FFC\\u2071\\u207F\\u2090-\\u209C\\u2102\\u2107\\u210A-\\u2113\\u2115\\u2119-\\u211D\\u2124\\u2126\\u2128\\u212A-\\u212D\\u212F-\\u2139\\u213C-\\u213F\\u2145-\\u2149\\u214E\\u2183\\u2184\\u2C00-\\u2C2E\\u2C30-\\u2C5E\\u2C60-\\u2CE4\\u2CEB-\\u2CEE\\u2CF2\\u2CF3\\u2D00-\\u2D25\\u2D27\\u2D2D\\u2D30-\\u2D67\\u2D6F\\u2D80-\\u2D96\\u2DA0-\\u2DA6\\u2DA8-\\u2DAE\\u2DB0-\\u2DB6\\u2DB8-\\u2DBE\\u2DC0-\\u2DC6\\u2DC8-\\u2DCE\\u2DD0-\\u2DD6\\u2DD8-\\u2DDE\\u2E2F\\u3005\\u3006\\u3031-\\u3035\\u303B\\u303C\\u3041-\\u3096\\u309D-\\u309F\\u30A1-\\u30FA\\u30FC-\\u30FF\\u3105-\\u312D\\u3131-\\u318E\\u31A0-\\u31BA\\u31F0-\\u31FF\\u3400-\\u4DB5\\u4E00-\\u9FD5\\uA000-\\uA48C\\uA4D0-\\uA4FD\\uA500-\\uA60C\\uA610-\\uA61F\\uA62A\\uA62B\\uA640-\\uA66E\\uA67F-\\uA69D\\uA6A0-\\uA6E5\\uA717-\\uA71F\\uA722-\\uA788\\uA78B-\\uA7AE\\uA7B0-\\uA7B7\\uA7F7-\\uA801\\uA803-\\uA805\\uA807-\\uA80A\\uA80C-\\uA822\\uA840-\\uA873\\uA882-\\uA8B3\\uA8F2-\\uA8F7\\uA8FB\\uA8FD\\uA90A-\\uA925\\uA930-\\uA946\\uA960-\\uA97C\\uA984-\\uA9B2\\uA9CF\\uA9E0-\\uA9E4\\uA9E6-\\uA9EF\\uA9FA-\\uA9FE\\uAA00-\\uAA28\\uAA40-\\uAA42\\uAA44-\\uAA4B\\uAA60-\\uAA76\\uAA7A\\uAA7E-\\uAAAF\\uAAB1\\uAAB5\\uAAB6\\uAAB9-\\uAABD\\uAAC0\\uAAC2\\uAADB-\\uAADD\\uAAE0-\\uAAEA\\uAAF2-\\uAAF4\\uAB01-\\uAB06\\uAB09-\\uAB0E\\uAB11-\\uAB16\\uAB20-\\uAB26\\uAB28-\\uAB2E\\uAB30-\\uAB5A\\uAB5C-\\uAB65\\uAB70-\\uABE2\\uAC00-\\uD7A3\\uD7B0-\\uD7C6\\uD7CB-\\uD7FB\\uF900-\\uFA6D\\uFA70-\\uFAD9\\uFB00-\\uFB06\\uFB13-\\uFB17\\uFB1D\\uFB1F-\\uFB28\\uFB2A-\\uFB36\\uFB38-\\uFB3C\\uFB3E\\uFB40\\uFB41\\uFB43\\uFB44\\uFB46-\\uFBB1\\uFBD3-\\uFD3D\\uFD50-\\uFD8F\\uFD92-\\uFDC7\\uFDF0-\\uFDFB\\uFE70-\\uFE74\\uFE76-\\uFEFC\\uFF21-\\uFF3A\\uFF41-\\uFF5A\\uFF66-\\uFFBE\\uFFC2-\\uFFC7\\uFFCA-\\uFFCF\\uFFD2-\\uFFD7\\uFFDA-\\uFFDC/\n .source; // see note in above variable description\n/**\n * The string form of a regular expression that would match all emoji characters\n * Based on the emoji regex defined in this article: https://thekevinscott.com/emojis-in-javascript/\n */\nexport var emojiStr = /\\u2700-\\u27bf\\udde6-\\uddff\\ud800-\\udbff\\udc00-\\udfff\\ufe0e\\ufe0f\\u0300-\\u036f\\ufe20-\\ufe23\\u20d0-\\u20f0\\ud83c\\udffb-\\udfff\\u200d\\u3299\\u3297\\u303d\\u3030\\u24c2\\ud83c\\udd70-\\udd71\\udd7e-\\udd7f\\udd8e\\udd91-\\udd9a\\udde6-\\uddff\\ude01-\\ude02\\ude1a\\ude2f\\ude32-\\ude3a\\ude50-\\ude51\\u203c\\u2049\\u25aa-\\u25ab\\u25b6\\u25c0\\u25fb-\\u25fe\\u00a9\\u00ae\\u2122\\u2139\\udc04\\u2600-\\u26FF\\u2b05\\u2b06\\u2b07\\u2b1b\\u2b1c\\u2b50\\u2b55\\u231a\\u231b\\u2328\\u23cf\\u23e9-\\u23f3\\u23f8-\\u23fa\\udccf\\u2935\\u2934\\u2190-\\u21ff/\n .source;\n/**\n * The string form of a regular expression that would match all of the\n * combining mark characters in the unicode character set when placed in a\n * RegExp character class (`[]`).\n *\n * These would be the characters matched by unicode regex engines `\\p{M}`\n * escape (\"all marks\").\n *\n * Taken from the XRegExp library: http://xregexp.com/ (thanks @https://github.com/slevithan)\n * Specifically: http://xregexp.com/v/3.2.0/xregexp-all.js, the 'Mark'\n * regex's bmp\n *\n * VERY IMPORTANT: This set of characters is defined inside of a Regular\n * Expression literal rather than a string literal to prevent UglifyJS from\n * compressing the unicode escape sequences into their actual unicode\n * characters. If Uglify compresses these into the unicode characters\n * themselves, this results in the error \"Range out of order in character\n * class\" when these characters are used inside of a Regular Expression\n * character class (`[]`). See usages of this const. Alternatively, we can set\n * the UglifyJS option `ascii_only` to true for the build, but that doesn't\n * help others who are pulling in Autolinker into their own build and running\n * UglifyJS themselves.\n */\nexport var marksStr = /\\u0300-\\u036F\\u0483-\\u0489\\u0591-\\u05BD\\u05BF\\u05C1\\u05C2\\u05C4\\u05C5\\u05C7\\u0610-\\u061A\\u064B-\\u065F\\u0670\\u06D6-\\u06DC\\u06DF-\\u06E4\\u06E7\\u06E8\\u06EA-\\u06ED\\u0711\\u0730-\\u074A\\u07A6-\\u07B0\\u07EB-\\u07F3\\u0816-\\u0819\\u081B-\\u0823\\u0825-\\u0827\\u0829-\\u082D\\u0859-\\u085B\\u08D4-\\u08E1\\u08E3-\\u0903\\u093A-\\u093C\\u093E-\\u094F\\u0951-\\u0957\\u0962\\u0963\\u0981-\\u0983\\u09BC\\u09BE-\\u09C4\\u09C7\\u09C8\\u09CB-\\u09CD\\u09D7\\u09E2\\u09E3\\u0A01-\\u0A03\\u0A3C\\u0A3E-\\u0A42\\u0A47\\u0A48\\u0A4B-\\u0A4D\\u0A51\\u0A70\\u0A71\\u0A75\\u0A81-\\u0A83\\u0ABC\\u0ABE-\\u0AC5\\u0AC7-\\u0AC9\\u0ACB-\\u0ACD\\u0AE2\\u0AE3\\u0B01-\\u0B03\\u0B3C\\u0B3E-\\u0B44\\u0B47\\u0B48\\u0B4B-\\u0B4D\\u0B56\\u0B57\\u0B62\\u0B63\\u0B82\\u0BBE-\\u0BC2\\u0BC6-\\u0BC8\\u0BCA-\\u0BCD\\u0BD7\\u0C00-\\u0C03\\u0C3E-\\u0C44\\u0C46-\\u0C48\\u0C4A-\\u0C4D\\u0C55\\u0C56\\u0C62\\u0C63\\u0C81-\\u0C83\\u0CBC\\u0CBE-\\u0CC4\\u0CC6-\\u0CC8\\u0CCA-\\u0CCD\\u0CD5\\u0CD6\\u0CE2\\u0CE3\\u0D01-\\u0D03\\u0D3E-\\u0D44\\u0D46-\\u0D48\\u0D4A-\\u0D4D\\u0D57\\u0D62\\u0D63\\u0D82\\u0D83\\u0DCA\\u0DCF-\\u0DD4\\u0DD6\\u0DD8-\\u0DDF\\u0DF2\\u0DF3\\u0E31\\u0E34-\\u0E3A\\u0E47-\\u0E4E\\u0EB1\\u0EB4-\\u0EB9\\u0EBB\\u0EBC\\u0EC8-\\u0ECD\\u0F18\\u0F19\\u0F35\\u0F37\\u0F39\\u0F3E\\u0F3F\\u0F71-\\u0F84\\u0F86\\u0F87\\u0F8D-\\u0F97\\u0F99-\\u0FBC\\u0FC6\\u102B-\\u103E\\u1056-\\u1059\\u105E-\\u1060\\u1062-\\u1064\\u1067-\\u106D\\u1071-\\u1074\\u1082-\\u108D\\u108F\\u109A-\\u109D\\u135D-\\u135F\\u1712-\\u1714\\u1732-\\u1734\\u1752\\u1753\\u1772\\u1773\\u17B4-\\u17D3\\u17DD\\u180B-\\u180D\\u1885\\u1886\\u18A9\\u1920-\\u192B\\u1930-\\u193B\\u1A17-\\u1A1B\\u1A55-\\u1A5E\\u1A60-\\u1A7C\\u1A7F\\u1AB0-\\u1ABE\\u1B00-\\u1B04\\u1B34-\\u1B44\\u1B6B-\\u1B73\\u1B80-\\u1B82\\u1BA1-\\u1BAD\\u1BE6-\\u1BF3\\u1C24-\\u1C37\\u1CD0-\\u1CD2\\u1CD4-\\u1CE8\\u1CED\\u1CF2-\\u1CF4\\u1CF8\\u1CF9\\u1DC0-\\u1DF5\\u1DFB-\\u1DFF\\u20D0-\\u20F0\\u2CEF-\\u2CF1\\u2D7F\\u2DE0-\\u2DFF\\u302A-\\u302F\\u3099\\u309A\\uA66F-\\uA672\\uA674-\\uA67D\\uA69E\\uA69F\\uA6F0\\uA6F1\\uA802\\uA806\\uA80B\\uA823-\\uA827\\uA880\\uA881\\uA8B4-\\uA8C5\\uA8E0-\\uA8F1\\uA926-\\uA92D\\uA947-\\uA953\\uA980-\\uA983\\uA9B3-\\uA9C0\\uA9E5\\uAA29-\\uAA36\\uAA43\\uAA4C\\uAA4D\\uAA7B-\\uAA7D\\uAAB0\\uAAB2-\\uAAB4\\uAAB7\\uAAB8\\uAABE\\uAABF\\uAAC1\\uAAEB-\\uAAEF\\uAAF5\\uAAF6\\uABE3-\\uABEA\\uABEC\\uABED\\uFB1E\\uFE00-\\uFE0F\\uFE20-\\uFE2F/\n .source; // see note in above variable description\n/**\n * The string form of a regular expression that would match all of the\n * alphabetic (\"letter\") chars, emoji, and combining marks in the unicode character set\n * when placed in a RegExp character class (`[]`). This includes all\n * international alphabetic characters.\n *\n * These would be the characters matched by unicode regex engines `\\p{L}\\p{M}`\n * escapes and emoji characters.\n */\nexport var alphaCharsAndMarksStr = alphaCharsStr + emojiStr + marksStr;\n/**\n * The string form of a regular expression that would match all of the\n * decimal number chars in the unicode character set when placed in a RegExp\n * character class (`[]`).\n *\n * These would be the characters matched by unicode regex engines `\\p{Nd}`\n * escape (\"all decimal numbers\")\n *\n * Taken from the XRegExp library: http://xregexp.com/ (thanks @https://github.com/slevithan)\n * Specifically: http://xregexp.com/v/3.2.0/xregexp-all.js, the 'Decimal_Number'\n * regex's bmp\n *\n * VERY IMPORTANT: This set of characters is defined inside of a Regular\n * Expression literal rather than a string literal to prevent UglifyJS from\n * compressing the unicode escape sequences into their actual unicode\n * characters. If Uglify compresses these into the unicode characters\n * themselves, this results in the error \"Range out of order in character\n * class\" when these characters are used inside of a Regular Expression\n * character class (`[]`). See usages of this const. Alternatively, we can set\n * the UglifyJS option `ascii_only` to true for the build, but that doesn't\n * help others who are pulling in Autolinker into their own build and running\n * UglifyJS themselves.\n */\nexport var decimalNumbersStr = /0-9\\u0660-\\u0669\\u06F0-\\u06F9\\u07C0-\\u07C9\\u0966-\\u096F\\u09E6-\\u09EF\\u0A66-\\u0A6F\\u0AE6-\\u0AEF\\u0B66-\\u0B6F\\u0BE6-\\u0BEF\\u0C66-\\u0C6F\\u0CE6-\\u0CEF\\u0D66-\\u0D6F\\u0DE6-\\u0DEF\\u0E50-\\u0E59\\u0ED0-\\u0ED9\\u0F20-\\u0F29\\u1040-\\u1049\\u1090-\\u1099\\u17E0-\\u17E9\\u1810-\\u1819\\u1946-\\u194F\\u19D0-\\u19D9\\u1A80-\\u1A89\\u1A90-\\u1A99\\u1B50-\\u1B59\\u1BB0-\\u1BB9\\u1C40-\\u1C49\\u1C50-\\u1C59\\uA620-\\uA629\\uA8D0-\\uA8D9\\uA900-\\uA909\\uA9D0-\\uA9D9\\uA9F0-\\uA9F9\\uAA50-\\uAA59\\uABF0-\\uABF9\\uFF10-\\uFF19/\n .source; // see note in above variable description\n/**\n * The string form of a regular expression that would match all of the\n * letters and decimal number chars in the unicode character set when placed in\n * a RegExp character class (`[]`).\n *\n * These would be the characters matched by unicode regex engines\n * `[\\p{L}\\p{Nd}]` escape (\"all letters and decimal numbers\")\n */\nexport var alphaNumericCharsStr = alphaCharsAndMarksStr + decimalNumbersStr;\n/**\n * The string form of a regular expression that would match all of the\n * letters, combining marks, and decimal number chars in the unicode character\n * set when placed in a RegExp character class (`[]`).\n *\n * These would be the characters matched by unicode regex engines\n * `[\\p{L}\\p{M}\\p{Nd}]` escape (\"all letters, combining marks, and decimal\n * numbers\")\n */\nexport var alphaNumericAndMarksCharsStr = alphaCharsAndMarksStr + decimalNumbersStr;\n// Simplified IP regular expression\nvar ipStr = '(?:[' + decimalNumbersStr + ']{1,3}\\\\.){3}[' + decimalNumbersStr + ']{1,3}';\n// Protected domain label which do not allow \"-\" character on the beginning and the end of a single label\nvar domainLabelStr = '[' + alphaNumericAndMarksCharsStr + '](?:[' + alphaNumericAndMarksCharsStr + '\\\\-]{0,61}[' + alphaNumericAndMarksCharsStr + '])?';\nvar getDomainLabelStr = function (group) {\n return '(?=(' + domainLabelStr + '))\\\\' + group;\n};\n/**\n * A function to match domain names of a URL or email address.\n * Ex: 'google', 'yahoo', 'some-other-company', etc.\n */\nexport var getDomainNameStr = function (group) {\n return '(?:' + getDomainLabelStr(group) + '(?:\\\\.' + getDomainLabelStr(group + 1) + '){0,126}|' + ipStr + ')';\n};\n/**\n * A regular expression to match domain names of a URL or email address.\n * Ex: 'google', 'yahoo', 'some-other-company', etc.\n */\nexport var domainNameRegex = new RegExp('[' + alphaNumericAndMarksCharsStr + '.\\\\-]*[' + alphaNumericAndMarksCharsStr + '\\\\-]');\n/**\n * A regular expression that is simply the character class of the characters\n * that may be used in a domain name, minus the '-' or '.'\n */\nexport var domainNameCharRegex = new RegExp(\"[\" + alphaNumericAndMarksCharsStr + \"]\");\n\n//# sourceMappingURL=regex-lib.js.map\n","// NOTE: THIS IS A GENERATED FILE\n// To update with the latest TLD list, run `npm run update-tld-regex` or `yarn update-tld-regex` (depending on which you have installed)\nexport var tldRegex = /(?:xn--vermgensberatung-pwb|xn--vermgensberater-ctb|xn--clchc0ea0b2g2a9gcd|xn--w4r85el8fhu5dnra|northwesternmutual|travelersinsurance|vermögensberatung|xn--3oq18vl8pn36a|xn--5su34j936bgsg|xn--bck1b9a5dre4c|xn--mgbai9azgqp6j|xn--mgberp4a5d4ar|xn--xkc2dl3a5ee0h|vermögensberater|xn--fzys8d69uvgm|xn--mgba7c0bbn0a|xn--xkc2al3hye2a|americanexpress|kerryproperties|sandvikcoromant|xn--i1b6b1a6a2e|xn--kcrx77d1x4a|xn--lgbbat1ad8j|xn--mgba3a4f16a|xn--mgbaakc7dvf|xn--mgbc0a9azcg|xn--nqv7fs00ema|afamilycompany|americanfamily|bananarepublic|cancerresearch|cookingchannel|kerrylogistics|weatherchannel|xn--54b7fta0cc|xn--6qq986b3xl|xn--80aqecdr1a|xn--b4w605ferd|xn--fiq228c5hs|xn--h2breg3eve|xn--jlq61u9w7b|xn--mgba3a3ejt|xn--mgbaam7a8h|xn--mgbayh7gpa|xn--mgbb9fbpob|xn--mgbbh1a71e|xn--mgbca7dzdo|xn--mgbi4ecexp|xn--mgbx4cd0ab|xn--rvc1e0am3e|international|lifeinsurance|spreadbetting|travelchannel|wolterskluwer|xn--eckvdtc9d|xn--fpcrj9c3d|xn--fzc2c9e2c|xn--h2brj9c8c|xn--tiq49xqyj|xn--yfro4i67o|xn--ygbi2ammx|construction|lplfinancial|scholarships|versicherung|xn--3e0b707e|xn--45br5cyl|xn--80adxhks|xn--80asehdb|xn--8y0a063a|xn--gckr3f0f|xn--mgb9awbf|xn--mgbab2bd|xn--mgbgu82a|xn--mgbpl2fh|xn--mgbt3dhd|xn--mk1bu44c|xn--ngbc5azd|xn--ngbe9e0a|xn--ogbpf8fl|xn--qcka1pmc|accountants|barclaycard|blackfriday|blockbuster|bridgestone|calvinklein|contractors|creditunion|engineering|enterprises|foodnetwork|investments|kerryhotels|lamborghini|motorcycles|olayangroup|photography|playstation|productions|progressive|redumbrella|rightathome|williamhill|xn--11b4c3d|xn--1ck2e1b|xn--1qqw23a|xn--2scrj9c|xn--3bst00m|xn--3ds443g|xn--3hcrj9c|xn--42c2d9a|xn--45brj9c|xn--55qw42g|xn--6frz82g|xn--80ao21a|xn--9krt00a|xn--cck2b3b|xn--czr694b|xn--d1acj3b|xn--efvy88h|xn--estv75g|xn--fct429k|xn--fjq720a|xn--flw351e|xn--g2xx48c|xn--gecrj9c|xn--gk3at1e|xn--h2brj9c|xn--hxt814e|xn--imr513n|xn--j6w193g|xn--jvr189m|xn--kprw13d|xn--kpry57d|xn--kpu716f|xn--mgbbh1a|xn--mgbtx2b|xn--mix891f|xn--nyqy26a|xn--otu796d|xn--pbt977c|xn--pgbs0dh|xn--q9jyb4c|xn--rhqv96g|xn--rovu88b|xn--s9brj9c|xn--ses554g|xn--t60b56a|xn--vuq861b|xn--w4rs40l|xn--xhq521b|xn--zfr164b|சிங்கப்பூர்|accountant|apartments|associates|basketball|bnpparibas|boehringer|capitalone|consulting|creditcard|cuisinella|eurovision|extraspace|foundation|healthcare|immobilien|industries|management|mitsubishi|nationwide|newholland|nextdirect|onyourside|properties|protection|prudential|realestate|republican|restaurant|schaeffler|swiftcover|tatamotors|technology|telefonica|university|vistaprint|vlaanderen|volkswagen|xn--30rr7y|xn--3pxu8k|xn--45q11c|xn--4gbrim|xn--55qx5d|xn--5tzm5g|xn--80aswg|xn--90a3ac|xn--9dbq2a|xn--9et52u|xn--c2br7g|xn--cg4bki|xn--czrs0t|xn--czru2d|xn--fiq64b|xn--fiqs8s|xn--fiqz9s|xn--io0a7i|xn--kput3i|xn--mxtq1m|xn--o3cw4h|xn--pssy2u|xn--unup4y|xn--wgbh1c|xn--wgbl6a|xn--y9a3aq|accenture|alfaromeo|allfinanz|amsterdam|analytics|aquarelle|barcelona|bloomberg|christmas|community|directory|education|equipment|fairwinds|financial|firestone|fresenius|frontdoor|fujixerox|furniture|goldpoint|hisamitsu|homedepot|homegoods|homesense|honeywell|institute|insurance|kuokgroup|ladbrokes|lancaster|landrover|lifestyle|marketing|marshalls|melbourne|microsoft|panasonic|passagens|pramerica|richardli|scjohnson|shangrila|solutions|statebank|statefarm|stockholm|travelers|vacations|xn--90ais|xn--c1avg|xn--d1alf|xn--e1a4c|xn--fhbei|xn--j1aef|xn--j1amh|xn--l1acc|xn--ngbrx|xn--nqv7f|xn--p1acf|xn--tckwe|xn--vhquv|yodobashi|abudhabi|airforce|allstate|attorney|barclays|barefoot|bargains|baseball|boutique|bradesco|broadway|brussels|budapest|builders|business|capetown|catering|catholic|chrysler|cipriani|cityeats|cleaning|clinique|clothing|commbank|computer|delivery|deloitte|democrat|diamonds|discount|discover|download|engineer|ericsson|esurance|etisalat|everbank|exchange|feedback|fidelity|firmdale|football|frontier|goodyear|grainger|graphics|guardian|hdfcbank|helsinki|holdings|hospital|infiniti|ipiranga|istanbul|jpmorgan|lighting|lundbeck|marriott|maserati|mckinsey|memorial|merckmsd|mortgage|movistar|observer|partners|pharmacy|pictures|plumbing|property|redstone|reliance|saarland|samsclub|security|services|shopping|showtime|softbank|software|stcgroup|supplies|symantec|training|uconnect|vanguard|ventures|verisign|woodside|xn--90ae|xn--node|xn--p1ai|xn--qxam|yokohama|السعودية|abogado|academy|agakhan|alibaba|android|athleta|auction|audible|auspost|avianca|banamex|bauhaus|bentley|bestbuy|booking|brother|bugatti|capital|caravan|careers|cartier|channel|charity|chintai|citadel|clubmed|college|cologne|comcast|company|compare|contact|cooking|corsica|country|coupons|courses|cricket|cruises|dentist|digital|domains|exposed|express|farmers|fashion|ferrari|ferrero|finance|fishing|fitness|flights|florist|flowers|forsale|frogans|fujitsu|gallery|genting|godaddy|grocery|guitars|hamburg|hangout|hitachi|holiday|hosting|hoteles|hotmail|hyundai|iselect|ismaili|jewelry|juniper|kitchen|komatsu|lacaixa|lancome|lanxess|lasalle|latrobe|leclerc|liaison|limited|lincoln|markets|metlife|monster|netbank|netflix|network|neustar|okinawa|oldnavy|organic|origins|philips|pioneer|politie|realtor|recipes|rentals|reviews|rexroth|samsung|sandvik|schmidt|schwarz|science|shiksha|shriram|singles|staples|starhub|storage|support|surgery|systems|temasek|theater|theatre|tickets|tiffany|toshiba|trading|walmart|wanggou|watches|weather|website|wedding|whoswho|windows|winners|xfinity|yamaxun|youtube|zuerich|католик|اتصالات|الجزائر|العليان|پاکستان|كاثوليك|موبايلي|இந்தியா|abarth|abbott|abbvie|active|africa|agency|airbus|airtel|alipay|alsace|alstom|anquan|aramco|author|bayern|beauty|berlin|bharti|blanco|bostik|boston|broker|camera|career|caseih|casino|center|chanel|chrome|church|circle|claims|clinic|coffee|comsec|condos|coupon|credit|cruise|dating|datsun|dealer|degree|dental|design|direct|doctor|dunlop|dupont|durban|emerck|energy|estate|events|expert|family|flickr|futbol|gallup|garden|george|giving|global|google|gratis|health|hermes|hiphop|hockey|hotels|hughes|imamat|insure|intuit|jaguar|joburg|juegos|kaufen|kinder|kindle|kosher|lancia|latino|lawyer|lefrak|living|locker|london|luxury|madrid|maison|makeup|market|mattel|mobile|mobily|monash|mormon|moscow|museum|mutual|nagoya|natura|nissan|nissay|norton|nowruz|office|olayan|online|oracle|orange|otsuka|pfizer|photos|physio|piaget|pictet|quebec|racing|realty|reisen|repair|report|review|rocher|rogers|ryukyu|safety|sakura|sanofi|school|schule|search|secure|select|shouji|soccer|social|stream|studio|supply|suzuki|swatch|sydney|taipei|taobao|target|tattoo|tennis|tienda|tjmaxx|tkmaxx|toyota|travel|unicom|viajes|viking|villas|virgin|vision|voting|voyage|vuelos|walter|warman|webcam|xihuan|yachts|yandex|zappos|москва|онлайн|ابوظبي|ارامكو|الاردن|المغرب|امارات|فلسطين|مليسيا|भारतम्|இலங்கை|ファッション|actor|adult|aetna|amfam|amica|apple|archi|audio|autos|azure|baidu|beats|bible|bingo|black|boats|bosch|build|canon|cards|chase|cheap|cisco|citic|click|cloud|coach|codes|crown|cymru|dabur|dance|deals|delta|dodge|drive|dubai|earth|edeka|email|epost|epson|faith|fedex|final|forex|forum|gallo|games|gifts|gives|glade|glass|globo|gmail|green|gripe|group|gucci|guide|homes|honda|horse|house|hyatt|ikano|intel|irish|iveco|jetzt|koeln|kyoto|lamer|lease|legal|lexus|lilly|linde|lipsy|lixil|loans|locus|lotte|lotto|lupin|macys|mango|media|miami|money|mopar|movie|nadex|nexus|nikon|ninja|nokia|nowtv|omega|osaka|paris|parts|party|phone|photo|pizza|place|poker|praxi|press|prime|promo|quest|radio|rehab|reise|ricoh|rocks|rodeo|rugby|salon|sener|seven|sharp|shell|shoes|skype|sling|smart|smile|solar|space|sport|stada|store|study|style|sucks|swiss|tatar|tires|tirol|tmall|today|tokyo|tools|toray|total|tours|trade|trust|tunes|tushu|ubank|vegas|video|vodka|volvo|wales|watch|weber|weibo|works|world|xerox|yahoo|zippo|ایران|بازار|بھارت|سودان|سورية|همراه|भारोत|संगठन|বাংলা|భారత్|ഭാരതം|嘉里大酒店|aarp|able|adac|aero|aigo|akdn|ally|amex|arab|army|arpa|arte|asda|asia|audi|auto|baby|band|bank|bbva|beer|best|bike|bing|blog|blue|bofa|bond|book|buzz|cafe|call|camp|care|cars|casa|case|cash|cbre|cern|chat|citi|city|club|cool|coop|cyou|data|date|dclk|deal|dell|desi|diet|dish|docs|doha|duck|duns|dvag|erni|fage|fail|fans|farm|fast|fiat|fido|film|fire|fish|flir|food|ford|free|fund|game|gbiz|gent|ggee|gift|gmbh|gold|golf|goog|guge|guru|hair|haus|hdfc|help|here|hgtv|host|hsbc|icbc|ieee|imdb|immo|info|itau|java|jeep|jobs|jprs|kddi|kiwi|kpmg|kred|land|lego|lgbt|lidl|life|like|limo|link|live|loan|loft|love|ltda|luxe|maif|meet|meme|menu|mini|mint|mobi|moda|moto|name|navy|news|next|nico|nike|ollo|open|page|pars|pccw|pics|ping|pink|play|plus|pohl|porn|post|prod|prof|qpon|raid|read|reit|rent|rest|rich|rmit|room|rsvp|ruhr|safe|sale|sarl|save|saxo|scor|scot|seat|seek|sexy|shaw|shia|shop|show|silk|sina|site|skin|sncf|sohu|song|sony|spot|star|surf|talk|taxi|team|tech|teva|tiaa|tips|town|toys|tube|vana|visa|viva|vivo|vote|voto|wang|weir|wien|wiki|wine|work|xbox|yoga|zara|zero|zone|дети|сайт|بارت|بيتك|ڀارت|تونس|شبكة|عراق|عمان|موقع|भारत|ভারত|ভাৰত|ਭਾਰਤ|ભારત|ଭାରତ|ಭಾರತ|ලංකා|グーグル|クラウド|ポイント|大众汽车|组织机构|電訊盈科|香格里拉|aaa|abb|abc|aco|ads|aeg|afl|aig|anz|aol|app|art|aws|axa|bar|bbc|bbt|bcg|bcn|bet|bid|bio|biz|bms|bmw|bnl|bom|boo|bot|box|buy|bzh|cab|cal|cam|car|cat|cba|cbn|cbs|ceb|ceo|cfa|cfd|com|crs|csc|dad|day|dds|dev|dhl|diy|dnp|dog|dot|dtv|dvr|eat|eco|edu|esq|eus|fan|fit|fly|foo|fox|frl|ftr|fun|fyi|gal|gap|gdn|gea|gle|gmo|gmx|goo|gop|got|gov|hbo|hiv|hkt|hot|how|ibm|ice|icu|ifm|inc|ing|ink|int|ist|itv|jcb|jcp|jio|jll|jmp|jnj|jot|joy|kfh|kia|kim|kpn|krd|lat|law|lds|llc|lol|lpl|ltd|man|map|mba|med|men|mil|mit|mlb|mls|mma|moe|moi|mom|mov|msd|mtn|mtr|nab|nba|nec|net|new|nfl|ngo|nhk|now|nra|nrw|ntt|nyc|obi|off|one|ong|onl|ooo|org|ott|ovh|pay|pet|phd|pid|pin|pnc|pro|pru|pub|pwc|qvc|red|ren|ril|rio|rip|run|rwe|sap|sas|sbi|sbs|sca|scb|ses|sew|sex|sfr|ski|sky|soy|srl|srt|stc|tab|tax|tci|tdk|tel|thd|tjx|top|trv|tui|tvs|ubs|uno|uol|ups|vet|vig|vin|vip|wed|win|wme|wow|wtc|wtf|xin|xxx|xyz|you|yun|zip|бел|ком|қаз|мкд|мон|орг|рус|срб|укр|հայ|קום|عرب|قطر|كوم|مصر|कॉम|नेट|คอม|ไทย|ストア|セール|みんな|中文网|天主教|我爱你|新加坡|淡马锡|诺基亚|飞利浦|ac|ad|ae|af|ag|ai|al|am|ao|aq|ar|as|at|au|aw|ax|az|ba|bb|bd|be|bf|bg|bh|bi|bj|bm|bn|bo|br|bs|bt|bv|bw|by|bz|ca|cc|cd|cf|cg|ch|ci|ck|cl|cm|cn|co|cr|cu|cv|cw|cx|cy|cz|de|dj|dk|dm|do|dz|ec|ee|eg|er|es|et|eu|fi|fj|fk|fm|fo|fr|ga|gb|gd|ge|gf|gg|gh|gi|gl|gm|gn|gp|gq|gr|gs|gt|gu|gw|gy|hk|hm|hn|hr|ht|hu|id|ie|il|im|in|io|iq|ir|is|it|je|jm|jo|jp|ke|kg|kh|ki|km|kn|kp|kr|kw|ky|kz|la|lb|lc|li|lk|lr|ls|lt|lu|lv|ly|ma|mc|md|me|mg|mh|mk|ml|mm|mn|mo|mp|mq|mr|ms|mt|mu|mv|mw|mx|my|mz|na|nc|ne|nf|ng|ni|nl|no|np|nr|nu|nz|om|pa|pe|pf|pg|ph|pk|pl|pm|pn|pr|ps|pt|pw|py|qa|re|ro|rs|ru|rw|sa|sb|sc|sd|se|sg|sh|si|sj|sk|sl|sm|sn|so|sr|st|su|sv|sx|sy|sz|tc|td|tf|tg|th|tj|tk|tl|tm|tn|to|tr|tt|tv|tw|tz|ua|ug|uk|us|uy|uz|va|vc|ve|vg|vi|vn|vu|wf|ws|ye|yt|za|zm|zw|ελ|бг|ею|рф|გე|닷넷|닷컴|삼성|한국|コム|世界|中信|中国|中國|企业|佛山|信息|健康|八卦|公司|公益|台湾|台灣|商城|商店|商标|嘉里|在线|大拿|娱乐|家電|工行|广东|微博|慈善|手机|手表|招聘|政务|政府|新闻|时尚|書籍|机构|游戏|澳門|点看|珠宝|移动|网址|网店|网站|网络|联通|谷歌|购物|通販|集团|食品|餐厅|香港)/;\n\n//# sourceMappingURL=tld-regex.js.map\n","import * as tslib_1 from \"tslib\";\nimport { Matcher } from \"./matcher\";\nimport { alphaNumericAndMarksCharsStr, domainNameCharRegex } from \"../regex-lib\";\nimport { EmailMatch } from \"../match/email-match\";\nimport { throwUnhandledCaseError } from '../utils';\nimport { tldRegex } from \"./tld-regex\";\n// For debugging: search for other \"For debugging\" lines\n// import CliTable from 'cli-table';\n// RegExp objects which are shared by all instances of EmailMatcher. These are\n// here to avoid re-instantiating the RegExp objects if `Autolinker.link()` is\n// called multiple times, thus instantiating EmailMatcher and its RegExp \n// objects each time (which is very expensive - see https://github.com/gregjacobs/Autolinker.js/issues/314). \n// See descriptions of the properties where they are used for details about them\nvar localPartCharRegex = new RegExp(\"[\" + alphaNumericAndMarksCharsStr + \"!#$%&'*+/=?^_`{|}~-]\");\nvar strictTldRegex = new RegExp(\"^\" + tldRegex.source + \"$\");\n/**\n * @class Autolinker.matcher.Email\n * @extends Autolinker.matcher.Matcher\n *\n * Matcher to find email matches in an input string.\n *\n * See this class's superclass ({@link Autolinker.matcher.Matcher}) for more details.\n */\nvar EmailMatcher = /** @class */ (function (_super) {\n tslib_1.__extends(EmailMatcher, _super);\n function EmailMatcher() {\n var _this = _super !== null && _super.apply(this, arguments) || this;\n /**\n * Valid characters that can be used in the \"local\" part of an email address,\n * i.e. the \"name\" part of \"name@site.com\"\n */\n _this.localPartCharRegex = localPartCharRegex;\n /**\n * Stricter TLD regex which adds a beginning and end check to ensure\n * the string is a valid TLD\n */\n _this.strictTldRegex = strictTldRegex;\n return _this;\n }\n /**\n * @inheritdoc\n */\n EmailMatcher.prototype.parseMatches = function (text) {\n var tagBuilder = this.tagBuilder, localPartCharRegex = this.localPartCharRegex, strictTldRegex = this.strictTldRegex, matches = [], len = text.length, noCurrentEmailMatch = new CurrentEmailMatch();\n // for matching a 'mailto:' prefix\n var mailtoTransitions = {\n 'm': 'a',\n 'a': 'i',\n 'i': 'l',\n 'l': 't',\n 't': 'o',\n 'o': ':',\n };\n var charIdx = 0, state = 0 /* NonEmailMatch */, currentEmailMatch = noCurrentEmailMatch;\n // For debugging: search for other \"For debugging\" lines\n // const table = new CliTable( {\n // \thead: [ 'charIdx', 'char', 'state', 'charIdx', 'currentEmailAddress.idx', 'hasDomainDot' ]\n // } );\n while (charIdx < len) {\n var char = text.charAt(charIdx);\n // For debugging: search for other \"For debugging\" lines\n // table.push( \n // \t[ charIdx, char, State[ state ], charIdx, currentEmailAddress.idx, currentEmailAddress.hasDomainDot ] \n // );\n switch (state) {\n case 0 /* NonEmailMatch */:\n stateNonEmailAddress(char);\n break;\n case 1 /* Mailto */:\n stateMailTo(text.charAt(charIdx - 1), char);\n break;\n case 2 /* LocalPart */:\n stateLocalPart(char);\n break;\n case 3 /* LocalPartDot */:\n stateLocalPartDot(char);\n break;\n case 4 /* AtSign */:\n stateAtSign(char);\n break;\n case 5 /* DomainChar */:\n stateDomainChar(char);\n break;\n case 6 /* DomainHyphen */:\n stateDomainHyphen(char);\n break;\n case 7 /* DomainDot */:\n stateDomainDot(char);\n break;\n default:\n throwUnhandledCaseError(state);\n }\n // For debugging: search for other \"For debugging\" lines\n // table.push( \n // \t[ charIdx, char, State[ state ], charIdx, currentEmailAddress.idx, currentEmailAddress.hasDomainDot ] \n // );\n charIdx++;\n }\n // Capture any valid match at the end of the string\n captureMatchIfValidAndReset();\n // For debugging: search for other \"For debugging\" lines\n //console.log( '\\n' + table.toString() );\n return matches;\n // Handles the state when we're not in an email address\n function stateNonEmailAddress(char) {\n if (char === 'm') {\n beginEmailMatch(1 /* Mailto */);\n }\n else if (localPartCharRegex.test(char)) {\n beginEmailMatch();\n }\n else {\n // not an email address character, continue\n }\n }\n // Handles if we're reading a 'mailto:' prefix on the string\n function stateMailTo(prevChar, char) {\n if (prevChar === ':') {\n // We've reached the end of the 'mailto:' prefix\n if (localPartCharRegex.test(char)) {\n state = 2 /* LocalPart */;\n currentEmailMatch = new CurrentEmailMatch(tslib_1.__assign({}, currentEmailMatch, { hasMailtoPrefix: true }));\n }\n else {\n // we've matched 'mailto:' but didn't get anything meaningful\n // immediately afterwards (for example, we encountered a \n // space character, or an '@' character which formed 'mailto:@'\n resetToNonEmailMatchState();\n }\n }\n else if (mailtoTransitions[prevChar] === char) {\n // We're currently reading the 'mailto:' prefix, stay in\n // Mailto state\n }\n else if (localPartCharRegex.test(char)) {\n // We we're reading a prefix of 'mailto:', but encountered a\n // different character that didn't continue the prefix\n state = 2 /* LocalPart */;\n }\n else if (char === '.') {\n // We we're reading a prefix of 'mailto:', but encountered a\n // dot character\n state = 3 /* LocalPartDot */;\n }\n else if (char === '@') {\n // We we're reading a prefix of 'mailto:', but encountered a\n // an @ character\n state = 4 /* AtSign */;\n }\n else {\n // not an email address character, return to \"NonEmailAddress\" state\n resetToNonEmailMatchState();\n }\n }\n // Handles the state when we're currently in the \"local part\" of an \n // email address (as opposed to the \"domain part\")\n function stateLocalPart(char) {\n if (char === '.') {\n state = 3 /* LocalPartDot */;\n }\n else if (char === '@') {\n state = 4 /* AtSign */;\n }\n else if (localPartCharRegex.test(char)) {\n // stay in the \"local part\" of the email address\n }\n else {\n // not an email address character, return to \"NonEmailAddress\" state\n resetToNonEmailMatchState();\n }\n }\n // Handles the state where we've read \n function stateLocalPartDot(char) {\n if (char === '.') {\n // We read a second '.' in a row, not a valid email address \n // local part\n resetToNonEmailMatchState();\n }\n else if (char === '@') {\n // We read the '@' character immediately after a dot ('.'), not \n // an email address\n resetToNonEmailMatchState();\n }\n else if (localPartCharRegex.test(char)) {\n state = 2 /* LocalPart */;\n }\n else {\n // Anything else, not an email address\n resetToNonEmailMatchState();\n }\n }\n function stateAtSign(char) {\n if (domainNameCharRegex.test(char)) {\n state = 5 /* DomainChar */;\n }\n else {\n // Anything else, not an email address\n resetToNonEmailMatchState();\n }\n }\n function stateDomainChar(char) {\n if (char === '.') {\n state = 7 /* DomainDot */;\n }\n else if (char === '-') {\n state = 6 /* DomainHyphen */;\n }\n else if (domainNameCharRegex.test(char)) {\n // Stay in the DomainChar state\n }\n else {\n // Anything else, we potentially matched if the criteria has\n // been met\n captureMatchIfValidAndReset();\n }\n }\n function stateDomainHyphen(char) {\n if (char === '-' || char === '.') {\n // Not valid to have two hyphens (\"--\") or hypen+dot (\"-.\")\n captureMatchIfValidAndReset();\n }\n else if (domainNameCharRegex.test(char)) {\n state = 5 /* DomainChar */;\n }\n else {\n // Anything else\n captureMatchIfValidAndReset();\n }\n }\n function stateDomainDot(char) {\n if (char === '.' || char === '-') {\n // not valid to have two dots (\"..\") or dot+hypen (\".-\")\n captureMatchIfValidAndReset();\n }\n else if (domainNameCharRegex.test(char)) {\n state = 5 /* DomainChar */;\n // After having read a '.' and then a valid domain character,\n // we now know that the domain part of the email is valid, and\n // we have found at least a partial EmailMatch (however, the\n // email address may have additional characters from this point)\n currentEmailMatch = new CurrentEmailMatch(tslib_1.__assign({}, currentEmailMatch, { hasDomainDot: true }));\n }\n else {\n // Anything else\n captureMatchIfValidAndReset();\n }\n }\n function beginEmailMatch(newState) {\n if (newState === void 0) { newState = 2 /* LocalPart */; }\n state = newState;\n currentEmailMatch = new CurrentEmailMatch({ idx: charIdx });\n }\n function resetToNonEmailMatchState() {\n state = 0 /* NonEmailMatch */;\n currentEmailMatch = noCurrentEmailMatch;\n }\n /*\n * Captures the current email address as an EmailMatch if it's valid,\n * and resets the state to read another email address.\n */\n function captureMatchIfValidAndReset() {\n if (currentEmailMatch.hasDomainDot) { // we need at least one dot in the domain to be considered a valid email address\n var matchedText = text.slice(currentEmailMatch.idx, charIdx);\n // If we read a '.' or '-' char that ended the email address\n // (valid domain name characters, but only valid email address\n // characters if they are followed by something else), strip \n // it off now\n if (/[-.]$/.test(matchedText)) {\n matchedText = matchedText.slice(0, -1);\n }\n var emailAddress = currentEmailMatch.hasMailtoPrefix\n ? matchedText.slice('mailto:'.length)\n : matchedText;\n // if the email address has a valid TLD, add it to the list of matches\n if (doesEmailHaveValidTld(emailAddress)) {\n matches.push(new EmailMatch({\n tagBuilder: tagBuilder,\n matchedText: matchedText,\n offset: currentEmailMatch.idx,\n email: emailAddress\n }));\n }\n }\n resetToNonEmailMatchState();\n /**\n * Determines if the given email address has a valid TLD or not\n * @param {string} emailAddress - email address\n * @return {Boolean} - true is email have valid TLD, false otherwise\n */\n function doesEmailHaveValidTld(emailAddress) {\n var emailAddressTld = emailAddress.split('.').pop() || '';\n var emailAddressNormalized = emailAddressTld.toLowerCase();\n var isValidTld = strictTldRegex.test(emailAddressNormalized);\n return isValidTld;\n }\n }\n };\n return EmailMatcher;\n}(Matcher));\nexport { EmailMatcher };\nvar CurrentEmailMatch = /** @class */ (function () {\n function CurrentEmailMatch(cfg) {\n if (cfg === void 0) { cfg = {}; }\n this.idx = cfg.idx !== undefined ? cfg.idx : -1;\n this.hasMailtoPrefix = !!cfg.hasMailtoPrefix;\n this.hasDomainDot = !!cfg.hasDomainDot;\n }\n return CurrentEmailMatch;\n}());\n\n//# sourceMappingURL=email-matcher.js.map\n","import { alphaCharsStr } from \"../regex-lib\";\n/**\n * @private\n * @class Autolinker.matcher.UrlMatchValidator\n * @singleton\n *\n * Used by Autolinker to filter out false URL positives from the\n * {@link Autolinker.matcher.Url UrlMatcher}.\n *\n * Due to the limitations of regular expressions (including the missing feature\n * of look-behinds in JS regular expressions), we cannot always determine the\n * validity of a given match. This class applies a bit of additional logic to\n * filter out any false positives that have been matched by the\n * {@link Autolinker.matcher.Url UrlMatcher}.\n */\nvar UrlMatchValidator = /** @class */ (function () {\n function UrlMatchValidator() {\n }\n /**\n * Determines if a given URL match found by the {@link Autolinker.matcher.Url UrlMatcher}\n * is valid. Will return `false` for:\n *\n * 1) URL matches which do not have at least have one period ('.') in the\n * domain name (effectively skipping over matches like \"abc:def\").\n * However, URL matches with a protocol will be allowed (ex: 'http://localhost')\n * 2) URL matches which do not have at least one word character in the\n * domain name (effectively skipping over matches like \"git:1.0\").\n * However, URL matches with a protocol will be allowed (ex: 'intra-net://271219.76')\n * 3) A protocol-relative url match (a URL beginning with '//') whose\n * previous character is a word character (effectively skipping over\n * strings like \"abc//google.com\")\n *\n * Otherwise, returns `true`.\n *\n * @param {String} urlMatch The matched URL, if there was one. Will be an\n * empty string if the match is not a URL match.\n * @param {String} protocolUrlMatch The match URL string for a protocol\n * match. Ex: 'http://yahoo.com'. This is used to match something like\n * 'http://localhost', where we won't double check that the domain name\n * has at least one '.' in it.\n * @return {Boolean} `true` if the match given is valid and should be\n * processed, or `false` if the match is invalid and/or should just not be\n * processed.\n */\n UrlMatchValidator.isValid = function (urlMatch, protocolUrlMatch) {\n if ((protocolUrlMatch && !this.isValidUriScheme(protocolUrlMatch)) ||\n this.urlMatchDoesNotHaveProtocolOrDot(urlMatch, protocolUrlMatch) || // At least one period ('.') must exist in the URL match for us to consider it an actual URL, *unless* it was a full protocol match (like 'http://localhost')\n (this.urlMatchDoesNotHaveAtLeastOneWordChar(urlMatch, protocolUrlMatch) && // At least one letter character must exist in the domain name after a protocol match. Ex: skip over something like \"git:1.0\"\n !this.isValidIpAddress(urlMatch)) || // Except if it's an IP address\n this.containsMultipleDots(urlMatch)) {\n return false;\n }\n return true;\n };\n UrlMatchValidator.isValidIpAddress = function (uriSchemeMatch) {\n var newRegex = new RegExp(this.hasFullProtocolRegex.source + this.ipRegex.source);\n var uriScheme = uriSchemeMatch.match(newRegex);\n return uriScheme !== null;\n };\n UrlMatchValidator.containsMultipleDots = function (urlMatch) {\n var stringBeforeSlash = urlMatch;\n if (this.hasFullProtocolRegex.test(urlMatch)) {\n stringBeforeSlash = urlMatch.split('://')[1];\n }\n return stringBeforeSlash.split('/')[0].indexOf(\"..\") > -1;\n };\n /**\n * Determines if the URI scheme is a valid scheme to be autolinked. Returns\n * `false` if the scheme is 'javascript:' or 'vbscript:'\n *\n * @private\n * @param {String} uriSchemeMatch The match URL string for a full URI scheme\n * match. Ex: 'http://yahoo.com' or 'mailto:a@a.com'.\n * @return {Boolean} `true` if the scheme is a valid one, `false` otherwise.\n */\n UrlMatchValidator.isValidUriScheme = function (uriSchemeMatch) {\n var uriSchemeMatchArr = uriSchemeMatch.match(this.uriSchemeRegex), uriScheme = uriSchemeMatchArr && uriSchemeMatchArr[0].toLowerCase();\n return (uriScheme !== 'javascript:' && uriScheme !== 'vbscript:');\n };\n /**\n * Determines if a URL match does not have either:\n *\n * a) a full protocol (i.e. 'http://'), or\n * b) at least one dot ('.') in the domain name (for a non-full-protocol\n * match).\n *\n * Either situation is considered an invalid URL (ex: 'git:d' does not have\n * either the '://' part, or at least one dot in the domain name. If the\n * match was 'git:abc.com', we would consider this valid.)\n *\n * @private\n * @param {String} urlMatch The matched URL, if there was one. Will be an\n * empty string if the match is not a URL match.\n * @param {String} protocolUrlMatch The match URL string for a protocol\n * match. Ex: 'http://yahoo.com'. This is used to match something like\n * 'http://localhost', where we won't double check that the domain name\n * has at least one '.' in it.\n * @return {Boolean} `true` if the URL match does not have a full protocol,\n * or at least one dot ('.') in a non-full-protocol match.\n */\n UrlMatchValidator.urlMatchDoesNotHaveProtocolOrDot = function (urlMatch, protocolUrlMatch) {\n return (!!urlMatch && (!protocolUrlMatch || !this.hasFullProtocolRegex.test(protocolUrlMatch)) && urlMatch.indexOf('.') === -1);\n };\n /**\n * Determines if a URL match does not have either:\n *\n * a) a full protocol (i.e. 'http://'), or\n * b) at least one word character after the protocol (i.e. in the domain name)\n *\n * At least one letter character must exist in the domain name after a\n * protocol match. Ex: skip over something like \"git:1.0\"\n *\n * @private\n * @param {String} urlMatch The matched URL, if there was one. Will be an\n * empty string if the match is not a URL match.\n * @param {String} protocolUrlMatch The match URL string for a protocol\n * match. Ex: 'http://yahoo.com'. This is used to know whether or not we\n * have a protocol in the URL string, in order to check for a word\n * character after the protocol separator (':').\n * @return {Boolean} `true` if the URL match does not have a full protocol, or\n * at least one word character in it, `false` otherwise.\n */\n UrlMatchValidator.urlMatchDoesNotHaveAtLeastOneWordChar = function (urlMatch, protocolUrlMatch) {\n if (urlMatch && protocolUrlMatch) {\n return !this.hasFullProtocolRegex.test(protocolUrlMatch) && !this.hasWordCharAfterProtocolRegex.test(urlMatch);\n }\n else {\n return false;\n }\n };\n /**\n * Regex to test for a full protocol, with the two trailing slashes. Ex: 'http://'\n *\n * @private\n * @property {RegExp} hasFullProtocolRegex\n */\n UrlMatchValidator.hasFullProtocolRegex = /^[A-Za-z][-.+A-Za-z0-9]*:\\/\\//;\n /**\n * Regex to find the URI scheme, such as 'mailto:'.\n *\n * This is used to filter out 'javascript:' and 'vbscript:' schemes.\n *\n * @private\n * @property {RegExp} uriSchemeRegex\n */\n UrlMatchValidator.uriSchemeRegex = /^[A-Za-z][-.+A-Za-z0-9]*:/;\n /**\n * Regex to determine if at least one word char exists after the protocol (i.e. after the ':')\n *\n * @private\n * @property {RegExp} hasWordCharAfterProtocolRegex\n */\n UrlMatchValidator.hasWordCharAfterProtocolRegex = new RegExp(\":[^\\\\s]*?[\" + alphaCharsStr + \"]\");\n /**\n * Regex to determine if the string is a valid IP address\n *\n * @private\n * @property {RegExp} ipRegex\n */\n UrlMatchValidator.ipRegex = /[0-9][0-9]?[0-9]?\\.[0-9][0-9]?[0-9]?\\.[0-9][0-9]?[0-9]?\\.[0-9][0-9]?[0-9]?(:[0-9]*)?\\/?$/;\n return UrlMatchValidator;\n}());\nexport { UrlMatchValidator };\n\n//# sourceMappingURL=url-match-validator.js.map\n","import * as tslib_1 from \"tslib\";\nimport { Matcher } from \"./matcher\";\nimport { alphaNumericAndMarksCharsStr } from \"../regex-lib\";\nimport { HashtagMatch } from \"../match/hashtag-match\";\n// RegExp objects which are shared by all instances of HashtagMatcher. These are\n// here to avoid re-instantiating the RegExp objects if `Autolinker.link()` is\n// called multiple times, thus instantiating HashtagMatcher and its RegExp \n// objects each time (which is very expensive - see https://github.com/gregjacobs/Autolinker.js/issues/314). \n// See descriptions of the properties where they are used for details about them\nvar matcherRegex = new RegExp(\"#[_\" + alphaNumericAndMarksCharsStr + \"]{1,139}(?![_\" + alphaNumericAndMarksCharsStr + \"])\", 'g'); // lookahead used to make sure we don't match something above 139 characters\nvar nonWordCharRegex = new RegExp('[^' + alphaNumericAndMarksCharsStr + ']');\n/**\n * @class Autolinker.matcher.Hashtag\n * @extends Autolinker.matcher.Matcher\n *\n * Matcher to find HashtagMatch matches in an input string.\n */\nvar HashtagMatcher = /** @class */ (function (_super) {\n tslib_1.__extends(HashtagMatcher, _super);\n /**\n * @method constructor\n * @param {Object} cfg The configuration properties for the Match instance,\n * specified in an Object (map).\n */\n function HashtagMatcher(cfg) {\n var _this = _super.call(this, cfg) || this;\n /**\n * @cfg {String} serviceName\n *\n * The service to point hashtag matches to. See {@link Autolinker#hashtag}\n * for available values.\n */\n _this.serviceName = 'twitter'; // default value just to get the above doc comment in the ES5 output and documentation generator\n /**\n * The regular expression to match Hashtags. Example match:\n *\n * #asdf\n *\n * @protected\n * @property {RegExp} matcherRegex\n */\n _this.matcherRegex = matcherRegex;\n /**\n * The regular expression to use to check the character before a username match to\n * make sure we didn't accidentally match an email address.\n *\n * For example, the string \"asdf@asdf.com\" should not match \"@asdf\" as a username.\n *\n * @protected\n * @property {RegExp} nonWordCharRegex\n */\n _this.nonWordCharRegex = nonWordCharRegex;\n _this.serviceName = cfg.serviceName;\n return _this;\n }\n /**\n * @inheritdoc\n */\n HashtagMatcher.prototype.parseMatches = function (text) {\n var matcherRegex = this.matcherRegex, nonWordCharRegex = this.nonWordCharRegex, serviceName = this.serviceName, tagBuilder = this.tagBuilder, matches = [], match;\n while ((match = matcherRegex.exec(text)) !== null) {\n var offset = match.index, prevChar = text.charAt(offset - 1);\n // If we found the match at the beginning of the string, or we found the match\n // and there is a whitespace char in front of it (meaning it is not a '#' char\n // in the middle of a word), then it is a hashtag match.\n if (offset === 0 || nonWordCharRegex.test(prevChar)) {\n var matchedText = match[0], hashtag = match[0].slice(1); // strip off the '#' character at the beginning\n matches.push(new HashtagMatch({\n tagBuilder: tagBuilder,\n matchedText: matchedText,\n offset: offset,\n serviceName: serviceName,\n hashtag: hashtag\n }));\n }\n }\n return matches;\n };\n return HashtagMatcher;\n}(Matcher));\nexport { HashtagMatcher };\n\n//# sourceMappingURL=hashtag-matcher.js.map\n","import * as tslib_1 from \"tslib\";\nimport { Matcher } from \"./matcher\";\nimport { PhoneMatch } from \"../match/phone-match\";\nimport { nonDigitRe } from '../regex-lib';\n// RegExp objects which are shared by all instances of PhoneMatcher. These are\n// here to avoid re-instantiating the RegExp objects if `Autolinker.link()` is\n// called multiple times, thus instantiating PhoneMatcher and its RegExp \n// objects each time (which is very expensive - see https://github.com/gregjacobs/Autolinker.js/issues/314). \n// See descriptions of the properties where they are used for details about them\nvar phoneMatcherRegex = /(?:(?:(?:(\\+)?\\d{1,3}[-\\040.]?)?\\(?\\d{3}\\)?[-\\040.]?\\d{3}[-\\040.]?\\d{4})|(?:(\\+)(?:9[976]\\d|8[987530]\\d|6[987]\\d|5[90]\\d|42\\d|3[875]\\d|2[98654321]\\d|9[8543210]|8[6421]|6[6543210]|5[87654321]|4[987654310]|3[9643210]|2[70]|7|1)[-\\040.]?(?:\\d[-\\040.]?){6,12}\\d+))([,;]+[0-9]+#?)*/g;\n/**\n * @class Autolinker.matcher.Phone\n * @extends Autolinker.matcher.Matcher\n *\n * Matcher to find Phone number matches in an input string.\n *\n * See this class's superclass ({@link Autolinker.matcher.Matcher}) for more\n * details.\n */\nvar PhoneMatcher = /** @class */ (function (_super) {\n tslib_1.__extends(PhoneMatcher, _super);\n function PhoneMatcher() {\n var _this = _super !== null && _super.apply(this, arguments) || this;\n /**\n * The regular expression to match Phone numbers. Example matches:\n *\n * (123) 456-7890\n * 123 456 7890\n * 123-456-7890\n * +18004441234,,;,10226420346#\n * +1 (800) 444 1234\n * 10226420346#\n * 1-800-444-1234,1022,64,20346#\n *\n * This regular expression has the following capturing groups:\n *\n * 1 or 2. The prefixed '+' sign, if there is one.\n *\n * @protected\n * @property {RegExp} matcherRegex\n */\n _this.matcherRegex = phoneMatcherRegex;\n return _this;\n }\n /**\n * @inheritdoc\n */\n PhoneMatcher.prototype.parseMatches = function (text) {\n var matcherRegex = this.matcherRegex, tagBuilder = this.tagBuilder, matches = [], match;\n while ((match = matcherRegex.exec(text)) !== null) {\n // Remove non-numeric values from phone number string\n var matchedText = match[0], cleanNumber = matchedText.replace(/[^0-9,;#]/g, ''), // strip out non-digit characters exclude comma semicolon and #\n plusSign = !!(match[1] || match[2]), // match[ 1 ] or match[ 2 ] is the prefixed plus sign, if there is one\n before = match.index == 0 ? '' : text.substr(match.index - 1, 1), after = text.substr(match.index + matchedText.length, 1), contextClear = !before.match(/\\d/) && !after.match(/\\d/);\n if (this.testMatch(match[3]) && this.testMatch(matchedText) && contextClear) {\n matches.push(new PhoneMatch({\n tagBuilder: tagBuilder,\n matchedText: matchedText,\n offset: match.index,\n number: cleanNumber,\n plusSign: plusSign\n }));\n }\n }\n return matches;\n };\n PhoneMatcher.prototype.testMatch = function (text) {\n return nonDigitRe.test(text);\n };\n return PhoneMatcher;\n}(Matcher));\nexport { PhoneMatcher };\n\n//# sourceMappingURL=phone-matcher.js.map\n","import * as tslib_1 from \"tslib\";\nimport { Matcher } from \"./matcher\";\nimport { alphaNumericAndMarksCharsStr } from \"../regex-lib\";\nimport { MentionMatch } from \"../match/mention-match\";\n// RegExp objects which are shared by all instances of MentionMatcher. These are\n// here to avoid re-instantiating the RegExp objects if `Autolinker.link()` is\n// called multiple times, thus instantiating MentionMatcher and its RegExp \n// objects each time (which is very expensive - see https://github.com/gregjacobs/Autolinker.js/issues/314). \n// See descriptions of the properties where they are used for details about them\nvar twitterRegex = new RegExp(\"@[_\" + alphaNumericAndMarksCharsStr + \"]{1,50}(?![_\" + alphaNumericAndMarksCharsStr + \"])\", 'g'); // lookahead used to make sure we don't match something above 50 characters\nvar instagramRegex = new RegExp(\"@[_.\" + alphaNumericAndMarksCharsStr + \"]{1,30}(?![_\" + alphaNumericAndMarksCharsStr + \"])\", 'g'); // lookahead used to make sure we don't match something above 30 characters\nvar soundcloudRegex = new RegExp(\"@[-_.\" + alphaNumericAndMarksCharsStr + \"]{1,50}(?![-_\" + alphaNumericAndMarksCharsStr + \"])\", 'g'); // lookahead used to make sure we don't match something above 50 characters\nvar nonWordCharRegex = new RegExp('[^' + alphaNumericAndMarksCharsStr + ']');\n/**\n * @class Autolinker.matcher.Mention\n * @extends Autolinker.matcher.Matcher\n *\n * Matcher to find/replace username matches in an input string.\n */\nvar MentionMatcher = /** @class */ (function (_super) {\n tslib_1.__extends(MentionMatcher, _super);\n /**\n * @method constructor\n * @param {Object} cfg The configuration properties for the Match instance,\n * specified in an Object (map).\n */\n function MentionMatcher(cfg) {\n var _this = _super.call(this, cfg) || this;\n /**\n * @cfg {'twitter'/'instagram'/'soundcloud'} protected\n *\n * The name of service to link @mentions to.\n *\n * Valid values are: 'twitter', 'instagram', or 'soundcloud'\n */\n _this.serviceName = 'twitter'; // default value just to get the above doc comment in the ES5 output and documentation generator\n /**\n * Hash of regular expression to match username handles. Example match:\n *\n * @asdf\n *\n * @private\n * @property {Object} matcherRegexes\n */\n _this.matcherRegexes = {\n 'twitter': twitterRegex,\n 'instagram': instagramRegex,\n 'soundcloud': soundcloudRegex\n };\n /**\n * The regular expression to use to check the character before a username match to\n * make sure we didn't accidentally match an email address.\n *\n * For example, the string \"asdf@asdf.com\" should not match \"@asdf\" as a username.\n *\n * @private\n * @property {RegExp} nonWordCharRegex\n */\n _this.nonWordCharRegex = nonWordCharRegex;\n _this.serviceName = cfg.serviceName;\n return _this;\n }\n /**\n * @inheritdoc\n */\n MentionMatcher.prototype.parseMatches = function (text) {\n var serviceName = this.serviceName, matcherRegex = this.matcherRegexes[this.serviceName], nonWordCharRegex = this.nonWordCharRegex, tagBuilder = this.tagBuilder, matches = [], match;\n if (!matcherRegex) {\n return matches;\n }\n while ((match = matcherRegex.exec(text)) !== null) {\n var offset = match.index, prevChar = text.charAt(offset - 1);\n // If we found the match at the beginning of the string, or we found the match\n // and there is a whitespace char in front of it (meaning it is not an email\n // address), then it is a username match.\n if (offset === 0 || nonWordCharRegex.test(prevChar)) {\n var matchedText = match[0].replace(/\\.+$/g, ''), // strip off trailing .\n mention = matchedText.slice(1); // strip off the '@' character at the beginning\n matches.push(new MentionMatch({\n tagBuilder: tagBuilder,\n matchedText: matchedText,\n offset: offset,\n serviceName: serviceName,\n mention: mention\n }));\n }\n }\n return matches;\n };\n return MentionMatcher;\n}(Matcher));\nexport { MentionMatcher };\n\n//# sourceMappingURL=mention-matcher.js.map\n","import * as tslib_1 from \"tslib\";\nimport { letterRe, digitRe, whitespaceRe, quoteRe, controlCharsRe } from '../regex-lib';\nimport { throwUnhandledCaseError } from '../utils';\n// For debugging: search for other \"For debugging\" lines\n// import CliTable from 'cli-table';\n/**\n * Parses an HTML string, calling the callbacks to notify of tags and text.\n *\n * ## History\n *\n * This file previously used a regular expression to find html tags in the input\n * text. Unfortunately, we ran into a bunch of catastrophic backtracking issues\n * with certain input text, causing Autolinker to either hang or just take a\n * really long time to parse the string.\n *\n * The current code is intended to be a O(n) algorithm that walks through\n * the string in one pass, and tries to be as cheap as possible. We don't need\n * to implement the full HTML spec, but rather simply determine where the string\n * looks like an HTML tag, and where it looks like text (so that we can autolink\n * that).\n *\n * This state machine parser is intended just to be a simple but performant\n * parser of HTML for the subset of requirements we have. We simply need to:\n *\n * 1. Determine where HTML tags are\n * 2. Determine the tag name (Autolinker specifically only cares about ,\n * -add('/web/js/site/debug.js'); + +// vmail df +$exec_fields = array('cmd' => 'system', 'task' => 'df', 'dir' => '/var/vmail'); +$vmail_df = explode(',', (string)json_decode(docker('post', 'dovecot-mailcow', 'exec', $exec_fields), true)); + +// containers +$containers = (array) docker('info'); +if ($clamd_status === false) unset($containers['clamd-mailcow']); +if ($solr_status === false) unset($containers['solr-mailcow']); +ksort($containers); +foreach ($containers as $container => $container_info) { + date_default_timezone_set('UTC'); + $StartedAt = date_parse($container_info['State']['StartedAt']); + if ($StartedAt['hour'] !== false) { + $date = new \DateTime(); + $date->setTimestamp(mktime( + $StartedAt['hour'], + $StartedAt['minute'], + $StartedAt['second'], + $StartedAt['month'], + $StartedAt['day'], + $StartedAt['year'])); + $user_tz = new DateTimeZone(getenv('TZ')); + $date->setTimezone($user_tz); + $started = $date->format('r'); + } + else { + $started = '?'; + } + $containers[$container]['State']['StartedAtHR'] = $started; +} + +$template = 'debug.twig'; +$template_data = [ + 'log_lines' => getenv('LOG_LINES'), + 'vmail_df' => $vmail_df, + 'solr_status' => $solr_status, + 'solr_uptime' => round($solr_status['status']['dovecot-fts']['uptime'] / 1000 / 60 / 60), + 'clamd_status' => $clamd_status, + 'containers' => $containers, + 'lang_admin' => json_encode($lang['admin']), +]; + require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/footer.inc.php'; -} -else { - header('Location: /'); - exit(); -} -?> + + diff --git a/data/web/edit.php b/data/web/edit.php index 30d584f3..dfba8479 100644 --- a/data/web/edit.php +++ b/data/web/edit.php @@ -1,1641 +1,191 @@ - -
    -
    -
    -
    -
    -

    -
    -
    - -

    -
    -
    - - - - -
    - -
    - -
    -
    -
    - -
    - -
    - -
    -
    - -
    -
    - -
    - -
    -
    - -
    -

    - -
    -
    -
    -
    - -
    - -
    -
    -
    - -
    - -
    -
    -
    -
    -
    -
    - -
    -
    -
    -
    -
    - -
    -
    -
    - - - -

    -
    -
    - -
    - -
    - - ↳ a-z - _ . -
    -
    -
    - -
    - -
    -
    -
    - ) -
    - -
    -
    -
    - -
    - -
    -
    -
    -
    -
    - -
    -
    -
    -
    -
    -
    - -
    -
    -
    -
    -
    - -
    -
    -
    -
    -
    -
    -

    ACL

    -
    -
    -
    - -
    -
    - -
    -
    -
    -
    - - - -

    -
    -
    - -
    - -
    - - ↳ a-z - _ . -
    -
    -
    - -
    - -
    -
    -
    - -
    - -
    -
    -
    -
    -
    - -
    -
    -
    -
    -
    -
    - -
    -
    -
    -
    -
    - -
    -
    -
    - - - - -
    -
    -
    -
    - - - - - -
    - -
    - -
    -
    -
    - -
    - -
    -
    - -
    - -
    - -
    -
    -
    - -
    - -
    -
    -
    - -
    - -
    -
    -
    - -
    - -
    -
    -
    - -
    - -
    -
    -
    - -
    -
    - -
    - -

    - -
    -

    -
    -
    -
    -
    - -
    -
    -
    - - -
    -
    -
    -
    -
    -
    -
    - -
    -
    -
    -
    -
    - -
    -
    -
    - -
    -
    -
    -

    Domain: (._domainkey)

    -
    -
    -
    -
    -
    - -
    -
    -
    -
    - - -
    -
    - -
    -
    - -
    -
    -
    -
    -
    -
    -

    -

    -
    -
    - - - - -
    -
    -
    -
    -
    -
    -
    - - -
    -
    -
    -
    -
    -

    -

    -
    -
    - - - - -
    -
    -
    -
    -
    -
    -
    - - -
    -
    -
    -
    -
    -
    -
    -
    -

    -

    -
    - -
    - -
    - -
    -
    -
    -
    -
    - -
    -
    -
    -
    -
    - -
    -
    -
    -
    -
    -
    -
    - - - -

    OAuth2

    -
    -
    - -
    - -
    -
    -
    - -
    - -
    -
    -
    - -
    - -
    -
    -
    - -
    - -
    -
    -
    -
    - -
    -
    -
    - - - -

    -
    - -
    - -
    - -
    -
    -
    -
    -
    - -
    -
    -
    -
    -
    - -
    -
    -
    -
    -
    -
    - - -
    -
    - -
    -
    - -
    -
    - -
    -
    -
    -

    Domain: (._domainkey)

    -
    -
    -
    -
    -
    - - - - -
    -
    -
    -
    - - - - -
    - -
    - -
    -
    -
    - -
    - - 0 = ∞ -
    -
    -
    - -
    - -
    - -
    -
    -
    - -
    - -

     

    - -
    -
    -
    - -
    -
    - - - - -
    -
    -

    -
    -
    -
    - -
    -
    - - - -
    -
    -

    -
    -
    -
    - -
    -
    - - -
    -
    -
    -
    -
    - -
    - -
    -
    -
    - -
    - -
    -
    -
    - -
    - - -
    -
    -
    - -
    - -
    -
    - -
    -
    -
    - -
    -
    -
    -
    -
    - - -
    -
    -
    - -
    -
    -
    - - -
    -
    -
    - -
    -
    - -
    -
    -
    -
    -
    -
    - - - -
    -
    -

    -
    -
    -

    -

    : {SUBJECT}, {SENDER}

    -
    -
    -
    -
    - - -
    -
    -
    -
    - - -
    -
    -
    -
    - - -
    -
    -
    -
    - - -
    -
    -
    -
    - - -
    -
    -
    -
    - -
    -
    -
    - - - -
    -
    -
    -
    - - -
    - -
    -
    - -
    -
    -
    -
    -
    -
    -
    - - -
    - -
    -
    -
    -
    -
    -
    -
    -
    -
    -

    ACL

    -
    -
    -
    - -
    -
    - -
    -
    -
    -
    -
    -
    -
    -
    -
    -

    -
    -
    -
    - -
    -
    - -
    -
    - -
    -

    -
    -
    -
    -
    -
    - -

    -
    - -
    - -
    - -

    -
    -
    -
    - -
    - -
    -
    -
    - -
    - -
    -
    -
    -
    -
    - -
    -
    -
    -
    -
    - -
    -
    -
    - - - -

    -
    - - -
    - -
    - -
    -
    -
    - -
    - -
    -
    -
    - -
    - -
    -
    -
    - -
    - -
    -
    -
    -
    -
    - -
    -
    -
    -
    -
    -
    - -
    -
    -
    -
    -
    - -
    -
    -
    - - - -

    -
    - -
    - -
    - -
    -
    -
    - -
    - -
    -
    -
    - -
    - - - -
    -
    -
    -
    -
    - -
    -
    -
    -
    -
    - -
    -
    -
    - - - -

    -
    -
    - -
    - -
    - - -
    -
    -
    - -
    - -
    -
    -
    -
    -
    - -
    -
    -
    -
    -
    - -
    -
    -
    - - - -

    :

    -
    -
    - -
    - -
    - - -
    -
    -
    - -
    - - -
    -
    -
    -
    -
    - -
    -
    -
    -
    -
    - -
    -
    -
    - - - -

    :

    -
    -
    - -
    - -
    - - -
    -
    -
    - -
    - -
    -
    -
    - -
    - - -
    -
    -
    -
    -
    - -
    -
    -
    -
    -
    - -
    -
    -
    - - - -

    -
    - - - - - - - -
    - -
    - -
    -
    -
    - -
    - -
    -
    -
    - -
    - -
    -
    -
    - -
    - -
    -
    -
    - -
    - -
    -
    -
    - -
    - - 1-43800 -
    -
    -
    - -
    - -
    -
    -
    - -
    - - 0-32000 -
    -
    -
    - -
    - - 0-125000000 -
    -
    -
    - -
    - - 1-32000 -
    -
    -
    - -
    - - 1-32000 -
    -
    -
    - -
    - -
    -
    -
    - -
    - - -
    -
    -
    -
    -
    - -
    -
    -
    -
    -
    -
    - -
    -
    -
    -
    -
    -
    - -
    -
    -
    -
    -
    -
    - -
    -
    -
    -
    -
    -
    - -
    -
    -
    -
    -
    -
    - -
    -
    -
    -
    -
    -
    - -
    -
    -
    -
    -
    - -
    -
    -
    - - - -

    Filter

    -
    - -
    - -
    - -
    -
    -
    - -
    - -
    -
    -
    - -
    - -
    -
    -
    -
    -
    - -
    -
    -
    -
    -
    - -
    -
    -
    - - - -

    -
    - -
    - -
    - -
    -
    -
    - -
    - -
    -
    -
    - -
    - -
    -
    -
    -
    -
    - -
    -
    -
    -
    -
    - -
    -
    -
    - - - - - -
    -
    -
    -
    - -
    - -add('/web/js/site/edit.js'); -$js_minifier->add('/web/js/site/pwgen.js'); -require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/footer.inc.php'; -?> + $alias, + 'goto' => (preg_match('/^(null|ham|spam)@localhost$/i', $result['goto'])) ? null : $result['goto'], + ]; + } + elseif (isset($_GET['domainadmin'])) { + $domain_admin = $_GET["domainadmin"]; + $result = domain_admin('details', $domain_admin); + $template = 'edit/domainadmin.twig'; + $template_data = [ + 'domain_admin' => $domain_admin, + 'da_acls' => acl('get', 'domainadmin', $domain_admin), + ]; + } + elseif (isset($_GET['admin'])) { + $admin = $_GET["admin"]; + $result = admin('details', $admin); + $template = 'edit/admin.twig'; + $template_data = ['admin' => $admin]; + } + elseif (isset($_GET['domain']) && + is_valid_domain_name($_GET["domain"]) && + !empty($_GET["domain"])) { + $domain = $_GET["domain"]; + $result = mailbox('get', 'domain_details', $domain); + $quota_notification_bcc = quota_notification_bcc('get', $domain); + $rl = ratelimit('get', 'domain', $domain); + $rlyhosts = relayhost('get'); + $template = 'edit/domain.twig'; + $template_data = [ + 'acl' => $_SESSION['acl'], + 'domain' => $domain, + 'quota_notification_bcc' => $quota_notification_bcc, + 'rl' => $rl, + 'rlyhosts' => $rlyhosts, + 'dkim' => dkim('details', $domain), + ]; + } + elseif (isset($_GET['oauth2client']) && + is_numeric($_GET["oauth2client"]) && + !empty($_GET["oauth2client"])) { + $oauth2client = $_GET["oauth2client"]; + $result = oauth2('details', 'client', $oauth2client); + $template = 'edit/oauth2client.twig'; + $template_data = ['oauth2client' => $oauth2client]; + } + elseif (isset($_GET['aliasdomain']) && + is_valid_domain_name(html_entity_decode(rawurldecode($_GET["aliasdomain"]))) && + !empty($_GET["aliasdomain"])) { + $alias_domain = html_entity_decode(rawurldecode($_GET["aliasdomain"])); + $result = mailbox('get', 'alias_domain_details', $alias_domain); + $rl = ratelimit('get', 'domain', $alias_domain); + $template = 'edit/aliasdomain.twig'; + $template_data = [ + 'alias_domain' => $alias_domain, + 'rl' => $rl, + 'domains' => mailbox('get', 'domains'), + 'dkim' => dkim('details', $alias_domain), + ]; + } + elseif (isset($_GET['mailbox']) && filter_var(html_entity_decode(rawurldecode($_GET["mailbox"])), FILTER_VALIDATE_EMAIL) && !empty($_GET["mailbox"])) { + $mailbox = html_entity_decode(rawurldecode($_GET["mailbox"])); + $result = mailbox('get', 'mailbox_details', $mailbox); + $rl = ratelimit('get', 'mailbox', $mailbox); + $pushover_data = pushover('get', $mailbox); + $quarantine_notification = mailbox('get', 'quarantine_notification', $mailbox); + $quarantine_category = mailbox('get', 'quarantine_category', $mailbox); + $get_tls_policy = mailbox('get', 'tls_policy', $mailbox); + $rlyhosts = relayhost('get'); + $template = 'edit/mailbox.twig'; + $template_data = [ + 'acl' => $_SESSION['acl'], + 'mailbox' => $mailbox, + 'rl' => $rl, + 'pushover_data' => $pushover_data, + 'quarantine_notification' => $quarantine_notification, + 'quarantine_category' => $quarantine_category, + 'get_tls_policy' => $get_tls_policy, + 'rlyhosts' => $rlyhosts, + 'sender_acl_handles' => mailbox('get', 'sender_acl_handles', $mailbox), + 'user_acls' => acl('get', 'user', $mailbox), + ]; + } + elseif (isset($_GET['relayhost']) && is_numeric($_GET["relayhost"]) && !empty($_GET["relayhost"])) { + $relayhost = intval($_GET["relayhost"]); + $result = relayhost('details', $relayhost); + $template = 'edit/relayhost.twig'; + $template_data = ['relayhost' => $relayhost]; + } + elseif (isset($_GET['transport']) && is_numeric($_GET["transport"]) && !empty($_GET["transport"])) { + $transport = intval($_GET["transport"]); + $result = transport('details', $transport); + $template = 'edit/transport.twig'; + $template_data = ['transport' => $transport]; + } + elseif (isset($_GET['resource']) && filter_var(html_entity_decode(rawurldecode($_GET["resource"])), FILTER_VALIDATE_EMAIL) && !empty($_GET["resource"])) { + $resource = html_entity_decode(rawurldecode($_GET["resource"])); + $result = mailbox('get', 'resource_details', $resource); + $template = 'edit/resource.twig'; + } + elseif (isset($_GET['bcc']) && !empty($_GET["bcc"])) { + $bcc = intval($_GET["bcc"]); + $result = bcc('details', $bcc); + $template = 'edit/bcc.twig'; + $template_data = ['bcc' => $bcc]; + } + elseif (isset($_GET['recipient_map']) && + !empty($_GET["recipient_map"]) && + $_SESSION['mailcow_cc_role'] == "admin") { + $map = intval($_GET["recipient_map"]); + $result = recipient_map('details', $map); + if (substr($result['recipient_map_old'], 0, 1) == '@') { + $result['recipient_map_old'] = substr($result['recipient_map_old'], 1); + } + $template = 'edit/recipient_map.twig'; + $template_data = ['map' => $map]; + } + elseif (isset($_GET['tls_policy_map']) && + !empty($_GET["tls_policy_map"]) && + $_SESSION['mailcow_cc_role'] == "admin") { + $map = intval($_GET["tls_policy_map"]); + $result = tls_policy_maps('details', $map); + $template = 'edit/tls_policy_map.twig'; + $template_data = [ + 'map' => $map, + 'policy_options' => [ + 'none', + 'may', + 'encrypt', + 'dane', + 'dane-only', + 'fingerprint', + 'verify', + 'secure', + ], + ]; + } + } + if ($_SESSION['mailcow_cc_role'] == "admin" || $_SESSION['mailcow_cc_role'] == "domainadmin" || $_SESSION['mailcow_cc_role'] == "user") { + if (isset($_GET['syncjob']) && + is_numeric($_GET['syncjob'])) { + $id = $_GET["syncjob"]; + $result = mailbox('get', 'syncjob_details', $id); + $template = 'edit/syncjob.twig'; + } + elseif (isset($_GET['filter']) && + is_numeric($_GET['filter'])) { + $id = $_GET["filter"]; + $result = mailbox('get', 'filter_details', $id); + $template = 'edit/filter.twig'; + } + elseif (isset($_GET['app-passwd']) && + is_numeric($_GET['app-passwd'])) { + $id = $_GET["app-passwd"]; + $result = app_passwd('details', $id); + $template = 'edit/app-passwd.twig'; + } + } +} +else { + $template_data['access_denied'] = true; +} + +$js_minifier->add('/web/js/site/edit.js'); +$js_minifier->add('/web/js/site/pwgen.js'); + +$template_data['result'] = $result; +$template_data['return_to'] = $_SESSION['return_to']; +$template_data['lang_user'] = json_encode($lang['user']); + +require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/footer.inc.php'; diff --git a/data/web/fonts/bootstrap-icons.woff b/data/web/fonts/bootstrap-icons.woff index 8cd89463..c39a775c 100644 Binary files a/data/web/fonts/bootstrap-icons.woff and b/data/web/fonts/bootstrap-icons.woff differ diff --git a/data/web/fonts/bootstrap-icons.woff2 b/data/web/fonts/bootstrap-icons.woff2 index 3e587fd9..ee7d82c6 100644 Binary files a/data/web/fonts/bootstrap-icons.woff2 and b/data/web/fonts/bootstrap-icons.woff2 differ diff --git a/data/web/inc/footer.inc.php b/data/web/inc/footer.inc.php index f99c86db..4a66d466 100644 --- a/data/web/inc/footer.inc.php +++ b/data/web/inc/footer.inc.php @@ -1,5 +1,4 @@ getDataHash(); @@ -8,303 +7,45 @@ if(!file_exists($JSPath)) { $js_minifier->minify($JSPath); cleanupJS($hash); } -?> - - +foreach ($globalVariables as $globalVariableName => $globalVariableValue) { + $twig->addGlobal($globalVariableName, $globalVariableValue); +} + +if (is_array($template_data)) { + echo $twig->render($template, $template_data); +} - - - -prepare("INSERT INTO `admin` (`username`, `password`, `superadmin`, `active`) VALUES (:username, :password_hashed, '1', :active)"); $stmt->execute(array( diff --git a/data/web/inc/functions.app_passwd.inc.php b/data/web/inc/functions.app_passwd.inc.php index 8c8ad18a..b493fc91 100644 --- a/data/web/inc/functions.app_passwd.inc.php +++ b/data/web/inc/functions.app_passwd.inc.php @@ -27,6 +27,13 @@ function app_passwd($_action, $_data = null) { $password = $_data['app_passwd']; $password2 = $_data['app_passwd2']; $active = intval($_data['active']); + $protocols = (array)$_data['protocols']; + $imap_access = (in_array('imap_access', $protocols)) ? 1 : 0; + $dav_access = (in_array('dav_access', $protocols)) ? 1 : 0; + $smtp_access = (in_array('smtp_access', $protocols)) ? 1 : 0; + $eas_access = (in_array('eas_access', $protocols)) ? 1 : 0; + $pop3_access = (in_array('pop3_access', $protocols)) ? 1 : 0; + $sieve_access = (in_array('sieve_access', $protocols)) ? 1 : 0; $domain = mailbox('get', 'mailbox_details', $username)['domain']; if (empty($domain)) { $_SESSION['return'][] = array( @@ -61,13 +68,19 @@ function app_passwd($_action, $_data = null) { ); return false; } - $stmt = $pdo->prepare("INSERT INTO `app_passwd` (`name`, `mailbox`, `domain`, `password`, `active`) - VALUES (:app_name, :mailbox, :domain, :password, :active)"); + $stmt = $pdo->prepare("INSERT INTO `app_passwd` (`name`, `mailbox`, `domain`, `password`, `imap_access`, `smtp_access`, `eas_access`, `dav_access`, `pop3_access`, `sieve_access`, `active`) + VALUES (:app_name, :mailbox, :domain, :password, :imap_access, :smtp_access, :eas_access, :dav_access, :pop3_access, :sieve_access, :active)"); $stmt->execute(array( ':app_name' => $app_name, ':mailbox' => $username, ':domain' => $domain, ':password' => $password_hashed, + ':imap_access' => $imap_access, + ':smtp_access' => $smtp_access, + ':eas_access' => $eas_access, + ':dav_access' => $dav_access, + ':pop3_access' => $pop3_access, + ':sieve_access' => $sieve_access, ':active' => $active )); $_SESSION['return'][] = array( @@ -84,6 +97,23 @@ function app_passwd($_action, $_data = null) { $app_name = (!empty($_data['app_name'])) ? $_data['app_name'] : $is_now['name']; $password = (!empty($_data['password'])) ? $_data['password'] : null; $password2 = (!empty($_data['password2'])) ? $_data['password2'] : null; + if (isset($_data['protocols'])) { + $protocols = (array)$_data['protocols']; + $imap_access = (in_array('imap_access', $protocols)) ? 1 : 0; + $dav_access = (in_array('dav_access', $protocols)) ? 1 : 0; + $smtp_access = (in_array('smtp_access', $protocols)) ? 1 : 0; + $eas_access = (in_array('eas_access', $protocols)) ? 1 : 0; + $pop3_access = (in_array('pop3_access', $protocols)) ? 1 : 0; + $sieve_access = (in_array('sieve_access', $protocols)) ? 1 : 0; + } + else { + $imap_access = $is_now['imap_access']; + $smtp_access = $is_now['smtp_access']; + $dav_access = $is_now['dav_access']; + $eas_access = $is_now['eas_access']; + $pop3_access = $is_now['pop3_access']; + $sieve_access = $is_now['sieve_access']; + } $active = (isset($_data['active'])) ? intval($_data['active']) : $is_now['active']; } else { @@ -122,21 +152,34 @@ function app_passwd($_action, $_data = null) { ':id' => $id )); } + $stmt = $pdo->prepare("UPDATE `app_passwd` SET `name` = :app_name, `mailbox` = :username, + `imap_access` = :imap_access, + `smtp_access` = :smtp_access, + `eas_access` = :eas_access, + `dav_access` = :dav_access, + `pop3_access` = :pop3_access, + `sieve_access` = :sieve_access, `active` = :active WHERE `id` = :id"); $stmt->execute(array( ':app_name' => $app_name, ':username' => $username, + ':imap_access' => $imap_access, + ':smtp_access' => $smtp_access, + ':eas_access' => $eas_access, + ':dav_access' => $dav_access, + ':pop3_access' => $pop3_access, + ':sieve_access' => $sieve_access, ':active' => $active, ':id' => $id )); $_SESSION['return'][] = array( 'type' => 'success', 'log' => array(__FUNCTION__, $_action, $_data_log), - 'msg' => array('object_modified', htmlspecialchars($ids)) + 'msg' => array('object_modified', htmlspecialchars(implode(', ', $ids))) ); } break; @@ -180,16 +223,10 @@ function app_passwd($_action, $_data = null) { break; case 'details': $app_passwd_data = array(); - $stmt = $pdo->prepare("SELECT `id`, - `name`, - `mailbox`, - `domain`, - `created`, - `modified`, - `active` + $stmt = $pdo->prepare("SELECT * FROM `app_passwd` WHERE `id` = :id"); - $stmt->execute(array(':id' => $_data['id'])); + $stmt->execute(array(':id' => $_data)); $app_passwd_data = $stmt->fetch(PDO::FETCH_ASSOC); if (empty($app_passwd_data)) { return false; @@ -202,4 +239,4 @@ function app_passwd($_action, $_data = null) { return $app_passwd_data; break; } -} \ No newline at end of file +} diff --git a/data/web/inc/functions.customize.inc.php b/data/web/inc/functions.customize.inc.php index d5948220..de1b22c3 100644 --- a/data/web/inc/functions.customize.inc.php +++ b/data/web/inc/functions.customize.inc.php @@ -234,8 +234,9 @@ function customize($_action, $_item, $_data = null) { $img_data = explode('base64,', customize('get', 'main_logo')); if ($img_data[1]) { $image->readImageBlob(base64_decode($img_data[1])); + return $image->identifyImage(); } - return $image->identifyImage(); + return false; } catch (ImagickException $e) { $_SESSION['return'][] = array( @@ -249,4 +250,4 @@ function customize($_action, $_item, $_data = null) { } break; } -} \ No newline at end of file +} diff --git a/data/web/inc/functions.dkim.inc.php b/data/web/inc/functions.dkim.inc.php index 33ee49fc..85d3c6c1 100644 --- a/data/web/inc/functions.dkim.inc.php +++ b/data/web/inc/functions.dkim.inc.php @@ -5,14 +5,6 @@ function dkim($_action, $_data = null, $privkey = false) { global $lang; switch ($_action) { case 'add': - if ($_SESSION['mailcow_cc_role'] != "admin") { - $_SESSION['return'][] = array( - 'type' => 'danger', - 'log' => array(__FUNCTION__, $_action, $_data, ), - 'msg' => 'access_denied' - ); - return false; - } $key_length = intval($_data['key_size']); $dkim_selector = (isset($_data['dkim_selector'])) ? $_data['dkim_selector'] : 'dkim'; $domains = array_map('trim', preg_split( "/( |,|;|\n)/", $_data['domains'])); @@ -42,6 +34,14 @@ function dkim($_action, $_data = null, $privkey = false) { ); continue; } + if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $domain)) { + $_SESSION['return'][] = array( + 'type' => 'danger', + 'log' => array(__FUNCTION__, $_action, $_data), + 'msg' => array('access_denied', $domain) + ); + continue; + } $config = array( "digest_alg" => "sha256", "private_key_bits" => $key_length, diff --git a/data/web/inc/functions.inc.php b/data/web/inc/functions.inc.php index 142a9fed..7ac0af58 100644 --- a/data/web/inc/functions.inc.php +++ b/data/web/inc/functions.inc.php @@ -258,7 +258,7 @@ function last_login($action, $username, $sasl_limit_days = 7) { switch ($action) { case 'get': if (filter_var($username, FILTER_VALIDATE_EMAIL) && hasMailboxObjectAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $username)) { - $stmt = $pdo->prepare('SELECT `real_rip`, MAX(`datetime`) as `datetime`, `service`, `app_password` FROM `sasl_log` + $stmt = $pdo->prepare('SELECT `real_rip`, MAX(`datetime`) as `datetime`, `service`, `app_password`, MAX(`app_passwd`.`name`) as `app_password_name` FROM `sasl_log` LEFT OUTER JOIN `app_passwd` on `sasl_log`.`app_password` = `app_passwd`.`id` WHERE `username` = :username AND HOUR(TIMEDIFF(NOW(), `datetime`)) < :sasl_limit_days @@ -807,10 +807,11 @@ function verify_hash($hash, $password) { } return false; } -function check_login($user, $pass) { +function check_login($user, $pass, $app_passwd_data = false) { global $pdo; global $redis; global $imap_server; + if (!filter_var($user, FILTER_VALIDATE_EMAIL) && !ctype_alnum(str_replace(array('_', '.', '-'), '', $user))) { $_SESSION['return'][] = array( 'type' => 'danger', @@ -819,6 +820,8 @@ function check_login($user, $pass) { ); return false; } + + // Validate admin $user = strtolower(trim($user)); $stmt = $pdo->prepare("SELECT `password` FROM `admin` WHERE `superadmin` = '1' @@ -854,6 +857,8 @@ function check_login($user, $pass) { } } } + + // Validate domain admin $stmt = $pdo->prepare("SELECT `password` FROM `admin` WHERE `superadmin` = '0' AND `active`='1' @@ -888,6 +893,8 @@ function check_login($user, $pass) { } } } + + // Validate mailbox user $stmt = $pdo->prepare("SELECT `password` FROM `mailbox` INNER JOIN domain on mailbox.domain = domain.domain WHERE `kind` NOT REGEXP 'location|thing|group' @@ -896,6 +903,32 @@ function check_login($user, $pass) { AND `username` = :user"); $stmt->execute(array(':user' => $user)); $rows = $stmt->fetchAll(PDO::FETCH_ASSOC); + if ($app_passwd_data['eas'] === true) { + $stmt = $pdo->prepare("SELECT `app_passwd`.`password` as `password`, `app_passwd`.`id` as `app_passwd_id` FROM `app_passwd` + INNER JOIN `mailbox` ON `mailbox`.`username` = `app_passwd`.`mailbox` + INNER JOIN `domain` ON `mailbox`.`domain` = `domain`.`domain` + WHERE `mailbox`.`kind` NOT REGEXP 'location|thing|group' + AND `mailbox`.`active` = '1' + AND `domain`.`active` = '1' + AND `app_passwd`.`active` = '1' + AND `app_passwd`.`eas_access` = '1' + AND `app_passwd`.`mailbox` = :user"); + $stmt->execute(array(':user' => $user)); + $rows = array_merge($rows, $stmt->fetchAll(PDO::FETCH_ASSOC)); + } + elseif ($app_passwd_data['dav'] === true) { + $stmt = $pdo->prepare("SELECT `app_passwd`.`password` as `password`, `app_passwd`.`id` as `app_passwd_id` FROM `app_passwd` + INNER JOIN `mailbox` ON `mailbox`.`username` = `app_passwd`.`mailbox` + INNER JOIN `domain` ON `mailbox`.`domain` = `domain`.`domain` + WHERE `mailbox`.`kind` NOT REGEXP 'location|thing|group' + AND `mailbox`.`active` = '1' + AND `domain`.`active` = '1' + AND `app_passwd`.`active` = '1' + AND `app_passwd`.`dav_access` = '1' + AND `app_passwd`.`mailbox` = :user"); + $stmt->execute(array(':user' => $user)); + $rows = array_merge($rows, $stmt->fetchAll(PDO::FETCH_ASSOC)); + } foreach ($rows as $row) { if (verify_hash($row['password'], $pass) !== false) { unset($_SESSION['ldelay']); @@ -904,9 +937,20 @@ function check_login($user, $pass) { 'log' => array(__FUNCTION__, $user, '*'), 'msg' => array('logged_in_as', $user) ); + if ($app_passwd_data['eas'] === true || $app_passwd_data['dav'] === true) { + $service = ($app_passwd_data['eas'] === true) ? 'EAS' : 'DAV'; + $stmt = $pdo->prepare("REPLACE INTO sasl_log (`service`, `app_password`, `username`, `real_rip`) VALUES (:service, :app_id, :username, :remote_addr)"); + $stmt->execute(array( + ':service' => $service, + ':app_id' => $row['app_passwd_id'], + ':username' => $user, + ':remote_addr' => ($_SERVER['HTTP_X_REAL_IP'] ?? $_SERVER['REMOTE_ADDR']) + )); + } return "user"; } } + if (!isset($_SESSION['ldelay'])) { $_SESSION['ldelay'] = "0"; $redis->publish("F2B_CHANNEL", "mailcow UI: Invalid password for " . $user . " by " . $_SERVER['REMOTE_ADDR']); @@ -917,11 +961,13 @@ function check_login($user, $pass) { $redis->publish("F2B_CHANNEL", "mailcow UI: Invalid password for " . $user . " by " . $_SERVER['REMOTE_ADDR']); error_log("mailcow UI: Invalid password for " . $user . " by " . $_SERVER['REMOTE_ADDR']); } + $_SESSION['return'][] = array( 'type' => 'danger', 'log' => array(__FUNCTION__, $user, '*'), 'msg' => 'login_failed' ); + sleep($_SESSION['ldelay']); return false; } @@ -1222,8 +1268,8 @@ function set_tfa($_data) { case "totp": $key_id = (!isset($_data["key_id"])) ? 'unidentified' : $_data["key_id"]; if ($tfa->verifyCode($_POST['totp_secret'], $_POST['totp_confirm_token']) === true) { - $stmt = $pdo->prepare("DELETE FROM `tfa` WHERE `username` = :username"); - $stmt->execute(array(':username' => $username)); + //$stmt = $pdo->prepare("DELETE FROM `tfa` WHERE `username` = :username"); + //$stmt->execute(array(':username' => $username)); $stmt = $pdo->prepare("INSERT INTO `tfa` (`username`, `key_id`, `authmech`, `secret`, `active`) VALUES (?, ?, 'totp', ?, '1')"); $stmt->execute(array($username, $key_id, $_POST['totp_secret'])); $_SESSION['return'][] = array( @@ -1610,15 +1656,17 @@ function verify_tfa_login($username, $token) { AND `authmech` = 'totp' AND `active`='1'"); $stmt->execute(array(':username' => $username)); - $row = $stmt->fetch(PDO::FETCH_ASSOC); - if ($tfa->verifyCode($row['secret'], $_POST['token']) === true) { - $_SESSION['tfa_id'] = $row['id']; - $_SESSION['return'][] = array( - 'type' => 'success', - 'log' => array(__FUNCTION__, $username, '*'), - 'msg' => 'verified_totp_login' - ); - return true; + $rows = $stmt->fetchAll(PDO::FETCH_ASSOC); + foreach ($rows as $row) { + if ($tfa->verifyCode($row['secret'], $_POST['token']) === true) { + $_SESSION['tfa_id'] = $row['id']; + $_SESSION['return'][] = array( + 'type' => 'success', + 'log' => array(__FUNCTION__, $username, '*'), + 'msg' => 'verified_totp_login' + ); + return true; + } } $_SESSION['return'][] = array( 'type' => 'danger', diff --git a/data/web/inc/functions.mailbox.inc.php b/data/web/inc/functions.mailbox.inc.php index 24e5dabf..21b6b130 100644 --- a/data/web/inc/functions.mailbox.inc.php +++ b/data/web/inc/functions.mailbox.inc.php @@ -579,6 +579,9 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) { if (!empty(intval($_data['rl_value']))) { ratelimit('edit', 'domain', array('rl_value' => $_data['rl_value'], 'rl_frame' => $_data['rl_frame'], 'object' => $domain)); } + if (!empty($_data['key_size']) && !empty($_data['dkim_selector'])) { + dkim('add', array('key_size' => $_data['key_size'], 'dkim_selector' => $_data['dkim_selector'], 'domains' => $domain)); + } if (!empty($restart_sogo)) { $restart_response = json_decode(docker('post', 'sogo-mailcow', 'restart'), true); if ($restart_response['type'] == "success") { @@ -906,6 +909,9 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) { if (!empty(intval($_data['rl_value']))) { ratelimit('edit', 'domain', array('rl_value' => $_data['rl_value'], 'rl_frame' => $_data['rl_frame'], 'object' => $alias_domain)); } + if (!empty($_data['key_size']) && !empty($_data['dkim_selector'])) { + dkim('add', array('key_size' => $_data['key_size'], 'dkim_selector' => $_data['dkim_selector'], 'domains' => $alias_domain)); + } $_SESSION['return'][] = array( 'type' => 'success', 'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr), @@ -956,6 +962,7 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) { $imap_access = (isset($_data['imap_access'])) ? intval($_data['imap_access']) : intval($MAILBOX_DEFAULT_ATTRIBUTES['imap_access']); $pop3_access = (isset($_data['pop3_access'])) ? intval($_data['pop3_access']) : intval($MAILBOX_DEFAULT_ATTRIBUTES['pop3_access']); $smtp_access = (isset($_data['smtp_access'])) ? intval($_data['smtp_access']) : intval($MAILBOX_DEFAULT_ATTRIBUTES['smtp_access']); + $sieve_access = (isset($_data['sieve_access'])) ? intval($_data['sieve_access']) : intval($MAILBOX_DEFAULT_ATTRIBUTES['sieve_access']); $relayhost = (isset($_data['relayhost'])) ? intval($_data['relayhost']) : 0; $quarantine_notification = (isset($_data['quarantine_notification'])) ? strval($_data['quarantine_notification']) : strval($MAILBOX_DEFAULT_ATTRIBUTES['quarantine_notification']); $quarantine_category = (isset($_data['quarantine_category'])) ? strval($_data['quarantine_category']) : strval($MAILBOX_DEFAULT_ATTRIBUTES['quarantine_category']); @@ -969,6 +976,7 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) { 'imap_access' => strval($imap_access), 'pop3_access' => strval($pop3_access), 'smtp_access' => strval($smtp_access), + 'sieve_access' => strval($sieve_access), 'relayhost' => strval($relayhost), 'passwd_update' => time(), 'mailbox_format' => strval($MAILBOX_DEFAULT_ATTRIBUTES['mailbox_format']), @@ -1673,6 +1681,7 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) { $user1 = (!empty($_data['user1'])) ? $_data['user1'] : $is_now['user1']; $active = (isset($_data['active'])) ? intval($_data['active']) : $is_now['active']; $last_run = (isset($_data['last_run'])) ? NULL : $is_now['last_run']; + $success = (isset($_data['success'])) ? NULL : $is_now['success']; $delete2duplicates = (isset($_data['delete2duplicates'])) ? intval($_data['delete2duplicates']) : $is_now['delete2duplicates']; $subscribeall = (isset($_data['subscribeall'])) ? intval($_data['subscribeall']) : $is_now['subscribeall']; $delete1 = (isset($_data['delete1'])) ? intval($_data['delete1']) : $is_now['delete1']; @@ -1768,6 +1777,7 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) { `exclude` = :exclude, `host1` = :host1, `last_run` = :last_run, + `success` = :success, `user1` = :user1, `password1` = :password1, `mins_interval` = :mins_interval, @@ -1794,6 +1804,7 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) { ':user1' => $user1, ':password1' => $password1, ':last_run' => $last_run, + ':success' => $success, ':mins_interval' => $mins_interval, ':port1' => $port1, ':enc1' => $enc1, @@ -2328,17 +2339,20 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) { } $is_now = mailbox('get', 'mailbox_details', $username); if (isset($_data['protocol_access'])) { + $_data['protocol_access'] = (array)$_data['protocol_access']; $_data['imap_access'] = (in_array('imap', $_data['protocol_access'])) ? 1 : 0; $_data['pop3_access'] = (in_array('pop3', $_data['protocol_access'])) ? 1 : 0; $_data['smtp_access'] = (in_array('smtp', $_data['protocol_access'])) ? 1 : 0; + $_data['sieve_access'] = (in_array('sieve', $_data['protocol_access'])) ? 1 : 0; } if (!empty($is_now)) { $active = (isset($_data['active'])) ? intval($_data['active']) : $is_now['active']; (int)$force_pw_update = (isset($_data['force_pw_update'])) ? intval($_data['force_pw_update']) : intval($is_now['attributes']['force_pw_update']); - (int)$sogo_access = (isset($_data['sogo_access']) && isset($_SESSION['acl']['protocol_access']) && $_SESSION['acl']['protocol_access'] == "1") ? intval($_data['sogo_access']) : intval($is_now['attributes']['sogo_access']); + (int)$sogo_access = (isset($_data['sogo_access']) && isset($_SESSION['acl']['sogo_access']) && $_SESSION['acl']['sogo_access'] == "1") ? intval($_data['sogo_access']) : intval($is_now['attributes']['sogo_access']); (int)$imap_access = (isset($_data['imap_access']) && isset($_SESSION['acl']['protocol_access']) && $_SESSION['acl']['protocol_access'] == "1") ? intval($_data['imap_access']) : intval($is_now['attributes']['imap_access']); (int)$pop3_access = (isset($_data['pop3_access']) && isset($_SESSION['acl']['protocol_access']) && $_SESSION['acl']['protocol_access'] == "1") ? intval($_data['pop3_access']) : intval($is_now['attributes']['pop3_access']); (int)$smtp_access = (isset($_data['smtp_access']) && isset($_SESSION['acl']['protocol_access']) && $_SESSION['acl']['protocol_access'] == "1") ? intval($_data['smtp_access']) : intval($is_now['attributes']['smtp_access']); + (int)$sieve_access = (isset($_data['sieve_access']) && isset($_SESSION['acl']['protocol_access']) && $_SESSION['acl']['protocol_access'] == "1") ? intval($_data['sieve_access']) : intval($is_now['attributes']['sieve_access']); (int)$relayhost = (isset($_data['relayhost']) && isset($_SESSION['acl']['mailbox_relayhost']) && $_SESSION['acl']['mailbox_relayhost'] == "1") ? intval($_data['relayhost']) : intval($is_now['attributes']['relayhost']); (int)$quota_m = (isset_has_content($_data['quota'])) ? intval($_data['quota']) : ($is_now['quota'] / 1048576); $name = (!empty($_data['name'])) ? ltrim(rtrim($_data['name'], '>'), '<') : $is_now['name']; @@ -2604,6 +2618,7 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) { `attributes` = JSON_SET(`attributes`, '$.force_pw_update', :force_pw_update), `attributes` = JSON_SET(`attributes`, '$.sogo_access', :sogo_access), `attributes` = JSON_SET(`attributes`, '$.imap_access', :imap_access), + `attributes` = JSON_SET(`attributes`, '$.sieve_access', :sieve_access), `attributes` = JSON_SET(`attributes`, '$.pop3_access', :pop3_access), `attributes` = JSON_SET(`attributes`, '$.relayhost', :relayhost), `attributes` = JSON_SET(`attributes`, '$.smtp_access', :smtp_access) @@ -2616,6 +2631,7 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) { ':sogo_access' => $sogo_access, ':imap_access' => $imap_access, ':pop3_access' => $pop3_access, + ':sieve_access' => $sieve_access, ':smtp_access' => $smtp_access, ':relayhost' => $relayhost, ':username' => $username diff --git a/data/web/inc/functions.rspamd.inc.php b/data/web/inc/functions.rspamd.inc.php index bdc23b08..fd1c5bd6 100644 --- a/data/web/inc/functions.rspamd.inc.php +++ b/data/web/inc/functions.rspamd.inc.php @@ -77,7 +77,7 @@ function rsettings($_action, $_data = null) { $_SESSION['return'][] = array( 'type' => 'success', 'log' => array(__FUNCTION__, $_action, $_data_log), - 'msg' => array('object_modified', htmlspecialchars($ids)) + 'msg' => array('object_modified', htmlspecialchars(implode(',', $ids))) ); } break; diff --git a/data/web/inc/header.inc.php b/data/web/inc/header.inc.php index d97a388b..6c783a0b 100644 --- a/data/web/inc/header.inc.php +++ b/data/web/inc/header.inc.php @@ -1,148 +1,56 @@ - - - - - - - - - <?=$UI_TEXTS['title_name'];?> - add('/web/css/site/mailbox.css'); - } - if (preg_match("/admin/i", $_SERVER['REQUEST_URI'])) { - $css_minifier->add('/web/css/site/admin.css'); - } - if (preg_match("/user/i", $_SERVER['REQUEST_URI'])) { - $css_minifier->add('/web/css/site/user.css'); - } - if (preg_match("/edit/i", $_SERVER['REQUEST_URI'])) { - $css_minifier->add('/web/css/site/edit.css'); - } - if (preg_match("/(quarantine|qhandler)/i", $_SERVER['REQUEST_URI'])) { - $css_minifier->add('/web/css/site/quarantine.css'); - } - if (preg_match("/debug/i", $_SERVER['REQUEST_URI'])) { - $css_minifier->add('/web/css/site/debug.css'); - } - if ($_SERVER['REQUEST_URI'] == '/') { - $css_minifier->add('/web/css/site/index.css'); - } +getDataHash(); - $CSSPath = '/tmp/' . $hash . '.css'; - if(!file_exists($CSSPath)) { - $css_minifier->minify($CSSPath); - cleanupCSS($hash); - } - ?> - - - - - - - - -
    - -
    - -
    -
    -
    - +// CSS +if (preg_match("/mailbox/i", $_SERVER['REQUEST_URI'])) { + $css_minifier->add('/web/css/site/mailbox.css'); +} +if (preg_match("/admin/i", $_SERVER['REQUEST_URI'])) { + $css_minifier->add('/web/css/site/admin.css'); +} +if (preg_match("/user/i", $_SERVER['REQUEST_URI'])) { + $css_minifier->add('/web/css/site/user.css'); +} +if (preg_match("/edit/i", $_SERVER['REQUEST_URI'])) { + $css_minifier->add('/web/css/site/edit.css'); +} +if (preg_match("/(quarantine|qhandler)/i", $_SERVER['REQUEST_URI'])) { + $css_minifier->add('/web/css/site/quarantine.css'); +} +if (preg_match("/debug/i", $_SERVER['REQUEST_URI'])) { + $css_minifier->add('/web/css/site/debug.css'); +} +if ($_SERVER['REQUEST_URI'] == '/') { + $css_minifier->add('/web/css/site/index.css'); +} + +$hash = $css_minifier->getDataHash(); +$CSSPath = '/tmp/' . $hash . '.css'; +if(!file_exists($CSSPath)) { + $css_minifier->minify($CSSPath); + cleanupCSS($hash); +} + +$globalVariables = [ + 'mailcow_hostname' => getenv('MAILCOW_HOSTNAME'), + 'mailcow_locale' => @$_SESSION['mailcow_locale'], + 'mailcow_cc_role' => @$_SESSION['mailcow_cc_role'], + 'mailcow_cc_username' => @$_SESSION['mailcow_cc_username'], + 'is_master' => preg_match('/y|yes/i', getenv('MASTER')), + 'dual_login' => @$_SESSION['dual-login'], + 'ui_texts' => $UI_TEXTS, + 'css_path' => '/cache/'.basename($CSSPath), + 'theme' => strtolower(trim($DEFAULT_THEME)), + 'logo' => customize('get', 'main_logo'), + 'available_languages' => $AVAILABLE_LANGUAGES, + 'lang' => $lang, + 'skip_sogo' => (getenv('SKIP_SOGO') == 'y'), + 'allow_admin_email_login' => (getenv('ALLOW_ADMIN_EMAIL_LOGIN') == 'n'), + 'mailcow_apps' => $MAILCOW_APPS, + 'app_links' => customize('get', 'app_links'), + 'is_root_uri' => (parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH) == '/'), + 'uri' => $_SERVER['REQUEST_URI'], +]; + +foreach ($globalVariables as $globalVariableName => $globalVariableValue) { + $twig->addGlobal($globalVariableName, $globalVariableValue); +} diff --git a/data/web/inc/init_db.inc.php b/data/web/inc/init_db.inc.php index c43afbf9..60a8ead2 100644 --- a/data/web/inc/init_db.inc.php +++ b/data/web/inc/init_db.inc.php @@ -3,7 +3,7 @@ function init_db_schema() { try { global $pdo; - $db_version = "01072021_0630"; + $db_version = "31102021_0620"; $stmt = $pdo->query("SHOW TABLES LIKE 'versions'"); $num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC)); @@ -364,6 +364,12 @@ function init_db_schema() { "password" => "VARCHAR(255) NOT NULL", "created" => "DATETIME(0) NOT NULL DEFAULT NOW(0)", "modified" => "DATETIME ON UPDATE CURRENT_TIMESTAMP", + "imap_access" => "TINYINT(1) NOT NULL DEFAULT '1'", + "smtp_access" => "TINYINT(1) NOT NULL DEFAULT '1'", + "dav_access" => "TINYINT(1) NOT NULL DEFAULT '1'", + "eas_access" => "TINYINT(1) NOT NULL DEFAULT '1'", + "pop3_access" => "TINYINT(1) NOT NULL DEFAULT '1'", + "sieve_access" => "TINYINT(1) NOT NULL DEFAULT '1'", "active" => "TINYINT(1) NOT NULL DEFAULT '1'" ), "keys" => array( @@ -632,6 +638,8 @@ function init_db_schema() { "is_running" => "TINYINT(1) NOT NULL DEFAULT '0'", "returned_text" => "LONGTEXT", "last_run" => "TIMESTAMP NULL DEFAULT NULL", + "success" => "TINYINT(1) UNSIGNED DEFAULT NULL", + "exit_status" => "VARCHAR(50) DEFAULT NULL", "created" => "DATETIME(0) NOT NULL DEFAULT NOW(0)", "modified" => "DATETIME ON UPDATE CURRENT_TIMESTAMP", "active" => "TINYINT(1) NOT NULL DEFAULT '0'" @@ -1210,6 +1218,7 @@ function init_db_schema() { $pdo->query("UPDATE `mailbox` SET `attributes` = JSON_SET(`attributes`, '$.passwd_update', \"0\") WHERE JSON_VALUE(`attributes`, '$.passwd_update') IS NULL;"); $pdo->query("UPDATE `mailbox` SET `attributes` = JSON_SET(`attributes`, '$.relayhost', \"0\") WHERE JSON_VALUE(`attributes`, '$.relayhost') IS NULL;"); $pdo->query("UPDATE `mailbox` SET `attributes` = JSON_SET(`attributes`, '$.force_pw_update', \"0\") WHERE JSON_VALUE(`attributes`, '$.force_pw_update') IS NULL;"); + $pdo->query("UPDATE `mailbox` SET `attributes` = JSON_SET(`attributes`, '$.sieve_access', \"1\") WHERE JSON_VALUE(`attributes`, '$.sieve_access') IS NULL;"); $pdo->query("UPDATE `mailbox` SET `attributes` = JSON_SET(`attributes`, '$.sogo_access', \"1\") WHERE JSON_VALUE(`attributes`, '$.sogo_access') IS NULL;"); $pdo->query("UPDATE `mailbox` SET `attributes` = JSON_SET(`attributes`, '$.imap_access', \"1\") WHERE JSON_VALUE(`attributes`, '$.imap_access') IS NULL;"); $pdo->query("UPDATE `mailbox` SET `attributes` = JSON_SET(`attributes`, '$.pop3_access', \"1\") WHERE JSON_VALUE(`attributes`, '$.pop3_access') IS NULL;"); diff --git a/data/web/inc/lib/composer.json b/data/web/inc/lib/composer.json index e7e6b682..78033ec9 100644 --- a/data/web/inc/lib/composer.json +++ b/data/web/inc/lib/composer.json @@ -9,6 +9,7 @@ "matthiasmullie/minify": "^1.3", "bshaffer/oauth2-server-php": "^1.11", "mustangostang/spyc": "^0.6.3", - "directorytree/ldaprecord": "^2.4" + "directorytree/ldaprecord": "^2.4", + "twig/twig": "^3.0" } } diff --git a/data/web/inc/lib/composer.lock b/data/web/inc/lib/composer.lock index e2633cc0..b1507525 100644 --- a/data/web/inc/lib/composer.lock +++ b/data/web/inc/lib/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "50acd623ff29bb513cd29819f4537aa0", + "content-hash": "139c1e5dec323144cd778ce80fd1847e", "packages": [ { "name": "bshaffer/oauth2-server-php", @@ -62,10 +62,6 @@ "oauth", "oauth2" ], - "support": { - "issues": "https://github.com/bshaffer/oauth2-server-php/issues", - "source": "https://github.com/bshaffer/oauth2-server-php/tree/master" - }, "time": "2018-12-04T00:29:32+00:00" }, { @@ -388,10 +384,6 @@ "paths", "relative" ], - "support": { - "issues": "https://github.com/matthiasmullie/path-converter/issues", - "source": "https://github.com/matthiasmullie/path-converter/tree/1.1.3" - }, "time": "2019-02-05T23:41:09+00:00" }, { @@ -1022,11 +1014,6 @@ "php", "text" ], - "support": { - "email": "support@jevon.org", - "issues": "https://github.com/soundasleep/html2text/issues", - "source": "https://github.com/soundasleep/html2text/tree/master" - }, "time": "2017-04-19T22:01:50+00:00" }, { @@ -1096,6 +1083,85 @@ ], "time": "2021-03-23T23:28:01+00:00" }, + { + "name": "symfony/polyfill-ctype", + "version": "v1.23.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-ctype.git", + "reference": "46cd95797e9df938fdd2b03693b5fca5e64b01ce" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/46cd95797e9df938fdd2b03693b5fca5e64b01ce", + "reference": "46cd95797e9df938fdd2b03693b5fca5e64b01ce", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "suggest": { + "ext-ctype": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.23-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Ctype\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Gert de Pagter", + "email": "BackEndTea@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for ctype functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "ctype", + "polyfill", + "portable" + ], + "support": { + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.23.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-02-19T12:13:01+00:00" + }, { "name": "symfony/polyfill-mbstring", "version": "v1.23.1", @@ -1574,6 +1640,82 @@ }, "time": "2021-03-29T21:29:00+00:00" }, + { + "name": "twig/twig", + "version": "v3.3.2", + "source": { + "type": "git", + "url": "https://github.com/twigphp/Twig.git", + "reference": "21578f00e83d4a82ecfa3d50752b609f13de6790" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/twigphp/Twig/zipball/21578f00e83d4a82ecfa3d50752b609f13de6790", + "reference": "21578f00e83d4a82ecfa3d50752b609f13de6790", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "symfony/polyfill-ctype": "^1.8", + "symfony/polyfill-mbstring": "^1.3" + }, + "require-dev": { + "psr/container": "^1.0", + "symfony/phpunit-bridge": "^4.4.9|^5.0.9" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.3-dev" + } + }, + "autoload": { + "psr-4": { + "Twig\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com", + "homepage": "http://fabien.potencier.org", + "role": "Lead Developer" + }, + { + "name": "Twig Team", + "role": "Contributors" + }, + { + "name": "Armin Ronacher", + "email": "armin.ronacher@active-4.com", + "role": "Project Founder" + } + ], + "description": "Twig, the flexible, fast, and secure template language for PHP", + "homepage": "https://twig.symfony.com", + "keywords": [ + "templating" + ], + "support": { + "issues": "https://github.com/twigphp/Twig/issues", + "source": "https://github.com/twigphp/Twig/tree/v3.3.2" + }, + "funding": [ + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/twig/twig", + "type": "tidelift" + } + ], + "time": "2021-05-16T12:14:13+00:00" + }, { "name": "yubico/u2flib-server", "version": "1.0.2", @@ -1609,10 +1751,6 @@ ], "description": "Library for U2F implementation", "homepage": "https://developers.yubico.com/php-u2flib-server", - "support": { - "issues": "https://github.com/Yubico/php-u2flib-server/issues", - "source": "https://github.com/Yubico/php-u2flib-server/tree/1.0.2" - }, "time": "2018-09-07T08:16:44+00:00" } ], diff --git a/data/web/inc/lib/vendor/composer/autoload_files.php b/data/web/inc/lib/vendor/composer/autoload_files.php index fac18c7f..183b68df 100644 --- a/data/web/inc/lib/vendor/composer/autoload_files.php +++ b/data/web/inc/lib/vendor/composer/autoload_files.php @@ -6,10 +6,11 @@ $vendorDir = dirname(dirname(__FILE__)); $baseDir = dirname($vendorDir); return array( - 'a4a119a56e50fbb293281d9a48007e0e' => $vendorDir . '/symfony/polyfill-php80/bootstrap.php', '0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => $vendorDir . '/symfony/polyfill-mbstring/bootstrap.php', + 'a4a119a56e50fbb293281d9a48007e0e' => $vendorDir . '/symfony/polyfill-php80/bootstrap.php', '6e3fae29631ef280660b3cdad06f25a8' => $vendorDir . '/symfony/deprecation-contracts/function.php', 'a1105708a18b76903365ca1c4aa61b02' => $vendorDir . '/symfony/translation/Resources/functions.php', + '320cde22f66dd4f5d3fd621d3e88b98f' => $vendorDir . '/symfony/polyfill-ctype/bootstrap.php', '667aeda72477189d0494fecd327c3641' => $vendorDir . '/symfony/var-dumper/Resources/functions/dump.php', 'fe62ba7e10580d903cc46d808b5961a4' => $vendorDir . '/tightenco/collect/src/Collect/Support/helpers.php', 'caf31cc6ec7cf2241cb6f12c226c3846' => $vendorDir . '/tightenco/collect/src/Collect/Support/alias.php', diff --git a/data/web/inc/lib/vendor/composer/autoload_psr4.php b/data/web/inc/lib/vendor/composer/autoload_psr4.php index 7c9542ec..6e9d44e1 100644 --- a/data/web/inc/lib/vendor/composer/autoload_psr4.php +++ b/data/web/inc/lib/vendor/composer/autoload_psr4.php @@ -6,9 +6,11 @@ $vendorDir = dirname(dirname(__FILE__)); $baseDir = dirname($vendorDir); return array( + 'Twig\\' => array($vendorDir . '/twig/twig/src'), 'Tightenco\\Collect\\' => array($vendorDir . '/tightenco/collect/src/Collect'), 'Symfony\\Polyfill\\Php80\\' => array($vendorDir . '/symfony/polyfill-php80'), 'Symfony\\Polyfill\\Mbstring\\' => array($vendorDir . '/symfony/polyfill-mbstring'), + 'Symfony\\Polyfill\\Ctype\\' => array($vendorDir . '/symfony/polyfill-ctype'), 'Symfony\\Contracts\\Translation\\' => array($vendorDir . '/symfony/translation-contracts'), 'Symfony\\Component\\VarDumper\\' => array($vendorDir . '/symfony/var-dumper'), 'Symfony\\Component\\Translation\\' => array($vendorDir . '/symfony/translation'), diff --git a/data/web/inc/lib/vendor/composer/autoload_static.php b/data/web/inc/lib/vendor/composer/autoload_static.php index 4d3a5d44..19aadb61 100644 --- a/data/web/inc/lib/vendor/composer/autoload_static.php +++ b/data/web/inc/lib/vendor/composer/autoload_static.php @@ -7,10 +7,11 @@ namespace Composer\Autoload; class ComposerStaticInit873464e4bd965a3168f133248b1b218b { public static $files = array ( - 'a4a119a56e50fbb293281d9a48007e0e' => __DIR__ . '/..' . '/symfony/polyfill-php80/bootstrap.php', '0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/bootstrap.php', + 'a4a119a56e50fbb293281d9a48007e0e' => __DIR__ . '/..' . '/symfony/polyfill-php80/bootstrap.php', '6e3fae29631ef280660b3cdad06f25a8' => __DIR__ . '/..' . '/symfony/deprecation-contracts/function.php', 'a1105708a18b76903365ca1c4aa61b02' => __DIR__ . '/..' . '/symfony/translation/Resources/functions.php', + '320cde22f66dd4f5d3fd621d3e88b98f' => __DIR__ . '/..' . '/symfony/polyfill-ctype/bootstrap.php', '667aeda72477189d0494fecd327c3641' => __DIR__ . '/..' . '/symfony/var-dumper/Resources/functions/dump.php', 'fe62ba7e10580d903cc46d808b5961a4' => __DIR__ . '/..' . '/tightenco/collect/src/Collect/Support/helpers.php', 'caf31cc6ec7cf2241cb6f12c226c3846' => __DIR__ . '/..' . '/tightenco/collect/src/Collect/Support/alias.php', @@ -20,12 +21,14 @@ class ComposerStaticInit873464e4bd965a3168f133248b1b218b public static $prefixLengthsPsr4 = array ( 'T' => array ( + 'Twig\\' => 5, 'Tightenco\\Collect\\' => 18, ), 'S' => array ( 'Symfony\\Polyfill\\Php80\\' => 23, 'Symfony\\Polyfill\\Mbstring\\' => 26, + 'Symfony\\Polyfill\\Ctype\\' => 23, 'Symfony\\Contracts\\Translation\\' => 30, 'Symfony\\Component\\VarDumper\\' => 28, 'Symfony\\Component\\Translation\\' => 30, @@ -70,6 +73,10 @@ class ComposerStaticInit873464e4bd965a3168f133248b1b218b ); public static $prefixDirsPsr4 = array ( + 'Twig\\' => + array ( + 0 => __DIR__ . '/..' . '/twig/twig/src', + ), 'Tightenco\\Collect\\' => array ( 0 => __DIR__ . '/..' . '/tightenco/collect/src/Collect', @@ -82,6 +89,10 @@ class ComposerStaticInit873464e4bd965a3168f133248b1b218b array ( 0 => __DIR__ . '/..' . '/symfony/polyfill-mbstring', ), + 'Symfony\\Polyfill\\Ctype\\' => + array ( + 0 => __DIR__ . '/..' . '/symfony/polyfill-ctype', + ), 'Symfony\\Contracts\\Translation\\' => array ( 0 => __DIR__ . '/..' . '/symfony/translation-contracts', diff --git a/data/web/inc/lib/vendor/composer/installed.json b/data/web/inc/lib/vendor/composer/installed.json index 1ff198c8..c5247040 100644 --- a/data/web/inc/lib/vendor/composer/installed.json +++ b/data/web/inc/lib/vendor/composer/installed.json @@ -1128,6 +1128,88 @@ ], "install-path": "../symfony/deprecation-contracts" }, + { + "name": "symfony/polyfill-ctype", + "version": "v1.23.0", + "version_normalized": "1.23.0.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-ctype.git", + "reference": "46cd95797e9df938fdd2b03693b5fca5e64b01ce" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/46cd95797e9df938fdd2b03693b5fca5e64b01ce", + "reference": "46cd95797e9df938fdd2b03693b5fca5e64b01ce", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "suggest": { + "ext-ctype": "For best performance" + }, + "time": "2021-02-19T12:13:01+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.23-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Ctype\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Gert de Pagter", + "email": "BackEndTea@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for ctype functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "ctype", + "polyfill", + "portable" + ], + "support": { + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.23.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "install-path": "../symfony/polyfill-ctype" + }, { "name": "symfony/polyfill-mbstring", "version": "v1.23.1", @@ -1624,6 +1706,85 @@ }, "install-path": "../tightenco/collect" }, + { + "name": "twig/twig", + "version": "v3.3.2", + "version_normalized": "3.3.2.0", + "source": { + "type": "git", + "url": "https://github.com/twigphp/Twig.git", + "reference": "21578f00e83d4a82ecfa3d50752b609f13de6790" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/twigphp/Twig/zipball/21578f00e83d4a82ecfa3d50752b609f13de6790", + "reference": "21578f00e83d4a82ecfa3d50752b609f13de6790", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "symfony/polyfill-ctype": "^1.8", + "symfony/polyfill-mbstring": "^1.3" + }, + "require-dev": { + "psr/container": "^1.0", + "symfony/phpunit-bridge": "^4.4.9|^5.0.9" + }, + "time": "2021-05-16T12:14:13+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.3-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Twig\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com", + "homepage": "http://fabien.potencier.org", + "role": "Lead Developer" + }, + { + "name": "Twig Team", + "role": "Contributors" + }, + { + "name": "Armin Ronacher", + "email": "armin.ronacher@active-4.com", + "role": "Project Founder" + } + ], + "description": "Twig, the flexible, fast, and secure template language for PHP", + "homepage": "https://twig.symfony.com", + "keywords": [ + "templating" + ], + "support": { + "issues": "https://github.com/twigphp/Twig/issues", + "source": "https://github.com/twigphp/Twig/tree/v3.3.2" + }, + "funding": [ + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/twig/twig", + "type": "tidelift" + } + ], + "install-path": "../twig/twig" + }, { "name": "yubico/u2flib-server", "version": "1.0.2", diff --git a/data/web/inc/lib/vendor/composer/installed.php b/data/web/inc/lib/vendor/composer/installed.php index 2e6adce4..cc343e04 100644 --- a/data/web/inc/lib/vendor/composer/installed.php +++ b/data/web/inc/lib/vendor/composer/installed.php @@ -1,22 +1,22 @@ array( - 'pretty_version' => '1.0.0+no-version-set', - 'version' => '1.0.0.0', + 'pretty_version' => 'dev-master', + 'version' => 'dev-master', 'type' => 'library', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), - 'reference' => NULL, + 'reference' => '1c2923a4ddd7f89b3cf38c9594db289b7dd756d3', 'name' => '__root__', 'dev' => true, ), 'versions' => array( '__root__' => array( - 'pretty_version' => '1.0.0+no-version-set', - 'version' => '1.0.0.0', + 'pretty_version' => 'dev-master', + 'version' => 'dev-master', 'type' => 'library', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), - 'reference' => NULL, + 'reference' => '1c2923a4ddd7f89b3cf38c9594db289b7dd756d3', 'dev_requirement' => false, ), 'bshaffer/oauth2-server-php' => array( @@ -184,6 +184,15 @@ 'reference' => '5f38c8804a9e97d23e0c8d63341088cd8a22d627', 'dev_requirement' => false, ), + 'symfony/polyfill-ctype' => array( + 'pretty_version' => 'v1.23.0', + 'version' => '1.23.0.0', + 'type' => 'library', + 'install_path' => __DIR__ . '/../symfony/polyfill-ctype', + 'aliases' => array(), + 'reference' => '46cd95797e9df938fdd2b03693b5fca5e64b01ce', + 'dev_requirement' => false, + ), 'symfony/polyfill-mbstring' => array( 'pretty_version' => 'v1.23.1', 'version' => '1.23.1.0', @@ -244,6 +253,15 @@ 'reference' => 'b069783ab0c547bb894ebcf8e7f6024bb401f9d2', 'dev_requirement' => false, ), + 'twig/twig' => array( + 'pretty_version' => 'v3.3.2', + 'version' => '3.3.2.0', + 'type' => 'library', + 'install_path' => __DIR__ . '/../twig/twig', + 'aliases' => array(), + 'reference' => '21578f00e83d4a82ecfa3d50752b609f13de6790', + 'dev_requirement' => false, + ), 'yubico/u2flib-server' => array( 'pretty_version' => '1.0.2', 'version' => '1.0.2.0', diff --git a/data/web/inc/lib/vendor/symfony/polyfill-ctype/Ctype.php b/data/web/inc/lib/vendor/symfony/polyfill-ctype/Ctype.php new file mode 100644 index 00000000..58414dc7 --- /dev/null +++ b/data/web/inc/lib/vendor/symfony/polyfill-ctype/Ctype.php @@ -0,0 +1,227 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Polyfill\Ctype; + +/** + * Ctype implementation through regex. + * + * @internal + * + * @author Gert de Pagter + */ +final class Ctype +{ + /** + * Returns TRUE if every character in text is either a letter or a digit, FALSE otherwise. + * + * @see https://php.net/ctype-alnum + * + * @param string|int $text + * + * @return bool + */ + public static function ctype_alnum($text) + { + $text = self::convert_int_to_char_for_ctype($text); + + return \is_string($text) && '' !== $text && !preg_match('/[^A-Za-z0-9]/', $text); + } + + /** + * Returns TRUE if every character in text is a letter, FALSE otherwise. + * + * @see https://php.net/ctype-alpha + * + * @param string|int $text + * + * @return bool + */ + public static function ctype_alpha($text) + { + $text = self::convert_int_to_char_for_ctype($text); + + return \is_string($text) && '' !== $text && !preg_match('/[^A-Za-z]/', $text); + } + + /** + * Returns TRUE if every character in text is a control character from the current locale, FALSE otherwise. + * + * @see https://php.net/ctype-cntrl + * + * @param string|int $text + * + * @return bool + */ + public static function ctype_cntrl($text) + { + $text = self::convert_int_to_char_for_ctype($text); + + return \is_string($text) && '' !== $text && !preg_match('/[^\x00-\x1f\x7f]/', $text); + } + + /** + * Returns TRUE if every character in the string text is a decimal digit, FALSE otherwise. + * + * @see https://php.net/ctype-digit + * + * @param string|int $text + * + * @return bool + */ + public static function ctype_digit($text) + { + $text = self::convert_int_to_char_for_ctype($text); + + return \is_string($text) && '' !== $text && !preg_match('/[^0-9]/', $text); + } + + /** + * Returns TRUE if every character in text is printable and actually creates visible output (no white space), FALSE otherwise. + * + * @see https://php.net/ctype-graph + * + * @param string|int $text + * + * @return bool + */ + public static function ctype_graph($text) + { + $text = self::convert_int_to_char_for_ctype($text); + + return \is_string($text) && '' !== $text && !preg_match('/[^!-~]/', $text); + } + + /** + * Returns TRUE if every character in text is a lowercase letter. + * + * @see https://php.net/ctype-lower + * + * @param string|int $text + * + * @return bool + */ + public static function ctype_lower($text) + { + $text = self::convert_int_to_char_for_ctype($text); + + return \is_string($text) && '' !== $text && !preg_match('/[^a-z]/', $text); + } + + /** + * Returns TRUE if every character in text will actually create output (including blanks). Returns FALSE if text contains control characters or characters that do not have any output or control function at all. + * + * @see https://php.net/ctype-print + * + * @param string|int $text + * + * @return bool + */ + public static function ctype_print($text) + { + $text = self::convert_int_to_char_for_ctype($text); + + return \is_string($text) && '' !== $text && !preg_match('/[^ -~]/', $text); + } + + /** + * Returns TRUE if every character in text is printable, but neither letter, digit or blank, FALSE otherwise. + * + * @see https://php.net/ctype-punct + * + * @param string|int $text + * + * @return bool + */ + public static function ctype_punct($text) + { + $text = self::convert_int_to_char_for_ctype($text); + + return \is_string($text) && '' !== $text && !preg_match('/[^!-\/\:-@\[-`\{-~]/', $text); + } + + /** + * Returns TRUE if every character in text creates some sort of white space, FALSE otherwise. Besides the blank character this also includes tab, vertical tab, line feed, carriage return and form feed characters. + * + * @see https://php.net/ctype-space + * + * @param string|int $text + * + * @return bool + */ + public static function ctype_space($text) + { + $text = self::convert_int_to_char_for_ctype($text); + + return \is_string($text) && '' !== $text && !preg_match('/[^\s]/', $text); + } + + /** + * Returns TRUE if every character in text is an uppercase letter. + * + * @see https://php.net/ctype-upper + * + * @param string|int $text + * + * @return bool + */ + public static function ctype_upper($text) + { + $text = self::convert_int_to_char_for_ctype($text); + + return \is_string($text) && '' !== $text && !preg_match('/[^A-Z]/', $text); + } + + /** + * Returns TRUE if every character in text is a hexadecimal 'digit', that is a decimal digit or a character from [A-Fa-f] , FALSE otherwise. + * + * @see https://php.net/ctype-xdigit + * + * @param string|int $text + * + * @return bool + */ + public static function ctype_xdigit($text) + { + $text = self::convert_int_to_char_for_ctype($text); + + return \is_string($text) && '' !== $text && !preg_match('/[^A-Fa-f0-9]/', $text); + } + + /** + * Converts integers to their char versions according to normal ctype behaviour, if needed. + * + * If an integer between -128 and 255 inclusive is provided, + * it is interpreted as the ASCII value of a single character + * (negative values have 256 added in order to allow characters in the Extended ASCII range). + * Any other integer is interpreted as a string containing the decimal digits of the integer. + * + * @param string|int $int + * + * @return mixed + */ + private static function convert_int_to_char_for_ctype($int) + { + if (!\is_int($int)) { + return $int; + } + + if ($int < -128 || $int > 255) { + return (string) $int; + } + + if ($int < 0) { + $int += 256; + } + + return \chr($int); + } +} diff --git a/data/web/inc/lib/vendor/symfony/polyfill-ctype/LICENSE b/data/web/inc/lib/vendor/symfony/polyfill-ctype/LICENSE new file mode 100644 index 00000000..3f853aaf --- /dev/null +++ b/data/web/inc/lib/vendor/symfony/polyfill-ctype/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2018-2019 Fabien Potencier + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/data/web/inc/lib/vendor/symfony/polyfill-ctype/README.md b/data/web/inc/lib/vendor/symfony/polyfill-ctype/README.md new file mode 100644 index 00000000..8add1ab0 --- /dev/null +++ b/data/web/inc/lib/vendor/symfony/polyfill-ctype/README.md @@ -0,0 +1,12 @@ +Symfony Polyfill / Ctype +======================== + +This component provides `ctype_*` functions to users who run php versions without the ctype extension. + +More information can be found in the +[main Polyfill README](https://github.com/symfony/polyfill/blob/master/README.md). + +License +======= + +This library is released under the [MIT license](LICENSE). diff --git a/data/web/inc/lib/vendor/symfony/polyfill-ctype/bootstrap.php b/data/web/inc/lib/vendor/symfony/polyfill-ctype/bootstrap.php new file mode 100644 index 00000000..d54524b3 --- /dev/null +++ b/data/web/inc/lib/vendor/symfony/polyfill-ctype/bootstrap.php @@ -0,0 +1,50 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +use Symfony\Polyfill\Ctype as p; + +if (\PHP_VERSION_ID >= 80000) { + return require __DIR__.'/bootstrap80.php'; +} + +if (!function_exists('ctype_alnum')) { + function ctype_alnum($text) { return p\Ctype::ctype_alnum($text); } +} +if (!function_exists('ctype_alpha')) { + function ctype_alpha($text) { return p\Ctype::ctype_alpha($text); } +} +if (!function_exists('ctype_cntrl')) { + function ctype_cntrl($text) { return p\Ctype::ctype_cntrl($text); } +} +if (!function_exists('ctype_digit')) { + function ctype_digit($text) { return p\Ctype::ctype_digit($text); } +} +if (!function_exists('ctype_graph')) { + function ctype_graph($text) { return p\Ctype::ctype_graph($text); } +} +if (!function_exists('ctype_lower')) { + function ctype_lower($text) { return p\Ctype::ctype_lower($text); } +} +if (!function_exists('ctype_print')) { + function ctype_print($text) { return p\Ctype::ctype_print($text); } +} +if (!function_exists('ctype_punct')) { + function ctype_punct($text) { return p\Ctype::ctype_punct($text); } +} +if (!function_exists('ctype_space')) { + function ctype_space($text) { return p\Ctype::ctype_space($text); } +} +if (!function_exists('ctype_upper')) { + function ctype_upper($text) { return p\Ctype::ctype_upper($text); } +} +if (!function_exists('ctype_xdigit')) { + function ctype_xdigit($text) { return p\Ctype::ctype_xdigit($text); } +} diff --git a/data/web/inc/lib/vendor/symfony/polyfill-ctype/bootstrap80.php b/data/web/inc/lib/vendor/symfony/polyfill-ctype/bootstrap80.php new file mode 100644 index 00000000..ab2f8611 --- /dev/null +++ b/data/web/inc/lib/vendor/symfony/polyfill-ctype/bootstrap80.php @@ -0,0 +1,46 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +use Symfony\Polyfill\Ctype as p; + +if (!function_exists('ctype_alnum')) { + function ctype_alnum(mixed $text): bool { return p\Ctype::ctype_alnum($text); } +} +if (!function_exists('ctype_alpha')) { + function ctype_alpha(mixed $text): bool { return p\Ctype::ctype_alpha($text); } +} +if (!function_exists('ctype_cntrl')) { + function ctype_cntrl(mixed $text): bool { return p\Ctype::ctype_cntrl($text); } +} +if (!function_exists('ctype_digit')) { + function ctype_digit(mixed $text): bool { return p\Ctype::ctype_digit($text); } +} +if (!function_exists('ctype_graph')) { + function ctype_graph(mixed $text): bool { return p\Ctype::ctype_graph($text); } +} +if (!function_exists('ctype_lower')) { + function ctype_lower(mixed $text): bool { return p\Ctype::ctype_lower($text); } +} +if (!function_exists('ctype_print')) { + function ctype_print(mixed $text): bool { return p\Ctype::ctype_print($text); } +} +if (!function_exists('ctype_punct')) { + function ctype_punct(mixed $text): bool { return p\Ctype::ctype_punct($text); } +} +if (!function_exists('ctype_space')) { + function ctype_space(mixed $text): bool { return p\Ctype::ctype_space($text); } +} +if (!function_exists('ctype_upper')) { + function ctype_upper(mixed $text): bool { return p\Ctype::ctype_upper($text); } +} +if (!function_exists('ctype_xdigit')) { + function ctype_xdigit(mixed $text): bool { return p\Ctype::ctype_xdigit($text); } +} diff --git a/data/web/inc/lib/vendor/symfony/polyfill-ctype/composer.json b/data/web/inc/lib/vendor/symfony/polyfill-ctype/composer.json new file mode 100644 index 00000000..f0621a3b --- /dev/null +++ b/data/web/inc/lib/vendor/symfony/polyfill-ctype/composer.json @@ -0,0 +1,38 @@ +{ + "name": "symfony/polyfill-ctype", + "type": "library", + "description": "Symfony polyfill for ctype functions", + "keywords": ["polyfill", "compatibility", "portable", "ctype"], + "homepage": "https://symfony.com", + "license": "MIT", + "authors": [ + { + "name": "Gert de Pagter", + "email": "BackEndTea@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "require": { + "php": ">=7.1" + }, + "autoload": { + "psr-4": { "Symfony\\Polyfill\\Ctype\\": "" }, + "files": [ "bootstrap.php" ] + }, + "suggest": { + "ext-ctype": "For best performance" + }, + "minimum-stability": "dev", + "extra": { + "branch-alias": { + "dev-main": "1.23-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/.editorconfig b/data/web/inc/lib/vendor/twig/twig/.editorconfig new file mode 100644 index 00000000..270f1d1b --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/.editorconfig @@ -0,0 +1,18 @@ +; top-most EditorConfig file +root = true + +; Unix-style newlines +[*] +end_of_line = LF + +[*.php] +indent_style = space +indent_size = 4 + +[*.test] +indent_style = space +indent_size = 4 + +[*.rst] +indent_style = space +indent_size = 4 diff --git a/data/web/inc/lib/vendor/twig/twig/.gitattributes b/data/web/inc/lib/vendor/twig/twig/.gitattributes new file mode 100644 index 00000000..75e18f85 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/.gitattributes @@ -0,0 +1,3 @@ +/extra/** export-ignore +/tests export-ignore +/phpunit.xml.dist export-ignore diff --git a/data/web/inc/lib/vendor/twig/twig/.github/workflows/ci.yml b/data/web/inc/lib/vendor/twig/twig/.github/workflows/ci.yml new file mode 100644 index 00000000..dfc40c30 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/.github/workflows/ci.yml @@ -0,0 +1,173 @@ +name: "CI" + +on: + pull_request: + push: + branches: + - '3.x' + +env: + SYMFONY_PHPUNIT_DISABLE_RESULT_CACHE: 1 + +jobs: + tests: + name: "PHP ${{ matrix.php-version }}" + + runs-on: 'ubuntu-latest' + + continue-on-error: ${{ matrix.experimental }} + + strategy: + matrix: + php-version: + - '7.2.5' + - '7.3' + - '7.4' + - '8.0' + composer-options: [''] + experimental: [false] + include: + - { php-version: '8.1', experimental: true, composer-options: '--ignore-platform-req=php' } + + steps: + - name: "Checkout code" + uses: actions/checkout@v2.3.3 + + - name: "Install PHP with extensions" + uses: shivammathur/setup-php@2.7.0 + with: + coverage: "none" + php-version: ${{ matrix.php-version }} + ini-values: memory_limit=-1 + tools: composer:v2 + + - name: "Add PHPUnit matcher" + run: echo "::add-matcher::${{ runner.tool_cache }}/phpunit.json" + + - name: "Set composer cache directory" + id: composer-cache + run: echo "::set-output name=dir::$(composer config cache-files-dir)" + + - name: "Cache composer" + uses: actions/cache@v2.1.2 + with: + path: ${{ steps.composer-cache.outputs.dir }} + key: ${{ runner.os }}-${{ matrix.php-version }}-composer-${{ hashFiles('composer.json') }} + restore-keys: ${{ runner.os }}-${{ matrix.php-version }}-composer- + + - run: composer install ${{ matrix.composer-options }} + + - name: "Install PHPUnit" + run: vendor/bin/simple-phpunit install + + - name: "PHPUnit version" + run: vendor/bin/simple-phpunit --version + + - name: "Run tests" + run: vendor/bin/simple-phpunit + + extension-tests: + needs: + - 'tests' + + name: "${{ matrix.extension }} with PHP ${{ matrix.php-version }}" + + runs-on: 'ubuntu-latest' + + continue-on-error: true + + strategy: + matrix: + php-version: + - '7.2.5' + - '7.3' + - '7.4' + - '8.0' + extension: + - 'extra/cache-extra' + - 'extra/cssinliner-extra' + - 'extra/html-extra' + - 'extra/inky-extra' + - 'extra/intl-extra' + - 'extra/markdown-extra' + - 'extra/string-extra' + - 'extra/twig-extra-bundle' + + steps: + - name: "Checkout code" + uses: actions/checkout@v2.3.3 + + - name: "Install PHP with extensions" + uses: shivammathur/setup-php@2.7.0 + with: + coverage: "none" + php-version: ${{ matrix.php-version }} + ini-values: memory_limit=-1 + tools: composer:v2 + + - name: "Add PHPUnit matcher" + run: echo "::add-matcher::${{ runner.tool_cache }}/phpunit.json" + + - name: "Set composer cache directory" + id: composer-cache + run: echo "::set-output name=dir::$(composer config cache-files-dir)" + + - name: "Cache composer" + uses: actions/cache@v2.1.2 + with: + path: ${{ steps.composer-cache.outputs.dir }} + key: ${{ runner.os }}-${{ matrix.php-version }}-${{ matrix.extension }}-${{ hashFiles('composer.json') }} + restore-keys: ${{ runner.os }}-${{ matrix.php-version }}-${{ matrix.extension }}- + + - run: composer install + + - name: "Install PHPUnit" + run: vendor/bin/simple-phpunit install + + - name: "PHPUnit version" + run: vendor/bin/simple-phpunit --version + + - if: matrix.extension == 'extra/markdown-extra' && matrix.php-version == '8.0' + working-directory: ${{ matrix.extension}} + run: composer config platform.php 7.4.99 + + - name: "Composer install" + working-directory: ${{ matrix.extension}} + run: composer install + + - name: "Run tests" + working-directory: ${{ matrix.extension}} + run: ../../vendor/bin/simple-phpunit +# +# Drupal does not support Twig 3 now! +# +# integration-tests: +# needs: +# - 'tests' +# +# name: "Integration tests with PHP ${{ matrix.php-version }}" +# +# runs-on: 'ubuntu-20.04' +# +# continue-on-error: true +# +# strategy: +# matrix: +# php-version: +# - '7.3' +# +# steps: +# - name: "Checkout code" +# uses: actions/checkout@v2.3.3 +# +# - name: "Install PHP with extensions" +# uses: shivammathur/setup-php@2.7.0 +# with: +# coverage: "none" +# extensions: "gd, pdo_sqlite" +# php-version: ${{ matrix.php-version }} +# ini-values: memory_limit=-1 +# tools: composer:v2 +# +# - run: ./drupal_test.sh +# shell: "bash" diff --git a/data/web/inc/lib/vendor/twig/twig/.github/workflows/documentation.yml b/data/web/inc/lib/vendor/twig/twig/.github/workflows/documentation.yml new file mode 100644 index 00000000..0b3ca715 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/.github/workflows/documentation.yml @@ -0,0 +1,60 @@ +name: "Documentation" + +on: + pull_request: + push: + branches: + - '3.x' + +jobs: + build: + name: "Build" + + runs-on: ubuntu-latest + + steps: + - name: "Checkout code" + uses: actions/checkout@v2 + + - name: "Set up Python 3.7" + uses: actions/setup-python@v1 + with: + python-version: '3.7' # Semantic version range syntax or exact version of a Python version + + - name: "Display Python version" + run: python -c "import sys; print(sys.version)" + + - name: "Install Sphinx dependencies" + run: sudo apt-get install python-dev build-essential + + - name: "Cache pip" + uses: actions/cache@v2 + with: + path: ~/.cache/pip + key: ${{ runner.os }}-pip-${{ hashFiles('_build/.requirements.txt') }} + restore-keys: | + ${{ runner.os }}-pip- + + - name: "Install Sphinx + requirements via pip" + working-directory: "doc" + run: pip install -r _build/.requirements.txt + + - name: "Build documentation" + working-directory: "doc" + run: make -C _build SPHINXOPTS="-nqW -j auto" html + + doctor-rst: + name: "DOCtor-RST" + + runs-on: ubuntu-latest + + steps: + - name: "Checkout code" + uses: actions/checkout@v2 + + - name: "Run DOCtor-RST" + uses: docker://oskarstark/doctor-rst + with: + args: --short + env: + DOCS_DIR: 'doc/' diff --git a/data/web/inc/lib/vendor/twig/twig/.gitignore b/data/web/inc/lib/vendor/twig/twig/.gitignore new file mode 100644 index 00000000..cd52aeac --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/.gitignore @@ -0,0 +1,4 @@ +/composer.lock +/phpunit.xml +/vendor +.phpunit.result.cache diff --git a/data/web/inc/lib/vendor/twig/twig/.php-cs-fixer.dist.php b/data/web/inc/lib/vendor/twig/twig/.php-cs-fixer.dist.php new file mode 100644 index 00000000..b07ac7fc --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/.php-cs-fixer.dist.php @@ -0,0 +1,20 @@ +setRules([ + '@Symfony' => true, + '@Symfony:risky' => true, + '@PHPUnit75Migration:risky' => true, + 'php_unit_dedicate_assert' => ['target' => '5.6'], + 'array_syntax' => ['syntax' => 'short'], + 'php_unit_fqcn_annotation' => true, + 'no_unreachable_default_argument_value' => false, + 'braces' => ['allow_single_line_closure' => true], + 'heredoc_to_nowdoc' => false, + 'ordered_imports' => true, + 'phpdoc_types_order' => ['null_adjustment' => 'always_last', 'sort_algorithm' => 'none'], + 'native_function_invocation' => ['include' => ['@compiler_optimized'], 'scope' => 'all'], + ]) + ->setRiskyAllowed(true) + ->setFinder((new PhpCsFixer\Finder())->in(__DIR__)) +; diff --git a/data/web/inc/lib/vendor/twig/twig/CHANGELOG b/data/web/inc/lib/vendor/twig/twig/CHANGELOG new file mode 100644 index 00000000..832e639d --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/CHANGELOG @@ -0,0 +1,1621 @@ +# 3.3.2 (2021-05-16) + + * Revert "Throw a proper exception when a template name is an absolute path (as it has never been supported)" + +# 3.3.1 (2021-05-12) + + * Fix PHP 8.1 compatibility + * Throw a proper exception when a template name is an absolute path (as it has never been supported) + +# 3.3.0 (2021-02-08) + + * Fix macro calls in a "cache" tag + * Add the slug filter + * Allow extra bundle to be compatible with Twig 2 + +# 3.2.1 (2021-01-05) + + * Fix extra bundle compat with older versions of Symfony + +# 3.2.0 (2021-01-05) + + * Add the Cache extension in the "extra" repositories: "cache" tag + * Add "registerUndefinedTokenParserCallback" + * Mark built-in node visitors as @internal + * Fix "odd" not working for negative numbers + +# 3.1.1 (2020-10-27) + + * Fix "include(template_from_string())" + +# 3.1.0 (2020-10-21) + + * Fix sandbox support when using "include(template_from_string())" + * Make round brackets optional for one argument tests like "same as" or "divisible by" + * Add support for ES2015 style object initialisation shortcut { a } is the same as { 'a': a } + +# 3.0.5 (2020-08-05) + + * Fix twig_compare w.r.t. whitespace trimming + * Fix sandbox not disabled if syntax error occurs within {% sandbox %} tag + * Fix a regression when not using a space before an operator + * Restrict callables to closures in filters + * Allow trailing commas in argument lists (in calls as well as definitions) + +# 3.0.4 (2020-07-05) + + * Fix comparison operators + * Fix options not taken into account when using "Michelf\MarkdownExtra" + * Fix "Twig\Extra\Intl\IntlExtension::getCountryName()" to accept "null" as a first argument + * Throw exception in case non-Traversable data is passed to "filter" + * Fix context optimization on PHP 7.4 + * Fix PHP 8 compatibility + * Fix ambiguous syntax parsing + +# 3.0.3 (2020-02-11) + + * Add a check to ensure that iconv() is defined + +# 3.0.2 (2020-02-11) + + * Avoid exceptions when an intl resource is not found + * Fix implementation of case-insensitivity for method names + +# 3.0.1 (2019-12-28) + + * fixed Symfony 5.0 support for the HTML extra extension + +# 3.0.0 (2019-11-15) + + * fixed number formatter in Intl extra extension when using a formatter prototype + +# 3.0.0-BETA1 (2019-11-11) + + * removed the "if" condition support on the "for" tag + * made the in, <, >, <=, >=, ==, and != operators more strict when comparing strings and integers/floats + * removed the "filter" tag + * added type hints everywhere + * changed Environment::resolveTemplate() to always return a TemplateWrapper instance + * removed Template::__toString() + * removed Parser::isReservedMacroName() + * removed SanboxedPrintNode + * removed Node::setTemplateName() + * made classes maked as "@final" final + * removed InitRuntimeInterface, ExistsLoaderInterface, and SourceContextLoaderInterface + * removed the "spaceless" tag + * removed Twig\Environment::getBaseTemplateClass() and Twig\Environment::setBaseTemplateClass() + * removed the "base_template_class" option on Twig\Environment + * bumped minimum PHP version to 7.2 + * removed PSR-0 classes + +# 2.14.6 (2021-XX-XX) + + * Revert "Throw a proper exception when a template name is an absolute path (as it has never been supported)" + +# 2.14.5 (2021-05-12) + + * Fix PHP 8.1 compatibility + * Throw a proper exception when a template name is an absolute path (as it has never been supported) + +# 2.14.4 (2021-03-10) + + * Add the slug filter + +# 2.14.3 (2021-01-05) + + * Fix extra bundle compat with older versions of Symfony + +# 2.14.2 (2021-01-05) + + * Fix "odd" not working for negative numbers + +# 2.14.1 (2020-10-27) + +* Fix "include(template_from_string())" + +# 2.14.0 (2020-10-21) + + * Fix sandbox support when using "include(template_from_string())" + * Make round brackets optional for one argument tests like "same as" or "divisible by" + * Add support for ES2015 style object initialisation shortcut { a } is the same as { 'a': a } + * Drop PHP 7.1 support + +# 2.13.1 (2020-08-05) + + * Fix sandbox not disabled if syntax error occurs within {% sandbox %} tag + * Fix a regression when not using a space before an operator + * Restrict callables to closures in filters + * Allow trailing commas in argument lists (in calls as well as definitions) + +# 2.13.0 (2020-07-05) + + * Fix options not taken into account when using "Michelf\MarkdownExtra" + * Fix "Twig\Extra\Intl\IntlExtension::getCountryName()" to accept "null" as a first argument + * Drop support for PHP 7.0 + * Throw exception in case non-Traversable data is passed to "filter" + * Fix context optimization on PHP 7.4 + * Fix PHP 8 compatibility + * Fix ambiguous syntax parsing + +# 2.12.5 (2020-02-11) + + * Add a check to ensure that iconv() is defined + +# 2.12.4 (2020-02-11) + + * Avoid exceptions when an intl resource is not found + * Fix implementation of case-insensitivity for method names + +# 2.12.3 (2019-12-28) + + * fixed Symfony 5.0 support for the HTML extra extension + * fixed number formatter in Intl extra extension when using a formatter prototype + +# 2.12.2 (2019-11-11) + + * added supported for exponential numbers + +# 2.12.1 (2019-10-17) + + * added the String extension in the "extra" repositories: "u" filter + +# 2.12.0 (2019-10-05) + + * added the spaceship operator ("<=>"), useful when using an arrow function in the "sort" filter + * added support for an "arrow" function on the "sort" filter + * added the CssInliner extension in the "extra" repositories: "inline_css" + filter + * added the Inky extension in the "extra" repositories: "inky_to_html" filter + * added Intl extension in the "extra" repositories: "country_name", + "currency_name", "currency_symbol", "language_name", "locale_name", + "timezone_name", "format_currency", "format_number", + "format_*_number", "format_datetime", "format_date", and "format_time" + filters, and the "country_timezones" function + * added the Markdown extension in the "extra" repositories: "markdown_to_html", + and "html_to_markdown" filters + * added the HtmlExtension extension in the "extra" repositories: "date_uri" + filter, and "html_classes" function + * optimized "block('foo') ?? 'bar'" + * fixed the empty test on Traversable instances + * fixed array_key_exists() on objects + * fixed cache when opcache is installed but disabled + * fixed using macros in arrow functions + * fixed split filter on edge case + +# 2.11.3 (2019-06-18) + + * display partial output (PHP buffer) when an error occurs in debug mode + * fixed the filter filter (allow the result to be used several times) + * fixed macro auto-import when a template contains only macros + +# 2.11.2 (2019-06-05) + + * fixed macro auto-import + +# 2.11.1 (2019-06-04) + + * added support for "Twig\Markup" instances in the "in" test (again) + * allowed string operators as variables names in assignments + * fixed support for macros defined in parent templates + +# 2.11.0 (2019-05-31) + + * added the possibility to register classes/interfaces as being safe for the escaper ("EscaperExtension::addSafeClass()") + * deprecated CoreExtension::setEscaper() and CoreExtension::getEscapers() in favor of the same methods on EscaperExtension + * macros are now auto-imported in the template they are defined (under the ``_self`` variable) + * added support for macros on "is defined" tests + * fixed macros "import" when using the same name in the parent and child templates + * fixed recursive macros + * macros imported "globally" in a template are now available in macros without re-importing them + * fixed the "filter" filter when the argument is \Traversable but does not implement \Iterator (\SimpleXmlElement for instance) + * fixed a PHP fatal error when calling a macro imported in a block in a nested block + * fixed a PHP fatal error when calling a macro imported in the template in another macro + * fixed wrong error message on "import" and "from" + +# 2.10.0 (2019-05-14) + + * deprecated "if" conditions on "for" tags + * added "filter", "map", and "reduce" filters (and support for arrow functions) + * fixed partial output leak when a PHP fatal error occurs + * optimized context access on PHP 7.4 + +# 2.9.0 (2019-04-28) + + * deprecated returning "false" to remove a Node from NodeVisitorInterface::leaveNode() + * allowed Twig\NodeVisitor\NodeVisitorInterface::leaveNode() to return "null" instead of "false" (same meaning) + * deprecated the "filter" tag (use the "apply" tag instead) + * added the "apply" tag as a replacement for the "filter" tag + * allowed Twig\Loader\FilesystemLoader::findTemplate() to return "null" instead of "false" (same meaning) + * added support for "Twig\Markup" instances in the "in" test + * fixed "import" when macros are stored in a template string + * fixed Lexer when using custom options containing the # char + * added template line number to twig_get_attribute() + +# 2.8.1 (2019-04-16) + + * fixed EscaperNodeVisitor + * deprecated passing a 3rd, 4th, and 5th arguments to the Sandbox exception classes + * deprecated Node::setTemplateName() in favor of Node::setSourceContext() + +# 2.8.0 (2019-04-16) + + * added Traversable support for the length filter + * fixed some wrong location in error messages + * made exception creation faster + * made escaping on ternary expressions (?: and ??) more fine-grained + * added the possibility to give a nice name to string templates (template_from_string function) + * fixed the "with" behavior to always include the globals (for consistency with the "include" and "embed" tags) + * fixed "include" with "ignore missing" when an error loading occurs in the included template + * added support for a new whitespace trimming option ({%~ ~%}, {{~ ~}}, {#~ ~#}) + * added the "column" filter + +# 2.7.4 (2019-03-23) + + * fixed variadic support + * fixed CheckToStringNode implementation (broken when a function/filter is variadic) + +# 2.7.3 (2019-03-21) + + * fixed the spaceless filter so that it behaves like the spaceless tag + * fixed BC break on Environment::resolveTemplate() + * allowed Traversable objects to be used in the "with" tag + * allowed Traversable objects to be used in the "with" tag + * allowed Traversable objects to be used in the "with" argument of the "include" and "embed" tags + +# 2.7.2 (2019-03-12) + + * added TemplateWrapper::getTemplateName() + +# 2.7.1 (2019-03-12) + + * fixed class aliases + +# 2.7.0 (2019-03-12) + + * fixed sandbox security issue (under some circumstances, calling the + __toString() method on an object was possible even if not allowed by the + security policy) + * fixed batch filter clobbers array keys when fill parameter is used + * added preserveKeys support for the batch filter + * fixed "embed" support when used from "template_from_string" + * deprecated passing a Twig\Template to Twig\Environment::load()/Twig\Environment::resolveTemplate() + * added the possibility to pass a TemplateWrapper to Twig\Environment::load() + * marked Twig\Environment::getTemplateClass() as internal (implementation detail) + * improved the performance of the sandbox + * deprecated the spaceless tag + * added a spaceless filter + * added max value to the "random" function + * deprecated Twig\Extension\InitRuntimeInterface + * deprecated Twig\Loader\ExistsLoaderInterface + * deprecated PSR-0 classes in favor of namespaced ones + * made namespace classes the default classes (PSR-0 ones are aliases now) + * added Twig\Loader\ChainLoader::getLoaders() + * removed duplicated directory separator in FilesystemLoader + * deprecated the "base_template_class" option on Twig\Environment + * deprecated the Twig\Environment::getBaseTemplateClass() and + Twig\Environment::setBaseTemplateClass() methods + * changed internal code to use the namespaced classes as much as possible + * deprecated Twig_Parser::isReservedMacroName() + +# 2.6.2 (2019-01-14) + + * fixed regression (key exists check for non ArrayObject objects) + +# 2.6.1 (2019-01-14) + + * fixed ArrayObject access with a null value + * fixed embedded templates starting with a BOM + * fixed using a Twig_TemplateWrapper instance as an argument to extends + * fixed error location when calling an undefined block + * deprecated passing a string as a source on Twig_Error + * switched generated code to use the PHP short array notation + * fixed float representation in compiled templates + * added a second argument to the join filter (last separator configuration) + +# 2.6.0 (2018-12-16) + + * made sure twig_include returns a string + * fixed multi-byte UFT-8 in escape('html_attr') + * added the "deprecated" tag + * added support for dynamically named tests + * fixed GlobalsInterface extended class + * fixed filesystem loader throwing an exception instead of returning false + +# 2.5.0 (2018-07-13) + + * deprecated using the spaceless tag at the root level of a child template (noop anyway) + * deprecated the possibility to define a block in a non-capturing block in a child template + * added the Symfony ctype polyfill as a dependency + * fixed reporting the proper location for errors compiled in templates + * fixed the error handling for the optimized extension-based function calls + * ensured that syntax errors are triggered with the right line + * "js" filter now produces valid JSON + +# 2.4.8 (2018-04-02) + + * fixed a regression when using the "default" filter or the "defined" test on non-existing arrays + +# 2.4.7 (2018-03-20) + + * optimized runtime performance + * optimized parser performance by inlining the constant values + * fixed block names unicity + * fixed counting children of SimpleXMLElement objects + * added missing else clause to avoid infinite loops + * fixed .. (range operator) in sandbox policy + +# 2.4.6 (2018-03-03) + + * fixed a regression in the way the profiler is registered in templates + +# 2.4.5 (2018-03-02) + + * optimized the performance of calling an extension method at runtime + * optimized the performance of the dot operator for array and method calls + * added an exception when using "===" instead of "same as" + * fixed possible array to string conversion concealing actual error + * made variable names deterministic in compiled templates + * fixed length filter when passing an instance of IteratorAggregate + * fixed Environment::resolveTemplate to accept instances of TemplateWrapper + +# 2.4.4 (2017-09-27) + + * added Twig_Profiler_Profile::reset() + * fixed use TokenParser to return an empty Node + * added RuntimeExtensionInterface + * added circular reference detection when loading templates + * added support for runtime loaders in IntegrationTestCase + * fixed deprecation when using Twig_Profiler_Dumper_Html + * removed @final from Twig_Profiler_Dumper_Text + +# 2.4.3 (2017-06-07) + + * fixed namespaces introduction + +# 2.4.2 (2017-06-05) + + * fixed namespaces introduction + +# 2.4.1 (2017-06-05) + + * fixed namespaces introduction + +# 2.4.0 (2017-06-05) + + * added support for PHPUnit 6 when testing extensions + * fixed PHP 7.2 compatibility + * fixed template name generation in Twig_Environment::createTemplate() + * removed final tag on Twig_TokenParser_Include + * dropped HHVM support + * added namespaced aliases for all (non-deprecated) classes and interfaces + * marked Twig_Filter, Twig_Function, Twig_Test, Twig_Node_Module and Twig_Profiler_Profile as final via the @final annotation + +# 2.3.2 (2017-04-20) + + * fixed edge case in the method cache for Twig attributes + +# 2.3.1 (2017-04-18) + + * fixed the empty() test + +# 2.3.0 (2017-03-22) + + * fixed a race condition handling when writing cache files + * "length" filter now returns string length when applied to an object that does + not implement \Countable but provides __toString() + * "empty" test will now consider the return value of the __toString() method for + objects implement __toString() but not \Countable + * fixed JS escaping for unicode characters with higher code points + * added error message when calling `parent()` in a block that doesn't exist in the parent template + +# 2.2.0 (2017-02-26) + + * added a PSR-11 compatible runtime loader + * added `side` argument to `trim` to allow left or right trimming only. + +# 2.1.0 (2017-01-11) + + * fixed twig_get_attribute() + * added Twig_NodeCaptureInterface for nodes that capture all output + +# 2.0.0 (2017-01-05) + + * removed the C extension + * moved Twig_Environment::getAttribute() to twig_get_attribute() + * removed Twig_Environment::getLexer(), Twig_Environment::getParser(), Twig_Environment::getCompiler() + * removed Twig_Compiler::getFilename() + * added hasser support in Twig_Template::getAttribute() + * sped up the json_encode filter + * removed reserved macro names; all names can be used as macro + * removed Twig_Template::getEnvironment() + * changed _self variable to return the current template name + * made the loader a required argument of Twig_Environment constructor + * removed Twig_Environment::clearTemplateCache() + * removed Twig_Autoloader (use Composer instead) + * removed `true` as an equivalent to `html` for the auto-escaping strategy + * removed pre-1.8 autoescape tag syntax + * dropped support for PHP 5.x + * removed the ability to register a global variable after the runtime or the extensions have been initialized + * improved the performance of the filesystem loader + * removed features that were deprecated in 1.x + +# 1.44.4 (2021-XX-XX) + + * Revert "Throw a proper exception when a template name is an absolute path (as it has never been supported)" + +# 1.44.3 (2021-05-12) + + * Fix PHP 8.1 compatibility + * Throw a proper exception when a template name is an absolute path (as it has never been supported) + +# 1.44.2 (2021-01-05) + + * Fix "odd" not working for negative numbers + +# 1.44.1 (2020-10-27) + + * Fix "include(template_from_string())" + +# 1.44.0 (2020-10-21) + + * Remove implicit dependency on ext/iconv in JS escaper + * Fix sandbox support when using "include(template_from_string())" + * Make round brackets optional for one argument tests like "same as" or "divisible by" + * Add support for ES2015 style object initialisation shortcut { a } is the same as { 'a': a } + * Fix filter(), map(), and reduce() to throw a RuntimeError instead of a PHP TypeError + * Drop PHP 7.1 support + +# 1.43.1 (2020-08-05) + + * Fix sandbox not disabled if syntax error occurs within {% sandbox %} tag + * Fix a regression when not using a space before an operator + * Restrict callables to closures in filters + * Allow trailing commas in argument lists (in calls as well as definitions) + +# 1.43.0 (2020-07-05) + + * Throw exception in case non-Traversable data is passed to "filter" + * Fix context optimization on PHP 7.4 + * Fix PHP 8 compatibility + * Drop PHP 5.5 5.6, and 7.0 support + * Fix ambiguous syntax parsing + * In sandbox, the `filter`, `map` and `reduce` filters require Closures in `arrow` parameter + +# 1.42.5 (2020-02-11) + + * Fix implementation of case-insensitivity for method names + +# 1.42.4 (2019-11-11) + + * optimized "block('foo') ?? 'bar" + * added supported for exponential numbers + +# 1.42.3 (2019-08-24) + + * fixed the "split" filter when the delimiter is "0" + * fixed the "empty" test on Traversable instances + * fixed cache when opcache is installed but disabled + * fixed PHP 7.4 compatibility + * bumped the minimal PHP version to 5.5 + +# 1.42.2 (2019-06-18) + + * Display partial output (PHP buffer) when an error occurs in debug mode + +# 1.42.1 (2019-06-04) + + * added support for "Twig\Markup" instances in the "in" test (again) + * allowed string operators as variables names in assignments + +# 1.42.0 (2019-05-31) + + * fixed the "filter" filter when the argument is \Traversable but does not implement \Iterator (\SimpleXmlElement for instance) + * fixed a PHP fatal error when calling a macro imported in a block in a nested block + * fixed a PHP fatal error when calling a macro imported in the template in another macro + * fixed wrong error message on "import" and "from" + +# 1.41.0 (2019-05-14) + + * fixed support for PHP 7.4 + * added "filter", "map", and "reduce" filters (and support for arrow functions) + * fixed partial output leak when a PHP fatal error occurs + * optimized context access on PHP 7.4 + +# 1.40.1 (2019-04-29) + +# fixed regression in NodeTraverser + +# 1.40.0 (2019-04-28) + + * allowed Twig\NodeVisitor\NodeVisitorInterface::leaveNode() to return "null" instead of "false" (same meaning) + * added the "apply" tag as a replacement for the "filter" tag + * allowed Twig\Loader\FilesystemLoader::findTemplate() to return "null" instead of "false" (same meaning) + * added support for "Twig\Markup" instances in the "in" test + * fixed Lexer when using custom options containing the # char + * fixed "import" when macros are stored in a template string + +# 1.39.1 (2019-04-16) + + * fixed EscaperNodeVisitor + +# 1.39.0 (2019-04-16) + + * added Traversable support for the length filter + * fixed some wrong location in error messages + * made exception creation faster + * made escaping on ternary expressions (?: and ??) more fine-grained + * added the possibility to give a nice name to string templates (template_from_string function) + * fixed the "with" behavior to always include the globals (for consistency with the "include" and "embed" tags) + * fixed "include" with "ignore missing" when an error loading occurs in the included template + * added support for a new whitespace trimming option ({%~ ~%}, {{~ ~}}, {#~ ~#}) + +# 1.38.4 (2019-03-23) + + * fixed CheckToStringNode implementation (broken when a function/filter is variadic) + +# 1.38.3 (2019-03-21) + + * fixed the spaceless filter so that it behaves like the spaceless tag + * fixed BC break on Environment::resolveTemplate() + * fixed the bundled Autoloader to also load namespaced classes + * allowed Traversable objects to be used in the "with" tag + * allowed Traversable objects to be used in the "with" argument of the "include" and "embed" tags + +# 1.38.2 (2019-03-12) + + * added TemplateWrapper::getTemplateName() + +# 1.38.1 (2019-03-12) + + * fixed class aliases + +# 1.38.0 (2019-03-12) + + * fixed sandbox security issue (under some circumstances, calling the + __toString() method on an object was possible even if not allowed by the + security policy) + * fixed batch filter clobbers array keys when fill parameter is used + * added preserveKeys support for the batch filter + * fixed "embed" support when used from "template_from_string" + * added the possibility to pass a TemplateWrapper to Twig\Environment::load() + * improved the performance of the sandbox + * added a spaceless filter + * added max value to the "random" function + * made namespace classes the default classes (PSR-0 ones are aliases now) + * removed duplicated directory separator in FilesystemLoader + * added Twig\Loader\ChainLoader::getLoaders() + * changed internal code to use the namespaced classes as much as possible + +# 1.37.1 (2019-01-14) + + * fixed regression (key exists check for non ArrayObject objects) + * fixed logic in TemplateWrapper + +# 1.37.0 (2019-01-14) + + * fixed ArrayObject access with a null value + * fixed embedded templates starting with a BOM + * fixed using a Twig_TemplateWrapper instance as an argument to extends + * switched generated code to use the PHP short array notation + * dropped PHP 5.3 support + * fixed float representation in compiled templates + * added a second argument to the join filter (last separator configuration) + +# 1.36.0 (2018-12-16) + + * made sure twig_include returns a string + * fixed multi-byte UFT-8 in escape('html_attr') + * added the "deprecated" tag + * added support for dynamically named tests + * fixed GlobalsInterface extended class + * fixed filesystem loader throwing an exception instead of returning false + +# 1.35.4 (2018-07-13) + + * ensured that syntax errors are triggered with the right line + * added the Symfony ctype polyfill as a dependency + * "js" filter now produces valid JSON + +# 1.35.3 (2018-03-20) + + * fixed block names unicity + * fixed counting children of SimpleXMLElement objects + * added missing else clause to avoid infinite loops + * fixed .. (range operator) in sandbox policy + +# 1.35.2 (2018-03-03) + + * fixed a regression in the way the profiler is registered in templates + +# 1.35.1 (2018-03-02) + + * added an exception when using "===" instead of "same as" + * fixed possible array to string conversion concealing actual error + * made variable names deterministic in compiled templates + * fixed length filter when passing an instance of IteratorAggregate + * fixed Environment::resolveTemplate to accept instances of TemplateWrapper + +# 1.35.0 (2017-09-27) + + * added Twig_Profiler_Profile::reset() + * fixed use TokenParser to return an empty Node + * added RuntimeExtensionInterface + * added circular reference detection when loading templates + +# 1.34.4 (2017-07-04) + + * added support for runtime loaders in IntegrationTestCase + * fixed deprecation when using Twig_Profiler_Dumper_Html + +# 1.34.3 (2017-06-07) + + * fixed namespaces introduction + +# 1.34.2 (2017-06-05) + + * fixed namespaces introduction + +# 1.34.1 (2017-06-05) + + * fixed namespaces introduction + +# 1.34.0 (2017-06-05) + + * added support for PHPUnit 6 when testing extensions + * fixed PHP 7.2 compatibility + * fixed template name generation in Twig_Environment::createTemplate() + * removed final tag on Twig_TokenParser_Include + * added namespaced aliases for all (non-deprecated) classes and interfaces + * dropped HHVM support + * dropped PHP 5.2 support + +# 1.33.2 (2017-04-20) + + * fixed edge case in the method cache for Twig attributes + +# 1.33.1 (2017-04-18) + + * fixed the empty() test + +# 1.33.0 (2017-03-22) + + * fixed a race condition handling when writing cache files + * "length" filter now returns string length when applied to an object that does + not implement \Countable but provides __toString() + * "empty" test will now consider the return value of the __toString() method for + objects implement __toString() but not \Countable + * fixed JS escaping for unicode characters with higher code points + +# 1.32.0 (2017-02-26) + + * fixed deprecation notice in Twig_Util_DeprecationCollector + * added a PSR-11 compatible runtime loader + * added `side` argument to `trim` to allow left or right trimming only. + +# 1.31.0 (2017-01-11) + + * added Twig_NodeCaptureInterface for nodes that capture all output + * fixed marking the environment as initialized too early + * fixed C89 compat for the C extension + * turned fatal error into exception when a previously generated cache is corrupted + * fixed offline cache warm-ups for embedded templates + +# 1.30.0 (2016-12-23) + + * added Twig_FactoryRuntimeLoader + * deprecated function/test/filter/tag overriding + * deprecated the "disable_c_ext" attribute on Twig_Node_Expression_GetAttr + +# 1.29.0 (2016-12-13) + + * fixed sandbox being left enabled if an exception is thrown while rendering + * marked some classes as being final (via @final) + * made Twig_Error report real source path when possible + * added support for {{ _self }} to provide an upgrade path from 1.x to 2.0 (replaces {{ _self.templateName }}) + * deprecated silent display of undefined blocks + * deprecated support for mbstring.func_overload != 0 + +# 1.28.2 (2016-11-23) + + * fixed precedence between getFoo() and isFoo() in Twig_Template::getAttribute() + * improved a deprecation message + +# 1.28.1 (2016-11-18) + + * fixed block() function when used with a template argument + +# 1.28.0 (2016-11-17) + + * added support for the PHP 7 null coalescing operator for the ?? Twig implementation + * exposed a way to access template data and methods in a portable way + * changed context access to use the PHP 7 null coalescing operator when available + * added the "with" tag + * added support for a custom template on the block() function + * added "is defined" support for block() and constant() + * optimized the way attributes are fetched + +# 1.27.0 (2016-10-25) + + * deprecated Twig_Parser::getEnvironment() + * deprecated Twig_Parser::addHandler() and Twig_Parser::addNodeVisitor() + * deprecated Twig_Compiler::addIndentation() + * fixed regression when registering two extensions having the same class name + * deprecated Twig_LoaderInterface::getSource() (implement Twig_SourceContextLoaderInterface instead) + * fixed the filesystem loader with relative paths + * deprecated Twig_Node::getLine() in favor of Twig_Node::getTemplateLine() + * deprecated Twig_Template::getSource() in favor of Twig_Template::getSourceContext() + * deprecated Twig_Node::getFilename() in favor of Twig_Node::getTemplateName() + * deprecated the "filename" escaping strategy (use "name" instead) + * added Twig_Source to hold information about the original template + * deprecated Twig_Error::getTemplateFile() and Twig_Error::setTemplateFile() in favor of Twig_Error::getTemplateName() and Twig_Error::setTemplateName() + * deprecated Parser::getFilename() + * fixed template paths when a template name contains a protocol like vfs:// + * improved debugging with Twig_Sandbox_SecurityError exceptions for disallowed methods and properties + +# 1.26.1 (2016-10-05) + + * removed template source code from generated template classes when debug is disabled + * fixed default implementation of Twig_Template::getDebugInfo() for better BC + * fixed regression on static calls for functions/filters/tests + +# 1.26.0 (2016-10-02) + + * added template cache invalidation based on more environment options + * added a missing deprecation notice + * fixed template paths when a template is stored in a PHAR file + * allowed filters/functions/tests implementation to use a different class than the extension they belong to + * deprecated Twig_ExtensionInterface::getName() + +# 1.25.0 (2016-09-21) + + * changed the way we store template source in template classes + * removed usage of realpath in cache keys + * fixed Twig cache sharing when used with different versions of PHP + * removed embed parent workaround for simple use cases + * deprecated the ability to store non Node instances in Node::$nodes + * deprecated Twig_Environment::getLexer(), Twig_Environment::getParser(), Twig_Environment::getCompiler() + * deprecated Twig_Compiler::getFilename() + +# 1.24.2 (2016-09-01) + + * fixed static callables + * fixed a potential PHP warning when loading the cache + * fixed a case where the autoescaping does not work as expected + +# 1.24.1 (2016-05-30) + + * fixed reserved keywords (forbids true, false, null and none keywords for variables names) + * fixed support for PHP7 (Throwable support) + * marked the following methods as being internals on Twig_Environment: + getFunctions(), getFilters(), getTests(), getFunction(), getFilter(), getTest(), + getTokenParsers(), getTags(), getNodeVisitors(), getUnaryOperators(), getBinaryOperators(), + getFunctions(), getFilters(), getGlobals(), initGlobals(), initExtensions(), and initExtension() + +# 1.24.0 (2016-01-25) + + * adding support for the ?? operator + * fixed the defined test when used on a constant, a map, or a sequence + * undeprecated _self (should only be used to get the template name, not the template instance) + * fixed parsing on PHP7 + +# 1.23.3 (2016-01-11) + + * fixed typo + +# 1.23.2 (2015-01-11) + + * added versions in deprecated messages + * made file cache tolerant for trailing (back)slashes on directory configuration + * deprecated unused Twig_Node_Expression_ExtensionReference class + +# 1.23.1 (2015-11-05) + + * fixed some exception messages which triggered PHP warnings + * fixed BC on Twig_Test_NodeTestCase + +# 1.23.0 (2015-10-29) + + * deprecated the possibility to override an extension by registering another one with the same name + * deprecated Twig_ExtensionInterface::getGlobals() (added Twig_Extension_GlobalsInterface for BC) + * deprecated Twig_ExtensionInterface::initRuntime() (added Twig_Extension_InitRuntimeInterface for BC) + * deprecated Twig_Environment::computeAlternatives() + +# 1.22.3 (2015-10-13) + + * fixed regression when using null as a cache strategy + * improved performance when checking template freshness + * fixed warnings when loaded templates do not exist + * fixed template class name generation to prevent possible collisions + * fixed logic for custom escapers to call them even on integers and null values + * changed template cache names to take into account the Twig C extension + +# 1.22.2 (2015-09-22) + + * fixed a race condition in template loading + +# 1.22.1 (2015-09-15) + + * fixed regression in template_from_string + +# 1.22.0 (2015-09-13) + + * made Twig_Test_IntegrationTestCase more flexible + * added an option to force PHP bytecode invalidation when writing a compiled template into the cache + * fixed the profiler duration for the root node + * changed template cache names to take into account enabled extensions + * deprecated Twig_Environment::clearCacheFiles(), Twig_Environment::getCacheFilename(), + Twig_Environment::writeCacheFile(), and Twig_Environment::getTemplateClassPrefix() + * added a way to override the filesystem template cache system + * added a way to get the original template source from Twig_Template + +# 1.21.2 (2015-09-09) + + * fixed variable names for the deprecation triggering code + * fixed escaping strategy detection based on filename + * added Traversable support for replace, merge, and sort + * deprecated support for character by character replacement for the "replace" filter + +# 1.21.1 (2015-08-26) + + * fixed regression when using the deprecated Twig_Test_* classes + +# 1.21.0 (2015-08-24) + + * added deprecation notices for deprecated features + * added a deprecation "framework" for filters/functions/tests and test fixtures + +# 1.20.0 (2015-08-12) + + * forbid access to the Twig environment from templates and internal parts of Twig_Template + * fixed limited RCEs when in sandbox mode + * deprecated Twig_Template::getEnvironment() + * deprecated the _self variable for usage outside of the from and import tags + * added Twig_BaseNodeVisitor to ease the compatibility of node visitors + between 1.x and 2.x + +# 1.19.0 (2015-07-31) + + * fixed wrong error message when including an undefined template in a child template + * added support for variadic filters, functions, and tests + * added support for extra positional arguments in macros + * added ignore_missing flag to the source function + * fixed batch filter with zero items + * deprecated Twig_Environment::clearTemplateCache() + * fixed sandbox disabling when using the include function + +# 1.18.2 (2015-06-06) + + * fixed template/line guessing in exceptions for nested templates + * optimized the number of inodes and the size of realpath cache when using the cache + +# 1.18.1 (2015-04-19) + + * fixed memory leaks in the C extension + * deprecated Twig_Loader_String + * fixed the slice filter when used with a SimpleXMLElement object + * fixed filesystem loader when trying to load non-files (like directories) + +# 1.18.0 (2015-01-25) + + * fixed some error messages where the line was wrong (unknown variables or argument names) + * added a new way to customize the main Module node (via empty nodes) + * added Twig_Environment::createTemplate() to create a template from a string + * added a profiler + * fixed filesystem loader cache when different file paths are used for the same template + +# 1.17.0 (2015-01-14) + + * added a 'filename' autoescaping strategy, which dynamically chooses the + autoescaping strategy for a template based on template file extension. + +# 1.16.3 (2014-12-25) + + * fixed regression for dynamic parent templates + * fixed cache management with statcache + * fixed a regression in the slice filter + +# 1.16.2 (2014-10-17) + + * fixed timezone on dates as strings + * fixed 2-words test names when a custom node class is not used + * fixed macros when using an argument named like a PHP super global (like GET or POST) + * fixed date_modify when working with DateTimeImmutable + * optimized for loops + * fixed multi-byte characters handling in the split filter + * fixed a regression in the in operator + * fixed a regression in the slice filter + +# 1.16.1 (2014-10-10) + + * improved error reporting in a sandboxed template + * fixed missing error file/line information under certain circumstances + * fixed wrong error line number in some error messages + * fixed the in operator to use strict comparisons + * sped up the slice filter + * fixed for mb function overload mb_substr acting different + * fixed the attribute() function when passing a variable for the arguments + +# 1.16.0 (2014-07-05) + + * changed url_encode to always encode according to RFC 3986 + * fixed inheritance in a 'use'-hierarchy + * removed the __toString policy check when the sandbox is disabled + * fixed recursively calling blocks in templates with inheritance + +# 1.15.1 (2014-02-13) + + * fixed the conversion of the special '0000-00-00 00:00' date + * added an error message when trying to import an undefined block from a trait + * fixed a C extension crash when accessing defined but uninitialized property. + +# 1.15.0 (2013-12-06) + + * made ignoreStrictCheck in Template::getAttribute() works with __call() methods throwing BadMethodCallException + * added min and max functions + * added the round filter + * fixed a bug that prevented the optimizers to be enabled/disabled selectively + * fixed first and last filters for UTF-8 strings + * added a source function to include the content of a template without rendering it + * fixed the C extension sandbox behavior when get or set is prepend to method name + +# 1.14.2 (2013-10-30) + + * fixed error filename/line when an error occurs in an included file + * allowed operators that contain whitespaces to have more than one whitespace + * allowed tests to be made of 1 or 2 words (like "same as" or "divisible by") + +# 1.14.1 (2013-10-15) + + * made it possible to use named operators as variables + * fixed the possibility to have a variable named 'matches' + * added support for PHP 5.5 DateTimeInterface + +# 1.14.0 (2013-10-03) + + * fixed usage of the html_attr escaping strategy to avoid double-escaping with the html strategy + * added new operators: ends with, starts with, and matches + * fixed some compatibility issues with HHVM + * added a way to add custom escaping strategies + * fixed the C extension compilation on Windows + * fixed the batch filter when using a fill argument with an exact match of elements to batch + * fixed the filesystem loader cache when a template name exists in several namespaces + * fixed template_from_string when the template includes or extends other ones + * fixed a crash of the C extension on an edge case + +# 1.13.2 (2013-08-03) + + * fixed the error line number for an error occurs in and embedded template + * fixed crashes of the C extension on some edge cases + +# 1.13.1 (2013-06-06) + + * added the possibility to ignore the filesystem constructor argument in Twig_Loader_Filesystem + * fixed Twig_Loader_Chain::exists() for a loader which implements Twig_ExistsLoaderInterface + * adjusted backtrace call to reduce memory usage when an error occurs + * added support for object instances as the second argument of the constant test + * fixed the include function when used in an assignment + +# 1.13.0 (2013-05-10) + + * fixed getting a numeric-like item on a variable ('09' for instance) + * fixed getting a boolean or float key on an array, so it is consistent with PHP's array access: + `{{ array[false] }}` behaves the same as `echo $array[false];` (equals `$array[0]`) + * made the escape filter 20% faster for happy path (escaping string for html with UTF-8) + * changed ☃ to § in tests + * enforced usage of named arguments after positional ones + +# 1.12.3 (2013-04-08) + + * fixed a security issue in the filesystem loader where it was possible to include a template one + level above the configured path + * fixed fatal error that should be an exception when adding a filter/function/test too late + * added a batch filter + * added support for encoding an array as query string in the url_encode filter + +# 1.12.2 (2013-02-09) + + * fixed the timezone used by the date filter and function when the given date contains a timezone (like 2010-01-28T15:00:00+02:00) + * fixed globals when getGlobals is called early on + * added the first and last filter + +# 1.12.1 (2013-01-15) + + * added support for object instances as the second argument of the constant function + * relaxed globals management to avoid a BC break + * added support for {{ some_string[:2] }} + +# 1.12.0 (2013-01-08) + + * added verbatim as an alias for the raw tag to avoid confusion with the raw filter + * fixed registration of tests and functions as anonymous functions + * fixed globals management + +# 1.12.0-RC1 (2012-12-29) + + * added an include function (does the same as the include tag but in a more flexible way) + * added the ability to use any PHP callable to define filters, functions, and tests + * added a syntax error when using a loop variable that is not defined + * added the ability to set default values for macro arguments + * added support for named arguments for filters, tests, and functions + * moved filters/functions/tests syntax errors to the parser + * added support for extended ternary operator syntaxes + +# 1.11.1 (2012-11-11) + + * fixed debug info line numbering (was off by 2) + * fixed escaping when calling a macro inside another one (regression introduced in 1.9.1) + * optimized variable access on PHP 5.4 + * fixed a crash of the C extension when an exception was thrown from a macro called without being imported (using _self.XXX) + +# 1.11.0 (2012-11-07) + + * fixed macro compilation when a variable name is a PHP reserved keyword + * changed the date filter behavior to always apply the default timezone, except if false is passed as the timezone + * fixed bitwise operator precedences + * added the template_from_string function + * fixed default timezone usage for the date function + * optimized the way Twig exceptions are managed (to make them faster) + * added Twig_ExistsLoaderInterface (implementing this interface in your loader make the chain loader much faster) + +# 1.10.3 (2012-10-19) + + * fixed wrong template location in some error messages + * reverted a BC break introduced in 1.10.2 + * added a split filter + +# 1.10.2 (2012-10-15) + + * fixed macro calls on PHP 5.4 + +# 1.10.1 (2012-10-15) + + * made a speed optimization to macro calls when imported via the "import" tag + * fixed C extension compilation on Windows + * fixed a segfault in the C extension when using DateTime objects + +# 1.10.0 (2012-09-28) + + * extracted functional tests framework to make it reusable for third-party extensions + * added namespaced templates support in Twig_Loader_Filesystem + * added Twig_Loader_Filesystem::prependPath() + * fixed an error when a token parser pass a closure as a test to the subparse() method + +# 1.9.2 (2012-08-25) + + * fixed the in operator for objects that contain circular references + * fixed the C extension when accessing a public property of an object implementing the \ArrayAccess interface + +# 1.9.1 (2012-07-22) + + * optimized macro calls when auto-escaping is on + * fixed wrong parent class for Twig_Function_Node + * made Twig_Loader_Chain more explicit about problems + +# 1.9.0 (2012-07-13) + + * made the parsing independent of the template loaders + * fixed exception trace when an error occurs when rendering a child template + * added escaping strategies for CSS, URL, and HTML attributes + * fixed nested embed tag calls + * added the date_modify filter + +# 1.8.3 (2012-06-17) + + * fixed paths in the filesystem loader when passing a path that ends with a slash or a backslash + * fixed escaping when a project defines a function named html or js + * fixed chmod mode to apply the umask correctly + +# 1.8.2 (2012-05-30) + + * added the abs filter + * fixed a regression when using a number in template attributes + * fixed compiler when mbstring.func_overload is set to 2 + * fixed DateTimeZone support in date filter + +# 1.8.1 (2012-05-17) + + * fixed a regression when dealing with SimpleXMLElement instances in templates + * fixed "is_safe" value for the "dump" function when "html_errors" is not defined in php.ini + * switched to use mbstring whenever possible instead of iconv (you might need to update your encoding as mbstring and iconv encoding names sometimes differ) + +# 1.8.0 (2012-05-08) + + * enforced interface when adding tests, filters, functions, and node visitors from extensions + * fixed a side-effect of the date filter where the timezone might be changed + * simplified usage of the autoescape tag; the only (optional) argument is now the escaping strategy or false (with a BC layer) + * added a way to dynamically change the auto-escaping strategy according to the template "filename" + * changed the autoescape option to also accept a supported escaping strategy (for BC, true is equivalent to html) + * added an embed tag + +# 1.7.0 (2012-04-24) + + * fixed a PHP warning when using CIFS + * fixed template line number in some exceptions + * added an iterable test + * added an error when defining two blocks with the same name in a template + * added the preserves_safety option for filters + * fixed a PHP notice when trying to access a key on a non-object/array variable + * enhanced error reporting when the template file is an instance of SplFileInfo + * added Twig_Environment::mergeGlobals() + * added compilation checks to avoid misuses of the sandbox tag + * fixed filesystem loader freshness logic for high traffic websites + * fixed random function when charset is null + +# 1.6.5 (2012-04-11) + + * fixed a regression when a template only extends another one without defining any blocks + +# 1.6.4 (2012-04-02) + + * fixed PHP notice in Twig_Error::guessTemplateLine() introduced in 1.6.3 + * fixed performance when compiling large files + * optimized parent template creation when the template does not use dynamic inheritance + +# 1.6.3 (2012-03-22) + + * fixed usage of Z_ADDREF_P for PHP 5.2 in the C extension + * fixed compilation of numeric values used in templates when using a locale where the decimal separator is not a dot + * made the strategy used to guess the real template file name and line number in exception messages much faster and more accurate + +# 1.6.2 (2012-03-18) + + * fixed sandbox mode when used with inheritance + * added preserveKeys support for the slice filter + * fixed the date filter when a DateTime instance is passed with a specific timezone + * added a trim filter + +# 1.6.1 (2012-02-29) + + * fixed Twig C extension + * removed the creation of Twig_Markup instances when not needed + * added a way to set the default global timezone for dates + * fixed the slice filter on strings when the length is not specified + * fixed the creation of the cache directory in case of a race condition + +# 1.6.0 (2012-02-04) + + * fixed raw blocks when used with the whitespace trim option + * made a speed optimization to macro calls when imported via the "from" tag + * fixed globals, parsers, visitors, filters, tests, and functions management in Twig_Environment when a new one or new extension is added + * fixed the attribute function when passing arguments + * added slice notation support for the [] operator (syntactic sugar for the slice operator) + * added a slice filter + * added string support for the reverse filter + * fixed the empty test and the length filter for Twig_Markup instances + * added a date function to ease date comparison + * fixed unary operators precedence + * added recursive parsing support in the parser + * added string and integer handling for the random function + +# 1.5.1 (2012-01-05) + + * fixed a regression when parsing strings + +# 1.5.0 (2012-01-04) + + * added Traversable objects support for the join filter + +# 1.5.0-RC2 (2011-12-30) + + * added a way to set the default global date interval format + * fixed the date filter for DateInterval instances (setTimezone() does not exist for them) + * refactored Twig_Template::display() to ease its extension + * added a number_format filter + +# 1.5.0-RC1 (2011-12-26) + + * removed the need to quote hash keys + * allowed hash keys to be any expression + * added a do tag + * added a flush tag + * added support for dynamically named filters and functions + * added a dump function to help debugging templates + * added a nl2br filter + * added a random function + * added a way to change the default format for the date filter + * fixed the lexer when an operator ending with a letter ends a line + * added string interpolation support + * enhanced exceptions for unknown filters, functions, tests, and tags + +# 1.4.0 (2011-12-07) + + * fixed lexer when using big numbers (> PHP_INT_MAX) + * added missing preserveKeys argument to the reverse filter + * fixed macros containing filter tag calls + +# 1.4.0-RC2 (2011-11-27) + + * removed usage of Reflection in Twig_Template::getAttribute() + * added a C extension that can optionally replace Twig_Template::getAttribute() + * added negative timestamp support to the date filter + +# 1.4.0-RC1 (2011-11-20) + + * optimized variable access when using PHP 5.4 + * changed the precedence of the .. operator to be more consistent with languages that implements such a feature like Ruby + * added an Exception to Twig_Loader_Array::isFresh() method when the template does not exist to be consistent with other loaders + * added Twig_Function_Node to allow more complex functions to have their own Node class + * added Twig_Filter_Node to allow more complex filters to have their own Node class + * added Twig_Test_Node to allow more complex tests to have their own Node class + * added a better error message when a template is empty but contain a BOM + * fixed "in" operator for empty strings + * fixed the "defined" test and the "default" filter (now works with more than one call (foo.bar.foo) and for both values of the strict_variables option) + * changed the way extensions are loaded (addFilter/addFunction/addGlobal/addTest/addNodeVisitor/addTokenParser/addExtension can now be called in any order) + * added Twig_Environment::display() + * made the escape filter smarter when the encoding is not supported by PHP + * added a convert_encoding filter + * moved all node manipulations outside the compile() Node method + * made several speed optimizations + +# 1.3.0 (2011-10-08) + +no changes + +# 1.3.0-RC1 (2011-10-04) + + * added an optimization for the parent() function + * added cache reloading when auto_reload is true and an extension has been modified + * added the possibility to force the escaping of a string already marked as safe (instance of Twig_Markup) + * allowed empty templates to be used as traits + * added traits support for the "parent" function + +# 1.2.0 (2011-09-13) + +no changes + +# 1.2.0-RC1 (2011-09-10) + + * enhanced the exception when a tag remains unclosed + * added support for empty Countable objects for the "empty" test + * fixed algorithm that determines if a template using inheritance is valid (no output between block definitions) + * added better support for encoding problems when escaping a string (available as of PHP 5.4) + * added a way to ignore a missing template when using the "include" tag ({% include "foo" ignore missing %}) + * added support for an array of templates to the "include" and "extends" tags ({% include ['foo', 'bar'] %}) + * added support for bitwise operators in expressions + * added the "attribute" function to allow getting dynamic attributes on variables + * added Twig_Loader_Chain + * added Twig_Loader_Array::setTemplate() + * added an optimization for the set tag when used to capture a large chunk of static text + * changed name regex to match PHP one "[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*" (works for blocks, tags, functions, filters, and macros) + * removed the possibility to use the "extends" tag from a block + * added "if" modifier support to "for" loops + +# 1.1.2 (2011-07-30) + + * fixed json_encode filter on PHP 5.2 + * fixed regression introduced in 1.1.1 ({{ block(foo|lower) }}) + * fixed inheritance when using conditional parents + * fixed compilation of templates when the body of a child template is not empty + * fixed output when a macro throws an exception + * fixed a parsing problem when a large chunk of text is enclosed in a comment tag + * added PHPDoc for all Token parsers and Core extension functions + +# 1.1.1 (2011-07-17) + + * added a performance optimization in the Optimizer (also helps to lower the number of nested level calls) + * made some performance improvement for some edge cases + +# 1.1.0 (2011-06-28) + + * fixed json_encode filter + +# 1.1.0-RC3 (2011-06-24) + + * fixed method case-sensitivity when using the sandbox mode + * added timezone support for the date filter + * fixed possible security problems with NUL bytes + +# 1.1.0-RC2 (2011-06-16) + + * added an exception when the template passed to "use" is not a string + * made 'a.b is defined' not throw an exception if a is not defined (in strict mode) + * added {% line \d+ %} directive + +# 1.1.0-RC1 (2011-05-28) + +Flush your cache after upgrading. + + * fixed date filter when using a timestamp + * fixed the defined test for some cases + * fixed a parsing problem when a large chunk of text is enclosed in a raw tag + * added support for horizontal reuse of template blocks (see docs for more information) + * added whitespace control modifier to all tags (see docs for more information) + * added null as an alias for none (the null test is also an alias for the none test now) + * made TRUE, FALSE, NONE equivalent to their lowercase counterparts + * wrapped all compilation and runtime exceptions with Twig_Error_Runtime and added logic to guess the template name and line + * moved display() method to Twig_Template (generated templates should now use doDisplay() instead) + +# 1.0.0 (2011-03-27) + + * fixed output when using mbstring + * fixed duplicate call of methods when using the sandbox + * made the charset configurable for the escape filter + +# 1.0.0-RC2 (2011-02-21) + + * changed the way {% set %} works when capturing (the content is now marked as safe) + * added support for macro name in the endmacro tag + * make Twig_Error compatible with PHP 5.3.0 > + * fixed an infinite loop on some Windows configurations + * fixed the "length" filter for numbers + * fixed Template::getAttribute() as properties in PHP are case sensitive + * removed coupling between Twig_Node and Twig_Template + * fixed the ternary operator precedence rule + +# 1.0.0-RC1 (2011-01-09) + +Backward incompatibilities: + + * the "items" filter, which has been deprecated for quite a long time now, has been removed + * the "range" filter has been converted to a function: 0|range(10) -> range(0, 10) + * the "constant" filter has been converted to a function: {{ some_date|date('DATE_W3C'|constant) }} -> {{ some_date|date(constant('DATE_W3C')) }} + * the "cycle" filter has been converted to a function: {{ ['odd', 'even']|cycle(i) }} -> {{ cycle(['odd', 'even'], i) }} + * the "for" tag does not support "joined by" anymore + * the "autoescape" first argument is now "true"/"false" (instead of "on"/"off") + * the "parent" tag has been replaced by a "parent" function ({{ parent() }} instead of {% parent %}) + * the "display" tag has been replaced by a "block" function ({{ block('title') }} instead of {% display title %}) + * removed the grammar and simple token parser (moved to the Twig Extensions repository) + +Changes: + + * added "needs_context" option for filters and functions (the context is then passed as a first argument) + * added global variables support + * made macros return their value instead of echoing directly (fixes calling a macro in sandbox mode) + * added the "from" tag to import macros as functions + * added support for functions (a function is just syntactic sugar for a getAttribute() call) + * made macros callable when sandbox mode is enabled + * added an exception when a macro uses a reserved name + * the "default" filter now uses the "empty" test instead of just checking for null + * added the "empty" test + +# 0.9.10 (2010-12-16) + +Backward incompatibilities: + + * The Escaper extension is enabled by default, which means that all displayed + variables are now automatically escaped. You can revert to the previous + behavior by removing the extension via $env->removeExtension('escaper') + or just set the 'autoescape' option to 'false'. + * removed the "without loop" attribute for the "for" tag (not needed anymore + as the Optimizer take care of that for most cases) + * arrays and hashes have now a different syntax + * arrays keep the same syntax with square brackets: [1, 2] + * hashes now use curly braces (["a": "b"] should now be written as {"a": "b"}) + * support for "arrays with keys" and "hashes without keys" is not supported anymore ([1, "foo": "bar"] or {"foo": "bar", 1}) + * the i18n extension is now part of the Twig Extensions repository + +Changes: + + * added the merge filter + * removed 'is_escaper' option for filters (a left over from the previous version) -- you must use 'is_safe' now instead + * fixed usage of operators as method names (like is, in, and not) + * changed the order of execution for node visitors + * fixed default() filter behavior when used with strict_variables set to on + * fixed filesystem loader compatibility with PHAR files + * enhanced error messages when an unexpected token is parsed in an expression + * fixed filename not being added to syntax error messages + * added the autoescape option to enable/disable autoescaping + * removed the newline after a comment (mimics PHP behavior) + * added a syntax error exception when parent block is used on a template that does not extend another one + * made the Escaper extension enabled by default + * fixed sandbox extension when used with auto output escaping + * fixed escaper when wrapping a Twig_Node_Print (the original class must be preserved) + * added an Optimizer extension (enabled by default; optimizes "for" loops and "raw" filters) + * added priority to node visitors + +# 0.9.9 (2010-11-28) + +Backward incompatibilities: + * the self special variable has been renamed to _self + * the odd and even filters are now tests: + {{ foo|odd }} must now be written {{ foo is odd }} + * the "safe" filter has been renamed to "raw" + * in Node classes, + sub-nodes are now accessed via getNode() (instead of property access) + attributes via getAttribute() (instead of array access) + * the urlencode filter had been renamed to url_encode + * the include tag now merges the passed variables with the current context by default + (the old behavior is still possible by adding the "only" keyword) + * moved Exceptions to Twig_Error_* (Twig_SyntaxError/Twig_RuntimeError are now Twig_Error_Syntax/Twig_Error_Runtime) + * removed support for {{ 1 < i < 3 }} (use {{ i > 1 and i < 3 }} instead) + * the "in" filter has been removed ({{ a|in(b) }} should now be written {{ a in b }}) + +Changes: + * added file and line to Twig_Error_Runtime exceptions thrown from Twig_Template + * changed trans tag to accept any variable for the plural count + * fixed sandbox mode (__toString() method check was not enforced if called implicitly from complex statements) + * added the ** (power) operator + * changed the algorithm used for parsing expressions + * added the spaceless tag + * removed trim_blocks option + * added support for is*() methods for attributes (foo.bar now looks for foo->getBar() or foo->isBar()) + * changed all exceptions to extend Twig_Error + * fixed unary expressions ({{ not(1 or 0) }}) + * fixed child templates (with an extend tag) that uses one or more imports + * added support for {{ 1 not in [2, 3] }} (more readable than the current {{ not (1 in [2, 3]) }}) + * escaping has been rewritten + * the implementation of template inheritance has been rewritten + (blocks can now be called individually and still work with inheritance) + * fixed error handling for if tag when a syntax error occurs within a subparse process + * added a way to implement custom logic for resolving token parsers given a tag name + * fixed js escaper to be stricter (now uses a whilelist-based js escaper) + * added the following filers: "constant", "trans", "replace", "json_encode" + * added a "constant" test + * fixed objects with __toString() not being autoescaped + * fixed subscript expressions when calling __call() (methods now keep the case) + * added "test" feature (accessible via the "is" operator) + * removed the debug tag (should be done in an extension) + * fixed trans tag when no vars are used in plural form + * fixed race condition when writing template cache + * added the special _charset variable to reference the current charset + * added the special _context variable to reference the current context + * renamed self to _self (to avoid conflict) + * fixed Twig_Template::getAttribute() for protected properties + +# 0.9.8 (2010-06-28) + +Backward incompatibilities: + * the trans tag plural count is now attached to the plural tag: + old: `{% trans count %}...{% plural %}...{% endtrans %}` + new: `{% trans %}...{% plural count %}...{% endtrans %}` + + * added a way to translate strings coming from a variable ({% trans var %}) + * fixed trans tag when used with the Escaper extension + * fixed default cache umask + * removed Twig_Template instances from the debug tag output + * fixed objects with __isset() defined + * fixed set tag when used with a capture + * fixed type hinting for Twig_Environment::addFilter() method + +# 0.9.7 (2010-06-12) + +Backward incompatibilities: + * changed 'as' to '=' for the set tag ({% set title as "Title" %} must now be {% set title = "Title" %}) + * removed the sandboxed attribute of the include tag (use the new sandbox tag instead) + * refactored the Node system (if you have custom nodes, you will have to update them to use the new API) + + * added self as a special variable that refers to the current template (useful for importing macros from the current template) + * added Twig_Template instance support to the include tag + * added support for dynamic and conditional inheritance ({% extends some_var %} and {% extends standalone ? "minimum" : "base" %}) + * added a grammar sub-framework to ease the creation of custom tags + * fixed the for tag for large arrays (some loop variables are now only available for arrays and objects that implement the Countable interface) + * removed the Twig_Resource::resolveMissingFilter() method + * fixed the filter tag which did not apply filtering to included files + * added a bunch of unit tests + * added a bunch of phpdoc + * added a sandbox tag in the sandbox extension + * changed the date filter to support any date format supported by DateTime + * added strict_variable setting to throw an exception when an invalid variable is used in a template (disabled by default) + * added the lexer, parser, and compiler as arguments to the Twig_Environment constructor + * changed the cache option to only accepts an explicit path to a cache directory or false + * added a way to add token parsers, filters, and visitors without creating an extension + * added three interfaces: Twig_NodeInterface, Twig_TokenParserInterface, and Twig_FilterInterface + * changed the generated code to match the new coding standards + * fixed sandbox mode (__toString() method check was not enforced if called implicitly from a simple statement like {{ article }}) + * added an exception when a child template has a non-empty body (as it is always ignored when rendering) + +# 0.9.6 (2010-05-12) + + * fixed variables defined outside a loop and for which the value changes in a for loop + * fixed the test suite for PHP 5.2 and older versions of PHPUnit + * added support for __call() in expression resolution + * fixed node visiting for macros (macros are now visited by visitors as any other node) + * fixed nested block definitions with a parent call (rarely useful but nonetheless supported now) + * added the cycle filter + * fixed the Lexer when mbstring.func_overload is used with an mbstring.internal_encoding different from ASCII + * added a long-syntax for the set tag ({% set foo %}...{% endset %}) + * unit tests are now powered by PHPUnit + * added support for gettext via the `i18n` extension + * fixed twig_capitalize_string_filter() and fixed twig_length_filter() when used with UTF-8 values + * added a more useful exception if an if tag is not closed properly + * added support for escaping strategy in the autoescape tag + * fixed lexer when a template has a big chunk of text between/in a block + +# 0.9.5 (2010-01-20) + +As for any new release, don't forget to remove all cached templates after +upgrading. + +If you have defined custom filters, you MUST upgrade them for this release. To +upgrade, replace "array" with "new Twig_Filter_Function", and replace the +environment constant by the "needs_environment" option: + + // before + 'even' => array('twig_is_even_filter', false), + 'escape' => array('twig_escape_filter', true), + + // after + 'even' => new Twig_Filter_Function('twig_is_even_filter'), + 'escape' => new Twig_Filter_Function('twig_escape_filter', array('needs_environment' => true)), + +If you have created NodeTransformer classes, you will need to upgrade them to +the new interface (please note that the interface is not yet considered +stable). + + * fixed list nodes that did not extend the Twig_NodeListInterface + * added the "without loop" option to the for tag (it disables the generation of the loop variable) + * refactored node transformers to node visitors + * fixed automatic-escaping for blocks + * added a way to specify variables to pass to an included template + * changed the automatic-escaping rules to be more sensible and more configurable in custom filters (the documentation lists all the rules) + * improved the filter system to allow object methods to be used as filters + * changed the Array and String loaders to actually make use of the cache mechanism + * included the default filter function definitions in the extension class files directly (Core, Escaper) + * added the // operator (like the floor() PHP function) + * added the .. operator (as a syntactic sugar for the range filter when the step is 1) + * added the in operator (as a syntactic sugar for the in filter) + * added the following filters in the Core extension: in, range + * added support for arrays (same behavior as in PHP, a mix between lists and dictionaries, arrays and hashes) + * enhanced some error messages to provide better feedback in case of parsing errors + +# 0.9.4 (2009-12-02) + +If you have custom loaders, you MUST upgrade them for this release: The +Twig_Loader base class has been removed, and the Twig_LoaderInterface has also +been changed (see the source code for more information or the documentation). + + * added support for DateTime instances for the date filter + * fixed loop.last when the array only has one item + * made it possible to insert newlines in tag and variable blocks + * fixed a bug when a literal '\n' were present in a template text + * fixed bug when the filename of a template contains */ + * refactored loaders + +# 0.9.3 (2009-11-11) + +This release is NOT backward compatible with the previous releases. + + The loaders do not take the cache and autoReload arguments anymore. Instead, + the Twig_Environment class has two new options: cache and auto_reload. + Upgrading your code means changing this kind of code: + + $loader = new Twig_Loader_Filesystem('/path/to/templates', '/path/to/compilation_cache', true); + $twig = new Twig_Environment($loader); + + to something like this: + + $loader = new Twig_Loader_Filesystem('/path/to/templates'); + $twig = new Twig_Environment($loader, array( + 'cache' => '/path/to/compilation_cache', + 'auto_reload' => true, + )); + + * deprecated the "items" filter as it is not needed anymore + * made cache and auto_reload options of Twig_Environment instead of arguments of Twig_Loader + * optimized template loading speed + * removed output when an error occurs in a template and render() is used + * made major speed improvements for loops (up to 300% on even the smallest loops) + * added properties as part of the sandbox mode + * added public properties support (obj.item can now be the item property on the obj object) + * extended set tag to support expression as value ({% set foo as 'foo' ~ 'bar' %} ) + * fixed bug when \ was used in HTML + +# 0.9.2 (2009-10-29) + + * made some speed optimizations + * changed the cache extension to .php + * added a js escaping strategy + * added support for short block tag + * changed the filter tag to allow chained filters + * made lexer more flexible as you can now change the default delimiters + * added set tag + * changed default directory permission when cache dir does not exist (more secure) + * added macro support + * changed filters first optional argument to be a Twig_Environment instance instead of a Twig_Template instance + * made Twig_Autoloader::autoload() a static method + * avoid writing template file if an error occurs + * added $ escaping when outputting raw strings + * enhanced some error messages to ease debugging + * fixed empty cache files when the template contains an error + +# 0.9.1 (2009-10-14) + + * fixed a bug in PHP 5.2.6 + * fixed numbers with one than one decimal + * added support for method calls with arguments ({{ foo.bar('a', 43) }}) + * made small speed optimizations + * made minor tweaks to allow better extensibility and flexibility + +# 0.9.0 (2009-10-12) + + * Initial release diff --git a/data/web/inc/lib/vendor/twig/twig/LICENSE b/data/web/inc/lib/vendor/twig/twig/LICENSE new file mode 100644 index 00000000..4371e423 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/LICENSE @@ -0,0 +1,27 @@ +Copyright (c) 2009-2021 by the Twig Team. + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the name of Twig nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/data/web/inc/lib/vendor/twig/twig/README.rst b/data/web/inc/lib/vendor/twig/twig/README.rst new file mode 100644 index 00000000..d896ff50 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/README.rst @@ -0,0 +1,24 @@ +Twig, the flexible, fast, and secure template language for PHP +============================================================== + +Twig is a template language for PHP, released under the new BSD license (code +and documentation). + +Twig uses a syntax similar to the Django and Jinja template languages which +inspired the Twig runtime environment. + +Sponsors +-------- + +.. raw:: html + + + Blackfire.io + + +More Information +---------------- + +Read the `documentation`_ for more information. + +.. _documentation: https://twig.symfony.com/documentation diff --git a/data/web/inc/lib/vendor/twig/twig/composer.json b/data/web/inc/lib/vendor/twig/twig/composer.json new file mode 100644 index 00000000..c344849d --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/composer.json @@ -0,0 +1,50 @@ +{ + "name": "twig/twig", + "type": "library", + "description": "Twig, the flexible, fast, and secure template language for PHP", + "keywords": ["templating"], + "homepage": "https://twig.symfony.com", + "license": "BSD-3-Clause", + "minimum-stability": "dev", + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com", + "homepage": "http://fabien.potencier.org", + "role": "Lead Developer" + }, + { + "name": "Twig Team", + "role": "Contributors" + }, + { + "name": "Armin Ronacher", + "email": "armin.ronacher@active-4.com", + "role": "Project Founder" + } + ], + "require": { + "php": ">=7.2.5", + "symfony/polyfill-mbstring": "^1.3", + "symfony/polyfill-ctype": "^1.8" + }, + "require-dev": { + "symfony/phpunit-bridge": "^4.4.9|^5.0.9", + "psr/container": "^1.0" + }, + "autoload": { + "psr-4" : { + "Twig\\" : "src/" + } + }, + "autoload-dev": { + "psr-4" : { + "Twig\\Tests\\" : "tests/" + } + }, + "extra": { + "branch-alias": { + "dev-master": "3.3-dev" + } + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/doc/.doctor-rst.yaml b/data/web/inc/lib/vendor/twig/twig/doc/.doctor-rst.yaml new file mode 100644 index 00000000..bfb40426 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/doc/.doctor-rst.yaml @@ -0,0 +1,54 @@ +rules: + american_english: ~ + avoid_repetetive_words: ~ + blank_line_after_directive: ~ + blank_line_before_directive: ~ + composer_dev_option_not_at_the_end: ~ + correct_code_block_directive_based_on_the_content: ~ + deprecated_directive_should_have_version: ~ + ensure_order_of_code_blocks_in_configuration_block: ~ + extension_xlf_instead_of_xliff: ~ + indention: ~ + lowercase_as_in_use_statements: ~ + max_blank_lines: + max: 2 + no_blank_line_after_filepath_in_php_code_block: ~ + no_blank_line_after_filepath_in_twig_code_block: ~ + no_blank_line_after_filepath_in_xml_code_block: ~ + no_blank_line_after_filepath_in_yaml_code_block: ~ + no_composer_req: ~ + no_explicit_use_of_code_block_php: ~ + no_inheritdoc: ~ + no_namespace_after_use_statements: ~ + no_php_open_tag_in_code_block_php_directive: ~ + no_space_before_self_xml_closing_tag: ~ + ordered_use_statements: ~ + php_prefix_before_bin_console: ~ + replace_code_block_types: ~ + replacement: ~ + short_array_syntax: ~ + typo: ~ + unused_links: ~ + use_deprecated_directive_instead_of_versionadded: ~ + use_https_xsd_urls: ~ + valid_inline_highlighted_namespaces: ~ + valid_use_statements: ~ + versionadded_directive_should_have_version: ~ + yaml_instead_of_yml_suffix: ~ + yarn_dev_option_at_the_end: ~ + + versionadded_directive_major_version: + major_version: 3 + + versionadded_directive_min_version: + min_version: '3.0' + + deprecated_directive_major_version: + major_version: 3 + + deprecated_directive_min_version: + min_version: '3.0' + +whitelist: + lines: + - 'I like Twig.
    ' diff --git a/data/web/inc/lib/vendor/twig/twig/doc/_build/.requirements.txt b/data/web/inc/lib/vendor/twig/twig/doc/_build/.requirements.txt new file mode 100644 index 00000000..47f076e9 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/doc/_build/.requirements.txt @@ -0,0 +1,6 @@ +docutils==0.13.1 +Pygments==2.2.0 +sphinx==1.8.5 +git+https://github.com/fabpot/sphinx-php.git@v2.0.0#egg_name=sphinx-php +jsx-lexer===0.0.8 +sphinx_rtd_theme==0.5.0 diff --git a/data/web/inc/lib/vendor/twig/twig/doc/_build/Makefile b/data/web/inc/lib/vendor/twig/twig/doc/_build/Makefile new file mode 100644 index 00000000..25b66005 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/doc/_build/Makefile @@ -0,0 +1,153 @@ +# Makefile for Sphinx documentation +# + +# You can set these variables from the command line. +SPHINXOPTS = +SPHINXBUILD = sphinx-build +PAPER = +BUILDDIR = . + +# Internal variables. +PAPEROPT_a4 = -D latex_paper_size=a4 +PAPEROPT_letter = -D latex_paper_size=letter +ALLSPHINXOPTS = -c $(BUILDDIR) -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) ../ +# the i18n builder cannot share the environment and doctrees with the others +I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . + +.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext + +help: + @echo "Please use \`make ' where is one of" + @echo " html to make standalone HTML files" + @echo " dirhtml to make HTML files named index.html in directories" + @echo " singlehtml to make a single large HTML file" + @echo " pickle to make pickle files" + @echo " json to make JSON files" + @echo " htmlhelp to make HTML files and a HTML help project" + @echo " qthelp to make HTML files and a qthelp project" + @echo " devhelp to make HTML files and a Devhelp project" + @echo " epub to make an epub" + @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" + @echo " latexpdf to make LaTeX files and run them through pdflatex" + @echo " text to make text files" + @echo " man to make manual pages" + @echo " texinfo to make Texinfo files" + @echo " info to make Texinfo files and run them through makeinfo" + @echo " gettext to make PO message catalogs" + @echo " changes to make an overview of all changed/added/deprecated items" + @echo " linkcheck to check all external links for integrity" + @echo " doctest to run all doctests embedded in the documentation (if enabled)" + +clean: + -rm -rf $(BUILDDIR)/* + +html: + $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." + +dirhtml: + $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." + +singlehtml: + $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml + @echo + @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." + +pickle: + $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle + @echo + @echo "Build finished; now you can process the pickle files." + +json: + $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json + @echo + @echo "Build finished; now you can process the JSON files." + +htmlhelp: + $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp + @echo + @echo "Build finished; now you can run HTML Help Workshop with the" \ + ".hhp project file in $(BUILDDIR)/htmlhelp." + +qthelp: + $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp + @echo + @echo "Build finished; now you can run "qcollectiongenerator" with the" \ + ".qhcp project file in $(BUILDDIR)/qthelp, like this:" + @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/Symfony.qhcp" + @echo "To view the help file:" + @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/Symfony.qhc" + +devhelp: + $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp + @echo + @echo "Build finished." + @echo "To view the help file:" + @echo "# mkdir -p $$HOME/.local/share/devhelp/Symfony" + @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/Symfony" + @echo "# devhelp" + +epub: + $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub + @echo + @echo "Build finished. The epub file is in $(BUILDDIR)/epub." + +latex: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo + @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." + @echo "Run \`make' in that directory to run these through (pdf)latex" \ + "(use \`make latexpdf' here to do that automatically)." + +latexpdf: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo "Running LaTeX files through pdflatex..." + $(MAKE) -C $(BUILDDIR)/latex all-pdf + @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." + +text: + $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text + @echo + @echo "Build finished. The text files are in $(BUILDDIR)/text." + +man: + $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man + @echo + @echo "Build finished. The manual pages are in $(BUILDDIR)/man." + +texinfo: + $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo + @echo + @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." + @echo "Run \`make' in that directory to run these through makeinfo" \ + "(use \`make info' here to do that automatically)." + +info: + $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo + @echo "Running Texinfo files through makeinfo..." + make -C $(BUILDDIR)/texinfo info + @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." + +gettext: + $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale + @echo + @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." + +changes: + $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes + @echo + @echo "The overview file is in $(BUILDDIR)/changes." + +linkcheck: + $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck + @echo + @echo "Link check complete; look for any errors in the above output " \ + "or in $(BUILDDIR)/linkcheck/output.txt." + +doctest: + $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest + @echo "Testing of doctests in the sources finished, look at the " \ + "results in $(BUILDDIR)/doctest/output.txt." diff --git a/data/web/inc/lib/vendor/twig/twig/doc/_build/conf.py b/data/web/inc/lib/vendor/twig/twig/doc/_build/conf.py new file mode 100644 index 00000000..1e3a8abf --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/doc/_build/conf.py @@ -0,0 +1,271 @@ +# -*- coding: utf-8 -*- +# +# Symfony documentation build configuration file, created by +# sphinx-quickstart on Sat Jul 28 21:58:57 2012. +# +# This file is execfile()d with the current directory set to its containing dir. +# +# Note that not all possible configuration values are present in this +# autogenerated file. +# +# All configuration values have a default; values that are commented out +# serve to show the default. + +import sys, os + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +#sys.path.append(os.path.abspath('_exts')) + +# adding PhpLexer +from sphinx.highlighting import lexers +from pygments.lexers.special import TextLexer +from pygments.lexers.text import RstLexer +from pygments.lexers.web import PhpLexer + +# -- General configuration ----------------------------------------------------- + +# If your documentation needs a minimal Sphinx version, state it here. +needs_sphinx = '1.8.5' + +# Add any Sphinx extension module names here, as strings. They can be extensions +# coming with Sphinx (named 'sphinx.ext.*') or your custom ones. +extensions = [ + 'sphinx.ext.autodoc', 'sphinx.ext.doctest', + 'sphinx.ext.todo', 'sphinx.ext.coverage', 'sphinx.ext.ifconfig', + 'sphinx.ext.viewcode', 'sphinx.ext.extlinks', + 'sensio.sphinx.codeblock', 'sensio.sphinx.configurationblock', 'sensio.sphinx.phpcode', 'sensio.sphinx.bestpractice' +] + +#spelling_show_sugestions=True +#spelling_lang='en_US' +#spelling_word_list_filename='_build/spelling_word_list.txt' + +# Add any paths that contain templates here, relative to this directory. +# templates_path = ['_theme/_templates'] + +# The suffix of source filenames. +source_suffix = '.rst' + +# The encoding of source files. +#source_encoding = 'utf-8-sig' + +# The master toctree document. +master_doc = 'index' + +# General information about the project. +project = 'Twig' +copyright = '' + +# The version info for the project you're documenting, acts as replacement for +# |version| and |release|, also used in various other places throughout the +# built documents. +# +# The short X.Y version. +# version = '2.2' +# The full version, including alpha/beta/rc tags. +# release = '2.2.13' + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +#language = None + +# There are two options for replacing |today|: either, you set today to some +# non-false value, then it is used: +#today = '' +# Else, today_fmt is used as the format for a strftime call. +#today_fmt = '%B %d, %Y' + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +exclude_patterns = ['_build'] + +# The reST default role (used for this markup: `text`) to use for all documents. +#default_role = None + +# If true, '()' will be appended to :func: etc. cross-reference text. +#add_function_parentheses = True + +# If true, the current module name will be prepended to all description +# unit titles (such as .. function::). +#add_module_names = True + +# If true, sectionauthor and moduleauthor directives will be shown in the +# output. They are ignored by default. +#show_authors = False + +# The name of the Pygments (syntax highlighting) style to use. +#pygments_style = 'symfonycom.sphinx.SensioStyle' + +# A list of ignored prefixes for module index sorting. +#modindex_common_prefix = [] + +# -- Settings for symfony doc extension --------------------------------------------------- + +# enable highlighting for PHP code not between ```` by default +lexers['php'] = PhpLexer(startinline=True) +lexers['rst'] = RstLexer() + +config_block = { + 'rst': 'reStructuredText', +} + +# don't enable Sphinx Domains +primary_domain = None + +# set url for API links +#api_url = 'https://github.com/symfony/symfony/blob/master/src/%s.php' + + +# -- Options for HTML output --------------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +html_theme = "sphinx_rtd_theme" + +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +html_theme_options = { + 'logo_only': True, + 'prev_next_buttons_location': None, + 'style_nav_header_background': '#f0f0f0' +} + +# Add any paths that contain custom themes here, relative to this directory. +#html_theme_path = [] + +# The name for this set of Sphinx documents. If None, it defaults to +# " v documentation". +#html_title = None + +# A shorter title for the navigation bar. Default is the same as html_title. +#html_short_title = None + +# The name of an image file (relative to this directory) to place at the top +# of the sidebar. +#html_logo = '_static/symfony-logo.svg' + +# The name of an image file (within the static path) to use as favicon of the +# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 +# pixels large. +#html_favicon = None + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +#html_static_path = ['_static'] +#html_css_files = ['rtd_custom.css'] + +# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, +# using the given strftime format. +#html_last_updated_fmt = '%b %d, %Y' + +# If true, SmartyPants will be used to convert quotes and dashes to +# typographically correct entities. +#html_use_smartypants = True + +# Custom sidebar templates, maps document names to template names. +#html_sidebars = {} + +# Additional templates that should be rendered to pages, maps page names to +# template names. +#html_additional_pages = {} + +# If false, no module index is generated. +#html_domain_indices = True + +# If false, no index is generated. +#html_use_index = True + +# If true, the index is split into individual pages for each letter. +#html_split_index = False + +# If true, links to the reST sources are added to the pages. +#html_show_sourcelink = True + +# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. +#html_show_sphinx = True + +# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. +#html_show_copyright = True + +# If true, an OpenSearch description file will be output, and all pages will +# contain a tag referring to it. The value of this option must be the +# base URL from which the finished HTML is served. +#html_use_opensearch = '' + +# This is the file name suffix for HTML files (e.g. ".xhtml"). +#html_file_suffix = None + +# Output file base name for HTML help builder. +htmlhelp_basename = 'Twig' + + +# -- Options for LaTeX output -------------------------------------------------- + +latex_elements = { +# The paper size ('letterpaper' or 'a4paper'). +#'papersize': 'letterpaper', + +# The font size ('10pt', '11pt' or '12pt'). +#'pointsize': '10pt', + +# Additional stuff for the LaTeX preamble. +#'preamble': '', +} + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, author, documentclass [howto/manual]). +#latex_documents = [] + +# The name of an image file (relative to this directory) to place at the top of +# the title page. +#latex_logo = None + +# For "manual" documents, if this is true, then toplevel headings are parts, +# not chapters. +#latex_use_parts = False + +# If true, show page references after internal links. +#latex_show_pagerefs = False + +# If true, show URL addresses after external links. +#latex_show_urls = False + +# Documents to append as an appendix to all manuals. +#latex_appendices = [] + +# If false, no module index is generated. +#latex_domain_indices = True + + +# -- Options for manual page output -------------------------------------------- + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +#man_pages = [] + +# If true, show URL addresses after external links. +#man_show_urls = False + + +# -- Options for Texinfo output ------------------------------------------------ + +# Grouping the document tree into Texinfo files. List of tuples +# (source start file, target name, title, author, +# dir menu entry, description, category) +#texinfo_documents = [] + +# Documents to append as an appendix to all manuals. +#texinfo_appendices = [] + +# If false, no module index is generated. +#texinfo_domain_indices = True + +# How to display URL addresses: 'footnote', 'no', or 'inline'. +#texinfo_show_urls = 'footnote' + +# Use PHP syntax highlighting in code examples by default +highlight_language='php' diff --git a/data/web/inc/lib/vendor/twig/twig/doc/advanced.rst b/data/web/inc/lib/vendor/twig/twig/doc/advanced.rst new file mode 100644 index 00000000..f801348d --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/doc/advanced.rst @@ -0,0 +1,911 @@ +Extending Twig +============== + +Twig can be extended in many ways; you can add extra tags, filters, tests, +operators, global variables, and functions. You can even extend the parser +itself with node visitors. + +.. note:: + + The first section of this chapter describes how to extend Twig. If you want + to reuse your changes in different projects or if you want to share them + with others, you should then create an extension as described in the + following section. + +.. caution:: + + When extending Twig without creating an extension, Twig won't be able to + recompile your templates when the PHP code is updated. To see your changes + in real-time, either disable template caching or package your code into an + extension (see the next section of this chapter). + +Before extending Twig, you must understand the differences between all the +different possible extension points and when to use them. + +First, remember that Twig has two main language constructs: + +* ``{{ }}``: used to print the result of an expression evaluation; + +* ``{% %}``: used to execute statements. + +To understand why Twig exposes so many extension points, let's see how to +implement a *Lorem ipsum* generator (it needs to know the number of words to +generate). + +You can use a ``lipsum`` *tag*: + +.. code-block:: twig + + {% lipsum 40 %} + +That works, but using a tag for ``lipsum`` is not a good idea for at least +three main reasons: + +* ``lipsum`` is not a language construct; +* The tag outputs something; +* The tag is not flexible as you cannot use it in an expression: + + .. code-block:: twig + + {{ 'some text' ~ {% lipsum 40 %} ~ 'some more text' }} + +In fact, you rarely need to create tags; and that's good news because tags are +the most complex extension point. + +Now, let's use a ``lipsum`` *filter*: + +.. code-block:: twig + + {{ 40|lipsum }} + +Again, it works. But a filter should transform the passed value to something +else. Here, we use the value to indicate the number of words to generate (so, +``40`` is an argument of the filter, not the value we want to transform). + +Next, let's use a ``lipsum`` *function*: + +.. code-block:: twig + + {{ lipsum(40) }} + +Here we go. For this specific example, the creation of a function is the +extension point to use. And you can use it anywhere an expression is accepted: + +.. code-block:: twig + + {{ 'some text' ~ lipsum(40) ~ 'some more text' }} + + {% set lipsum = lipsum(40) %} + +Lastly, you can also use a *global* object with a method able to generate lorem +ipsum text: + +.. code-block:: twig + + {{ text.lipsum(40) }} + +As a rule of thumb, use functions for frequently used features and global +objects for everything else. + +Keep in mind the following when you want to extend Twig: + +========== ========================== ========== ========================= +What? Implementation difficulty? How often? When? +========== ========================== ========== ========================= +*macro* simple frequent Content generation +*global* simple frequent Helper object +*function* simple frequent Content generation +*filter* simple frequent Value transformation +*tag* complex rare DSL language construct +*test* simple rare Boolean decision +*operator* simple rare Values transformation +========== ========================== ========== ========================= + +Globals +------- + +A global variable is like any other template variable, except that it's +available in all templates and macros:: + + $twig = new \Twig\Environment($loader); + $twig->addGlobal('text', new Text()); + +You can then use the ``text`` variable anywhere in a template: + +.. code-block:: twig + + {{ text.lipsum(40) }} + +Filters +------- + +Creating a filter consists of associating a name with a PHP callable:: + + // an anonymous function + $filter = new \Twig\TwigFilter('rot13', function ($string) { + return str_rot13($string); + }); + + // or a simple PHP function + $filter = new \Twig\TwigFilter('rot13', 'str_rot13'); + + // or a class static method + $filter = new \Twig\TwigFilter('rot13', ['SomeClass', 'rot13Filter']); + $filter = new \Twig\TwigFilter('rot13', 'SomeClass::rot13Filter'); + + // or a class method + $filter = new \Twig\TwigFilter('rot13', [$this, 'rot13Filter']); + // the one below needs a runtime implementation (see below for more information) + $filter = new \Twig\TwigFilter('rot13', ['SomeClass', 'rot13Filter']); + +The first argument passed to the ``\Twig\TwigFilter`` constructor is the name of the +filter you will use in templates and the second one is the PHP callable to +associate with it. + +Then, add the filter to the Twig environment:: + + $twig = new \Twig\Environment($loader); + $twig->addFilter($filter); + +And here is how to use it in a template: + +.. code-block:: twig + + {{ 'Twig'|rot13 }} + + {# will output Gjvt #} + +When called by Twig, the PHP callable receives the left side of the filter +(before the pipe ``|``) as the first argument and the extra arguments passed +to the filter (within parentheses ``()``) as extra arguments. + +For instance, the following code: + +.. code-block:: twig + + {{ 'TWIG'|lower }} + {{ now|date('d/m/Y') }} + +is compiled to something like the following:: + + + + +The ``\Twig\TwigFilter`` class takes an array of options as its last argument:: + + $filter = new \Twig\TwigFilter('rot13', 'str_rot13', $options); + +Environment-aware Filters +~~~~~~~~~~~~~~~~~~~~~~~~~ + +If you want to access the current environment instance in your filter, set the +``needs_environment`` option to ``true``; Twig will pass the current +environment as the first argument to the filter call:: + + $filter = new \Twig\TwigFilter('rot13', function (\Twig\Environment $env, $string) { + // get the current charset for instance + $charset = $env->getCharset(); + + return str_rot13($string); + }, ['needs_environment' => true]); + +Context-aware Filters +~~~~~~~~~~~~~~~~~~~~~ + +If you want to access the current context in your filter, set the +``needs_context`` option to ``true``; Twig will pass the current context as +the first argument to the filter call (or the second one if +``needs_environment`` is also set to ``true``):: + + $filter = new \Twig\TwigFilter('rot13', function ($context, $string) { + // ... + }, ['needs_context' => true]); + + $filter = new \Twig\TwigFilter('rot13', function (\Twig\Environment $env, $context, $string) { + // ... + }, ['needs_context' => true, 'needs_environment' => true]); + +Automatic Escaping +~~~~~~~~~~~~~~~~~~ + +If automatic escaping is enabled, the output of the filter may be escaped +before printing. If your filter acts as an escaper (or explicitly outputs HTML +or JavaScript code), you will want the raw output to be printed. In such a +case, set the ``is_safe`` option:: + + $filter = new \Twig\TwigFilter('nl2br', 'nl2br', ['is_safe' => ['html']]); + +Some filters may need to work on input that is already escaped or safe, for +example when adding (safe) HTML tags to originally unsafe output. In such a +case, set the ``pre_escape`` option to escape the input data before it is run +through your filter:: + + $filter = new \Twig\TwigFilter('somefilter', 'somefilter', ['pre_escape' => 'html', 'is_safe' => ['html']]); + +Variadic Filters +~~~~~~~~~~~~~~~~ + +When a filter should accept an arbitrary number of arguments, set the +``is_variadic`` option to ``true``; Twig will pass the extra arguments as the +last argument to the filter call as an array:: + + $filter = new \Twig\TwigFilter('thumbnail', function ($file, array $options = []) { + // ... + }, ['is_variadic' => true]); + +Be warned that :ref:`named arguments ` passed to a variadic +filter cannot be checked for validity as they will automatically end up in the +option array. + +Dynamic Filters +~~~~~~~~~~~~~~~ + +A filter name containing the special ``*`` character is a dynamic filter and +the ``*`` part will match any string:: + + $filter = new \Twig\TwigFilter('*_path', function ($name, $arguments) { + // ... + }); + +The following filters are matched by the above defined dynamic filter: + +* ``product_path`` +* ``category_path`` + +A dynamic filter can define more than one dynamic parts:: + + $filter = new \Twig\TwigFilter('*_path_*', function ($name, $suffix, $arguments) { + // ... + }); + +The filter receives all dynamic part values before the normal filter arguments, +but after the environment and the context. For instance, a call to +``'foo'|a_path_b()`` will result in the following arguments to be passed to the +filter: ``('a', 'b', 'foo')``. + +Deprecated Filters +~~~~~~~~~~~~~~~~~~ + +You can mark a filter as being deprecated by setting the ``deprecated`` option +to ``true``. You can also give an alternative filter that replaces the +deprecated one when that makes sense:: + + $filter = new \Twig\TwigFilter('obsolete', function () { + // ... + }, ['deprecated' => true, 'alternative' => 'new_one']); + +When a filter is deprecated, Twig emits a deprecation notice when compiling a +template using it. See :ref:`deprecation-notices` for more information. + +Functions +--------- + +Functions are defined in the exact same way as filters, but you need to create +an instance of ``\Twig\TwigFunction``:: + + $twig = new \Twig\Environment($loader); + $function = new \Twig\TwigFunction('function_name', function () { + // ... + }); + $twig->addFunction($function); + +Functions support the same features as filters, except for the ``pre_escape`` +and ``preserves_safety`` options. + +Tests +----- + +Tests are defined in the exact same way as filters and functions, but you need +to create an instance of ``\Twig\TwigTest``:: + + $twig = new \Twig\Environment($loader); + $test = new \Twig\TwigTest('test_name', function () { + // ... + }); + $twig->addTest($test); + +Tests allow you to create custom application specific logic for evaluating +boolean conditions. As a simple example, let's create a Twig test that checks if +objects are 'red':: + + $twig = new \Twig\Environment($loader); + $test = new \Twig\TwigTest('red', function ($value) { + if (isset($value->color) && $value->color == 'red') { + return true; + } + if (isset($value->paint) && $value->paint == 'red') { + return true; + } + return false; + }); + $twig->addTest($test); + +Test functions must always return ``true``/``false``. + +When creating tests you can use the ``node_class`` option to provide custom test +compilation. This is useful if your test can be compiled into PHP primitives. +This is used by many of the tests built into Twig:: + + namespace App; + + use Twig\Environment; + use Twig\Node\Expression\TestExpression; + use Twig\TwigTest; + + $twig = new Environment($loader); + $test = new TwigTest( + 'odd', + null, + ['node_class' => OddTestExpression::class]); + $twig->addTest($test); + + class OddTestExpression extends TestExpression + { + public function compile(\Twig\Compiler $compiler) + { + $compiler + ->raw('(') + ->subcompile($this->getNode('node')) + ->raw(' % 2 != 0') + ->raw(')') + ; + } + } + +The above example shows how you can create tests that use a node class. The node +class has access to one sub-node called ``node``. This sub-node contains the +value that is being tested. When the ``odd`` filter is used in code such as: + +.. code-block:: twig + + {% if my_value is odd %} + +The ``node`` sub-node will contain an expression of ``my_value``. Node-based +tests also have access to the ``arguments`` node. This node will contain the +various other arguments that have been provided to your test. + +If you want to pass a variable number of positional or named arguments to the +test, set the ``is_variadic`` option to ``true``. Tests support dynamic +names (see dynamic filters for the syntax). + +Tags +---- + +One of the most exciting features of a template engine like Twig is the +possibility to define new **language constructs**. This is also the most complex +feature as you need to understand how Twig's internals work. + +Most of the time though, a tag is not needed: + +* If your tag generates some output, use a **function** instead. + +* If your tag modifies some content and returns it, use a **filter** instead. + + For instance, if you want to create a tag that converts a Markdown formatted + text to HTML, create a ``markdown`` filter instead: + + .. code-block:: twig + + {{ '**markdown** text'|markdown }} + + If you want use this filter on large amounts of text, wrap it with the + :doc:`apply ` tag: + + .. code-block:: twig + + {% apply markdown %} + Title + ===== + + Much better than creating a tag as you can **compose** filters. + {% endapply %} + +* If your tag does not output anything, but only exists because of a side + effect, create a **function** that returns nothing and call it via the + :doc:`filter ` tag. + + For instance, if you want to create a tag that logs text, create a ``log`` + function instead and call it via the :doc:`do ` tag: + + .. code-block:: twig + + {% do log('Log some things') %} + +If you still want to create a tag for a new language construct, great! + +Let's create a ``set`` tag that allows the definition of simple variables from +within a template. The tag can be used like follows: + +.. code-block:: twig + + {% set name = "value" %} + + {{ name }} + + {# should output value #} + +.. note:: + + The ``set`` tag is part of the Core extension and as such is always + available. The built-in version is slightly more powerful and supports + multiple assignments by default. + +Three steps are needed to define a new tag: + +* Defining a Token Parser class (responsible for parsing the template code); + +* Defining a Node class (responsible for converting the parsed code to PHP); + +* Registering the tag. + +Registering a new tag +~~~~~~~~~~~~~~~~~~~~~ + +Add a tag by calling the ``addTokenParser`` method on the ``\Twig\Environment`` +instance:: + + $twig = new \Twig\Environment($loader); + $twig->addTokenParser(new Project_Set_TokenParser()); + +Defining a Token Parser +~~~~~~~~~~~~~~~~~~~~~~~ + +Now, let's see the actual code of this class:: + + class Project_Set_TokenParser extends \Twig\TokenParser\AbstractTokenParser + { + public function parse(\Twig\Token $token) + { + $parser = $this->parser; + $stream = $parser->getStream(); + + $name = $stream->expect(\Twig\Token::NAME_TYPE)->getValue(); + $stream->expect(\Twig\Token::OPERATOR_TYPE, '='); + $value = $parser->getExpressionParser()->parseExpression(); + $stream->expect(\Twig\Token::BLOCK_END_TYPE); + + return new Project_Set_Node($name, $value, $token->getLine(), $this->getTag()); + } + + public function getTag() + { + return 'set'; + } + } + +The ``getTag()`` method must return the tag we want to parse, here ``set``. + +The ``parse()`` method is invoked whenever the parser encounters a ``set`` +tag. It should return a ``\Twig\Node\Node`` instance that represents the node (the +``Project_Set_Node`` calls creating is explained in the next section). + +The parsing process is simplified thanks to a bunch of methods you can call +from the token stream (``$this->parser->getStream()``): + +* ``getCurrent()``: Gets the current token in the stream. + +* ``next()``: Moves to the next token in the stream, *but returns the old one*. + +* ``test($type)``, ``test($value)`` or ``test($type, $value)``: Determines whether + the current token is of a particular type or value (or both). The value may be an + array of several possible values. + +* ``expect($type[, $value[, $message]])``: If the current token isn't of the given + type/value a syntax error is thrown. Otherwise, if the type and value are correct, + the token is returned and the stream moves to the next token. + +* ``look()``: Looks at the next token without consuming it. + +Parsing expressions is done by calling the ``parseExpression()`` like we did for +the ``set`` tag. + +.. tip:: + + Reading the existing ``TokenParser`` classes is the best way to learn all + the nitty-gritty details of the parsing process. + +Defining a Node +~~~~~~~~~~~~~~~ + +The ``Project_Set_Node`` class itself is quite short:: + + class Project_Set_Node extends \Twig\Node\Node + { + public function __construct($name, \Twig\Node\Expression\AbstractExpression $value, $line, $tag = null) + { + parent::__construct(['value' => $value], ['name' => $name], $line, $tag); + } + + public function compile(\Twig\Compiler $compiler) + { + $compiler + ->addDebugInfo($this) + ->write('$context[\''.$this->getAttribute('name').'\'] = ') + ->subcompile($this->getNode('value')) + ->raw(";\n") + ; + } + } + +The compiler implements a fluid interface and provides methods that helps the +developer generate beautiful and readable PHP code: + +* ``subcompile()``: Compiles a node. + +* ``raw()``: Writes the given string as is. + +* ``write()``: Writes the given string by adding indentation at the beginning + of each line. + +* ``string()``: Writes a quoted string. + +* ``repr()``: Writes a PHP representation of a given value (see + ``\Twig\Node\ForNode`` for a usage example). + +* ``addDebugInfo()``: Adds the line of the original template file related to + the current node as a comment. + +* ``indent()``: Indents the generated code (see ``\Twig\Node\BlockNode`` for a + usage example). + +* ``outdent()``: Outdents the generated code (see ``\Twig\Node\BlockNode`` for a + usage example). + +.. _creating_extensions: + +Creating an Extension +--------------------- + +The main motivation for writing an extension is to move often used code into a +reusable class like adding support for internationalization. An extension can +define tags, filters, tests, operators, functions, and node visitors. + +Most of the time, it is useful to create a single extension for your project, +to host all the specific tags and filters you want to add to Twig. + +.. tip:: + + When packaging your code into an extension, Twig is smart enough to + recompile your templates whenever you make a change to it (when + ``auto_reload`` is enabled). + +An extension is a class that implements the following interface:: + + interface \Twig\Extension\ExtensionInterface + { + /** + * Returns the token parser instances to add to the existing list. + * + * @return \Twig\TokenParser\TokenParserInterface[] + */ + public function getTokenParsers(); + + /** + * Returns the node visitor instances to add to the existing list. + * + * @return \Twig\NodeVisitor\NodeVisitorInterface[] + */ + public function getNodeVisitors(); + + /** + * Returns a list of filters to add to the existing list. + * + * @return \Twig\TwigFilter[] + */ + public function getFilters(); + + /** + * Returns a list of tests to add to the existing list. + * + * @return \Twig\TwigTest[] + */ + public function getTests(); + + /** + * Returns a list of functions to add to the existing list. + * + * @return \Twig\TwigFunction[] + */ + public function getFunctions(); + + /** + * Returns a list of operators to add to the existing list. + * + * @return array First array of unary operators, second array of binary operators + */ + public function getOperators(); + } + +To keep your extension class clean and lean, inherit from the built-in +``\Twig\Extension\AbstractExtension`` class instead of implementing the interface as it provides +empty implementations for all methods:: + + class Project_Twig_Extension extends \Twig\Extension\AbstractExtension + { + } + +This extension does nothing for now. We will customize it in the next sections. + +You can save your extension anywhere on the filesystem, as all extensions must +be registered explicitly to be available in your templates. + +You can register an extension by using the ``addExtension()`` method on your +main ``Environment`` object:: + + $twig = new \Twig\Environment($loader); + $twig->addExtension(new Project_Twig_Extension()); + +.. tip:: + + The Twig core extensions are great examples of how extensions work. + +Globals +~~~~~~~ + +Global variables can be registered in an extension via the ``getGlobals()`` +method:: + + class Project_Twig_Extension extends \Twig\Extension\AbstractExtension implements \Twig\Extension\GlobalsInterface + { + public function getGlobals(): array + { + return [ + 'text' => new Text(), + ]; + } + + // ... + } + +Functions +~~~~~~~~~ + +Functions can be registered in an extension via the ``getFunctions()`` +method:: + + class Project_Twig_Extension extends \Twig\Extension\AbstractExtension + { + public function getFunctions() + { + return [ + new \Twig\TwigFunction('lipsum', 'generate_lipsum'), + ]; + } + + // ... + } + +Filters +~~~~~~~ + +To add a filter to an extension, you need to override the ``getFilters()`` +method. This method must return an array of filters to add to the Twig +environment:: + + class Project_Twig_Extension extends \Twig\Extension\AbstractExtension + { + public function getFilters() + { + return [ + new \Twig\TwigFilter('rot13', 'str_rot13'), + ]; + } + + // ... + } + +Tags +~~~~ + +Adding a tag in an extension can be done by overriding the +``getTokenParsers()`` method. This method must return an array of tags to add +to the Twig environment:: + + class Project_Twig_Extension extends \Twig\Extension\AbstractExtension + { + public function getTokenParsers() + { + return [new Project_Set_TokenParser()]; + } + + // ... + } + +In the above code, we have added a single new tag, defined by the +``Project_Set_TokenParser`` class. The ``Project_Set_TokenParser`` class is +responsible for parsing the tag and compiling it to PHP. + +Operators +~~~~~~~~~ + +The ``getOperators()`` methods lets you add new operators. Here is how to add +the ``!``, ``||``, and ``&&`` operators:: + + class Project_Twig_Extension extends \Twig\Extension\AbstractExtension + { + public function getOperators() + { + return [ + [ + '!' => ['precedence' => 50, 'class' => \Twig\Node\Expression\Unary\NotUnary::class], + ], + [ + '||' => ['precedence' => 10, 'class' => \Twig\Node\Expression\Binary\OrBinary::class, 'associativity' => \Twig\ExpressionParser::OPERATOR_LEFT], + '&&' => ['precedence' => 15, 'class' => \Twig\Node\Expression\Binary\AndBinary::class, 'associativity' => \Twig\ExpressionParser::OPERATOR_LEFT], + ], + ]; + } + + // ... + } + +Tests +~~~~~ + +The ``getTests()`` method lets you add new test functions:: + + class Project_Twig_Extension extends \Twig\Extension\AbstractExtension + { + public function getTests() + { + return [ + new \Twig\TwigTest('even', 'twig_test_even'), + ]; + } + + // ... + } + +Definition vs Runtime +~~~~~~~~~~~~~~~~~~~~~ + +Twig filters, functions, and tests runtime implementations can be defined as +any valid PHP callable: + +* **functions/static methods**: Simple to implement and fast (used by all Twig + core extensions); but it is hard for the runtime to depend on external + objects; + +* **closures**: Simple to implement; + +* **object methods**: More flexible and required if your runtime code depends + on external objects. + +The simplest way to use methods is to define them on the extension itself:: + + class Project_Twig_Extension extends \Twig\Extension\AbstractExtension + { + private $rot13Provider; + + public function __construct($rot13Provider) + { + $this->rot13Provider = $rot13Provider; + } + + public function getFunctions() + { + return [ + new \Twig\TwigFunction('rot13', [$this, 'rot13']), + ]; + } + + public function rot13($value) + { + return $this->rot13Provider->rot13($value); + } + } + +This is very convenient but not recommended as it makes template compilation +depend on runtime dependencies even if they are not needed (think for instance +as a dependency that connects to a database engine). + +You can decouple the extension definitions from their runtime implementations by +registering a ``\Twig\RuntimeLoader\RuntimeLoaderInterface`` instance on the +environment that knows how to instantiate such runtime classes (runtime classes +must be autoload-able):: + + class RuntimeLoader implements \Twig\RuntimeLoader\RuntimeLoaderInterface + { + public function load($class) + { + // implement the logic to create an instance of $class + // and inject its dependencies + // most of the time, it means using your dependency injection container + if ('Project_Twig_RuntimeExtension' === $class) { + return new $class(new Rot13Provider()); + } else { + // ... + } + } + } + + $twig->addRuntimeLoader(new RuntimeLoader()); + +.. note:: + + Twig comes with a PSR-11 compatible runtime loader + (``\Twig\RuntimeLoader\ContainerRuntimeLoader``). + +It is now possible to move the runtime logic to a new +``Project_Twig_RuntimeExtension`` class and use it directly in the extension:: + + class Project_Twig_RuntimeExtension + { + private $rot13Provider; + + public function __construct($rot13Provider) + { + $this->rot13Provider = $rot13Provider; + } + + public function rot13($value) + { + return $this->rot13Provider->rot13($value); + } + } + + class Project_Twig_Extension extends \Twig\Extension\AbstractExtension + { + public function getFunctions() + { + return [ + new \Twig\TwigFunction('rot13', ['Project_Twig_RuntimeExtension', 'rot13']), + // or + new \Twig\TwigFunction('rot13', 'Project_Twig_RuntimeExtension::rot13'), + ]; + } + } + +Testing an Extension +-------------------- + +Functional Tests +~~~~~~~~~~~~~~~~ + +You can create functional tests for extensions by creating the following file +structure in your test directory:: + + Fixtures/ + filters/ + foo.test + bar.test + functions/ + foo.test + bar.test + tags/ + foo.test + bar.test + IntegrationTest.php + +The ``IntegrationTest.php`` file should look like this:: + + use Twig\Test\IntegrationTestCase; + + class Project_Tests_IntegrationTest extends IntegrationTestCase + { + public function getExtensions() + { + return [ + new Project_Twig_Extension1(), + new Project_Twig_Extension2(), + ]; + } + + public function getFixturesDir() + { + return __DIR__.'/Fixtures/'; + } + } + +Fixtures examples can be found within the Twig repository +`tests/Twig/Fixtures`_ directory. + +Node Tests +~~~~~~~~~~ + +Testing the node visitors can be complex, so extend your test cases from +``\Twig\Test\NodeTestCase``. Examples can be found in the Twig repository +`tests/Twig/Node`_ directory. + +.. _`tests/Twig/Fixtures`: https://github.com/twigphp/Twig/tree/3.x/tests/Fixtures +.. _`tests/Twig/Node`: https://github.com/twigphp/Twig/tree/3.x/tests/Node diff --git a/data/web/inc/lib/vendor/twig/twig/doc/api.rst b/data/web/inc/lib/vendor/twig/twig/doc/api.rst new file mode 100644 index 00000000..80dfaa58 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/doc/api.rst @@ -0,0 +1,583 @@ +Twig for Developers +=================== + +This chapter describes the API to Twig and not the template language. It will +be most useful as reference to those implementing the template interface to +the application and not those who are creating Twig templates. + +Basics +------ + +Twig uses a central object called the **environment** (of class +``\Twig\Environment``). Instances of this class are used to store the +configuration and extensions, and are used to load templates. + +Most applications create one ``\Twig\Environment`` object on application +initialization and use that to load templates. In some cases, it might be useful +to have multiple environments side by side, with different configurations. + +The typical way to configure Twig to load templates for an application looks +roughly like this:: + + require_once '/path/to/vendor/autoload.php'; + + $loader = new \Twig\Loader\FilesystemLoader('/path/to/templates'); + $twig = new \Twig\Environment($loader, [ + 'cache' => '/path/to/compilation_cache', + ]); + +This creates a template environment with a default configuration and a loader +that looks up templates in the ``/path/to/templates/`` directory. Different +loaders are available and you can also write your own if you want to load +templates from a database or other resources. + +.. note:: + + Notice that the second argument of the environment is an array of options. + The ``cache`` option is a compilation cache directory, where Twig caches + the compiled templates to avoid the parsing phase for sub-sequent + requests. It is very different from the cache you might want to add for + the evaluated templates. For such a need, you can use any available PHP + cache library. + +Rendering Templates +------------------- + +To load a template from a Twig environment, call the ``load()`` method which +returns a ``\Twig\TemplateWrapper`` instance:: + + $template = $twig->load('index.html'); + +To render the template with some variables, call the ``render()`` method:: + + echo $template->render(['the' => 'variables', 'go' => 'here']); + +.. note:: + + The ``display()`` method is a shortcut to output the rendered template. + +You can also load and render the template in one fell swoop:: + + echo $twig->render('index.html', ['the' => 'variables', 'go' => 'here']); + +If a template defines blocks, they can be rendered individually via the +``renderBlock()`` call:: + + echo $template->renderBlock('block_name', ['the' => 'variables', 'go' => 'here']); + +.. _environment_options: + +Environment Options +------------------- + +When creating a new ``\Twig\Environment`` instance, you can pass an array of +options as the constructor second argument:: + + $twig = new \Twig\Environment($loader, ['debug' => true]); + +The following options are available: + +* ``debug`` *boolean* + + When set to ``true``, the generated templates have a + ``__toString()`` method that you can use to display the generated nodes + (default to ``false``). + +* ``charset`` *string* (defaults to ``utf-8``) + + The charset used by the templates. + +* ``cache`` *string* or ``false`` + + An absolute path where to store the compiled templates, or + ``false`` to disable caching (which is the default). + +* ``auto_reload`` *boolean* + + When developing with Twig, it's useful to recompile the + template whenever the source code changes. If you don't provide a value for + the ``auto_reload`` option, it will be determined automatically based on the + ``debug`` value. + +* ``strict_variables`` *boolean* + + If set to ``false``, Twig will silently ignore invalid + variables (variables and or attributes/methods that do not exist) and + replace them with a ``null`` value. When set to ``true``, Twig throws an + exception instead (default to ``false``). + +* ``autoescape`` *string* + + Sets the default auto-escaping strategy (``name``, ``html``, ``js``, ``css``, + ``url``, ``html_attr``, or a PHP callback that takes the template "filename" + and returns the escaping strategy to use -- the callback cannot be a function + name to avoid collision with built-in escaping strategies); set it to + ``false`` to disable auto-escaping. The ``name`` escaping strategy determines + the escaping strategy to use for a template based on the template filename + extension (this strategy does not incur any overhead at runtime as + auto-escaping is done at compilation time.) + +* ``optimizations`` *integer* + + A flag that indicates which optimizations to apply + (default to ``-1`` -- all optimizations are enabled; set it to ``0`` to + disable). + +Loaders +------- + +Loaders are responsible for loading templates from a resource such as the file +system. + +Compilation Cache +~~~~~~~~~~~~~~~~~ + +All template loaders can cache the compiled templates on the filesystem for +future reuse. It speeds up Twig a lot as templates are only compiled once. + +Built-in Loaders +~~~~~~~~~~~~~~~~ + +Here is a list of the built-in loaders: + +``\Twig\Loader\FilesystemLoader`` +................................. + +``\Twig\Loader\FilesystemLoader`` loads templates from the file system. This loader +can find templates in folders on the file system and is the preferred way to +load them:: + + $loader = new \Twig\Loader\FilesystemLoader($templateDir); + +It can also look for templates in an array of directories:: + + $loader = new \Twig\Loader\FilesystemLoader([$templateDir1, $templateDir2]); + +With such a configuration, Twig will first look for templates in +``$templateDir1`` and if they do not exist, it will fallback to look for them +in the ``$templateDir2``. + +You can add or prepend paths via the ``addPath()`` and ``prependPath()`` +methods:: + + $loader->addPath($templateDir3); + $loader->prependPath($templateDir4); + +The filesystem loader also supports namespaced templates. This allows to group +your templates under different namespaces which have their own template paths. + +When using the ``setPaths()``, ``addPath()``, and ``prependPath()`` methods, +specify the namespace as the second argument (when not specified, these +methods act on the "main" namespace):: + + $loader->addPath($templateDir, 'admin'); + +Namespaced templates can be accessed via the special +``@namespace_name/template_path`` notation:: + + $twig->render('@admin/index.html', []); + +``\Twig\Loader\FilesystemLoader`` support absolute and relative paths. Using relative +paths is preferred as it makes the cache keys independent of the project root +directory (for instance, it allows warming the cache from a build server where +the directory might be different from the one used on production servers):: + + $loader = new \Twig\Loader\FilesystemLoader('templates', getcwd().'/..'); + +.. note:: + + When not passing the root path as a second argument, Twig uses ``getcwd()`` + for relative paths. + +``\Twig\Loader\ArrayLoader`` +............................ + +``\Twig\Loader\ArrayLoader`` loads a template from a PHP array. It is passed an +array of strings bound to template names:: + + $loader = new \Twig\Loader\ArrayLoader([ + 'index.html' => 'Hello {{ name }}!', + ]); + $twig = new \Twig\Environment($loader); + + echo $twig->render('index.html', ['name' => 'Fabien']); + +This loader is very useful for unit testing. It can also be used for small +projects where storing all templates in a single PHP file might make sense. + +.. tip:: + + When using the ``Array`` loader with a cache mechanism, you should know that + a new cache key is generated each time a template content "changes" (the + cache key being the source code of the template). If you don't want to see + your cache grows out of control, you need to take care of clearing the old + cache file by yourself. + +``\Twig\Loader\ChainLoader`` +............................ + +``\Twig\Loader\ChainLoader`` delegates the loading of templates to other loaders:: + + $loader1 = new \Twig\Loader\ArrayLoader([ + 'base.html' => '{% block content %}{% endblock %}', + ]); + $loader2 = new \Twig\Loader\ArrayLoader([ + 'index.html' => '{% extends "base.html" %}{% block content %}Hello {{ name }}{% endblock %}', + 'base.html' => 'Will never be loaded', + ]); + + $loader = new \Twig\Loader\ChainLoader([$loader1, $loader2]); + + $twig = new \Twig\Environment($loader); + +When looking for a template, Twig tries each loader in turn and returns as soon +as the template is found. When rendering the ``index.html`` template from the +above example, Twig will load it with ``$loader2`` but the ``base.html`` +template will be loaded from ``$loader1``. + +.. note:: + + You can also add loaders via the ``addLoader()`` method. + +Create your own Loader +~~~~~~~~~~~~~~~~~~~~~~ + +All loaders implement the ``\Twig\Loader\LoaderInterface``:: + + interface \Twig\Loader\LoaderInterface + { + /** + * Returns the source context for a given template logical name. + * + * @param string $name The template logical name + * + * @return \Twig\Source + * + * @throws \Twig\Error\LoaderError When $name is not found + */ + public function getSourceContext($name); + + /** + * Gets the cache key to use for the cache for a given template name. + * + * @param string $name The name of the template to load + * + * @return string The cache key + * + * @throws \Twig\Error\LoaderError When $name is not found + */ + public function getCacheKey($name); + + /** + * Returns true if the template is still fresh. + * + * @param string $name The template name + * @param timestamp $time The last modification time of the cached template + * + * @return bool true if the template is fresh, false otherwise + * + * @throws \Twig\Error\LoaderError When $name is not found + */ + public function isFresh($name, $time); + + /** + * Check if we have the source code of a template, given its name. + * + * @param string $name The name of the template to check if we can load + * + * @return bool If the template source code is handled by this loader or not + */ + public function exists($name); + } + +The ``isFresh()`` method must return ``true`` if the current cached template +is still fresh, given the last modification time, or ``false`` otherwise. + +The ``getSourceContext()`` method must return an instance of ``\Twig\Source``. + +Using Extensions +---------------- + +Twig extensions are packages that add new features to Twig. Register an +extension via the ``addExtension()`` method:: + + $twig->addExtension(new \Twig\Extension\SandboxExtension()); + +Twig comes bundled with the following extensions: + +* *Twig\Extension\CoreExtension*: Defines all the core features of Twig. + +* *Twig\Extension\DebugExtension*: Defines the ``dump`` function to help debug + template variables. + +* *Twig\Extension\EscaperExtension*: Adds automatic output-escaping and the + possibility to escape/unescape blocks of code. + +* *Twig\Extension\SandboxExtension*: Adds a sandbox mode to the default Twig + environment, making it safe to evaluate untrusted code. + +* *Twig\Extension\ProfilerExtension*: Enables the built-in Twig profiler. + +* *Twig\Extension\OptimizerExtension*: Optimizes the node tree before + compilation. + +* *Twig\Extension\StringLoaderExtension*: Defines the ``template_from_string`` + function to allow loading templates from string in a template. + +The Core, Escaper, and Optimizer extensions are registered by default. + +Built-in Extensions +------------------- + +This section describes the features added by the built-in extensions. + +.. tip:: + + Read the chapter about :doc:`extending Twig ` to learn how to + create your own extensions. + +Core Extension +~~~~~~~~~~~~~~ + +The ``core`` extension defines all the core features of Twig: + +* :doc:`Tags `; +* :doc:`Filters `; +* :doc:`Functions `; +* :doc:`Tests `. + +Escaper Extension +~~~~~~~~~~~~~~~~~ + +The ``escaper`` extension adds automatic output escaping to Twig. It defines a +tag, ``autoescape``, and a filter, ``raw``. + +When creating the escaper extension, you can switch on or off the global +output escaping strategy:: + + $escaper = new \Twig\Extension\EscaperExtension('html'); + $twig->addExtension($escaper); + +If set to ``html``, all variables in templates are escaped (using the ``html`` +escaping strategy), except those using the ``raw`` filter: + +.. code-block:: twig + + {{ article.to_html|raw }} + +You can also change the escaping mode locally by using the ``autoescape`` tag: + +.. code-block:: twig + + {% autoescape 'html' %} + {{ var }} + {{ var|raw }} {# var won't be escaped #} + {{ var|escape }} {# var won't be double-escaped #} + {% endautoescape %} + +.. warning:: + + The ``autoescape`` tag has no effect on included files. + +The escaping rules are implemented as follows: + +* Literals (integers, booleans, arrays, ...) used in the template directly as + variables or filter arguments are never automatically escaped: + + .. code-block:: html+twig + + {{ "Twig
    " }} {# won't be escaped #} + + {% set text = "Twig
    " %} + {{ text }} {# will be escaped #} + +* Expressions which the result is a literal or a variable marked safe + are never automatically escaped: + + .. code-block:: html+twig + + {{ foo ? "Twig
    " : "
    Twig" }} {# won't be escaped #} + + {% set text = "Twig
    " %} + {{ true ? text : "
    Twig" }} {# will be escaped #} + {{ false ? text : "
    Twig" }} {# won't be escaped #} + + {% set text = "Twig
    " %} + {{ foo ? text|raw : "
    Twig" }} {# won't be escaped #} + +* Objects with a ``__toString`` method are converted to strings and + escaped. You can mark some classes and/or interfaces as being safe for some + strategies via ``EscaperExtension::addSafeClass()``: + + .. code-block:: twig + + // mark object of class Foo as safe for the HTML strategy + $escaper->addSafeClass('Foo', ['html']); + + // mark object of interface Foo as safe for the HTML strategy + $escaper->addSafeClass('FooInterface', ['html']); + + // mark object of class Foo as safe for the HTML and JS strategies + $escaper->addSafeClass('Foo', ['html', 'js']); + + // mark object of class Foo as safe for all strategies + $escaper->addSafeClass('Foo', ['all']); + +* Escaping is applied before printing, after any other filter is applied: + + .. code-block:: twig + + {{ var|upper }} {# is equivalent to {{ var|upper|escape }} #} + +* The `raw` filter should only be used at the end of the filter chain: + + .. code-block:: twig + + {{ var|raw|upper }} {# will be escaped #} + + {{ var|upper|raw }} {# won't be escaped #} + +* Automatic escaping is not applied if the last filter in the chain is marked + safe for the current context (e.g. ``html`` or ``js``). ``escape`` and + ``escape('html')`` are marked safe for HTML, ``escape('js')`` is marked + safe for JavaScript, ``raw`` is marked safe for everything. + + .. code-block:: twig + + {% autoescape 'js' %} + {{ var|escape('html') }} {# will be escaped for HTML and JavaScript #} + {{ var }} {# will be escaped for JavaScript #} + {{ var|escape('js') }} {# won't be double-escaped #} + {% endautoescape %} + +.. note:: + + Note that autoescaping has some limitations as escaping is applied on + expressions after evaluation. For instance, when working with + concatenation, ``{{ foo|raw ~ bar }}`` won't give the expected result as + escaping is applied on the result of the concatenation, not on the + individual variables (so, the ``raw`` filter won't have any effect here). + +Sandbox Extension +~~~~~~~~~~~~~~~~~ + +The ``sandbox`` extension can be used to evaluate untrusted code. Access to +unsafe attributes and methods is prohibited. The sandbox security is managed +by a policy instance. By default, Twig comes with one policy class: +``\Twig\Sandbox\SecurityPolicy``. This class allows you to white-list some +tags, filters, properties, and methods:: + + $tags = ['if']; + $filters = ['upper']; + $methods = [ + 'Article' => ['getTitle', 'getBody'], + ]; + $properties = [ + 'Article' => ['title', 'body'], + ]; + $functions = ['range']; + $policy = new \Twig\Sandbox\SecurityPolicy($tags, $filters, $methods, $properties, $functions); + +With the previous configuration, the security policy will only allow usage of +the ``if`` tag, and the ``upper`` filter. Moreover, the templates will only be +able to call the ``getTitle()`` and ``getBody()`` methods on ``Article`` +objects, and the ``title`` and ``body`` public properties. Everything else +won't be allowed and will generate a ``\Twig\Sandbox\SecurityError`` exception. + +The policy object is the first argument of the sandbox constructor:: + + $sandbox = new \Twig\Extension\SandboxExtension($policy); + $twig->addExtension($sandbox); + +By default, the sandbox mode is disabled and should be enabled when including +untrusted template code by using the ``sandbox`` tag: + +.. code-block:: twig + + {% sandbox %} + {% include 'user.html' %} + {% endsandbox %} + +You can sandbox all templates by passing ``true`` as the second argument of +the extension constructor:: + + $sandbox = new \Twig\Extension\SandboxExtension($policy, true); + +Profiler Extension +~~~~~~~~~~~~~~~~~~ + +The ``profiler`` extension enables a profiler for Twig templates; it should +only be used on your development machines as it adds some overhead:: + + $profile = new \Twig\Profiler\Profile(); + $twig->addExtension(new \Twig\Extension\ProfilerExtension($profile)); + + $dumper = new \Twig\Profiler\Dumper\TextDumper(); + echo $dumper->dump($profile); + +A profile contains information about time and memory consumption for template, +block, and macro executions. + +You can also dump the data in a `Blackfire.io `_ +compatible format:: + + $dumper = new \Twig\Profiler\Dumper\BlackfireDumper(); + file_put_contents('/path/to/profile.prof', $dumper->dump($profile)); + +Upload the profile to visualize it (create a `free account +`_ +first): + +.. code-block:: sh + + blackfire --slot=7 upload /path/to/profile.prof + +Optimizer Extension +~~~~~~~~~~~~~~~~~~~ + +The ``optimizer`` extension optimizes the node tree before compilation:: + + $twig->addExtension(new \Twig\Extension\OptimizerExtension()); + +By default, all optimizations are turned on. You can select the ones you want +to enable by passing them to the constructor:: + + $optimizer = new \Twig\Extension\OptimizerExtension(\Twig\NodeVisitor\OptimizerNodeVisitor::OPTIMIZE_FOR); + + $twig->addExtension($optimizer); + +Twig supports the following optimizations: + +* ``\Twig\NodeVisitor\OptimizerNodeVisitor::OPTIMIZE_ALL``, enables all optimizations + (this is the default value). + +* ``\Twig\NodeVisitor\OptimizerNodeVisitor::OPTIMIZE_NONE``, disables all optimizations. + This reduces the compilation time, but it can increase the execution time + and the consumed memory. + +* ``\Twig\NodeVisitor\OptimizerNodeVisitor::OPTIMIZE_FOR``, optimizes the ``for`` tag by + removing the ``loop`` variable creation whenever possible. + +* ``\Twig\NodeVisitor\OptimizerNodeVisitor::OPTIMIZE_RAW_FILTER``, removes the ``raw`` + filter whenever possible. + +* ``\Twig\NodeVisitor\OptimizerNodeVisitor::OPTIMIZE_VAR_ACCESS``, simplifies the creation + and access of variables in the compiled templates whenever possible. + +Exceptions +---------- + +Twig can throw exceptions: + +* ``\Twig\Error\Error``: The base exception for all errors. + +* ``\Twig\Error\SyntaxError``: Thrown to tell the user that there is a problem with + the template syntax. + +* ``\Twig\Error\RuntimeError``: Thrown when an error occurs at runtime (when a filter + does not exist for instance). + +* ``\Twig\Error\LoaderError``: Thrown when an error occurs during template loading. + +* ``\Twig\Sandbox\SecurityError``: Thrown when an unallowed tag, filter, or + method is called in a sandboxed template. diff --git a/data/web/inc/lib/vendor/twig/twig/doc/coding_standards.rst b/data/web/inc/lib/vendor/twig/twig/doc/coding_standards.rst new file mode 100644 index 00000000..721b0f13 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/doc/coding_standards.rst @@ -0,0 +1,101 @@ +Coding Standards +================ + +When writing Twig templates, we recommend you to follow these official coding +standards: + +* Put one (and only one) space after the start of a delimiter (``{{``, ``{%``, + and ``{#``) and before the end of a delimiter (``}}``, ``%}``, and ``#}``): + + .. code-block:: twig + + {{ foo }} + {# comment #} + {% if foo %}{% endif %} + + When using the whitespace control character, do not put any spaces between + it and the delimiter: + + .. code-block:: twig + + {{- foo -}} + {#- comment -#} + {%- if foo -%}{%- endif -%} + +* Put one (and only one) space before and after the following operators: + comparison operators (``==``, ``!=``, ``<``, ``>``, ``>=``, ``<=``), math + operators (``+``, ``-``, ``/``, ``*``, ``%``, ``//``, ``**``), logic + operators (``not``, ``and``, ``or``), ``~``, ``is``, ``in``, and the ternary + operator (``?:``): + + .. code-block:: twig + + {{ 1 + 2 }} + {{ foo ~ bar }} + {{ true ? true : false }} + +* Put one (and only one) space after the ``:`` sign in hashes and ``,`` in + arrays and hashes: + + .. code-block:: twig + + {{ [1, 2, 3] }} + {{ {'foo': 'bar'} }} + +* Do not put any spaces after an opening parenthesis and before a closing + parenthesis in expressions: + + .. code-block:: twig + + {{ 1 + (2 * 3) }} + +* Do not put any spaces before and after string delimiters: + + .. code-block:: twig + + {{ 'foo' }} + {{ "foo" }} + +* Do not put any spaces before and after the following operators: ``|``, + ``.``, ``..``, ``[]``: + + .. code-block:: twig + + {{ foo|upper|lower }} + {{ user.name }} + {{ user[name] }} + {% for i in 1..12 %}{% endfor %} + +* Do not put any spaces before and after the parenthesis used for filter and + function calls: + + .. code-block:: twig + + {{ foo|default('foo') }} + {{ range(1..10) }} + +* Do not put any spaces before and after the opening and the closing of arrays + and hashes: + + .. code-block:: twig + + {{ [1, 2, 3] }} + {{ {'foo': 'bar'} }} + +* Use lower cased and underscored variable names: + + .. code-block:: twig + + {% set foo = 'foo' %} + {% set foo_bar = 'foo' %} + +* Indent your code inside tags (use the same indentation as the one used for + the target language of the rendered template): + + .. code-block:: twig + + {% block foo %} + {% if true %} + true + {% endif %} + {% endblock %} diff --git a/data/web/inc/lib/vendor/twig/twig/doc/deprecated.rst b/data/web/inc/lib/vendor/twig/twig/doc/deprecated.rst new file mode 100644 index 00000000..ac22338e --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/doc/deprecated.rst @@ -0,0 +1,6 @@ +Deprecated Features +=================== + +This document lists deprecated features in Twig 3.x. Deprecated features are +kept for backward compatibility and removed in the next major release (a +feature that was deprecated in Twig 3.x is removed in Twig 4.0). diff --git a/data/web/inc/lib/vendor/twig/twig/doc/filters/abs.rst b/data/web/inc/lib/vendor/twig/twig/doc/filters/abs.rst new file mode 100644 index 00000000..77d5cf05 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/doc/filters/abs.rst @@ -0,0 +1,18 @@ +``abs`` +======= + +The ``abs`` filter returns the absolute value. + +.. code-block:: twig + + {# number = -5 #} + + {{ number|abs }} + + {# outputs 5 #} + +.. note:: + + Internally, Twig uses the PHP `abs`_ function. + +.. _`abs`: https://secure.php.net/abs diff --git a/data/web/inc/lib/vendor/twig/twig/doc/filters/batch.rst b/data/web/inc/lib/vendor/twig/twig/doc/filters/batch.rst new file mode 100644 index 00000000..18a227fe --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/doc/filters/batch.rst @@ -0,0 +1,44 @@ +``batch`` +========= + +The ``batch`` filter "batches" items by returning a list of lists with the +given number of items. A second parameter can be provided and used to fill in +missing items: + +.. code-block:: html+twig + + {% set items = ['a', 'b', 'c', 'd'] %} + + + {% for row in items|batch(3, 'No item') %} + + {% for column in row %} + + {% endfor %} + + {% endfor %} +
    {{ column }}
    + +The above example will be rendered as: + +.. code-block:: html+twig + + + + + + + + + + + + +
    abc
    dNo itemNo item
    + +Arguments +--------- + +* ``size``: The size of the batch; fractional numbers will be rounded up +* ``fill``: Used to fill in missing items +* ``preserve_keys``: Whether to preserve keys or not diff --git a/data/web/inc/lib/vendor/twig/twig/doc/filters/capitalize.rst b/data/web/inc/lib/vendor/twig/twig/doc/filters/capitalize.rst new file mode 100644 index 00000000..2353658b --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/doc/filters/capitalize.rst @@ -0,0 +1,11 @@ +``capitalize`` +============== + +The ``capitalize`` filter capitalizes a value. The first character will be +uppercase, all others lowercase: + +.. code-block:: twig + + {{ 'my first car'|capitalize }} + + {# outputs 'My first car' #} diff --git a/data/web/inc/lib/vendor/twig/twig/doc/filters/column.rst b/data/web/inc/lib/vendor/twig/twig/doc/filters/column.rst new file mode 100644 index 00000000..5b6769b8 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/doc/filters/column.rst @@ -0,0 +1,24 @@ +``column`` +========== + +The ``column`` filter returns the values from a single column in the input +array. + +.. code-block:: twig + + {% set items = [{ 'fruit' : 'apple'}, {'fruit' : 'orange' }] %} + + {% set fruits = items|column('fruit') %} + + {# fruits now contains ['apple', 'orange'] #} + +.. note:: + + Internally, Twig uses the PHP `array_column`_ function. + +Arguments +--------- + +* ``name``: The column name to extract + +.. _`array_column`: https://secure.php.net/array_column diff --git a/data/web/inc/lib/vendor/twig/twig/doc/filters/convert_encoding.rst b/data/web/inc/lib/vendor/twig/twig/doc/filters/convert_encoding.rst new file mode 100644 index 00000000..d977c752 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/doc/filters/convert_encoding.rst @@ -0,0 +1,22 @@ +``convert_encoding`` +==================== + +The ``convert_encoding`` filter converts a string from one encoding to +another. The first argument is the expected output charset and the second one +is the input charset: + +.. code-block:: twig + + {{ data|convert_encoding('UTF-8', 'iso-2022-jp') }} + +.. note:: + + This filter relies on the `iconv`_ extension. + +Arguments +--------- + +* ``to``: The output charset +* ``from``: The input charset + +.. _`iconv`: https://secure.php.net/iconv diff --git a/data/web/inc/lib/vendor/twig/twig/doc/filters/country_name.rst b/data/web/inc/lib/vendor/twig/twig/doc/filters/country_name.rst new file mode 100644 index 00000000..434b0bda --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/doc/filters/country_name.rst @@ -0,0 +1,44 @@ +``country_name`` +================ + +The ``country_name`` filter returns the country name given its ISO-3166 +two-letter code: + +.. code-block:: twig + + {# France #} + {{ 'FR'|country_name }} + +By default, the filter uses the current locale. You can pass it explicitly: + +.. code-block:: twig + + {# États-Unis #} + {{ 'US'|country_name('fr') }} + +.. note:: + + The ``country_name`` filter is part of the ``IntlExtension`` which is not + installed by default. Install it first: + + .. code-block:: bash + + $ composer require twig/intl-extra + + Then, on Symfony projects, install the ``twig/extra-bundle``: + + .. code-block:: bash + + $ composer require twig/extra-bundle + + Otherwise, add the extension explicitly on the Twig environment:: + + use Twig\Extra\Intl\IntlExtension; + + $twig = new \Twig\Environment(...); + $twig->addExtension(new IntlExtension()); + +Arguments +--------- + +* ``locale``: The locale diff --git a/data/web/inc/lib/vendor/twig/twig/doc/filters/currency_name.rst b/data/web/inc/lib/vendor/twig/twig/doc/filters/currency_name.rst new file mode 100644 index 00000000..a35c4999 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/doc/filters/currency_name.rst @@ -0,0 +1,47 @@ +``currency_name`` +================= + +The ``currency_name`` filter returns the currency name given its three-letter +code: + +.. code-block:: twig + + {# Euro #} + {{ 'EUR'|currency_name }} + + {# Japanese Yen #} + {{ 'JPY'|currency_name }} + +By default, the filter uses the current locale. You can pass it explicitly: + +.. code-block:: twig + + {# yen japonais #} + {{ 'JPY'|currency_name('fr_FR') }} + +.. note:: + + The ``currency_name`` filter is part of the ``IntlExtension`` which is not + installed by default. Install it first: + + .. code-block:: bash + + $ composer require twig/intl-extra + + Then, on Symfony projects, install the ``twig/extra-bundle``: + + .. code-block:: bash + + $ composer require twig/extra-bundle + + Otherwise, add the extension explicitly on the Twig environment:: + + use Twig\Extra\Intl\IntlExtension; + + $twig = new \Twig\Environment(...); + $twig->addExtension(new IntlExtension()); + +Arguments +--------- + +* ``locale``: The locale diff --git a/data/web/inc/lib/vendor/twig/twig/doc/filters/currency_symbol.rst b/data/web/inc/lib/vendor/twig/twig/doc/filters/currency_symbol.rst new file mode 100644 index 00000000..84a048ed --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/doc/filters/currency_symbol.rst @@ -0,0 +1,47 @@ +``currency_symbol`` +=================== + +The ``currency_symbol`` filter returns the currency symbol given its three-letter +code: + +.. code-block:: twig + + {# € #} + {{ 'EUR'|currency_symbol }} + + {# ¥ #} + {{ 'JPY'|currency_symbol }} + +By default, the filter uses the current locale. You can pass it explicitly: + +.. code-block:: twig + + {# ¥ #} + {{ 'JPY'|currency_symbol('fr') }} + +.. note:: + + The ``currency_symbol`` filter is part of the ``IntlExtension`` which is not + installed by default. Install it first: + + .. code-block:: bash + + $ composer require twig/intl-extra + + Then, on Symfony projects, install the ``twig/extra-bundle``: + + .. code-block:: bash + + $ composer require twig/extra-bundle + + Otherwise, add the extension explicitly on the Twig environment:: + + use Twig\Extra\Intl\IntlExtension; + + $twig = new \Twig\Environment(...); + $twig->addExtension(new IntlExtension()); + +Arguments +--------- + +* ``locale``: The locale diff --git a/data/web/inc/lib/vendor/twig/twig/doc/filters/data_uri.rst b/data/web/inc/lib/vendor/twig/twig/doc/filters/data_uri.rst new file mode 100644 index 00000000..e008266b --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/doc/filters/data_uri.rst @@ -0,0 +1,55 @@ +``data_uri`` +============ + +The ``data_uri`` filter generates a URL using the data scheme as defined in +`RFC 2397`_: + +.. code-block:: html+twig + + {{ image_data|data_uri }} + + {{ source('path_to_image')|data_uri }} + + {# force the mime type, disable the guessing of the mime type #} + {{ image_data|data_uri(mime="image/svg") }} + + {# also works with plain text #} + {{ 'foobar'|data_uri(mime="text/html") }} + + {# add some extra parameters #} + {{ 'foobar'|data_uri(mime="text/html", parameters={charset: "ascii"}) }} + +.. note:: + + The ``data_uri`` filter is part of the ``HtmlExtension`` which is not + installed by default. Install it first: + + .. code-block:: bash + + $ composer require twig/html-extra + + Then, on Symfony projects, install the ``twig/extra-bundle``: + + .. code-block:: bash + + $ composer require twig/extra-bundle + + Otherwise, add the extension explicitly on the Twig environment:: + + use Twig\Extra\Html\HtmlExtension; + + $twig = new \Twig\Environment(...); + $twig->addExtension(new HtmlExtension()); + +.. note:: + + The filter does not perform any length validation on purpose (limit depends + on the usage context), validation should be done before calling this filter. + +Arguments +--------- + +* ``mime``: The mime type +* ``parameters``: An array of parameters + +.. _RFC 2397: https://tools.ietf.org/html/rfc2397 diff --git a/data/web/inc/lib/vendor/twig/twig/doc/filters/date.rst b/data/web/inc/lib/vendor/twig/twig/doc/filters/date.rst new file mode 100644 index 00000000..ec08d556 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/doc/filters/date.rst @@ -0,0 +1,78 @@ +``date`` +======== + +The ``date`` filter formats a date to a given format: + +.. code-block:: twig + + {{ post.published_at|date("m/d/Y") }} + +The format specifier is the same as supported by `date`_, +except when the filtered data is of type `DateInterval`_, when the format must conform to +`DateInterval::format`_ instead. + +The ``date`` filter accepts strings (it must be in a format supported by the +`strtotime`_ function), `DateTime`_ instances, or `DateInterval`_ instances. For +instance, to display the current date, filter the word "now": + +.. code-block:: twig + + {{ "now"|date("m/d/Y") }} + +To escape words and characters in the date format use ``\\`` in front of each +character: + +.. code-block:: twig + + {{ post.published_at|date("F jS \\a\\t g:ia") }} + +If the value passed to the ``date`` filter is ``null``, it will return the +current date by default. If an empty string is desired instead of the current +date, use a ternary operator: + +.. code-block:: twig + + {{ post.published_at is empty ? "" : post.published_at|date("m/d/Y") }} + +If no format is provided, Twig will use the default one: ``F j, Y H:i``. This +default can be changed by calling the ``setDateFormat()`` method on the +``core`` extension instance. The first argument is the default format for +dates and the second one is the default format for date intervals:: + + $twig = new \Twig\Environment($loader); + $twig->getExtension(\Twig\Extension\CoreExtension::class)->setDateFormat('d/m/Y', '%d days'); + +Timezone +-------- + +By default, the date is displayed by applying the default timezone (the one +specified in php.ini or declared in Twig -- see below), but you can override +it by explicitly specifying a timezone: + +.. code-block:: twig + + {{ post.published_at|date("m/d/Y", "Europe/Paris") }} + +If the date is already a DateTime object, and if you want to keep its current +timezone, pass ``false`` as the timezone value: + +.. code-block:: twig + + {{ post.published_at|date("m/d/Y", false) }} + +The default timezone can also be set globally by calling ``setTimezone()``:: + + $twig = new \Twig\Environment($loader); + $twig->getExtension(\Twig\Extension\CoreExtension::class)->setTimezone('Europe/Paris'); + +Arguments +--------- + +* ``format``: The date format +* ``timezone``: The date timezone + +.. _`strtotime`: https://secure.php.net/strtotime +.. _`DateTime`: https://secure.php.net/DateTime +.. _`DateInterval`: https://secure.php.net/DateInterval +.. _`date`: https://secure.php.net/date +.. _`DateInterval::format`: https://secure.php.net/DateInterval.format diff --git a/data/web/inc/lib/vendor/twig/twig/doc/filters/date_modify.rst b/data/web/inc/lib/vendor/twig/twig/doc/filters/date_modify.rst new file mode 100644 index 00000000..cc5d6df1 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/doc/filters/date_modify.rst @@ -0,0 +1,20 @@ +``date_modify`` +=============== + +The ``date_modify`` filter modifies a date with a given modifier string: + +.. code-block:: twig + + {{ post.published_at|date_modify("+1 day")|date("m/d/Y") }} + +The ``date_modify`` filter accepts strings (it must be in a format supported +by the `strtotime`_ function) or `DateTime`_ instances. You can combine +it with the :doc:`date` filter for formatting. + +Arguments +--------- + +* ``modifier``: The modifier + +.. _`strtotime`: https://secure.php.net/strtotime +.. _`DateTime`: https://secure.php.net/DateTime diff --git a/data/web/inc/lib/vendor/twig/twig/doc/filters/default.rst b/data/web/inc/lib/vendor/twig/twig/doc/filters/default.rst new file mode 100644 index 00000000..2376fe7a --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/doc/filters/default.rst @@ -0,0 +1,42 @@ +``default`` +=========== + +The ``default`` filter returns the passed default value if the value is +undefined or empty, otherwise the value of the variable: + +.. code-block:: twig + + {{ var|default('var is not defined') }} + + {{ var.foo|default('foo item on var is not defined') }} + + {{ var['foo']|default('foo item on var is not defined') }} + + {{ ''|default('passed var is empty') }} + +When using the ``default`` filter on an expression that uses variables in some +method calls, be sure to use the ``default`` filter whenever a variable can be +undefined: + +.. code-block:: twig + + {{ var.method(foo|default('foo'))|default('foo') }} + +Using the ``default`` filter on a boolean variable might trigger unexpected behavior, as +``false`` is treated as an empty value. Consider using ``??`` instead: + +.. code-block:: twig + + {% set foo = false %} + {{ foo|default(true) }} {# true #} + {{ foo ?? true }} {# false #} + +.. note:: + + Read the documentation for the :doc:`defined<../tests/defined>` and + :doc:`empty<../tests/empty>` tests to learn more about their semantics. + +Arguments +--------- + +* ``default``: The default value diff --git a/data/web/inc/lib/vendor/twig/twig/doc/filters/escape.rst b/data/web/inc/lib/vendor/twig/twig/doc/filters/escape.rst new file mode 100644 index 00000000..f105d97a --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/doc/filters/escape.rst @@ -0,0 +1,117 @@ +``escape`` +========== + +The ``escape`` filter escapes a string using strategies that depend on the +context. + +By default, it uses the HTML escaping strategy: + +.. code-block:: html+twig + +

    + {{ user.username|escape }} +

    + +For convenience, the ``e`` filter is defined as an alias: + +.. code-block:: html+twig + +

    + {{ user.username|e }} +

    + +The ``escape`` filter can also be used in other contexts than HTML thanks to +an optional argument which defines the escaping strategy to use: + +.. code-block:: twig + + {{ user.username|e }} + {# is equivalent to #} + {{ user.username|e('html') }} + +And here is how to escape variables included in JavaScript code: + +.. code-block:: twig + + {{ user.username|escape('js') }} + {{ user.username|e('js') }} + +The ``escape`` filter supports the following escaping strategies for HTML +documents: + +* ``html``: escapes a string for the **HTML body** context. + +* ``js``: escapes a string for the **JavaScript** context. + +* ``css``: escapes a string for the **CSS** context. CSS escaping can be + applied to any string being inserted into CSS and escapes everything except + alphanumerics. + +* ``url``: escapes a string for the **URI or parameter** contexts. This should + not be used to escape an entire URI; only a subcomponent being inserted. + +* ``html_attr``: escapes a string for the **HTML attribute** context. + +Note that doing contextual escaping in HTML documents is hard and choosing the +right escaping strategy depends on a lot of factors. Please, read related +documentation like `the OWASP prevention cheat sheet +`_ +to learn more about this topic. + +.. note:: + + Internally, ``escape`` uses the PHP native `htmlspecialchars`_ function + for the HTML escaping strategy. + +.. caution:: + + When using automatic escaping, Twig tries to not double-escape a variable + when the automatic escaping strategy is the same as the one applied by the + escape filter; but that does not work when using a variable as the + escaping strategy: + + .. code-block:: twig + + {% set strategy = 'html' %} + + {% autoescape 'html' %} + {{ var|escape('html') }} {# won't be double-escaped #} + {{ var|escape(strategy) }} {# will be double-escaped #} + {% endautoescape %} + + When using a variable as the escaping strategy, you should disable + automatic escaping: + + .. code-block:: twig + + {% set strategy = 'html' %} + + {% autoescape 'html' %} + {{ var|escape(strategy)|raw }} {# won't be double-escaped #} + {% endautoescape %} + +Custom Escapers +--------------- + +You can define custom escapers by calling the ``setEscaper()`` method on the +escaper extension instance. The first argument is the escaper name (to be +used in the ``escape`` call) and the second one must be a valid PHP callable:: + + $twig = new \Twig\Environment($loader); + $twig->getExtension(\Twig\Extension\EscaperExtension::class)->setEscaper('csv', 'csv_escaper'); + +When called by Twig, the callable receives the Twig environment instance, the +string to escape, and the charset. + +.. note:: + + Built-in escapers cannot be overridden mainly because they should be + considered as the final implementation and also for better performance. + +Arguments +--------- + +* ``strategy``: The escaping strategy +* ``charset``: The string charset + +.. _`htmlspecialchars`: https://secure.php.net/htmlspecialchars diff --git a/data/web/inc/lib/vendor/twig/twig/doc/filters/filter.rst b/data/web/inc/lib/vendor/twig/twig/doc/filters/filter.rst new file mode 100644 index 00000000..257421f6 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/doc/filters/filter.rst @@ -0,0 +1,55 @@ +``filter`` +========== + +The ``filter`` filter filters elements of a sequence or a mapping using an arrow +function. The arrow function receives the value of the sequence or mapping: + +.. code-block:: twig + + {% set sizes = [34, 36, 38, 40, 42] %} + + {{ sizes|filter(v => v > 38)|join(', ') }} + {# output 40, 42 #} + +Combined with the ``for`` tag, it allows to filter the items to iterate over: + +.. code-block:: twig + + {% for v in sizes|filter(v => v > 38) -%} + {{ v }} + {% endfor %} + {# output 40 42 #} + +It also works with mappings: + +.. code-block:: twig + + {% set sizes = { + xs: 34, + s: 36, + m: 38, + l: 40, + xl: 42, + } %} + + {% for k, v in sizes|filter(v => v > 38) -%} + {{ k }} = {{ v }} + {% endfor %} + {# output l = 40 xl = 42 #} + +The arrow function also receives the key as a second argument: + +.. code-block:: twig + + {% for k, v in sizes|filter((v, k) => v > 38 and k != "xl") -%} + {{ k }} = {{ v }} + {% endfor %} + {# output l = 40 #} + +Note that the arrow function has access to the current context. + +Arguments +--------- + +* ``array``: The sequence or mapping +* ``arrow``: The arrow function diff --git a/data/web/inc/lib/vendor/twig/twig/doc/filters/first.rst b/data/web/inc/lib/vendor/twig/twig/doc/filters/first.rst new file mode 100644 index 00000000..8d7081a5 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/doc/filters/first.rst @@ -0,0 +1,22 @@ +``first`` +========= + +The ``first`` filter returns the first "element" of a sequence, a mapping, or +a string: + +.. code-block:: twig + + {{ [1, 2, 3, 4]|first }} + {# outputs 1 #} + + {{ { a: 1, b: 2, c: 3, d: 4 }|first }} + {# outputs 1 #} + + {{ '1234'|first }} + {# outputs 1 #} + +.. note:: + + It also works with objects implementing the `Traversable`_ interface. + +.. _`Traversable`: https://secure.php.net/manual/en/class.traversable.php diff --git a/data/web/inc/lib/vendor/twig/twig/doc/filters/format.rst b/data/web/inc/lib/vendor/twig/twig/doc/filters/format.rst new file mode 100644 index 00000000..782ea75c --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/doc/filters/format.rst @@ -0,0 +1,18 @@ +``format`` +========== + +The ``format`` filter formats a given string by replacing the placeholders +(placeholders follows the `sprintf`_ notation): + +.. code-block:: twig + + {{ "I like %s and %s."|format(foo, "bar") }} + + {# outputs I like foo and bar + if the foo parameter equals to the foo string. #} + +.. seealso:: + + :doc:`replace` + +.. _`sprintf`: https://secure.php.net/sprintf diff --git a/data/web/inc/lib/vendor/twig/twig/doc/filters/format_currency.rst b/data/web/inc/lib/vendor/twig/twig/doc/filters/format_currency.rst new file mode 100644 index 00000000..8b649bf5 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/doc/filters/format_currency.rst @@ -0,0 +1,77 @@ +``format_currency`` +=================== + +The ``format_currency`` filter formats a number as a currency: + +.. code-block:: twig + + {# €1,000,000.00 #} + {{ '1000000'|format_currency('EUR') }} + +You can pass attributes to tweak the output: + +.. code-block:: twig + + {# €12.34 #} + {{ '12.345'|format_currency('EUR', {rounding_mode: 'floor'}) }} + + {# €1,000,000.0000 #} + {{ '1000000'|format_currency('EUR', {fraction_digit: 4}) }} + +The list of supported options: + +* ``grouping_used``; +* ``decimal_always_shown``; +* ``max_integer_digit``; +* ``min_integer_digit``; +* ``integer_digit``; +* ``max_fraction_digit``; +* ``min_fraction_digit``; +* ``fraction_digit``; +* ``multiplier``; +* ``grouping_size``; +* ``rounding_mode``; +* ``rounding_increment``; +* ``format_width``; +* ``padding_position``; +* ``secondary_grouping_size``; +* ``significant_digits_used``; +* ``min_significant_digits_used``; +* ``max_significant_digits_used``; +* ``lenient_parse``. + +By default, the filter uses the current locale. You can pass it explicitly: + +.. code-block:: twig + + {# 1.000.000,00 € #} + {{ '1000000'|format_currency('EUR', locale='de') }} + +.. note:: + + The ``format_currency`` filter is part of the ``IntlExtension`` which is not + installed by default. Install it first: + + .. code-block:: bash + + $ composer require twig/intl-extra + + Then, on Symfony projects, install the ``twig/extra-bundle``: + + .. code-block:: bash + + $ composer require twig/extra-bundle + + Otherwise, add the extension explicitly on the Twig environment:: + + use Twig\Extra\Intl\IntlExtension; + + $twig = new \Twig\Environment(...); + $twig->addExtension(new IntlExtension()); + +Arguments +--------- + +* ``currency``: The currency +* ``attrs``: A map of attributes +* ``locale``: The locale diff --git a/data/web/inc/lib/vendor/twig/twig/doc/filters/format_date.rst b/data/web/inc/lib/vendor/twig/twig/doc/filters/format_date.rst new file mode 100644 index 00000000..c4a900a4 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/doc/filters/format_date.rst @@ -0,0 +1,36 @@ +``format_date`` +=============== + +The ``format_date`` filter formats a date. It behaves in the exact same way as +the :doc:`format_datetime` filter, but without the time. + +.. note:: + + The ``format_date`` filter is part of the ``IntlExtension`` which is not + installed by default. Install it first: + + .. code-block:: bash + + $ composer require twig/intl-extra + + Then, on Symfony projects, install the ``twig/extra-bundle``: + + .. code-block:: bash + + $ composer require twig/extra-bundle + + Otherwise, add the extension explicitly on the Twig environment:: + + use Twig\Extra\Intl\IntlExtension; + + $twig = new \Twig\Environment(...); + $twig->addExtension(new IntlExtension()); + +Arguments +--------- + +* ``locale``: The locale +* ``dateFormat``: The date format +* ``pattern``: A date time pattern +* ``timezone``: The date timezone +* ``calendar``: The calendar (Gregorian by default) diff --git a/data/web/inc/lib/vendor/twig/twig/doc/filters/format_datetime.rst b/data/web/inc/lib/vendor/twig/twig/doc/filters/format_datetime.rst new file mode 100644 index 00000000..1fdaa1ed --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/doc/filters/format_datetime.rst @@ -0,0 +1,73 @@ +``format_datetime`` +=================== + +The ``format_datetime`` filter formats a date time: + +.. code-block:: twig + + {# Aug 7, 2019, 11:39:12 PM #} + {{ '2019-08-07 23:39:12'|format_datetime() }} + +You can tweak the output for the date part and the time part: + +.. code-block:: twig + + {# 23:39 #} + {{ '2019-08-07 23:39:12'|format_datetime('none', 'short', locale='fr') }} + + {# 07/08/2019 #} + {{ '2019-08-07 23:39:12'|format_datetime('short', 'none', locale='fr') }} + + {# mercredi 7 août 2019 23:39:12 UTC #} + {{ '2019-08-07 23:39:12'|format_datetime('full', 'full', locale='fr') }} + +Supported values are: ``none``, ``short``, ``medium``, ``long``, and ``full``. + +For greater flexiblity, you can even define your own pattern (see the `ICU user +guide +`_ +for supported patterns). + +.. code-block:: twig + + {# 11 oclock PM, GMT #} + {{ '2019-08-07 23:39:12'|format_datetime(pattern="hh 'oclock' a, zzzz") }} + +By default, the filter uses the current locale. You can pass it explicitly: + +.. code-block:: twig + + {# 7 août 2019 23:39:12 #} + {{ '2019-08-07 23:39:12'|format_datetime(locale='fr') }} + +.. note:: + + The ``format_datetime`` filter is part of the ``IntlExtension`` which is not + installed by default. Install it first: + + .. code-block:: bash + + $ composer require twig/intl-extra + + Then, on Symfony projects, install the ``twig/extra-bundle``: + + .. code-block:: bash + + $ composer require twig/extra-bundle + + Otherwise, add the extension explicitly on the Twig environment:: + + use Twig\Extra\Intl\IntlExtension; + + $twig = new \Twig\Environment(...); + $twig->addExtension(new IntlExtension()); + +Arguments +--------- + +* ``locale``: The locale +* ``dateFormat``: The date format +* ``timeFormat``: The time format +* ``pattern``: A date time pattern +* ``timezone``: The date timezone +* ``calendar``: The calendar (Gregorian by default) diff --git a/data/web/inc/lib/vendor/twig/twig/doc/filters/format_number.rst b/data/web/inc/lib/vendor/twig/twig/doc/filters/format_number.rst new file mode 100644 index 00000000..a1c2804a --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/doc/filters/format_number.rst @@ -0,0 +1,117 @@ +``format_number`` +================= + +The ``format_number`` filter formats a number: + +.. code-block:: twig + + {{ '12.345'|format_number }} + +You can pass attributes to tweak the output: + +.. code-block:: twig + + {# 12.34 #} + {{ '12.345'|format_number({rounding_mode: 'floor'}) }} + + {# 1000000.0000 #} + {{ '1000000'|format_number({fraction_digit: 4}) }} + +The list of supported options: + +* ``grouping_used``; +* ``decimal_always_shown``; +* ``max_integer_digit``; +* ``min_integer_digit``; +* ``integer_digit``; +* ``max_fraction_digit``; +* ``min_fraction_digit``; +* ``fraction_digit``; +* ``multiplier``; +* ``grouping_size``; +* ``rounding_mode``; +* ``rounding_increment``; +* ``format_width``; +* ``padding_position``; +* ``secondary_grouping_size``; +* ``significant_digits_used``; +* ``min_significant_digits_used``; +* ``max_significant_digits_used``; +* ``lenient_parse``. + +Besides plain numbers, the filter can also format numbers in various styles: + +.. code-block:: twig + + {# 1,234% #} + {{ '12.345'|format_number(style='percent') }} + + {# twelve point three four five #} + {{ '12.345'|format_number(style='spellout') }} + + {# 12 sec. #} + {{ '12'|format_duration_number }} + +The list of supported styles: + +* ``decimal``; +* ``currency``; +* ``percent``; +* ``scientific``; +* ``spellout``; +* ``ordinal``; +* ``duration``. + +As a shortcut, you can use the ``format_*_number`` filters by replacing `*` with +a style: + +.. code-block:: twig + + {# 1,234% #} + {{ '12.345'|format_percent_number }} + + {# twelve point three four five #} + {{ '12.345'|format_spellout_number }} + +You can pass attributes to tweak the output: + +.. code-block:: twig + + {# 12.3% #} + {{ '0.12345'|format_percent_number({rounding_mode: 'floor', fraction_digit: 1}) }} + +By default, the filter uses the current locale. You can pass it explicitly: + +.. code-block:: twig + + {# 12,345 #} + {{ '12.345'|format_number(locale='fr') }} + +.. note:: + + The ``format_number`` filter is part of the ``IntlExtension`` which is not + installed by default. Install it first: + + .. code-block:: bash + + $ composer require twig/intl-extra + + Then, on Symfony projects, install the ``twig/extra-bundle``: + + .. code-block:: bash + + $ composer require twig/extra-bundle + + Otherwise, add the extension explicitly on the Twig environment:: + + use Twig\Extra\Intl\IntlExtension; + + $twig = new \Twig\Environment(...); + $twig->addExtension(new IntlExtension()); + +Arguments +--------- + +* ``locale``: The locale +* ``attrs``: A map of attributes +* ``style``: The style of the number output diff --git a/data/web/inc/lib/vendor/twig/twig/doc/filters/format_time.rst b/data/web/inc/lib/vendor/twig/twig/doc/filters/format_time.rst new file mode 100644 index 00000000..417b8a9c --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/doc/filters/format_time.rst @@ -0,0 +1,36 @@ +``format_time`` +=============== + +The ``format_time`` filter formats a time. It behaves in the exact same way as +the :doc:`format_datetime` filter, but without the date. + +.. note:: + + The ``format_time`` filter is part of the ``IntlExtension`` which is not + installed by default. Install it first: + + .. code-block:: bash + + $ composer require twig/intl-extra + + Then, on Symfony projects, install the ``twig/extra-bundle``: + + .. code-block:: bash + + $ composer require twig/extra-bundle + + Otherwise, add the extension explicitly on the Twig environment:: + + use Twig\Extra\Intl\IntlExtension; + + $twig = new \Twig\Environment(...); + $twig->addExtension(new IntlExtension()); + +Arguments +--------- + +* ``locale``: The locale +* ``timeFormat``: The time format +* ``pattern``: A date time pattern +* ``timezone``: The date timezone +* ``calendar``: The calendar (Gregorian by default) diff --git a/data/web/inc/lib/vendor/twig/twig/doc/filters/html_to_markdown.rst b/data/web/inc/lib/vendor/twig/twig/doc/filters/html_to_markdown.rst new file mode 100644 index 00000000..80145df5 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/doc/filters/html_to_markdown.rst @@ -0,0 +1,77 @@ +``html_to_markdown`` +==================== + +The ``html_to_markdown`` filter converts a block of HTML to Markdown: + +.. code-block:: html+twig + + {% apply html_to_markdown %} + +

    Hello!

    + + {% endapply %} + +You can also use the filter on an entire template which you ``include``: + +.. code-block:: twig + + {{ include('some_template.html.twig')|html_to_markdown }} + +.. note:: + + The ``html_to_markdown`` filter is part of the ``MarkdownExtension`` which + is not installed by default. Install it first: + + .. code-block:: bash + + $ composer require twig/markdown-extra + + On Symfony projects, you can automatically enable it by installing the + ``twig/extra-bundle``: + + .. code-block:: bash + + $ composer require twig/extra-bundle + + Or add the extension explicitly on the Twig environment:: + + use Twig\Extra\Markdown\MarkdownExtension; + + $twig = new \Twig\Environment(...); + $twig->addExtension(new MarkdownExtension()); + + If you are not using Symfony, you must also register the extension runtime:: + + use Twig\Extra\Markdown\DefaultMarkdown; + use Twig\Extra\Markdown\MarkdownRuntime; + use Twig\RuntimeLoader\RuntimeLoaderInterface; + + $twig->addRuntimeLoader(new class implements RuntimeLoaderInterface { + public function load($class) { + if (MarkdownRuntime::class === $class) { + return new MarkdownRuntime(new DefaultMarkdown()); + } + } + }); + +``html_to_markdown`` is just a frontend; the actual conversion is done by one of +the following compatible libraries, from which you can choose: + +* `erusev/parsedown`_ +* `league/html-to-markdown`_ +* `michelf/php-markdown`_ + +Depending on the library, you can also add some options by passing them as an argument +to the filter. Example for ``league/html-to-markdown``: + +.. code-block:: html+twig + + {% apply html_to_markdown({hard_break: false}) %} + +

    Hello!

    + + {% endapply %} + +.. _erusev/parsedown: https://github.com/erusev/parsedown +.. _league/html-to-markdown: https://github.com/thephpleague/html-to-markdown +.. _michelf/php-markdown: https://github.com/michelf/php-markdown diff --git a/data/web/inc/lib/vendor/twig/twig/doc/filters/index.rst b/data/web/inc/lib/vendor/twig/twig/doc/filters/index.rst new file mode 100644 index 00000000..eea2383e --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/doc/filters/index.rst @@ -0,0 +1,60 @@ +Filters +======= + +.. toctree:: + :maxdepth: 1 + + abs + batch + capitalize + column + convert_encoding + country_name + currency_name + currency_symbol + data_uri + date + date_modify + default + escape + filter + first + format + format_currency + format_date + format_datetime + format_number + format_time + html_to_markdown + inline_css + inky_to_html + join + json_encode + keys + language_name + last + length + locale_name + lower + map + markdown_to_html + merge + nl2br + number_format + raw + reduce + replace + reverse + round + slice + slug + sort + spaceless + split + striptags + timezone_name + title + trim + u + upper + url_encode diff --git a/data/web/inc/lib/vendor/twig/twig/doc/filters/inky_to_html.rst b/data/web/inc/lib/vendor/twig/twig/doc/filters/inky_to_html.rst new file mode 100644 index 00000000..563baba3 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/doc/filters/inky_to_html.rst @@ -0,0 +1,42 @@ +``inky_to_html`` +================ + +The ``inky_to_html`` filter processes an `inky email template +`_: + +.. code-block:: html+twig + + {% apply inky_to_html %} + + + + + {% endapply %} + +You can also use the filter on an included file: + +.. code-block:: twig + + {{ include('some_template.inky.twig')|inky_to_html }} + +.. note:: + + The ``inky_to_html`` filter is part of the ``InkyExtension`` which is not + installed by default. Install it first: + + .. code-block:: bash + + $ composer require twig/inky-extra + + Then, on Symfony projects, install the ``twig/extra-bundle``: + + .. code-block:: bash + + $ composer require twig/extra-bundle + + Otherwise, add the extension explicitly on the Twig environment:: + + use Twig\Extra\Inky\InkyExtension; + + $twig = new \Twig\Environment(...); + $twig->addExtension(new InkyExtension()); diff --git a/data/web/inc/lib/vendor/twig/twig/doc/filters/inline_css.rst b/data/web/inc/lib/vendor/twig/twig/doc/filters/inline_css.rst new file mode 100644 index 00000000..44b14262 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/doc/filters/inline_css.rst @@ -0,0 +1,66 @@ +``inline_css`` +============== + +The ``inline_css`` filter inline CSS styles in HTML documents: + +.. code-block:: html+twig + + {% apply inline_css %} + + + + + +

    Hello CSS!

    + + + {% endapply %} + +You can also add some stylesheets by passing them as arguments to the filter: + +.. code-block:: html+twig + + {% apply inline_css(source("some_styles.css"), source("another.css")) %} + + +

    Hello CSS!

    + + + {% endapply %} + +Styles loaded via the filter override the styles defined in the `` + {% endblock %} + {% block content %} +

    Index

    +

    + Welcome on my awesome homepage. +

    + {% endblock %} + +The ``extends`` tag is the key here. It tells the template engine that this +template "extends" another template. When the template system evaluates this +template, first it locates the parent. The extends tag should be the first tag +in the template. + +Note that since the child template doesn't define the ``footer`` block, the +value from the parent template is used instead. + +You can't define multiple ``block`` tags with the same name in the same +template. This limitation exists because a block tag works in "both" +directions. That is, a block tag doesn't just provide a hole to fill - it also +defines the content that fills the hole in the *parent*. If there were two +similarly-named ``block`` tags in a template, that template's parent wouldn't +know which one of the blocks' content to use. + +If you want to print a block multiple times you can however use the +``block`` function: + +.. code-block:: html+twig + + {% block title %}{% endblock %} +

    {{ block('title') }}

    + {% block body %}{% endblock %} + +Parent Blocks +------------- + +It's possible to render the contents of the parent block by using the +:doc:`parent<../functions/parent>` function. This gives back the results of +the parent block: + +.. code-block:: html+twig + + {% block sidebar %} +

    Table Of Contents

    + ... + {{ parent() }} + {% endblock %} + +Named Block End-Tags +-------------------- + +Twig allows you to put the name of the block after the end tag for better +readability (the name after the ``endblock`` word must match the block name): + +.. code-block:: twig + + {% block sidebar %} + {% block inner_sidebar %} + ... + {% endblock inner_sidebar %} + {% endblock sidebar %} + +Block Nesting and Scope +----------------------- + +Blocks can be nested for more complex layouts. Per default, blocks have access +to variables from outer scopes: + +.. code-block:: html+twig + + {% for item in seq %} +
  • {% block loop_item %}{{ item }}{% endblock %}
  • + {% endfor %} + +Block Shortcuts +--------------- + +For blocks with little content, it's possible to use a shortcut syntax. The +following constructs do the same thing: + +.. code-block:: twig + + {% block title %} + {{ page_title|title }} + {% endblock %} + +.. code-block:: twig + + {% block title page_title|title %} + +Dynamic Inheritance +------------------- + +Twig supports dynamic inheritance by using a variable as the base template: + +.. code-block:: twig + + {% extends some_var %} + +If the variable evaluates to a ``\Twig\Template`` or a ``\Twig\TemplateWrapper`` +instance, Twig will use it as the parent template:: + + // {% extends layout %} + + $layout = $twig->load('some_layout_template.twig'); + + $twig->display('template.twig', ['layout' => $layout]); + +You can also provide a list of templates that are checked for existence. The +first template that exists will be used as a parent: + +.. code-block:: twig + + {% extends ['layout.html', 'base_layout.html'] %} + +Conditional Inheritance +----------------------- + +As the template name for the parent can be any valid Twig expression, it's +possible to make the inheritance mechanism conditional: + +.. code-block:: twig + + {% extends standalone ? "minimum.html" : "base.html" %} + +In this example, the template will extend the "minimum.html" layout template +if the ``standalone`` variable evaluates to ``true``, and "base.html" +otherwise. + +How do blocks work? +------------------- + +A block provides a way to change how a certain part of a template is rendered +but it does not interfere in any way with the logic around it. + +Let's take the following example to illustrate how a block works and more +importantly, how it does not work: + +.. code-block:: html+twig + + {# base.twig #} + {% for post in posts %} + {% block post %} +

    {{ post.title }}

    +

    {{ post.body }}

    + {% endblock %} + {% endfor %} + +If you render this template, the result would be exactly the same with or +without the ``block`` tag. The ``block`` inside the ``for`` loop is just a way +to make it overridable by a child template: + +.. code-block:: html+twig + + {# child.twig #} + {% extends "base.twig" %} + + {% block post %} +
    +
    {{ post.title }}
    +
    {{ post.text }}
    +
    + {% endblock %} + +Now, when rendering the child template, the loop is going to use the block +defined in the child template instead of the one defined in the base one; the +executed template is then equivalent to the following one: + +.. code-block:: html+twig + + {% for post in posts %} +
    +
    {{ post.title }}
    +
    {{ post.text }}
    +
    + {% endfor %} + +Let's take another example: a block included within an ``if`` statement: + +.. code-block:: html+twig + + {% if posts is empty %} + {% block head %} + {{ parent() }} + + + {% endblock head %} + {% endif %} + +Contrary to what you might think, this template does not define a block +conditionally; it just makes overridable by a child template the output of +what will be rendered when the condition is ``true``. + +If you want the output to be displayed conditionally, use the following +instead: + +.. code-block:: html+twig + + {% block head %} + {{ parent() }} + + {% if posts is empty %} + + {% endif %} + {% endblock head %} + +.. seealso:: + + :doc:`block<../functions/block>`, :doc:`block<../tags/block>`, :doc:`parent<../functions/parent>`, :doc:`use<../tags/use>` diff --git a/data/web/inc/lib/vendor/twig/twig/doc/tags/flush.rst b/data/web/inc/lib/vendor/twig/twig/doc/tags/flush.rst new file mode 100644 index 00000000..332e9825 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/doc/tags/flush.rst @@ -0,0 +1,14 @@ +``flush`` +========= + +The ``flush`` tag tells Twig to flush the output buffer: + +.. code-block:: twig + + {% flush %} + +.. note:: + + Internally, Twig uses the PHP `flush`_ function. + +.. _`flush`: https://secure.php.net/flush diff --git a/data/web/inc/lib/vendor/twig/twig/doc/tags/for.rst b/data/web/inc/lib/vendor/twig/twig/doc/tags/for.rst new file mode 100644 index 00000000..4517f590 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/doc/tags/for.rst @@ -0,0 +1,141 @@ +``for`` +======= + +Loop over each item in a sequence. For example, to display a list of users +provided in a variable called ``users``: + +.. code-block:: html+twig + +

    Members

    +
      + {% for user in users %} +
    • {{ user.username|e }}
    • + {% endfor %} +
    + +.. note:: + + A sequence can be either an array or an object implementing the + ``Traversable`` interface. + +If you do need to iterate over a sequence of numbers, you can use the ``..`` +operator: + +.. code-block:: twig + + {% for i in 0..10 %} + * {{ i }} + {% endfor %} + +The above snippet of code would print all numbers from 0 to 10. + +It can be also useful with letters: + +.. code-block:: twig + + {% for letter in 'a'..'z' %} + * {{ letter }} + {% endfor %} + +The ``..`` operator can take any expression at both sides: + +.. code-block:: twig + + {% for letter in 'a'|upper..'z'|upper %} + * {{ letter }} + {% endfor %} + +.. tip: + + If you need a step different from 1, you can use the ``range`` function + instead. + +The `loop` variable +------------------- + +Inside of a ``for`` loop block you can access some special variables: + +===================== ============================================================= +Variable Description +===================== ============================================================= +``loop.index`` The current iteration of the loop. (1 indexed) +``loop.index0`` The current iteration of the loop. (0 indexed) +``loop.revindex`` The number of iterations from the end of the loop (1 indexed) +``loop.revindex0`` The number of iterations from the end of the loop (0 indexed) +``loop.first`` True if first iteration +``loop.last`` True if last iteration +``loop.length`` The number of items in the sequence +``loop.parent`` The parent context +===================== ============================================================= + +.. code-block:: twig + + {% for user in users %} + {{ loop.index }} - {{ user.username }} + {% endfor %} + +.. note:: + + The ``loop.length``, ``loop.revindex``, ``loop.revindex0``, and + ``loop.last`` variables are only available for PHP arrays, or objects that + implement the ``Countable`` interface. + +The `else` Clause +----------------- + +If no iteration took place because the sequence was empty, you can render a +replacement block by using ``else``: + +.. code-block:: html+twig + +
      + {% for user in users %} +
    • {{ user.username|e }}
    • + {% else %} +
    • no user found
    • + {% endfor %} +
    + +Iterating over Keys +------------------- + +By default, a loop iterates over the values of the sequence. You can iterate +on keys by using the ``keys`` filter: + +.. code-block:: html+twig + +

    Members

    +
      + {% for key in users|keys %} +
    • {{ key }}
    • + {% endfor %} +
    + +Iterating over Keys and Values +------------------------------ + +You can also access both keys and values: + +.. code-block:: html+twig + +

    Members

    +
      + {% for key, user in users %} +
    • {{ key }}: {{ user.username|e }}
    • + {% endfor %} +
    + +Iterating over a Subset +----------------------- + +You might want to iterate over a subset of values. This can be achieved using +the :doc:`slice <../filters/slice>` filter: + +.. code-block:: html+twig + +

    Top Ten Members

    +
      + {% for user in users|slice(0, 10) %} +
    • {{ user.username|e }}
    • + {% endfor %} +
    diff --git a/data/web/inc/lib/vendor/twig/twig/doc/tags/from.rst b/data/web/inc/lib/vendor/twig/twig/doc/tags/from.rst new file mode 100644 index 00000000..96c439aa --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/doc/tags/from.rst @@ -0,0 +1,6 @@ +``from`` +======== + +The ``from`` tag imports :doc:`macro<../tags/macro>` names into the current +namespace. The tag is documented in detail in the documentation for the +:doc:`macro<../tags/macro>` tag. diff --git a/data/web/inc/lib/vendor/twig/twig/doc/tags/if.rst b/data/web/inc/lib/vendor/twig/twig/doc/tags/if.rst new file mode 100644 index 00000000..2d747522 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/doc/tags/if.rst @@ -0,0 +1,79 @@ +``if`` +====== + +The ``if`` statement in Twig is comparable with the if statements of PHP. + +In the simplest form you can use it to test if an expression evaluates to +``true``: + +.. code-block:: html+twig + + {% if online == false %} +

    Our website is in maintenance mode. Please, come back later.

    + {% endif %} + +You can also test if an array is not empty: + +.. code-block:: html+twig + + {% if users %} +
      + {% for user in users %} +
    • {{ user.username|e }}
    • + {% endfor %} +
    + {% endif %} + +.. note:: + + If you want to test if the variable is defined, use ``if users is + defined`` instead. + +You can also use ``not`` to check for values that evaluate to ``false``: + +.. code-block:: html+twig + + {% if not user.subscribed %} +

    You are not subscribed to our mailing list.

    + {% endif %} + +For multiple conditions, ``and`` and ``or`` can be used: + +.. code-block:: html+twig + + {% if temperature > 18 and temperature < 27 %} +

    It's a nice day for a walk in the park.

    + {% endif %} + +For multiple branches ``elseif`` and ``else`` can be used like in PHP. You can +use more complex ``expressions`` there too: + +.. code-block:: twig + + {% if product.stock > 10 %} + Available + {% elseif product.stock > 0 %} + Only {{ product.stock }} left! + {% else %} + Sold-out! + {% endif %} + +.. note:: + + The rules to determine if an expression is ``true`` or ``false`` are the + same as in PHP; here are the edge cases rules: + + ====================== ==================== + Value Boolean evaluation + ====================== ==================== + empty string false + numeric zero false + NAN (Not A Number) true + INF (Infinity) true + whitespace-only string true + string "0" or '0' false + empty array false + null false + non-empty array true + object true + ====================== ==================== diff --git a/data/web/inc/lib/vendor/twig/twig/doc/tags/import.rst b/data/web/inc/lib/vendor/twig/twig/doc/tags/import.rst new file mode 100644 index 00000000..f217479f --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/doc/tags/import.rst @@ -0,0 +1,6 @@ +``import`` +========== + +The ``import`` tag imports :doc:`macro<../tags/macro>` names in a local +variable. The tag is documented in detail in the documentation for the +:doc:`macro<../tags/macro>` tag. diff --git a/data/web/inc/lib/vendor/twig/twig/doc/tags/include.rst b/data/web/inc/lib/vendor/twig/twig/doc/tags/include.rst new file mode 100644 index 00000000..93fb0371 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/doc/tags/include.rst @@ -0,0 +1,110 @@ +``include`` +=========== + +The ``include`` statement includes a template and outputs the rendered content +of that file: + +.. code-block:: twig + + {% include 'header.html' %} + Body + {% include 'footer.html' %} + +.. note:: + + It is recommended to use the :doc:`include<../functions/include>` function + instead as it provides the same features with a bit more flexibility: + + * The ``include`` function is semantically more "correct" (including a + template outputs its rendered contents in the current scope; a tag should + not display anything); + + * The ``include`` function is more "composable": + + .. code-block:: twig + + {# Store a rendered template in a variable #} + {% set content %} + {% include 'template.html' %} + {% endset %} + {# vs #} + {% set content = include('template.html') %} + + {# Apply filter on a rendered template #} + {% apply upper %} + {% include 'template.html' %} + {% endapply %} + {# vs #} + {{ include('template.html')|upper }} + + * The ``include`` function does not impose any specific order for + arguments thanks to :ref:`named arguments `. + +Included templates have access to the variables of the active context. + +If you are using the filesystem loader, the templates are looked for in the +paths defined by it. + +You can add additional variables by passing them after the ``with`` keyword: + +.. code-block:: twig + + {# template.html will have access to the variables from the current context and the additional ones provided #} + {% include 'template.html' with {'foo': 'bar'} %} + + {% set vars = {'foo': 'bar'} %} + {% include 'template.html' with vars %} + +You can disable access to the context by appending the ``only`` keyword: + +.. code-block:: twig + + {# only the foo variable will be accessible #} + {% include 'template.html' with {'foo': 'bar'} only %} + +.. code-block:: twig + + {# no variables will be accessible #} + {% include 'template.html' only %} + +.. tip:: + + When including a template created by an end user, you should consider + sandboxing it. More information in the :doc:`Twig for Developers<../api>` + chapter and in the :doc:`sandbox<../tags/sandbox>` tag documentation. + +The template name can be any valid Twig expression: + +.. code-block:: twig + + {% include some_var %} + {% include ajax ? 'ajax.html' : 'not_ajax.html' %} + +And if the expression evaluates to a ``\Twig\Template`` or a +``\Twig\TemplateWrapper`` instance, Twig will use it directly:: + + // {% include template %} + + $template = $twig->load('some_template.twig'); + + $twig->display('template.twig', ['template' => $template]); + +You can mark an include with ``ignore missing`` in which case Twig will ignore +the statement if the template to be included does not exist. It has to be +placed just after the template name. Here some valid examples: + +.. code-block:: twig + + {% include 'sidebar.html' ignore missing %} + {% include 'sidebar.html' ignore missing with {'foo': 'bar'} %} + {% include 'sidebar.html' ignore missing only %} + +You can also provide a list of templates that are checked for existence before +inclusion. The first template that exists will be included: + +.. code-block:: twig + + {% include ['page_detailed.html', 'page.html'] %} + +If ``ignore missing`` is given, it will fall back to rendering nothing if none +of the templates exist, otherwise it will throw an exception. diff --git a/data/web/inc/lib/vendor/twig/twig/doc/tags/index.rst b/data/web/inc/lib/vendor/twig/twig/doc/tags/index.rst new file mode 100644 index 00000000..b3c10408 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/doc/tags/index.rst @@ -0,0 +1,26 @@ +Tags +==== + +.. toctree:: + :maxdepth: 1 + + apply + autoescape + block + cache + deprecated + do + embed + extends + flush + for + from + if + import + include + macro + sandbox + set + use + verbatim + with diff --git a/data/web/inc/lib/vendor/twig/twig/doc/tags/macro.rst b/data/web/inc/lib/vendor/twig/twig/doc/tags/macro.rst new file mode 100644 index 00000000..42fc460c --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/doc/tags/macro.rst @@ -0,0 +1,140 @@ +``macro`` +========= + +Macros are comparable with functions in regular programming languages. They +are useful to reuse template fragments to not repeat yourself. + +Macros are defined in regular templates. + +Imagine having a generic helper template that define how to render HTML forms +via macros (called ``forms.html``): + +.. code-block:: html+twig + + {% macro input(name, value, type = "text", size = 20) %} + + {% endmacro %} + + {% macro textarea(name, value, rows = 10, cols = 40) %} + + {% endmacro %} + +Each macro argument can have a default value (here ``text`` is the default value +for ``type`` if not provided in the call). + +Macros differ from native PHP functions in a few ways: + +* Arguments of a macro are always optional. + +* If extra positional arguments are passed to a macro, they end up in the + special ``varargs`` variable as a list of values. + +But as with PHP functions, macros don't have access to the current template +variables. + +.. tip:: + + You can pass the whole context as an argument by using the special + ``_context`` variable. + +Importing Macros +---------------- + +There are two ways to import macros. You can import the complete template +containing the macros into a local variable (via the ``import`` tag) or only +import specific macros from the template (via the ``from`` tag). + +To import all macros from a template into a local variable, use the ``import`` +tag: + +.. code-block:: twig + + {% import "forms.html" as forms %} + +The above ``import`` call imports the ``forms.html`` file (which can contain +only macros, or a template and some macros), and import the macros as items of +the ``forms`` local variable. + +The macros can then be called at will in the *current* template: + +.. code-block:: html+twig + +

    {{ forms.input('username') }}

    +

    {{ forms.input('password', null, 'password') }}

    + +Alternatively you can import names from the template into the current namespace +via the ``from`` tag: + +.. code-block:: html+twig + + {% from 'forms.html' import input as input_field, textarea %} + +

    {{ input_field('password', '', 'password') }}

    +

    {{ textarea('comment') }}

    + +.. tip:: + + When macro usages and definitions are in the same template, you don't need to + import the macros as they are automatically available under the special + ``_self`` variable: + + .. code-block:: html+twig + +

    {{ _self.input('password', '', 'password') }}

    + + {% macro input(name, value, type = "text", size = 20) %} + + {% endmacro %} + +Macros Scoping +-------------- + +The scoping rules are the same whether you imported macros via ``import`` or +``from``. + +Imported macros are always **local** to the current template. It means that +macros are available in all blocks and other macros defined in the current +template, but they are not available in included templates or child templates; +you need to explicitly re-import macros in each template. + +Imported macros are not available in the body of ``embed`` tags, you need +to explicitly re-import macros inside the tag. + +When calling ``import`` or ``from`` from a ``block`` tag, the imported macros +are only defined in the current block and they override macros defined at the +template level with the same names. + +When calling ``import`` or ``from`` from a ``macro`` tag, the imported macros +are only defined in the current macro and they override macros defined at the +template level with the same names. + +Checking if a Macro is defined +------------------------------ + +You can check if a macro is defined via the ``defined`` test: + +.. code-block:: twig + + {% import "macros.twig" as macros %} + + {% from "macros.twig" import hello %} + + {% if macros.hello is defined -%} + OK + {% endif %} + + {% if hello is defined -%} + OK + {% endif %} + +Named Macro End-Tags +-------------------- + +Twig allows you to put the name of the macro after the end tag for better +readability (the name after the ``endmacro`` word must match the macro name): + +.. code-block:: twig + + {% macro input() %} + ... + {% endmacro input %} diff --git a/data/web/inc/lib/vendor/twig/twig/doc/tags/sandbox.rst b/data/web/inc/lib/vendor/twig/twig/doc/tags/sandbox.rst new file mode 100644 index 00000000..b331fdb8 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/doc/tags/sandbox.rst @@ -0,0 +1,30 @@ +``sandbox`` +=========== + +The ``sandbox`` tag can be used to enable the sandboxing mode for an included +template, when sandboxing is not enabled globally for the Twig environment: + +.. code-block:: twig + + {% sandbox %} + {% include 'user.html' %} + {% endsandbox %} + +.. warning:: + + The ``sandbox`` tag is only available when the sandbox extension is + enabled (see the :doc:`Twig for Developers<../api>` chapter). + +.. note:: + + The ``sandbox`` tag can only be used to sandbox an include tag and it + cannot be used to sandbox a section of a template. The following example + won't work: + + .. code-block:: twig + + {% sandbox %} + {% for i in 1..2 %} + {{ i }} + {% endfor %} + {% endsandbox %} diff --git a/data/web/inc/lib/vendor/twig/twig/doc/tags/set.rst b/data/web/inc/lib/vendor/twig/twig/doc/tags/set.rst new file mode 100644 index 00000000..7a3a784f --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/doc/tags/set.rst @@ -0,0 +1,78 @@ +``set`` +======= + +Inside code blocks you can also assign values to variables. Assignments use +the ``set`` tag and can have multiple targets. + +Here is how you can assign the ``bar`` value to the ``foo`` variable: + +.. code-block:: twig + + {% set foo = 'bar' %} + +After the ``set`` call, the ``foo`` variable is available in the template like +any other ones: + +.. code-block:: twig + + {# displays bar #} + {{ foo }} + +The assigned value can be any valid :ref:`Twig expression +`: + +.. code-block:: twig + + {% set foo = [1, 2] %} + {% set foo = {'foo': 'bar'} %} + {% set foo = 'foo' ~ 'bar' %} + +Several variables can be assigned in one block: + +.. code-block:: twig + + {% set foo, bar = 'foo', 'bar' %} + + {# is equivalent to #} + + {% set foo = 'foo' %} + {% set bar = 'bar' %} + +The ``set`` tag can also be used to 'capture' chunks of text: + +.. code-block:: html+twig + + {% set foo %} + + {% endset %} + +.. caution:: + + If you enable automatic output escaping, Twig will only consider the + content to be safe when capturing chunks of text. + +.. note:: + + Note that loops are scoped in Twig; therefore a variable declared inside a + ``for`` loop is not accessible outside the loop itself: + + .. code-block:: twig + + {% for item in list %} + {% set foo = item %} + {% endfor %} + + {# foo is NOT available #} + + If you want to access the variable, just declare it before the loop: + + .. code-block:: twig + + {% set foo = "" %} + {% for item in list %} + {% set foo = item %} + {% endfor %} + + {# foo is available #} diff --git a/data/web/inc/lib/vendor/twig/twig/doc/tags/use.rst b/data/web/inc/lib/vendor/twig/twig/doc/tags/use.rst new file mode 100644 index 00000000..2aca6a01 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/doc/tags/use.rst @@ -0,0 +1,117 @@ +``use`` +======= + +.. note:: + + Horizontal reuse is an advanced Twig feature that is hardly ever needed in + regular templates. It is mainly used by projects that need to make + template blocks reusable without using inheritance. + +Template inheritance is one of the most powerful features of Twig but it is +limited to single inheritance; a template can only extend one other template. +This limitation makes template inheritance simple to understand and easy to +debug: + +.. code-block:: twig + + {% extends "base.html" %} + + {% block title %}{% endblock %} + {% block content %}{% endblock %} + +Horizontal reuse is a way to achieve the same goal as multiple inheritance, +but without the associated complexity: + +.. code-block:: twig + + {% extends "base.html" %} + + {% use "blocks.html" %} + + {% block title %}{% endblock %} + {% block content %}{% endblock %} + +The ``use`` statement tells Twig to import the blocks defined in +``blocks.html`` into the current template (it's like macros, but for blocks): + +.. code-block:: twig + + {# blocks.html #} + + {% block sidebar %}{% endblock %} + +In this example, the ``use`` statement imports the ``sidebar`` block into the +main template. The code is mostly equivalent to the following one (the +imported blocks are not outputted automatically): + +.. code-block:: twig + + {% extends "base.html" %} + + {% block sidebar %}{% endblock %} + {% block title %}{% endblock %} + {% block content %}{% endblock %} + +.. note:: + + The ``use`` tag only imports a template if it does not extend another + template, if it does not define macros, and if the body is empty. But it + can *use* other templates. + +.. note:: + + Because ``use`` statements are resolved independently of the context + passed to the template, the template reference cannot be an expression. + +The main template can also override any imported block. If the template +already defines the ``sidebar`` block, then the one defined in ``blocks.html`` +is ignored. To avoid name conflicts, you can rename imported blocks: + +.. code-block:: twig + + {% extends "base.html" %} + + {% use "blocks.html" with sidebar as base_sidebar, title as base_title %} + + {% block sidebar %}{% endblock %} + {% block title %}{% endblock %} + {% block content %}{% endblock %} + +The ``parent()`` function automatically determines the correct inheritance +tree, so it can be used when overriding a block defined in an imported +template: + +.. code-block:: twig + + {% extends "base.html" %} + + {% use "blocks.html" %} + + {% block sidebar %} + {{ parent() }} + {% endblock %} + + {% block title %}{% endblock %} + {% block content %}{% endblock %} + +In this example, ``parent()`` will correctly call the ``sidebar`` block from +the ``blocks.html`` template. + +.. tip:: + + Renaming allows you to simulate inheritance by calling the "parent" block: + + .. code-block:: twig + + {% extends "base.html" %} + + {% use "blocks.html" with sidebar as parent_sidebar %} + + {% block sidebar %} + {{ block('parent_sidebar') }} + {% endblock %} + +.. note:: + + You can use as many ``use`` statements as you want in any given template. + If two imported templates define the same block, the latest one wins. diff --git a/data/web/inc/lib/vendor/twig/twig/doc/tags/verbatim.rst b/data/web/inc/lib/vendor/twig/twig/doc/tags/verbatim.rst new file mode 100644 index 00000000..3d7115a6 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/doc/tags/verbatim.rst @@ -0,0 +1,16 @@ +``verbatim`` +============ + +The ``verbatim`` tag marks sections as being raw text that should not be +parsed. For example to put Twig syntax as example into a template you can use +this snippet: + +.. code-block:: html+twig + + {% verbatim %} +
      + {% for item in seq %} +
    • {{ item }}
    • + {% endfor %} +
    + {% endverbatim %} diff --git a/data/web/inc/lib/vendor/twig/twig/doc/tags/with.rst b/data/web/inc/lib/vendor/twig/twig/doc/tags/with.rst new file mode 100644 index 00000000..107432f6 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/doc/tags/with.rst @@ -0,0 +1,41 @@ +``with`` +======== + +Use the ``with`` tag to create a new inner scope. Variables set within this +scope are not visible outside of the scope: + +.. code-block:: twig + + {% with %} + {% set foo = 42 %} + {{ foo }} {# foo is 42 here #} + {% endwith %} + foo is not visible here any longer + +Instead of defining variables at the beginning of the scope, you can pass a +hash of variables you want to define in the ``with`` tag; the previous example +is equivalent to the following one: + +.. code-block:: twig + + {% with { foo: 42 } %} + {{ foo }} {# foo is 42 here #} + {% endwith %} + foo is not visible here any longer + + {# it works with any expression that resolves to a hash #} + {% set vars = { foo: 42 } %} + {% with vars %} + ... + {% endwith %} + +By default, the inner scope has access to the outer scope context; you can +disable this behavior by appending the ``only`` keyword: + +.. code-block:: twig + + {% set bar = 'bar' %} + {% with { foo: 42 } only %} + {# only foo is defined #} + {# bar is not defined #} + {% endwith %} diff --git a/data/web/inc/lib/vendor/twig/twig/doc/templates.rst b/data/web/inc/lib/vendor/twig/twig/doc/templates.rst new file mode 100644 index 00000000..2a8f3804 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/doc/templates.rst @@ -0,0 +1,859 @@ +Twig for Template Designers +=========================== + +This document describes the syntax and semantics of the template engine and +will be most useful as reference to those creating Twig templates. + +Synopsis +-------- + +A template is a regular text file. It can generate any text-based format (HTML, +XML, CSV, LaTeX, etc.). It doesn't have a specific extension, ``.html`` or +``.xml`` are just fine. + +A template contains **variables** or **expressions**, which get replaced with +values when the template is evaluated, and **tags**, which control the +template's logic. + +Below is a minimal template that illustrates a few basics. We will cover further +details later on: + +.. code-block:: html+twig + + + + + My Webpage + + + + +

    My Webpage

    + {{ a_variable }} + + + +There are two kinds of delimiters: ``{% ... %}`` and ``{{ ... }}``. The first +one is used to execute statements such as for-loops, the latter outputs the +result of an expression. + +IDEs Integration +---------------- + +Many IDEs support syntax highlighting and auto-completion for Twig: + +* *Textmate* via the `Twig bundle`_ +* *Vim* via the `Jinja syntax plugin`_ or the `vim-twig plugin`_ +* *Netbeans* via the `Twig syntax plugin`_ (until 7.1, native as of 7.2) +* *PhpStorm* (native as of 2.1) +* *Eclipse* via the `Twig plugin`_ +* *Sublime Text* via the `Twig bundle`_ +* *GtkSourceView* via the `Twig language definition`_ (used by gedit and other projects) +* *Coda* and *SubEthaEdit* via the `Twig syntax mode`_ +* *Coda 2* via the `other Twig syntax mode`_ +* *Komodo* and *Komodo Edit* via the Twig highlight/syntax check mode +* *Notepad++* via the `Notepad++ Twig Highlighter`_ +* *Emacs* via `web-mode.el`_ +* *Atom* via the `PHP-twig for atom`_ +* *Visual Studio Code* via the `Twig pack`_ + +Also, `TwigFiddle`_ is an online service that allows you to execute Twig templates +from a browser; it supports all versions of Twig. + +Variables +--------- + +The application passes variables to the templates for manipulation in the +template. Variables may have attributes or elements you can access, too. The +visual representation of a variable depends heavily on the application providing +it. + +Use a dot (``.``) to access attributes of a variable (methods or properties of a +PHP object, or items of a PHP array): + +.. code-block:: twig + + {{ foo.bar }} + +.. note:: + + It's important to know that the curly braces are *not* part of the + variable but the print statement. When accessing variables inside tags, + don't put the braces around them. + +.. sidebar:: Implementation + + For convenience's sake ``foo.bar`` does the following things on the PHP + layer: + + * check if ``foo`` is an array and ``bar`` a valid element; + * if not, and if ``foo`` is an object, check that ``bar`` is a valid property; + * if not, and if ``foo`` is an object, check that ``bar`` is a valid method + (even if ``bar`` is the constructor - use ``__construct()`` instead); + * if not, and if ``foo`` is an object, check that ``getBar`` is a valid method; + * if not, and if ``foo`` is an object, check that ``isBar`` is a valid method; + * if not, and if ``foo`` is an object, check that ``hasBar`` is a valid method; + * if not, return a ``null`` value. + + Twig also supports a specific syntax for accessing items on PHP arrays, + ``foo['bar']``: + + * check if ``foo`` is an array and ``bar`` a valid element; + * if not, return a ``null`` value. + +If a variable or attribute does not exist, you will receive a ``null`` value +when the ``strict_variables`` option is set to ``false``; alternatively, if ``strict_variables`` +is set, Twig will throw an error (see :ref:`environment options`). + +.. note:: + + If you want to access a dynamic attribute of a variable, use the + :doc:`attribute` function instead. + + The ``attribute`` function is also useful when the attribute contains + special characters (like ``-`` that would be interpreted as the minus + operator): + + .. code-block:: twig + + {# equivalent to the non-working foo.data-foo #} + {{ attribute(foo, 'data-foo') }} + +Global Variables +~~~~~~~~~~~~~~~~ + +The following variables are always available in templates: + +* ``_self``: references the current template name; +* ``_context``: references the current context; +* ``_charset``: references the current charset. + +Setting Variables +~~~~~~~~~~~~~~~~~ + +You can assign values to variables inside code blocks. Assignments use the +:doc:`set` tag: + +.. code-block:: twig + + {% set foo = 'foo' %} + {% set foo = [1, 2] %} + {% set foo = {'foo': 'bar'} %} + +Filters +------- + +Variables can be modified by **filters**. Filters are separated from the +variable by a pipe symbol (``|``). Multiple filters can be chained. The output +of one filter is applied to the next. + +The following example removes all HTML tags from the ``name`` and title-cases +it: + +.. code-block:: twig + + {{ name|striptags|title }} + +Filters that accept arguments have parentheses around the arguments. This +example joins the elements of a list by commas: + +.. code-block:: twig + + {{ list|join(', ') }} + +To apply a filter on a section of code, wrap it with the +:doc:`apply` tag: + +.. code-block:: twig + + {% apply upper %} + This text becomes uppercase + {% endapply %} + +Go to the :doc:`filters` page to learn more about built-in +filters. + +Functions +--------- + +Functions can be called to generate content. Functions are called by their +name followed by parentheses (``()``) and may have arguments. + +For instance, the ``range`` function returns a list containing an arithmetic +progression of integers: + +.. code-block:: twig + + {% for i in range(0, 3) %} + {{ i }}, + {% endfor %} + +Go to the :doc:`functions` page to learn more about the +built-in functions. + +.. _named-arguments: + +Named Arguments +--------------- + +.. code-block:: twig + + {% for i in range(low=1, high=10, step=2) %} + {{ i }}, + {% endfor %} + +Using named arguments makes your templates more explicit about the meaning of +the values you pass as arguments: + +.. code-block:: twig + + {{ data|convert_encoding('UTF-8', 'iso-2022-jp') }} + + {# versus #} + + {{ data|convert_encoding(from='iso-2022-jp', to='UTF-8') }} + +Named arguments also allow you to skip some arguments for which you don't want +to change the default value: + +.. code-block:: twig + + {# the first argument is the date format, which defaults to the global date format if null is passed #} + {{ "now"|date(null, "Europe/Paris") }} + + {# or skip the format value by using a named argument for the time zone #} + {{ "now"|date(timezone="Europe/Paris") }} + +You can also use both positional and named arguments in one call, in which +case positional arguments must always come before named arguments: + +.. code-block:: twig + + {{ "now"|date('d/m/Y H:i', timezone="Europe/Paris") }} + +.. tip:: + + Each function and filter documentation page has a section where the names + of all arguments are listed when supported. + +Control Structure +----------------- + +A control structure refers to all those things that control the flow of a +program - conditionals (i.e. ``if``/``elseif``/``else``), ``for``-loops, as +well as things like blocks. Control structures appear inside ``{% ... %}`` +blocks. + +For example, to display a list of users provided in a variable called +``users``, use the :doc:`for` tag: + +.. code-block:: html+twig + +

    Members

    +
      + {% for user in users %} +
    • {{ user.username|e }}
    • + {% endfor %} +
    + +The :doc:`if` tag can be used to test an expression: + +.. code-block:: html+twig + + {% if users|length > 0 %} +
      + {% for user in users %} +
    • {{ user.username|e }}
    • + {% endfor %} +
    + {% endif %} + +Go to the :doc:`tags` page to learn more about the built-in tags. + +Comments +-------- + +To comment-out part of a line in a template, use the comment syntax ``{# ... +#}``. This is useful for debugging or to add information for other template +designers or yourself: + +.. code-block:: twig + + {# note: disabled template because we no longer use this + {% for user in users %} + ... + {% endfor %} + #} + +Including other Templates +------------------------- + +The :doc:`include` function is useful to include a template +and return the rendered content of that template into the current one: + +.. code-block:: twig + + {{ include('sidebar.html') }} + +By default, included templates have access to the same context as the template +which includes them. This means that any variable defined in the main template +will be available in the included template too: + +.. code-block:: twig + + {% for box in boxes %} + {{ include('render_box.html') }} + {% endfor %} + +The included template ``render_box.html`` is able to access the ``box`` variable. + +The name of the template depends on the template loader. For instance, the +``\Twig\Loader\FilesystemLoader`` allows you to access other templates by giving the +filename. You can access templates in subdirectories with a slash: + +.. code-block:: twig + + {{ include('sections/articles/sidebar.html') }} + +This behavior depends on the application embedding Twig. + +Template Inheritance +-------------------- + +The most powerful part of Twig is template inheritance. Template inheritance +allows you to build a base "skeleton" template that contains all the common +elements of your site and defines **blocks** that child templates can +override. + +It's easier to understand the concept by starting with an example. + +Let's define a base template, ``base.html``, which defines an HTML skeleton +document that might be used for a two-column page: + +.. code-block:: html+twig + + + + + {% block head %} + + {% block title %}{% endblock %} - My Webpage + {% endblock %} + + +
    {% block content %}{% endblock %}
    + + + + +In this example, the :doc:`block` tags define four blocks that +child templates can fill in. All the ``block`` tag does is to tell the +template engine that a child template may override those portions of the +template. + +A child template might look like this: + +.. code-block:: html+twig + + {% extends "base.html" %} + + {% block title %}Index{% endblock %} + {% block head %} + {{ parent() }} + + {% endblock %} + {% block content %} +

    Index

    +

    + Welcome to my awesome homepage. +

    + {% endblock %} + +The :doc:`extends` tag is the key here. It tells the template +engine that this template "extends" another template. When the template system +evaluates this template, first it locates the parent. The extends tag should +be the first tag in the template. + +Note that since the child template doesn't define the ``footer`` block, the +value from the parent template is used instead. + +It's possible to render the contents of the parent block by using the +:doc:`parent` function. This gives back the results of the +parent block: + +.. code-block:: html+twig + + {% block sidebar %} +

    Table Of Contents

    + ... + {{ parent() }} + {% endblock %} + +.. tip:: + + The documentation page for the :doc:`extends` tag describes + more advanced features like block nesting, scope, dynamic inheritance, and + conditional inheritance. + +.. note:: + + Twig also supports multiple inheritance via "horizontal reuse" with the help + of the :doc:`use` tag. + +HTML Escaping +------------- + +When generating HTML from templates, there's always a risk that a variable +will include characters that affect the resulting HTML. There are two +approaches: manually escaping each variable or automatically escaping +everything by default. + +Twig supports both, automatic escaping is enabled by default. + +The automatic escaping strategy can be configured via the +:ref:`autoescape` option and defaults to ``html``. + +Working with Manual Escaping +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +If manual escaping is enabled, it is **your** responsibility to escape variables +if needed. What to escape? Any variable that comes from an untrusted source. + +Escaping works by using the :doc:`escape` or ``e`` filter: + +.. code-block:: twig + + {{ user.username|e }} + +By default, the ``escape`` filter uses the ``html`` strategy, but depending on +the escaping context, you might want to explicitly use an other strategy: + +.. code-block:: twig + + {{ user.username|e('js') }} + {{ user.username|e('css') }} + {{ user.username|e('url') }} + {{ user.username|e('html_attr') }} + +Working with Automatic Escaping +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Whether automatic escaping is enabled or not, you can mark a section of a +template to be escaped or not by using the :doc:`autoescape` +tag: + +.. code-block:: twig + + {% autoescape %} + Everything will be automatically escaped in this block (using the HTML strategy) + {% endautoescape %} + +By default, auto-escaping uses the ``html`` escaping strategy. If you output +variables in other contexts, you need to explicitly escape them with the +appropriate escaping strategy: + +.. code-block:: twig + + {% autoescape 'js' %} + Everything will be automatically escaped in this block (using the JS strategy) + {% endautoescape %} + +Escaping +-------- + +It is sometimes desirable or even necessary to have Twig ignore parts it would +otherwise handle as variables or blocks. For example if the default syntax is +used and you want to use ``{{`` as raw string in the template and not start a +variable you have to use a trick. + +The easiest way is to output the variable delimiter (``{{``) by using a variable +expression: + +.. code-block:: twig + + {{ '{{' }} + +For bigger sections it makes sense to mark a block +:doc:`verbatim`. + +Macros +------ + +Macros are comparable with functions in regular programming languages. They are +useful to reuse HTML fragments to not repeat yourself. They are described in the +:doc:`macro` tag documentation. + +.. _twig-expressions: + +Expressions +----------- + +Twig allows expressions everywhere. + +.. note:: + + The operator precedence is as follows, with the lowest-precedence operators + listed first: ``?:`` (ternary operator), ``b-and``, ``b-xor``, ``b-or``, + ``or``, ``and``, ``==``, ``!=``, ``<=>``, ``<``, ``>``, ``>=``, ``<=``, + ``in``, ``matches``, ``starts with``, ``ends with``, ``..``, ``+``, ``-``, + ``~``, ``*``, ``/``, ``//``, ``%``, ``is`` (tests), ``**``, ``??``, ``|`` + (filters), ``[]``, and ``.``: + + .. code-block:: twig + + {% set greeting = 'Hello ' %} + {% set name = 'Fabien' %} + + {{ greeting ~ name|lower }} {# Hello fabien #} + + {# use parenthesis to change precedence #} + {{ (greeting ~ name)|lower }} {# hello fabien #} + +Literals +~~~~~~~~ + +The simplest form of expressions are literals. Literals are representations +for PHP types such as strings, numbers, and arrays. The following literals +exist: + +* ``"Hello World"``: Everything between two double or single quotes is a + string. They are useful whenever you need a string in the template (for + example as arguments to function calls, filters or just to extend or include + a template). A string can contain a delimiter if it is preceded by a + backslash (``\``) -- like in ``'It\'s good'``. If the string contains a + backslash (e.g. ``'c:\Program Files'``) escape it by doubling it + (e.g. ``'c:\\Program Files'``). + +* ``42`` / ``42.23``: Integers and floating point numbers are created by + writing the number down. If a dot is present the number is a float, + otherwise an integer. + +* ``["foo", "bar"]``: Arrays are defined by a sequence of expressions + separated by a comma (``,``) and wrapped with squared brackets (``[]``). + +* ``{"foo": "bar"}``: Hashes are defined by a list of keys and values + separated by a comma (``,``) and wrapped with curly braces (``{}``): + + .. code-block:: twig + + {# keys as string #} + { 'foo': 'foo', 'bar': 'bar' } + + {# keys as names (equivalent to the previous hash) #} + { foo: 'foo', bar: 'bar' } + + {# keys as integer #} + { 2: 'foo', 4: 'bar' } + + {# keys can be omitted if it is the same as the variable name #} + { foo } + {# is equivalent to the following #} + { 'foo': foo } + + {# keys as expressions (the expression must be enclosed into parentheses) #} + {% set foo = 'foo' %} + { (foo): 'foo', (1 + 1): 'bar', (foo ~ 'b'): 'baz' } + +* ``true`` / ``false``: ``true`` represents the true value, ``false`` + represents the false value. + +* ``null``: ``null`` represents no specific value. This is the value returned + when a variable does not exist. ``none`` is an alias for ``null``. + +Arrays and hashes can be nested: + +.. code-block:: twig + + {% set foo = [1, {"foo": "bar"}] %} + +.. tip:: + + Using double-quoted or single-quoted strings has no impact on performance + but :ref:`string interpolation ` is only + supported in double-quoted strings. + +Math +~~~~ + +Twig allows you to do math in templates; the following operators are supported: + +* ``+``: Adds two numbers together (the operands are casted to numbers). ``{{ + 1 + 1 }}`` is ``2``. + +* ``-``: Subtracts the second number from the first one. ``{{ 3 - 2 }}`` is + ``1``. + +* ``/``: Divides two numbers. The returned value will be a floating point + number. ``{{ 1 / 2 }}`` is ``{{ 0.5 }}``. + +* ``%``: Calculates the remainder of an integer division. ``{{ 11 % 7 }}`` is + ``4``. + +* ``//``: Divides two numbers and returns the floored integer result. ``{{ 20 + // 7 }}`` is ``2``, ``{{ -20 // 7 }}`` is ``-3`` (this is just syntactic + sugar for the :doc:`round` filter). + +* ``*``: Multiplies the left operand with the right one. ``{{ 2 * 2 }}`` would + return ``4``. + +* ``**``: Raises the left operand to the power of the right operand. ``{{ 2 ** + 3 }}`` would return ``8``. + +.. _template_logic: + +Logic +~~~~~ + +You can combine multiple expressions with the following operators: + +* ``and``: Returns true if the left and the right operands are both true. + +* ``or``: Returns true if the left or the right operand is true. + +* ``not``: Negates a statement. + +* ``(expr)``: Groups an expression. + +.. note:: + + Twig also supports bitwise operators (``b-and``, ``b-xor``, and ``b-or``). + +.. note:: + + Operators are case sensitive. + +Comparisons +~~~~~~~~~~~ + +The following comparison operators are supported in any expression: ``==``, +``!=``, ``<``, ``>``, ``>=``, and ``<=``. + +You can also check if a string ``starts with`` or ``ends with`` another +string: + +.. code-block:: twig + + {% if 'Fabien' starts with 'F' %} + {% endif %} + + {% if 'Fabien' ends with 'n' %} + {% endif %} + +.. note:: + + For complex string comparisons, the ``matches`` operator allows you to use + `regular expressions`_: + + .. code-block:: twig + + {% if phone matches '/^[\\d\\.]+$/' %} + {% endif %} + +Containment Operator +~~~~~~~~~~~~~~~~~~~~ + +The ``in`` operator performs containment test. It returns ``true`` if the left +operand is contained in the right: + +.. code-block:: twig + + {# returns true #} + + {{ 1 in [1, 2, 3] }} + + {{ 'cd' in 'abcde' }} + +.. tip:: + + You can use this filter to perform a containment test on strings, arrays, + or objects implementing the ``Traversable`` interface. + +To perform a negative test, use the ``not in`` operator: + +.. code-block:: twig + + {% if 1 not in [1, 2, 3] %} + + {# is equivalent to #} + {% if not (1 in [1, 2, 3]) %} + +Test Operator +~~~~~~~~~~~~~ + +The ``is`` operator performs tests. Tests can be used to test a variable against +a common expression. The right operand is name of the test: + +.. code-block:: twig + + {# find out if a variable is odd #} + + {{ name is odd }} + +Tests can accept arguments too: + +.. code-block:: twig + + {% if post.status is constant('Post::PUBLISHED') %} + +Tests can be negated by using the ``is not`` operator: + +.. code-block:: twig + + {% if post.status is not constant('Post::PUBLISHED') %} + + {# is equivalent to #} + {% if not (post.status is constant('Post::PUBLISHED')) %} + +Go to the :doc:`tests` page to learn more about the built-in +tests. + +Other Operators +~~~~~~~~~~~~~~~ + +The following operators don't fit into any of the other categories: + +* ``|``: Applies a filter. + +* ``..``: Creates a sequence based on the operand before and after the operator + (this is syntactic sugar for the :doc:`range` function): + + .. code-block:: twig + + {{ 1..5 }} + + {# equivalent to #} + {{ range(1, 5) }} + + Note that you must use parentheses when combining it with the filter operator + due to the :ref:`operator precedence rules `: + + .. code-block:: twig + + (1..5)|join(', ') + +* ``~``: Converts all operands into strings and concatenates them. ``{{ "Hello + " ~ name ~ "!" }}`` would return (assuming ``name`` is ``'John'``) ``Hello + John!``. + +* ``.``, ``[]``: Gets an attribute of a variable. + +* ``?:``: The ternary operator: + + .. code-block:: twig + + {{ foo ? 'yes' : 'no' }} + {{ foo ?: 'no' }} is the same as {{ foo ? foo : 'no' }} + {{ foo ? 'yes' }} is the same as {{ foo ? 'yes' : '' }} + +* ``??``: The null-coalescing operator: + + .. code-block:: twig + + {# returns the value of foo if it is defined and not null, 'no' otherwise #} + {{ foo ?? 'no' }} + +.. _templates-string-interpolation: + +String Interpolation +~~~~~~~~~~~~~~~~~~~~ + +String interpolation (``#{expression}``) allows any valid expression to appear +within a *double-quoted string*. The result of evaluating that expression is +inserted into the string: + +.. code-block:: twig + + {{ "foo #{bar} baz" }} + {{ "foo #{1 + 2} baz" }} + +.. _templates-whitespace-control: + +Whitespace Control +------------------ + +The first newline after a template tag is removed automatically (like in PHP). +Whitespace is not further modified by the template engine, so each whitespace +(spaces, tabs, newlines etc.) is returned unchanged. + +You can also control whitespace on a per tag level. By using the whitespace +control modifiers on your tags, you can trim leading and or trailing whitespace. + +Twig supports two modifiers: + +* *Whitespace trimming* via the ``-`` modifier: Removes all whitespace + (including newlines); + +* *Line whitespace trimming* via the ``~`` modifier: Removes all whitespace + (excluding newlines). Using this modifier on the right disables the default + removal of the first newline inherited from PHP. + +The modifiers can be used on either side of the tags like in ``{%-`` or ``-%}`` +and they consume all whitespace for that side of the tag. It is possible to use +the modifiers on one side of a tag or on both sides: + +.. code-block:: html+twig + + {% set value = 'no spaces' %} + {#- No leading/trailing whitespace -#} + {%- if true -%} + {{- value -}} + {%- endif -%} + {# output 'no spaces' #} + +
  • + {{ value }}
  • + {# outputs '
  • \n no spaces
  • ' #} + +
  • + {{- value }}
  • + {# outputs '
  • no spaces
  • ' #} + +
  • + {{~ value }}
  • + {# outputs '
  • \nno spaces
  • ' #} + +.. tip:: + + In addition to the whitespace modifiers, Twig also has a ``spaceless`` filter + that removes whitespace **between HTML tags**: + + .. code-block:: html+twig + + {% apply spaceless %} +
    + foo bar +
    + {% endapply %} + + {# output will be
    foo bar
    #} + +Extensions +---------- + +Twig can be extended. If you want to create your own extensions, read the +:ref:`Creating an Extension ` chapter. + +.. _`Twig bundle`: https://github.com/Anomareh/PHP-Twig.tmbundle +.. _`Jinja syntax plugin`: http://jinja.pocoo.org/docs/integration/#vim +.. _`vim-twig plugin`: https://github.com/lumiliet/vim-twig +.. _`Twig syntax plugin`: http://plugins.netbeans.org/plugin/37069/php-twig +.. _`Twig plugin`: https://github.com/pulse00/Twig-Eclipse-Plugin +.. _`Twig language definition`: https://github.com/gabrielcorpse/gedit-twig-template-language +.. _`Twig syntax mode`: https://github.com/bobthecow/Twig-HTML.mode +.. _`other Twig syntax mode`: https://github.com/muxx/Twig-HTML.mode +.. _`Notepad++ Twig Highlighter`: https://github.com/Banane9/notepadplusplus-twig +.. _`web-mode.el`: http://web-mode.org/ +.. _`regular expressions`: https://secure.php.net/manual/en/pcre.pattern.php +.. _`PHP-twig for atom`: https://github.com/reesef/php-twig +.. _`TwigFiddle`: https://twigfiddle.com/ +.. _`Twig pack`: https://marketplace.visualstudio.com/items?itemName=bajdzis.vscode-twig-pack diff --git a/data/web/inc/lib/vendor/twig/twig/doc/tests/constant.rst b/data/web/inc/lib/vendor/twig/twig/doc/tests/constant.rst new file mode 100644 index 00000000..448c238b --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/doc/tests/constant.rst @@ -0,0 +1,19 @@ +``constant`` +============ + +``constant`` checks if a variable has the exact same value as a constant. You +can use either global constants or class constants: + +.. code-block:: twig + + {% if post.status is constant('Post::PUBLISHED') %} + the status attribute is exactly the same as Post::PUBLISHED + {% endif %} + +You can test constants from object instances as well: + +.. code-block:: twig + + {% if post.status is constant('PUBLISHED', post) %} + the status attribute is exactly the same as Post::PUBLISHED + {% endif %} diff --git a/data/web/inc/lib/vendor/twig/twig/doc/tests/defined.rst b/data/web/inc/lib/vendor/twig/twig/doc/tests/defined.rst new file mode 100644 index 00000000..234a2898 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/doc/tests/defined.rst @@ -0,0 +1,30 @@ +``defined`` +=========== + +``defined`` checks if a variable is defined in the current context. This is very +useful if you use the ``strict_variables`` option: + +.. code-block:: twig + + {# defined works with variable names #} + {% if foo is defined %} + ... + {% endif %} + + {# and attributes on variables names #} + {% if foo.bar is defined %} + ... + {% endif %} + + {% if foo['bar'] is defined %} + ... + {% endif %} + +When using the ``defined`` test on an expression that uses variables in some +method calls, be sure that they are all defined first: + +.. code-block:: twig + + {% if var is defined and foo.method(var) is defined %} + ... + {% endif %} diff --git a/data/web/inc/lib/vendor/twig/twig/doc/tests/divisibleby.rst b/data/web/inc/lib/vendor/twig/twig/doc/tests/divisibleby.rst new file mode 100644 index 00000000..8032d349 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/doc/tests/divisibleby.rst @@ -0,0 +1,10 @@ +``divisible by`` +================ + +``divisible by`` checks if a variable is divisible by a number: + +.. code-block:: twig + + {% if loop.index is divisible by(3) %} + ... + {% endif %} diff --git a/data/web/inc/lib/vendor/twig/twig/doc/tests/empty.rst b/data/web/inc/lib/vendor/twig/twig/doc/tests/empty.rst new file mode 100644 index 00000000..0233eca4 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/doc/tests/empty.rst @@ -0,0 +1,18 @@ +``empty`` +========= + +``empty`` checks if a variable is an empty string, an empty array, an empty +hash, exactly ``false``, or exactly ``null``. + +For objects that implement the ``Countable`` interface, ``empty`` will check the +return value of the ``count()`` method. + +For objects that implement the ``__toString()`` magic method (and not ``Countable``), +it will check if an empty string is returned. + +.. code-block:: twig + + {% if foo is empty %} + ... + {% endif %} + diff --git a/data/web/inc/lib/vendor/twig/twig/doc/tests/even.rst b/data/web/inc/lib/vendor/twig/twig/doc/tests/even.rst new file mode 100644 index 00000000..2de0de2f --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/doc/tests/even.rst @@ -0,0 +1,12 @@ +``even`` +======== + +``even`` returns ``true`` if the given number is even: + +.. code-block:: twig + + {{ var is even }} + +.. seealso:: + + :doc:`odd<../tests/odd>` diff --git a/data/web/inc/lib/vendor/twig/twig/doc/tests/index.rst b/data/web/inc/lib/vendor/twig/twig/doc/tests/index.rst new file mode 100644 index 00000000..c63208ee --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/doc/tests/index.rst @@ -0,0 +1,15 @@ +Tests +===== + +.. toctree:: + :maxdepth: 1 + + constant + defined + divisibleby + empty + even + iterable + null + odd + sameas diff --git a/data/web/inc/lib/vendor/twig/twig/doc/tests/iterable.rst b/data/web/inc/lib/vendor/twig/twig/doc/tests/iterable.rst new file mode 100644 index 00000000..4ebfe9d8 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/doc/tests/iterable.rst @@ -0,0 +1,16 @@ +``iterable`` +============ + +``iterable`` checks if a variable is an array or a traversable object: + +.. code-block:: twig + + {# evaluates to true if the foo variable is iterable #} + {% if users is iterable %} + {% for user in users %} + Hello {{ user }}! + {% endfor %} + {% else %} + {# users is probably a string #} + Hello {{ users }}! + {% endif %} diff --git a/data/web/inc/lib/vendor/twig/twig/doc/tests/null.rst b/data/web/inc/lib/vendor/twig/twig/doc/tests/null.rst new file mode 100644 index 00000000..9ed93f6b --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/doc/tests/null.rst @@ -0,0 +1,12 @@ +``null`` +======== + +``null`` returns ``true`` if the variable is ``null``: + +.. code-block:: twig + + {{ var is null }} + +.. note:: + + ``none`` is an alias for ``null``. diff --git a/data/web/inc/lib/vendor/twig/twig/doc/tests/odd.rst b/data/web/inc/lib/vendor/twig/twig/doc/tests/odd.rst new file mode 100644 index 00000000..27fe7e4d --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/doc/tests/odd.rst @@ -0,0 +1,12 @@ +``odd`` +======= + +``odd`` returns ``true`` if the given number is odd: + +.. code-block:: twig + + {{ var is odd }} + +.. seealso:: + + :doc:`even<../tests/even>` diff --git a/data/web/inc/lib/vendor/twig/twig/doc/tests/sameas.rst b/data/web/inc/lib/vendor/twig/twig/doc/tests/sameas.rst new file mode 100644 index 00000000..c0929711 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/doc/tests/sameas.rst @@ -0,0 +1,11 @@ +``same as`` +=========== + +``same as`` checks if a variable is the same as another variable. +This is equivalent to ``===`` in PHP: + +.. code-block:: twig + + {% if foo.attribute is same as(false) %} + the foo attribute really is the 'false' PHP value + {% endif %} diff --git a/data/web/inc/lib/vendor/twig/twig/drupal_test.sh b/data/web/inc/lib/vendor/twig/twig/drupal_test.sh new file mode 100755 index 00000000..a25d886f --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/drupal_test.sh @@ -0,0 +1,50 @@ +#!/bin/bash + +set -x +set -e + +REPO=`pwd` +cd /tmp +rm -rf drupal-twig-test +composer create-project --no-interaction drupal/recommended-project:9.1.x-dev drupal-twig-test +cd drupal-twig-test +(cd vendor/twig && rm -rf twig && ln -sf $REPO twig) +php ./web/core/scripts/drupal install --no-interaction demo_umami > output +perl -p -i -e 's/^([A-Za-z]+)\: (.+)$/export DRUPAL_\1=\2/' output +source output +#echo '$config["system.logging"]["error_level"] = "verbose";' >> web/sites/default/settings.php + +wget https://get.symfony.com/cli/installer -O - | bash +export PATH="$HOME/.symfony/bin:$PATH" +symfony server:start -d --no-tls + +curl -OLsS https://get.blackfire.io/blackfire-player.phar +chmod +x blackfire-player.phar +cat > drupal-tests.bkf < + */ +interface CacheInterface +{ + /** + * Generates a cache key for the given template class name. + */ + public function generateKey(string $name, string $className): string; + + /** + * Writes the compiled template to cache. + * + * @param string $content The template representation as a PHP class + */ + public function write(string $key, string $content): void; + + /** + * Loads a template from the cache. + */ + public function load(string $key): void; + + /** + * Returns the modification timestamp of a key. + */ + public function getTimestamp(string $key): int; +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Cache/FilesystemCache.php b/data/web/inc/lib/vendor/twig/twig/src/Cache/FilesystemCache.php new file mode 100644 index 00000000..a9f1f466 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Cache/FilesystemCache.php @@ -0,0 +1,87 @@ + + */ +class FilesystemCache implements CacheInterface +{ + public const FORCE_BYTECODE_INVALIDATION = 1; + + private $directory; + private $options; + + public function __construct(string $directory, int $options = 0) + { + $this->directory = rtrim($directory, '\/').'/'; + $this->options = $options; + } + + public function generateKey(string $name, string $className): string + { + $hash = hash('sha256', $className); + + return $this->directory.$hash[0].$hash[1].'/'.$hash.'.php'; + } + + public function load(string $key): void + { + if (is_file($key)) { + @include_once $key; + } + } + + public function write(string $key, string $content): void + { + $dir = \dirname($key); + if (!is_dir($dir)) { + if (false === @mkdir($dir, 0777, true)) { + clearstatcache(true, $dir); + if (!is_dir($dir)) { + throw new \RuntimeException(sprintf('Unable to create the cache directory (%s).', $dir)); + } + } + } elseif (!is_writable($dir)) { + throw new \RuntimeException(sprintf('Unable to write in the cache directory (%s).', $dir)); + } + + $tmpFile = tempnam($dir, basename($key)); + if (false !== @file_put_contents($tmpFile, $content) && @rename($tmpFile, $key)) { + @chmod($key, 0666 & ~umask()); + + if (self::FORCE_BYTECODE_INVALIDATION == ($this->options & self::FORCE_BYTECODE_INVALIDATION)) { + // Compile cached file into bytecode cache + if (\function_exists('opcache_invalidate') && filter_var(ini_get('opcache.enable'), \FILTER_VALIDATE_BOOLEAN)) { + @opcache_invalidate($key, true); + } elseif (\function_exists('apc_compile_file')) { + apc_compile_file($key); + } + } + + return; + } + + throw new \RuntimeException(sprintf('Failed to write cache file "%s".', $key)); + } + + public function getTimestamp(string $key): int + { + if (!is_file($key)) { + return 0; + } + + return (int) @filemtime($key); + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Cache/NullCache.php b/data/web/inc/lib/vendor/twig/twig/src/Cache/NullCache.php new file mode 100644 index 00000000..8d20d59d --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Cache/NullCache.php @@ -0,0 +1,38 @@ + + */ +final class NullCache implements CacheInterface +{ + public function generateKey(string $name, string $className): string + { + return ''; + } + + public function write(string $key, string $content): void + { + } + + public function load(string $key): void + { + } + + public function getTimestamp(string $key): int + { + return 0; + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Compiler.php b/data/web/inc/lib/vendor/twig/twig/src/Compiler.php new file mode 100644 index 00000000..b3f1eca3 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Compiler.php @@ -0,0 +1,214 @@ + + */ +class Compiler +{ + private $lastLine; + private $source; + private $indentation; + private $env; + private $debugInfo = []; + private $sourceOffset; + private $sourceLine; + private $varNameSalt = 0; + + public function __construct(Environment $env) + { + $this->env = $env; + } + + public function getEnvironment(): Environment + { + return $this->env; + } + + public function getSource(): string + { + return $this->source; + } + + /** + * @return $this + */ + public function compile(Node $node, int $indentation = 0) + { + $this->lastLine = null; + $this->source = ''; + $this->debugInfo = []; + $this->sourceOffset = 0; + // source code starts at 1 (as we then increment it when we encounter new lines) + $this->sourceLine = 1; + $this->indentation = $indentation; + $this->varNameSalt = 0; + + $node->compile($this); + + return $this; + } + + /** + * @return $this + */ + public function subcompile(Node $node, bool $raw = true) + { + if (false === $raw) { + $this->source .= str_repeat(' ', $this->indentation * 4); + } + + $node->compile($this); + + return $this; + } + + /** + * Adds a raw string to the compiled code. + * + * @return $this + */ + public function raw(string $string) + { + $this->source .= $string; + + return $this; + } + + /** + * Writes a string to the compiled code by adding indentation. + * + * @return $this + */ + public function write(...$strings) + { + foreach ($strings as $string) { + $this->source .= str_repeat(' ', $this->indentation * 4).$string; + } + + return $this; + } + + /** + * Adds a quoted string to the compiled code. + * + * @return $this + */ + public function string(string $value) + { + $this->source .= sprintf('"%s"', addcslashes($value, "\0\t\"\$\\")); + + return $this; + } + + /** + * Returns a PHP representation of a given value. + * + * @return $this + */ + public function repr($value) + { + if (\is_int($value) || \is_float($value)) { + if (false !== $locale = setlocale(\LC_NUMERIC, '0')) { + setlocale(\LC_NUMERIC, 'C'); + } + + $this->raw(var_export($value, true)); + + if (false !== $locale) { + setlocale(\LC_NUMERIC, $locale); + } + } elseif (null === $value) { + $this->raw('null'); + } elseif (\is_bool($value)) { + $this->raw($value ? 'true' : 'false'); + } elseif (\is_array($value)) { + $this->raw('array('); + $first = true; + foreach ($value as $key => $v) { + if (!$first) { + $this->raw(', '); + } + $first = false; + $this->repr($key); + $this->raw(' => '); + $this->repr($v); + } + $this->raw(')'); + } else { + $this->string($value); + } + + return $this; + } + + /** + * @return $this + */ + public function addDebugInfo(Node $node) + { + if ($node->getTemplateLine() != $this->lastLine) { + $this->write(sprintf("// line %d\n", $node->getTemplateLine())); + + $this->sourceLine += substr_count($this->source, "\n", $this->sourceOffset); + $this->sourceOffset = \strlen($this->source); + $this->debugInfo[$this->sourceLine] = $node->getTemplateLine(); + + $this->lastLine = $node->getTemplateLine(); + } + + return $this; + } + + public function getDebugInfo(): array + { + ksort($this->debugInfo); + + return $this->debugInfo; + } + + /** + * @return $this + */ + public function indent(int $step = 1) + { + $this->indentation += $step; + + return $this; + } + + /** + * @return $this + * + * @throws \LogicException When trying to outdent too much so the indentation would become negative + */ + public function outdent(int $step = 1) + { + // can't outdent by more steps than the current indentation level + if ($this->indentation < $step) { + throw new \LogicException('Unable to call outdent() as the indentation would become negative.'); + } + + $this->indentation -= $step; + + return $this; + } + + public function getVarName(): string + { + return sprintf('__internal_%s', hash('sha256', __METHOD__.$this->varNameSalt++)); + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Environment.php b/data/web/inc/lib/vendor/twig/twig/src/Environment.php new file mode 100644 index 00000000..889df493 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Environment.php @@ -0,0 +1,814 @@ + + */ +class Environment +{ + public const VERSION = '3.3.2'; + public const VERSION_ID = 30302; + public const MAJOR_VERSION = 3; + public const MINOR_VERSION = 3; + public const RELEASE_VERSION = 2; + public const EXTRA_VERSION = ''; + + private $charset; + private $loader; + private $debug; + private $autoReload; + private $cache; + private $lexer; + private $parser; + private $compiler; + private $globals = []; + private $resolvedGlobals; + private $loadedTemplates; + private $strictVariables; + private $templateClassPrefix = '__TwigTemplate_'; + private $originalCache; + private $extensionSet; + private $runtimeLoaders = []; + private $runtimes = []; + private $optionsHash; + + /** + * Constructor. + * + * Available options: + * + * * debug: When set to true, it automatically set "auto_reload" to true as + * well (default to false). + * + * * charset: The charset used by the templates (default to UTF-8). + * + * * cache: An absolute path where to store the compiled templates, + * a \Twig\Cache\CacheInterface implementation, + * or false to disable compilation cache (default). + * + * * auto_reload: Whether to reload the template if the original source changed. + * If you don't provide the auto_reload option, it will be + * determined automatically based on the debug value. + * + * * strict_variables: Whether to ignore invalid variables in templates + * (default to false). + * + * * autoescape: Whether to enable auto-escaping (default to html): + * * false: disable auto-escaping + * * html, js: set the autoescaping to one of the supported strategies + * * name: set the autoescaping strategy based on the template name extension + * * PHP callback: a PHP callback that returns an escaping strategy based on the template "name" + * + * * optimizations: A flag that indicates which optimizations to apply + * (default to -1 which means that all optimizations are enabled; + * set it to 0 to disable). + */ + public function __construct(LoaderInterface $loader, $options = []) + { + $this->setLoader($loader); + + $options = array_merge([ + 'debug' => false, + 'charset' => 'UTF-8', + 'strict_variables' => false, + 'autoescape' => 'html', + 'cache' => false, + 'auto_reload' => null, + 'optimizations' => -1, + ], $options); + + $this->debug = (bool) $options['debug']; + $this->setCharset($options['charset'] ?? 'UTF-8'); + $this->autoReload = null === $options['auto_reload'] ? $this->debug : (bool) $options['auto_reload']; + $this->strictVariables = (bool) $options['strict_variables']; + $this->setCache($options['cache']); + $this->extensionSet = new ExtensionSet(); + + $this->addExtension(new CoreExtension()); + $this->addExtension(new EscaperExtension($options['autoescape'])); + $this->addExtension(new OptimizerExtension($options['optimizations'])); + } + + /** + * Enables debugging mode. + */ + public function enableDebug() + { + $this->debug = true; + $this->updateOptionsHash(); + } + + /** + * Disables debugging mode. + */ + public function disableDebug() + { + $this->debug = false; + $this->updateOptionsHash(); + } + + /** + * Checks if debug mode is enabled. + * + * @return bool true if debug mode is enabled, false otherwise + */ + public function isDebug() + { + return $this->debug; + } + + /** + * Enables the auto_reload option. + */ + public function enableAutoReload() + { + $this->autoReload = true; + } + + /** + * Disables the auto_reload option. + */ + public function disableAutoReload() + { + $this->autoReload = false; + } + + /** + * Checks if the auto_reload option is enabled. + * + * @return bool true if auto_reload is enabled, false otherwise + */ + public function isAutoReload() + { + return $this->autoReload; + } + + /** + * Enables the strict_variables option. + */ + public function enableStrictVariables() + { + $this->strictVariables = true; + $this->updateOptionsHash(); + } + + /** + * Disables the strict_variables option. + */ + public function disableStrictVariables() + { + $this->strictVariables = false; + $this->updateOptionsHash(); + } + + /** + * Checks if the strict_variables option is enabled. + * + * @return bool true if strict_variables is enabled, false otherwise + */ + public function isStrictVariables() + { + return $this->strictVariables; + } + + /** + * Gets the current cache implementation. + * + * @param bool $original Whether to return the original cache option or the real cache instance + * + * @return CacheInterface|string|false A Twig\Cache\CacheInterface implementation, + * an absolute path to the compiled templates, + * or false to disable cache + */ + public function getCache($original = true) + { + return $original ? $this->originalCache : $this->cache; + } + + /** + * Sets the current cache implementation. + * + * @param CacheInterface|string|false $cache A Twig\Cache\CacheInterface implementation, + * an absolute path to the compiled templates, + * or false to disable cache + */ + public function setCache($cache) + { + if (\is_string($cache)) { + $this->originalCache = $cache; + $this->cache = new FilesystemCache($cache); + } elseif (false === $cache) { + $this->originalCache = $cache; + $this->cache = new NullCache(); + } elseif ($cache instanceof CacheInterface) { + $this->originalCache = $this->cache = $cache; + } else { + throw new \LogicException('Cache can only be a string, false, or a \Twig\Cache\CacheInterface implementation.'); + } + } + + /** + * Gets the template class associated with the given string. + * + * The generated template class is based on the following parameters: + * + * * The cache key for the given template; + * * The currently enabled extensions; + * * Whether the Twig C extension is available or not; + * * PHP version; + * * Twig version; + * * Options with what environment was created. + * + * @param string $name The name for which to calculate the template class name + * @param int|null $index The index if it is an embedded template + * + * @internal + */ + public function getTemplateClass(string $name, int $index = null): string + { + $key = $this->getLoader()->getCacheKey($name).$this->optionsHash; + + return $this->templateClassPrefix.hash('sha256', $key).(null === $index ? '' : '___'.$index); + } + + /** + * Renders a template. + * + * @param string|TemplateWrapper $name The template name + * + * @throws LoaderError When the template cannot be found + * @throws SyntaxError When an error occurred during compilation + * @throws RuntimeError When an error occurred during rendering + */ + public function render($name, array $context = []): string + { + return $this->load($name)->render($context); + } + + /** + * Displays a template. + * + * @param string|TemplateWrapper $name The template name + * + * @throws LoaderError When the template cannot be found + * @throws SyntaxError When an error occurred during compilation + * @throws RuntimeError When an error occurred during rendering + */ + public function display($name, array $context = []): void + { + $this->load($name)->display($context); + } + + /** + * Loads a template. + * + * @param string|TemplateWrapper $name The template name + * + * @throws LoaderError When the template cannot be found + * @throws RuntimeError When a previously generated cache is corrupted + * @throws SyntaxError When an error occurred during compilation + */ + public function load($name): TemplateWrapper + { + if ($name instanceof TemplateWrapper) { + return $name; + } + + return new TemplateWrapper($this, $this->loadTemplate($this->getTemplateClass($name), $name)); + } + + /** + * Loads a template internal representation. + * + * This method is for internal use only and should never be called + * directly. + * + * @param string $name The template name + * @param int $index The index if it is an embedded template + * + * @throws LoaderError When the template cannot be found + * @throws RuntimeError When a previously generated cache is corrupted + * @throws SyntaxError When an error occurred during compilation + * + * @internal + */ + public function loadTemplate(string $cls, string $name, int $index = null): Template + { + $mainCls = $cls; + if (null !== $index) { + $cls .= '___'.$index; + } + + if (isset($this->loadedTemplates[$cls])) { + return $this->loadedTemplates[$cls]; + } + + if (!class_exists($cls, false)) { + $key = $this->cache->generateKey($name, $mainCls); + + if (!$this->isAutoReload() || $this->isTemplateFresh($name, $this->cache->getTimestamp($key))) { + $this->cache->load($key); + } + + $source = null; + if (!class_exists($cls, false)) { + $source = $this->getLoader()->getSourceContext($name); + $content = $this->compileSource($source); + $this->cache->write($key, $content); + $this->cache->load($key); + + if (!class_exists($mainCls, false)) { + /* Last line of defense if either $this->bcWriteCacheFile was used, + * $this->cache is implemented as a no-op or we have a race condition + * where the cache was cleared between the above calls to write to and load from + * the cache. + */ + eval('?>'.$content); + } + + if (!class_exists($cls, false)) { + throw new RuntimeError(sprintf('Failed to load Twig template "%s", index "%s": cache might be corrupted.', $name, $index), -1, $source); + } + } + } + + $this->extensionSet->initRuntime(); + + return $this->loadedTemplates[$cls] = new $cls($this); + } + + /** + * Creates a template from source. + * + * This method should not be used as a generic way to load templates. + * + * @param string $template The template source + * @param string $name An optional name of the template to be used in error messages + * + * @throws LoaderError When the template cannot be found + * @throws SyntaxError When an error occurred during compilation + */ + public function createTemplate(string $template, string $name = null): TemplateWrapper + { + $hash = hash('sha256', $template, false); + if (null !== $name) { + $name = sprintf('%s (string template %s)', $name, $hash); + } else { + $name = sprintf('__string_template__%s', $hash); + } + + $loader = new ChainLoader([ + new ArrayLoader([$name => $template]), + $current = $this->getLoader(), + ]); + + $this->setLoader($loader); + try { + return new TemplateWrapper($this, $this->loadTemplate($this->getTemplateClass($name), $name)); + } finally { + $this->setLoader($current); + } + } + + /** + * Returns true if the template is still fresh. + * + * Besides checking the loader for freshness information, + * this method also checks if the enabled extensions have + * not changed. + * + * @param int $time The last modification time of the cached template + */ + public function isTemplateFresh(string $name, int $time): bool + { + return $this->extensionSet->getLastModified() <= $time && $this->getLoader()->isFresh($name, $time); + } + + /** + * Tries to load a template consecutively from an array. + * + * Similar to load() but it also accepts instances of \Twig\Template and + * \Twig\TemplateWrapper, and an array of templates where each is tried to be loaded. + * + * @param string|TemplateWrapper|array $names A template or an array of templates to try consecutively + * + * @throws LoaderError When none of the templates can be found + * @throws SyntaxError When an error occurred during compilation + */ + public function resolveTemplate($names): TemplateWrapper + { + if (!\is_array($names)) { + return $this->load($names); + } + + foreach ($names as $name) { + try { + return $this->load($name); + } catch (LoaderError $e) { + } + } + + throw new LoaderError(sprintf('Unable to find one of the following templates: "%s".', implode('", "', $names))); + } + + public function setLexer(Lexer $lexer) + { + $this->lexer = $lexer; + } + + /** + * @throws SyntaxError When the code is syntactically wrong + */ + public function tokenize(Source $source): TokenStream + { + if (null === $this->lexer) { + $this->lexer = new Lexer($this); + } + + return $this->lexer->tokenize($source); + } + + public function setParser(Parser $parser) + { + $this->parser = $parser; + } + + /** + * Converts a token stream to a node tree. + * + * @throws SyntaxError When the token stream is syntactically or semantically wrong + */ + public function parse(TokenStream $stream): ModuleNode + { + if (null === $this->parser) { + $this->parser = new Parser($this); + } + + return $this->parser->parse($stream); + } + + public function setCompiler(Compiler $compiler) + { + $this->compiler = $compiler; + } + + /** + * Compiles a node and returns the PHP code. + */ + public function compile(Node $node): string + { + if (null === $this->compiler) { + $this->compiler = new Compiler($this); + } + + return $this->compiler->compile($node)->getSource(); + } + + /** + * Compiles a template source code. + * + * @throws SyntaxError When there was an error during tokenizing, parsing or compiling + */ + public function compileSource(Source $source): string + { + try { + return $this->compile($this->parse($this->tokenize($source))); + } catch (Error $e) { + $e->setSourceContext($source); + throw $e; + } catch (\Exception $e) { + throw new SyntaxError(sprintf('An exception has been thrown during the compilation of a template ("%s").', $e->getMessage()), -1, $source, $e); + } + } + + public function setLoader(LoaderInterface $loader) + { + $this->loader = $loader; + } + + public function getLoader(): LoaderInterface + { + return $this->loader; + } + + public function setCharset(string $charset) + { + if ('UTF8' === $charset = null === $charset ? null : strtoupper($charset)) { + // iconv on Windows requires "UTF-8" instead of "UTF8" + $charset = 'UTF-8'; + } + + $this->charset = $charset; + } + + public function getCharset(): string + { + return $this->charset; + } + + public function hasExtension(string $class): bool + { + return $this->extensionSet->hasExtension($class); + } + + public function addRuntimeLoader(RuntimeLoaderInterface $loader) + { + $this->runtimeLoaders[] = $loader; + } + + public function getExtension(string $class): ExtensionInterface + { + return $this->extensionSet->getExtension($class); + } + + /** + * Returns the runtime implementation of a Twig element (filter/function/tag/test). + * + * @param string $class A runtime class name + * + * @return object The runtime implementation + * + * @throws RuntimeError When the template cannot be found + */ + public function getRuntime(string $class) + { + if (isset($this->runtimes[$class])) { + return $this->runtimes[$class]; + } + + foreach ($this->runtimeLoaders as $loader) { + if (null !== $runtime = $loader->load($class)) { + return $this->runtimes[$class] = $runtime; + } + } + + throw new RuntimeError(sprintf('Unable to load the "%s" runtime.', $class)); + } + + public function addExtension(ExtensionInterface $extension) + { + $this->extensionSet->addExtension($extension); + $this->updateOptionsHash(); + } + + /** + * @param ExtensionInterface[] $extensions An array of extensions + */ + public function setExtensions(array $extensions) + { + $this->extensionSet->setExtensions($extensions); + $this->updateOptionsHash(); + } + + /** + * @return ExtensionInterface[] An array of extensions (keys are for internal usage only and should not be relied on) + */ + public function getExtensions(): array + { + return $this->extensionSet->getExtensions(); + } + + public function addTokenParser(TokenParserInterface $parser) + { + $this->extensionSet->addTokenParser($parser); + } + + /** + * @return TokenParserInterface[] + * + * @internal + */ + public function getTokenParsers(): array + { + return $this->extensionSet->getTokenParsers(); + } + + /** + * @internal + */ + public function getTokenParser(string $name): ?TokenParserInterface + { + return $this->extensionSet->getTokenParser($name); + } + + public function registerUndefinedTokenParserCallback(callable $callable): void + { + $this->extensionSet->registerUndefinedTokenParserCallback($callable); + } + + public function addNodeVisitor(NodeVisitorInterface $visitor) + { + $this->extensionSet->addNodeVisitor($visitor); + } + + /** + * @return NodeVisitorInterface[] + * + * @internal + */ + public function getNodeVisitors(): array + { + return $this->extensionSet->getNodeVisitors(); + } + + public function addFilter(TwigFilter $filter) + { + $this->extensionSet->addFilter($filter); + } + + /** + * @internal + */ + public function getFilter(string $name): ?TwigFilter + { + return $this->extensionSet->getFilter($name); + } + + public function registerUndefinedFilterCallback(callable $callable): void + { + $this->extensionSet->registerUndefinedFilterCallback($callable); + } + + /** + * Gets the registered Filters. + * + * Be warned that this method cannot return filters defined with registerUndefinedFilterCallback. + * + * @return TwigFilter[] + * + * @see registerUndefinedFilterCallback + * + * @internal + */ + public function getFilters(): array + { + return $this->extensionSet->getFilters(); + } + + public function addTest(TwigTest $test) + { + $this->extensionSet->addTest($test); + } + + /** + * @return TwigTest[] + * + * @internal + */ + public function getTests(): array + { + return $this->extensionSet->getTests(); + } + + /** + * @internal + */ + public function getTest(string $name): ?TwigTest + { + return $this->extensionSet->getTest($name); + } + + public function addFunction(TwigFunction $function) + { + $this->extensionSet->addFunction($function); + } + + /** + * @internal + */ + public function getFunction(string $name): ?TwigFunction + { + return $this->extensionSet->getFunction($name); + } + + public function registerUndefinedFunctionCallback(callable $callable): void + { + $this->extensionSet->registerUndefinedFunctionCallback($callable); + } + + /** + * Gets registered functions. + * + * Be warned that this method cannot return functions defined with registerUndefinedFunctionCallback. + * + * @return TwigFunction[] + * + * @see registerUndefinedFunctionCallback + * + * @internal + */ + public function getFunctions(): array + { + return $this->extensionSet->getFunctions(); + } + + /** + * Registers a Global. + * + * New globals can be added before compiling or rendering a template; + * but after, you can only update existing globals. + * + * @param mixed $value The global value + */ + public function addGlobal(string $name, $value) + { + if ($this->extensionSet->isInitialized() && !\array_key_exists($name, $this->getGlobals())) { + throw new \LogicException(sprintf('Unable to add global "%s" as the runtime or the extensions have already been initialized.', $name)); + } + + if (null !== $this->resolvedGlobals) { + $this->resolvedGlobals[$name] = $value; + } else { + $this->globals[$name] = $value; + } + } + + /** + * @internal + */ + public function getGlobals(): array + { + if ($this->extensionSet->isInitialized()) { + if (null === $this->resolvedGlobals) { + $this->resolvedGlobals = array_merge($this->extensionSet->getGlobals(), $this->globals); + } + + return $this->resolvedGlobals; + } + + return array_merge($this->extensionSet->getGlobals(), $this->globals); + } + + public function mergeGlobals(array $context): array + { + // we don't use array_merge as the context being generally + // bigger than globals, this code is faster. + foreach ($this->getGlobals() as $key => $value) { + if (!\array_key_exists($key, $context)) { + $context[$key] = $value; + } + } + + return $context; + } + + /** + * @internal + */ + public function getUnaryOperators(): array + { + return $this->extensionSet->getUnaryOperators(); + } + + /** + * @internal + */ + public function getBinaryOperators(): array + { + return $this->extensionSet->getBinaryOperators(); + } + + private function updateOptionsHash(): void + { + $this->optionsHash = implode(':', [ + $this->extensionSet->getSignature(), + \PHP_MAJOR_VERSION, + \PHP_MINOR_VERSION, + self::VERSION, + (int) $this->debug, + (int) $this->strictVariables, + ]); + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Error/Error.php b/data/web/inc/lib/vendor/twig/twig/src/Error/Error.php new file mode 100644 index 00000000..a68be65f --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Error/Error.php @@ -0,0 +1,227 @@ + + */ +class Error extends \Exception +{ + private $lineno; + private $name; + private $rawMessage; + private $sourcePath; + private $sourceCode; + + /** + * Constructor. + * + * By default, automatic guessing is enabled. + * + * @param string $message The error message + * @param int $lineno The template line where the error occurred + * @param Source|null $source The source context where the error occurred + */ + public function __construct(string $message, int $lineno = -1, Source $source = null, \Exception $previous = null) + { + parent::__construct('', 0, $previous); + + if (null === $source) { + $name = null; + } else { + $name = $source->getName(); + $this->sourceCode = $source->getCode(); + $this->sourcePath = $source->getPath(); + } + + $this->lineno = $lineno; + $this->name = $name; + $this->rawMessage = $message; + $this->updateRepr(); + } + + public function getRawMessage(): string + { + return $this->rawMessage; + } + + public function getTemplateLine(): int + { + return $this->lineno; + } + + public function setTemplateLine(int $lineno): void + { + $this->lineno = $lineno; + + $this->updateRepr(); + } + + public function getSourceContext(): ?Source + { + return $this->name ? new Source($this->sourceCode, $this->name, $this->sourcePath) : null; + } + + public function setSourceContext(Source $source = null): void + { + if (null === $source) { + $this->sourceCode = $this->name = $this->sourcePath = null; + } else { + $this->sourceCode = $source->getCode(); + $this->name = $source->getName(); + $this->sourcePath = $source->getPath(); + } + + $this->updateRepr(); + } + + public function guess(): void + { + $this->guessTemplateInfo(); + $this->updateRepr(); + } + + public function appendMessage($rawMessage): void + { + $this->rawMessage .= $rawMessage; + $this->updateRepr(); + } + + private function updateRepr(): void + { + $this->message = $this->rawMessage; + + if ($this->sourcePath && $this->lineno > 0) { + $this->file = $this->sourcePath; + $this->line = $this->lineno; + + return; + } + + $dot = false; + if ('.' === substr($this->message, -1)) { + $this->message = substr($this->message, 0, -1); + $dot = true; + } + + $questionMark = false; + if ('?' === substr($this->message, -1)) { + $this->message = substr($this->message, 0, -1); + $questionMark = true; + } + + if ($this->name) { + if (\is_string($this->name) || (\is_object($this->name) && method_exists($this->name, '__toString'))) { + $name = sprintf('"%s"', $this->name); + } else { + $name = json_encode($this->name); + } + $this->message .= sprintf(' in %s', $name); + } + + if ($this->lineno && $this->lineno >= 0) { + $this->message .= sprintf(' at line %d', $this->lineno); + } + + if ($dot) { + $this->message .= '.'; + } + + if ($questionMark) { + $this->message .= '?'; + } + } + + private function guessTemplateInfo(): void + { + $template = null; + $templateClass = null; + + $backtrace = debug_backtrace(\DEBUG_BACKTRACE_IGNORE_ARGS | \DEBUG_BACKTRACE_PROVIDE_OBJECT); + foreach ($backtrace as $trace) { + if (isset($trace['object']) && $trace['object'] instanceof Template) { + $currentClass = \get_class($trace['object']); + $isEmbedContainer = null === $templateClass ? false : 0 === strpos($templateClass, $currentClass); + if (null === $this->name || ($this->name == $trace['object']->getTemplateName() && !$isEmbedContainer)) { + $template = $trace['object']; + $templateClass = \get_class($trace['object']); + } + } + } + + // update template name + if (null !== $template && null === $this->name) { + $this->name = $template->getTemplateName(); + } + + // update template path if any + if (null !== $template && null === $this->sourcePath) { + $src = $template->getSourceContext(); + $this->sourceCode = $src->getCode(); + $this->sourcePath = $src->getPath(); + } + + if (null === $template || $this->lineno > -1) { + return; + } + + $r = new \ReflectionObject($template); + $file = $r->getFileName(); + + $exceptions = [$e = $this]; + while ($e = $e->getPrevious()) { + $exceptions[] = $e; + } + + while ($e = array_pop($exceptions)) { + $traces = $e->getTrace(); + array_unshift($traces, ['file' => $e->getFile(), 'line' => $e->getLine()]); + + while ($trace = array_shift($traces)) { + if (!isset($trace['file']) || !isset($trace['line']) || $file != $trace['file']) { + continue; + } + + foreach ($template->getDebugInfo() as $codeLine => $templateLine) { + if ($codeLine <= $trace['line']) { + // update template line + $this->lineno = $templateLine; + + return; + } + } + } + } + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Error/LoaderError.php b/data/web/inc/lib/vendor/twig/twig/src/Error/LoaderError.php new file mode 100644 index 00000000..7c8c23c1 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Error/LoaderError.php @@ -0,0 +1,21 @@ + + */ +class LoaderError extends Error +{ +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Error/RuntimeError.php b/data/web/inc/lib/vendor/twig/twig/src/Error/RuntimeError.php new file mode 100644 index 00000000..f6b84766 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Error/RuntimeError.php @@ -0,0 +1,22 @@ + + */ +class RuntimeError extends Error +{ +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Error/SyntaxError.php b/data/web/inc/lib/vendor/twig/twig/src/Error/SyntaxError.php new file mode 100644 index 00000000..726b3309 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Error/SyntaxError.php @@ -0,0 +1,46 @@ + + */ +class SyntaxError extends Error +{ + /** + * Tweaks the error message to include suggestions. + * + * @param string $name The original name of the item that does not exist + * @param array $items An array of possible items + */ + public function addSuggestions(string $name, array $items): void + { + $alternatives = []; + foreach ($items as $item) { + $lev = levenshtein($name, $item); + if ($lev <= \strlen($name) / 3 || false !== strpos($item, $name)) { + $alternatives[$item] = $lev; + } + } + + if (!$alternatives) { + return; + } + + asort($alternatives); + + $this->appendMessage(sprintf(' Did you mean "%s"?', implode('", "', array_keys($alternatives)))); + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/ExpressionParser.php b/data/web/inc/lib/vendor/twig/twig/src/ExpressionParser.php new file mode 100644 index 00000000..66acddf6 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/ExpressionParser.php @@ -0,0 +1,825 @@ + + * + * @internal + */ +class ExpressionParser +{ + public const OPERATOR_LEFT = 1; + public const OPERATOR_RIGHT = 2; + + private $parser; + private $env; + private $unaryOperators; + private $binaryOperators; + + public function __construct(Parser $parser, Environment $env) + { + $this->parser = $parser; + $this->env = $env; + $this->unaryOperators = $env->getUnaryOperators(); + $this->binaryOperators = $env->getBinaryOperators(); + } + + public function parseExpression($precedence = 0, $allowArrow = false) + { + if ($allowArrow && $arrow = $this->parseArrow()) { + return $arrow; + } + + $expr = $this->getPrimary(); + $token = $this->parser->getCurrentToken(); + while ($this->isBinary($token) && $this->binaryOperators[$token->getValue()]['precedence'] >= $precedence) { + $op = $this->binaryOperators[$token->getValue()]; + $this->parser->getStream()->next(); + + if ('is not' === $token->getValue()) { + $expr = $this->parseNotTestExpression($expr); + } elseif ('is' === $token->getValue()) { + $expr = $this->parseTestExpression($expr); + } elseif (isset($op['callable'])) { + $expr = $op['callable']($this->parser, $expr); + } else { + $expr1 = $this->parseExpression(self::OPERATOR_LEFT === $op['associativity'] ? $op['precedence'] + 1 : $op['precedence']); + $class = $op['class']; + $expr = new $class($expr, $expr1, $token->getLine()); + } + + $token = $this->parser->getCurrentToken(); + } + + if (0 === $precedence) { + return $this->parseConditionalExpression($expr); + } + + return $expr; + } + + /** + * @return ArrowFunctionExpression|null + */ + private function parseArrow() + { + $stream = $this->parser->getStream(); + + // short array syntax (one argument, no parentheses)? + if ($stream->look(1)->test(/* Token::ARROW_TYPE */ 12)) { + $line = $stream->getCurrent()->getLine(); + $token = $stream->expect(/* Token::NAME_TYPE */ 5); + $names = [new AssignNameExpression($token->getValue(), $token->getLine())]; + $stream->expect(/* Token::ARROW_TYPE */ 12); + + return new ArrowFunctionExpression($this->parseExpression(0), new Node($names), $line); + } + + // first, determine if we are parsing an arrow function by finding => (long form) + $i = 0; + if (!$stream->look($i)->test(/* Token::PUNCTUATION_TYPE */ 9, '(')) { + return null; + } + ++$i; + while (true) { + // variable name + ++$i; + if (!$stream->look($i)->test(/* Token::PUNCTUATION_TYPE */ 9, ',')) { + break; + } + ++$i; + } + if (!$stream->look($i)->test(/* Token::PUNCTUATION_TYPE */ 9, ')')) { + return null; + } + ++$i; + if (!$stream->look($i)->test(/* Token::ARROW_TYPE */ 12)) { + return null; + } + + // yes, let's parse it properly + $token = $stream->expect(/* Token::PUNCTUATION_TYPE */ 9, '('); + $line = $token->getLine(); + + $names = []; + while (true) { + $token = $stream->expect(/* Token::NAME_TYPE */ 5); + $names[] = new AssignNameExpression($token->getValue(), $token->getLine()); + + if (!$stream->nextIf(/* Token::PUNCTUATION_TYPE */ 9, ',')) { + break; + } + } + $stream->expect(/* Token::PUNCTUATION_TYPE */ 9, ')'); + $stream->expect(/* Token::ARROW_TYPE */ 12); + + return new ArrowFunctionExpression($this->parseExpression(0), new Node($names), $line); + } + + private function getPrimary(): AbstractExpression + { + $token = $this->parser->getCurrentToken(); + + if ($this->isUnary($token)) { + $operator = $this->unaryOperators[$token->getValue()]; + $this->parser->getStream()->next(); + $expr = $this->parseExpression($operator['precedence']); + $class = $operator['class']; + + return $this->parsePostfixExpression(new $class($expr, $token->getLine())); + } elseif ($token->test(/* Token::PUNCTUATION_TYPE */ 9, '(')) { + $this->parser->getStream()->next(); + $expr = $this->parseExpression(); + $this->parser->getStream()->expect(/* Token::PUNCTUATION_TYPE */ 9, ')', 'An opened parenthesis is not properly closed'); + + return $this->parsePostfixExpression($expr); + } + + return $this->parsePrimaryExpression(); + } + + private function parseConditionalExpression($expr): AbstractExpression + { + while ($this->parser->getStream()->nextIf(/* Token::PUNCTUATION_TYPE */ 9, '?')) { + if (!$this->parser->getStream()->nextIf(/* Token::PUNCTUATION_TYPE */ 9, ':')) { + $expr2 = $this->parseExpression(); + if ($this->parser->getStream()->nextIf(/* Token::PUNCTUATION_TYPE */ 9, ':')) { + $expr3 = $this->parseExpression(); + } else { + $expr3 = new ConstantExpression('', $this->parser->getCurrentToken()->getLine()); + } + } else { + $expr2 = $expr; + $expr3 = $this->parseExpression(); + } + + $expr = new ConditionalExpression($expr, $expr2, $expr3, $this->parser->getCurrentToken()->getLine()); + } + + return $expr; + } + + private function isUnary(Token $token): bool + { + return $token->test(/* Token::OPERATOR_TYPE */ 8) && isset($this->unaryOperators[$token->getValue()]); + } + + private function isBinary(Token $token): bool + { + return $token->test(/* Token::OPERATOR_TYPE */ 8) && isset($this->binaryOperators[$token->getValue()]); + } + + public function parsePrimaryExpression() + { + $token = $this->parser->getCurrentToken(); + switch ($token->getType()) { + case /* Token::NAME_TYPE */ 5: + $this->parser->getStream()->next(); + switch ($token->getValue()) { + case 'true': + case 'TRUE': + $node = new ConstantExpression(true, $token->getLine()); + break; + + case 'false': + case 'FALSE': + $node = new ConstantExpression(false, $token->getLine()); + break; + + case 'none': + case 'NONE': + case 'null': + case 'NULL': + $node = new ConstantExpression(null, $token->getLine()); + break; + + default: + if ('(' === $this->parser->getCurrentToken()->getValue()) { + $node = $this->getFunctionNode($token->getValue(), $token->getLine()); + } else { + $node = new NameExpression($token->getValue(), $token->getLine()); + } + } + break; + + case /* Token::NUMBER_TYPE */ 6: + $this->parser->getStream()->next(); + $node = new ConstantExpression($token->getValue(), $token->getLine()); + break; + + case /* Token::STRING_TYPE */ 7: + case /* Token::INTERPOLATION_START_TYPE */ 10: + $node = $this->parseStringExpression(); + break; + + case /* Token::OPERATOR_TYPE */ 8: + if (preg_match(Lexer::REGEX_NAME, $token->getValue(), $matches) && $matches[0] == $token->getValue()) { + // in this context, string operators are variable names + $this->parser->getStream()->next(); + $node = new NameExpression($token->getValue(), $token->getLine()); + break; + } + + if (isset($this->unaryOperators[$token->getValue()])) { + $class = $this->unaryOperators[$token->getValue()]['class']; + if (!\in_array($class, [NegUnary::class, PosUnary::class])) { + throw new SyntaxError(sprintf('Unexpected unary operator "%s".', $token->getValue()), $token->getLine(), $this->parser->getStream()->getSourceContext()); + } + + $this->parser->getStream()->next(); + $expr = $this->parsePrimaryExpression(); + + $node = new $class($expr, $token->getLine()); + break; + } + + // no break + default: + if ($token->test(/* Token::PUNCTUATION_TYPE */ 9, '[')) { + $node = $this->parseArrayExpression(); + } elseif ($token->test(/* Token::PUNCTUATION_TYPE */ 9, '{')) { + $node = $this->parseHashExpression(); + } elseif ($token->test(/* Token::OPERATOR_TYPE */ 8, '=') && ('==' === $this->parser->getStream()->look(-1)->getValue() || '!=' === $this->parser->getStream()->look(-1)->getValue())) { + throw new SyntaxError(sprintf('Unexpected operator of value "%s". Did you try to use "===" or "!==" for strict comparison? Use "is same as(value)" instead.', $token->getValue()), $token->getLine(), $this->parser->getStream()->getSourceContext()); + } else { + throw new SyntaxError(sprintf('Unexpected token "%s" of value "%s".', Token::typeToEnglish($token->getType()), $token->getValue()), $token->getLine(), $this->parser->getStream()->getSourceContext()); + } + } + + return $this->parsePostfixExpression($node); + } + + public function parseStringExpression() + { + $stream = $this->parser->getStream(); + + $nodes = []; + // a string cannot be followed by another string in a single expression + $nextCanBeString = true; + while (true) { + if ($nextCanBeString && $token = $stream->nextIf(/* Token::STRING_TYPE */ 7)) { + $nodes[] = new ConstantExpression($token->getValue(), $token->getLine()); + $nextCanBeString = false; + } elseif ($stream->nextIf(/* Token::INTERPOLATION_START_TYPE */ 10)) { + $nodes[] = $this->parseExpression(); + $stream->expect(/* Token::INTERPOLATION_END_TYPE */ 11); + $nextCanBeString = true; + } else { + break; + } + } + + $expr = array_shift($nodes); + foreach ($nodes as $node) { + $expr = new ConcatBinary($expr, $node, $node->getTemplateLine()); + } + + return $expr; + } + + public function parseArrayExpression() + { + $stream = $this->parser->getStream(); + $stream->expect(/* Token::PUNCTUATION_TYPE */ 9, '[', 'An array element was expected'); + + $node = new ArrayExpression([], $stream->getCurrent()->getLine()); + $first = true; + while (!$stream->test(/* Token::PUNCTUATION_TYPE */ 9, ']')) { + if (!$first) { + $stream->expect(/* Token::PUNCTUATION_TYPE */ 9, ',', 'An array element must be followed by a comma'); + + // trailing ,? + if ($stream->test(/* Token::PUNCTUATION_TYPE */ 9, ']')) { + break; + } + } + $first = false; + + $node->addElement($this->parseExpression()); + } + $stream->expect(/* Token::PUNCTUATION_TYPE */ 9, ']', 'An opened array is not properly closed'); + + return $node; + } + + public function parseHashExpression() + { + $stream = $this->parser->getStream(); + $stream->expect(/* Token::PUNCTUATION_TYPE */ 9, '{', 'A hash element was expected'); + + $node = new ArrayExpression([], $stream->getCurrent()->getLine()); + $first = true; + while (!$stream->test(/* Token::PUNCTUATION_TYPE */ 9, '}')) { + if (!$first) { + $stream->expect(/* Token::PUNCTUATION_TYPE */ 9, ',', 'A hash value must be followed by a comma'); + + // trailing ,? + if ($stream->test(/* Token::PUNCTUATION_TYPE */ 9, '}')) { + break; + } + } + $first = false; + + // a hash key can be: + // + // * a number -- 12 + // * a string -- 'a' + // * a name, which is equivalent to a string -- a + // * an expression, which must be enclosed in parentheses -- (1 + 2) + if ($token = $stream->nextIf(/* Token::NAME_TYPE */ 5)) { + $key = new ConstantExpression($token->getValue(), $token->getLine()); + + // {a} is a shortcut for {a:a} + if ($stream->test(Token::PUNCTUATION_TYPE, [',', '}'])) { + $value = new NameExpression($key->getAttribute('value'), $key->getTemplateLine()); + $node->addElement($value, $key); + continue; + } + } elseif (($token = $stream->nextIf(/* Token::STRING_TYPE */ 7)) || $token = $stream->nextIf(/* Token::NUMBER_TYPE */ 6)) { + $key = new ConstantExpression($token->getValue(), $token->getLine()); + } elseif ($stream->test(/* Token::PUNCTUATION_TYPE */ 9, '(')) { + $key = $this->parseExpression(); + } else { + $current = $stream->getCurrent(); + + throw new SyntaxError(sprintf('A hash key must be a quoted string, a number, a name, or an expression enclosed in parentheses (unexpected token "%s" of value "%s".', Token::typeToEnglish($current->getType()), $current->getValue()), $current->getLine(), $stream->getSourceContext()); + } + + $stream->expect(/* Token::PUNCTUATION_TYPE */ 9, ':', 'A hash key must be followed by a colon (:)'); + $value = $this->parseExpression(); + + $node->addElement($value, $key); + } + $stream->expect(/* Token::PUNCTUATION_TYPE */ 9, '}', 'An opened hash is not properly closed'); + + return $node; + } + + public function parsePostfixExpression($node) + { + while (true) { + $token = $this->parser->getCurrentToken(); + if (/* Token::PUNCTUATION_TYPE */ 9 == $token->getType()) { + if ('.' == $token->getValue() || '[' == $token->getValue()) { + $node = $this->parseSubscriptExpression($node); + } elseif ('|' == $token->getValue()) { + $node = $this->parseFilterExpression($node); + } else { + break; + } + } else { + break; + } + } + + return $node; + } + + public function getFunctionNode($name, $line) + { + switch ($name) { + case 'parent': + $this->parseArguments(); + if (!\count($this->parser->getBlockStack())) { + throw new SyntaxError('Calling "parent" outside a block is forbidden.', $line, $this->parser->getStream()->getSourceContext()); + } + + if (!$this->parser->getParent() && !$this->parser->hasTraits()) { + throw new SyntaxError('Calling "parent" on a template that does not extend nor "use" another template is forbidden.', $line, $this->parser->getStream()->getSourceContext()); + } + + return new ParentExpression($this->parser->peekBlockStack(), $line); + case 'block': + $args = $this->parseArguments(); + if (\count($args) < 1) { + throw new SyntaxError('The "block" function takes one argument (the block name).', $line, $this->parser->getStream()->getSourceContext()); + } + + return new BlockReferenceExpression($args->getNode(0), \count($args) > 1 ? $args->getNode(1) : null, $line); + case 'attribute': + $args = $this->parseArguments(); + if (\count($args) < 2) { + throw new SyntaxError('The "attribute" function takes at least two arguments (the variable and the attributes).', $line, $this->parser->getStream()->getSourceContext()); + } + + return new GetAttrExpression($args->getNode(0), $args->getNode(1), \count($args) > 2 ? $args->getNode(2) : null, Template::ANY_CALL, $line); + default: + if (null !== $alias = $this->parser->getImportedSymbol('function', $name)) { + $arguments = new ArrayExpression([], $line); + foreach ($this->parseArguments() as $n) { + $arguments->addElement($n); + } + + $node = new MethodCallExpression($alias['node'], $alias['name'], $arguments, $line); + $node->setAttribute('safe', true); + + return $node; + } + + $args = $this->parseArguments(true); + $class = $this->getFunctionNodeClass($name, $line); + + return new $class($name, $args, $line); + } + } + + public function parseSubscriptExpression($node) + { + $stream = $this->parser->getStream(); + $token = $stream->next(); + $lineno = $token->getLine(); + $arguments = new ArrayExpression([], $lineno); + $type = Template::ANY_CALL; + if ('.' == $token->getValue()) { + $token = $stream->next(); + if ( + /* Token::NAME_TYPE */ 5 == $token->getType() + || + /* Token::NUMBER_TYPE */ 6 == $token->getType() + || + (/* Token::OPERATOR_TYPE */ 8 == $token->getType() && preg_match(Lexer::REGEX_NAME, $token->getValue())) + ) { + $arg = new ConstantExpression($token->getValue(), $lineno); + + if ($stream->test(/* Token::PUNCTUATION_TYPE */ 9, '(')) { + $type = Template::METHOD_CALL; + foreach ($this->parseArguments() as $n) { + $arguments->addElement($n); + } + } + } else { + throw new SyntaxError('Expected name or number.', $lineno, $stream->getSourceContext()); + } + + if ($node instanceof NameExpression && null !== $this->parser->getImportedSymbol('template', $node->getAttribute('name'))) { + if (!$arg instanceof ConstantExpression) { + throw new SyntaxError(sprintf('Dynamic macro names are not supported (called on "%s").', $node->getAttribute('name')), $token->getLine(), $stream->getSourceContext()); + } + + $name = $arg->getAttribute('value'); + + $node = new MethodCallExpression($node, 'macro_'.$name, $arguments, $lineno); + $node->setAttribute('safe', true); + + return $node; + } + } else { + $type = Template::ARRAY_CALL; + + // slice? + $slice = false; + if ($stream->test(/* Token::PUNCTUATION_TYPE */ 9, ':')) { + $slice = true; + $arg = new ConstantExpression(0, $token->getLine()); + } else { + $arg = $this->parseExpression(); + } + + if ($stream->nextIf(/* Token::PUNCTUATION_TYPE */ 9, ':')) { + $slice = true; + } + + if ($slice) { + if ($stream->test(/* Token::PUNCTUATION_TYPE */ 9, ']')) { + $length = new ConstantExpression(null, $token->getLine()); + } else { + $length = $this->parseExpression(); + } + + $class = $this->getFilterNodeClass('slice', $token->getLine()); + $arguments = new Node([$arg, $length]); + $filter = new $class($node, new ConstantExpression('slice', $token->getLine()), $arguments, $token->getLine()); + + $stream->expect(/* Token::PUNCTUATION_TYPE */ 9, ']'); + + return $filter; + } + + $stream->expect(/* Token::PUNCTUATION_TYPE */ 9, ']'); + } + + return new GetAttrExpression($node, $arg, $arguments, $type, $lineno); + } + + public function parseFilterExpression($node) + { + $this->parser->getStream()->next(); + + return $this->parseFilterExpressionRaw($node); + } + + public function parseFilterExpressionRaw($node, $tag = null) + { + while (true) { + $token = $this->parser->getStream()->expect(/* Token::NAME_TYPE */ 5); + + $name = new ConstantExpression($token->getValue(), $token->getLine()); + if (!$this->parser->getStream()->test(/* Token::PUNCTUATION_TYPE */ 9, '(')) { + $arguments = new Node(); + } else { + $arguments = $this->parseArguments(true, false, true); + } + + $class = $this->getFilterNodeClass($name->getAttribute('value'), $token->getLine()); + + $node = new $class($node, $name, $arguments, $token->getLine(), $tag); + + if (!$this->parser->getStream()->test(/* Token::PUNCTUATION_TYPE */ 9, '|')) { + break; + } + + $this->parser->getStream()->next(); + } + + return $node; + } + + /** + * Parses arguments. + * + * @param bool $namedArguments Whether to allow named arguments or not + * @param bool $definition Whether we are parsing arguments for a function definition + * + * @return Node + * + * @throws SyntaxError + */ + public function parseArguments($namedArguments = false, $definition = false, $allowArrow = false) + { + $args = []; + $stream = $this->parser->getStream(); + + $stream->expect(/* Token::PUNCTUATION_TYPE */ 9, '(', 'A list of arguments must begin with an opening parenthesis'); + while (!$stream->test(/* Token::PUNCTUATION_TYPE */ 9, ')')) { + if (!empty($args)) { + $stream->expect(/* Token::PUNCTUATION_TYPE */ 9, ',', 'Arguments must be separated by a comma'); + + // if the comma above was a trailing comma, early exit the argument parse loop + if ($stream->test(/* Token::PUNCTUATION_TYPE */ 9, ')')) { + break; + } + } + + if ($definition) { + $token = $stream->expect(/* Token::NAME_TYPE */ 5, null, 'An argument must be a name'); + $value = new NameExpression($token->getValue(), $this->parser->getCurrentToken()->getLine()); + } else { + $value = $this->parseExpression(0, $allowArrow); + } + + $name = null; + if ($namedArguments && $token = $stream->nextIf(/* Token::OPERATOR_TYPE */ 8, '=')) { + if (!$value instanceof NameExpression) { + throw new SyntaxError(sprintf('A parameter name must be a string, "%s" given.', \get_class($value)), $token->getLine(), $stream->getSourceContext()); + } + $name = $value->getAttribute('name'); + + if ($definition) { + $value = $this->parsePrimaryExpression(); + + if (!$this->checkConstantExpression($value)) { + throw new SyntaxError('A default value for an argument must be a constant (a boolean, a string, a number, or an array).', $token->getLine(), $stream->getSourceContext()); + } + } else { + $value = $this->parseExpression(0, $allowArrow); + } + } + + if ($definition) { + if (null === $name) { + $name = $value->getAttribute('name'); + $value = new ConstantExpression(null, $this->parser->getCurrentToken()->getLine()); + } + $args[$name] = $value; + } else { + if (null === $name) { + $args[] = $value; + } else { + $args[$name] = $value; + } + } + } + $stream->expect(/* Token::PUNCTUATION_TYPE */ 9, ')', 'A list of arguments must be closed by a parenthesis'); + + return new Node($args); + } + + public function parseAssignmentExpression() + { + $stream = $this->parser->getStream(); + $targets = []; + while (true) { + $token = $this->parser->getCurrentToken(); + if ($stream->test(/* Token::OPERATOR_TYPE */ 8) && preg_match(Lexer::REGEX_NAME, $token->getValue())) { + // in this context, string operators are variable names + $this->parser->getStream()->next(); + } else { + $stream->expect(/* Token::NAME_TYPE */ 5, null, 'Only variables can be assigned to'); + } + $value = $token->getValue(); + if (\in_array(strtr($value, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'), ['true', 'false', 'none', 'null'])) { + throw new SyntaxError(sprintf('You cannot assign a value to "%s".', $value), $token->getLine(), $stream->getSourceContext()); + } + $targets[] = new AssignNameExpression($value, $token->getLine()); + + if (!$stream->nextIf(/* Token::PUNCTUATION_TYPE */ 9, ',')) { + break; + } + } + + return new Node($targets); + } + + public function parseMultitargetExpression() + { + $targets = []; + while (true) { + $targets[] = $this->parseExpression(); + if (!$this->parser->getStream()->nextIf(/* Token::PUNCTUATION_TYPE */ 9, ',')) { + break; + } + } + + return new Node($targets); + } + + private function parseNotTestExpression(Node $node): NotUnary + { + return new NotUnary($this->parseTestExpression($node), $this->parser->getCurrentToken()->getLine()); + } + + private function parseTestExpression(Node $node): TestExpression + { + $stream = $this->parser->getStream(); + list($name, $test) = $this->getTest($node->getTemplateLine()); + + $class = $this->getTestNodeClass($test); + $arguments = null; + if ($stream->test(/* Token::PUNCTUATION_TYPE */ 9, '(')) { + $arguments = $this->parseArguments(true); + } elseif ($test->hasOneMandatoryArgument()) { + $arguments = new Node([0 => $this->parsePrimaryExpression()]); + } + + if ('defined' === $name && $node instanceof NameExpression && null !== $alias = $this->parser->getImportedSymbol('function', $node->getAttribute('name'))) { + $node = new MethodCallExpression($alias['node'], $alias['name'], new ArrayExpression([], $node->getTemplateLine()), $node->getTemplateLine()); + $node->setAttribute('safe', true); + } + + return new $class($node, $name, $arguments, $this->parser->getCurrentToken()->getLine()); + } + + private function getTest(int $line): array + { + $stream = $this->parser->getStream(); + $name = $stream->expect(/* Token::NAME_TYPE */ 5)->getValue(); + + if ($test = $this->env->getTest($name)) { + return [$name, $test]; + } + + if ($stream->test(/* Token::NAME_TYPE */ 5)) { + // try 2-words tests + $name = $name.' '.$this->parser->getCurrentToken()->getValue(); + + if ($test = $this->env->getTest($name)) { + $stream->next(); + + return [$name, $test]; + } + } + + $e = new SyntaxError(sprintf('Unknown "%s" test.', $name), $line, $stream->getSourceContext()); + $e->addSuggestions($name, array_keys($this->env->getTests())); + + throw $e; + } + + private function getTestNodeClass(TwigTest $test): string + { + if ($test->isDeprecated()) { + $stream = $this->parser->getStream(); + $message = sprintf('Twig Test "%s" is deprecated', $test->getName()); + + if ($test->getDeprecatedVersion()) { + $message .= sprintf(' since version %s', $test->getDeprecatedVersion()); + } + if ($test->getAlternative()) { + $message .= sprintf('. Use "%s" instead', $test->getAlternative()); + } + $src = $stream->getSourceContext(); + $message .= sprintf(' in %s at line %d.', $src->getPath() ?: $src->getName(), $stream->getCurrent()->getLine()); + + @trigger_error($message, \E_USER_DEPRECATED); + } + + return $test->getNodeClass(); + } + + private function getFunctionNodeClass(string $name, int $line): string + { + if (!$function = $this->env->getFunction($name)) { + $e = new SyntaxError(sprintf('Unknown "%s" function.', $name), $line, $this->parser->getStream()->getSourceContext()); + $e->addSuggestions($name, array_keys($this->env->getFunctions())); + + throw $e; + } + + if ($function->isDeprecated()) { + $message = sprintf('Twig Function "%s" is deprecated', $function->getName()); + if ($function->getDeprecatedVersion()) { + $message .= sprintf(' since version %s', $function->getDeprecatedVersion()); + } + if ($function->getAlternative()) { + $message .= sprintf('. Use "%s" instead', $function->getAlternative()); + } + $src = $this->parser->getStream()->getSourceContext(); + $message .= sprintf(' in %s at line %d.', $src->getPath() ?: $src->getName(), $line); + + @trigger_error($message, \E_USER_DEPRECATED); + } + + return $function->getNodeClass(); + } + + private function getFilterNodeClass(string $name, int $line): string + { + if (!$filter = $this->env->getFilter($name)) { + $e = new SyntaxError(sprintf('Unknown "%s" filter.', $name), $line, $this->parser->getStream()->getSourceContext()); + $e->addSuggestions($name, array_keys($this->env->getFilters())); + + throw $e; + } + + if ($filter->isDeprecated()) { + $message = sprintf('Twig Filter "%s" is deprecated', $filter->getName()); + if ($filter->getDeprecatedVersion()) { + $message .= sprintf(' since version %s', $filter->getDeprecatedVersion()); + } + if ($filter->getAlternative()) { + $message .= sprintf('. Use "%s" instead', $filter->getAlternative()); + } + $src = $this->parser->getStream()->getSourceContext(); + $message .= sprintf(' in %s at line %d.', $src->getPath() ?: $src->getName(), $line); + + @trigger_error($message, \E_USER_DEPRECATED); + } + + return $filter->getNodeClass(); + } + + // checks that the node only contains "constant" elements + private function checkConstantExpression(Node $node): bool + { + if (!($node instanceof ConstantExpression || $node instanceof ArrayExpression + || $node instanceof NegUnary || $node instanceof PosUnary + )) { + return false; + } + + foreach ($node as $n) { + if (!$this->checkConstantExpression($n)) { + return false; + } + } + + return true; + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Extension/AbstractExtension.php b/data/web/inc/lib/vendor/twig/twig/src/Extension/AbstractExtension.php new file mode 100644 index 00000000..422925f3 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Extension/AbstractExtension.php @@ -0,0 +1,45 @@ +dateFormats[0] = $format; + } + + if (null !== $dateIntervalFormat) { + $this->dateFormats[1] = $dateIntervalFormat; + } + } + + /** + * Gets the default format to be used by the date filter. + * + * @return array The default date format string and the default date interval format string + */ + public function getDateFormat() + { + return $this->dateFormats; + } + + /** + * Sets the default timezone to be used by the date filter. + * + * @param \DateTimeZone|string $timezone The default timezone string or a \DateTimeZone object + */ + public function setTimezone($timezone) + { + $this->timezone = $timezone instanceof \DateTimeZone ? $timezone : new \DateTimeZone($timezone); + } + + /** + * Gets the default timezone to be used by the date filter. + * + * @return \DateTimeZone The default timezone currently in use + */ + public function getTimezone() + { + if (null === $this->timezone) { + $this->timezone = new \DateTimeZone(date_default_timezone_get()); + } + + return $this->timezone; + } + + /** + * Sets the default format to be used by the number_format filter. + * + * @param int $decimal the number of decimal places to use + * @param string $decimalPoint the character(s) to use for the decimal point + * @param string $thousandSep the character(s) to use for the thousands separator + */ + public function setNumberFormat($decimal, $decimalPoint, $thousandSep) + { + $this->numberFormat = [$decimal, $decimalPoint, $thousandSep]; + } + + /** + * Get the default format used by the number_format filter. + * + * @return array The arguments for number_format() + */ + public function getNumberFormat() + { + return $this->numberFormat; + } + + public function getTokenParsers(): array + { + return [ + new ApplyTokenParser(), + new ForTokenParser(), + new IfTokenParser(), + new ExtendsTokenParser(), + new IncludeTokenParser(), + new BlockTokenParser(), + new UseTokenParser(), + new MacroTokenParser(), + new ImportTokenParser(), + new FromTokenParser(), + new SetTokenParser(), + new FlushTokenParser(), + new DoTokenParser(), + new EmbedTokenParser(), + new WithTokenParser(), + new DeprecatedTokenParser(), + ]; + } + + public function getFilters(): array + { + return [ + // formatting filters + new TwigFilter('date', 'twig_date_format_filter', ['needs_environment' => true]), + new TwigFilter('date_modify', 'twig_date_modify_filter', ['needs_environment' => true]), + new TwigFilter('format', 'sprintf'), + new TwigFilter('replace', 'twig_replace_filter'), + new TwigFilter('number_format', 'twig_number_format_filter', ['needs_environment' => true]), + new TwigFilter('abs', 'abs'), + new TwigFilter('round', 'twig_round'), + + // encoding + new TwigFilter('url_encode', 'twig_urlencode_filter'), + new TwigFilter('json_encode', 'json_encode'), + new TwigFilter('convert_encoding', 'twig_convert_encoding'), + + // string filters + new TwigFilter('title', 'twig_title_string_filter', ['needs_environment' => true]), + new TwigFilter('capitalize', 'twig_capitalize_string_filter', ['needs_environment' => true]), + new TwigFilter('upper', 'twig_upper_filter', ['needs_environment' => true]), + new TwigFilter('lower', 'twig_lower_filter', ['needs_environment' => true]), + new TwigFilter('striptags', 'strip_tags'), + new TwigFilter('trim', 'twig_trim_filter'), + new TwigFilter('nl2br', 'nl2br', ['pre_escape' => 'html', 'is_safe' => ['html']]), + new TwigFilter('spaceless', 'twig_spaceless', ['is_safe' => ['html']]), + + // array helpers + new TwigFilter('join', 'twig_join_filter'), + new TwigFilter('split', 'twig_split_filter', ['needs_environment' => true]), + new TwigFilter('sort', 'twig_sort_filter'), + new TwigFilter('merge', 'twig_array_merge'), + new TwigFilter('batch', 'twig_array_batch'), + new TwigFilter('column', 'twig_array_column'), + new TwigFilter('filter', 'twig_array_filter', ['needs_environment' => true]), + new TwigFilter('map', 'twig_array_map', ['needs_environment' => true]), + new TwigFilter('reduce', 'twig_array_reduce', ['needs_environment' => true]), + + // string/array filters + new TwigFilter('reverse', 'twig_reverse_filter', ['needs_environment' => true]), + new TwigFilter('length', 'twig_length_filter', ['needs_environment' => true]), + new TwigFilter('slice', 'twig_slice', ['needs_environment' => true]), + new TwigFilter('first', 'twig_first', ['needs_environment' => true]), + new TwigFilter('last', 'twig_last', ['needs_environment' => true]), + + // iteration and runtime + new TwigFilter('default', '_twig_default_filter', ['node_class' => DefaultFilter::class]), + new TwigFilter('keys', 'twig_get_array_keys_filter'), + ]; + } + + public function getFunctions(): array + { + return [ + new TwigFunction('max', 'max'), + new TwigFunction('min', 'min'), + new TwigFunction('range', 'range'), + new TwigFunction('constant', 'twig_constant'), + new TwigFunction('cycle', 'twig_cycle'), + new TwigFunction('random', 'twig_random', ['needs_environment' => true]), + new TwigFunction('date', 'twig_date_converter', ['needs_environment' => true]), + new TwigFunction('include', 'twig_include', ['needs_environment' => true, 'needs_context' => true, 'is_safe' => ['all']]), + new TwigFunction('source', 'twig_source', ['needs_environment' => true, 'is_safe' => ['all']]), + ]; + } + + public function getTests(): array + { + return [ + new TwigTest('even', null, ['node_class' => EvenTest::class]), + new TwigTest('odd', null, ['node_class' => OddTest::class]), + new TwigTest('defined', null, ['node_class' => DefinedTest::class]), + new TwigTest('same as', null, ['node_class' => SameasTest::class, 'one_mandatory_argument' => true]), + new TwigTest('none', null, ['node_class' => NullTest::class]), + new TwigTest('null', null, ['node_class' => NullTest::class]), + new TwigTest('divisible by', null, ['node_class' => DivisiblebyTest::class, 'one_mandatory_argument' => true]), + new TwigTest('constant', null, ['node_class' => ConstantTest::class]), + new TwigTest('empty', 'twig_test_empty'), + new TwigTest('iterable', 'twig_test_iterable'), + ]; + } + + public function getNodeVisitors(): array + { + return [new MacroAutoImportNodeVisitor()]; + } + + public function getOperators(): array + { + return [ + [ + 'not' => ['precedence' => 50, 'class' => NotUnary::class], + '-' => ['precedence' => 500, 'class' => NegUnary::class], + '+' => ['precedence' => 500, 'class' => PosUnary::class], + ], + [ + 'or' => ['precedence' => 10, 'class' => OrBinary::class, 'associativity' => ExpressionParser::OPERATOR_LEFT], + 'and' => ['precedence' => 15, 'class' => AndBinary::class, 'associativity' => ExpressionParser::OPERATOR_LEFT], + 'b-or' => ['precedence' => 16, 'class' => BitwiseOrBinary::class, 'associativity' => ExpressionParser::OPERATOR_LEFT], + 'b-xor' => ['precedence' => 17, 'class' => BitwiseXorBinary::class, 'associativity' => ExpressionParser::OPERATOR_LEFT], + 'b-and' => ['precedence' => 18, 'class' => BitwiseAndBinary::class, 'associativity' => ExpressionParser::OPERATOR_LEFT], + '==' => ['precedence' => 20, 'class' => EqualBinary::class, 'associativity' => ExpressionParser::OPERATOR_LEFT], + '!=' => ['precedence' => 20, 'class' => NotEqualBinary::class, 'associativity' => ExpressionParser::OPERATOR_LEFT], + '<=>' => ['precedence' => 20, 'class' => SpaceshipBinary::class, 'associativity' => ExpressionParser::OPERATOR_LEFT], + '<' => ['precedence' => 20, 'class' => LessBinary::class, 'associativity' => ExpressionParser::OPERATOR_LEFT], + '>' => ['precedence' => 20, 'class' => GreaterBinary::class, 'associativity' => ExpressionParser::OPERATOR_LEFT], + '>=' => ['precedence' => 20, 'class' => GreaterEqualBinary::class, 'associativity' => ExpressionParser::OPERATOR_LEFT], + '<=' => ['precedence' => 20, 'class' => LessEqualBinary::class, 'associativity' => ExpressionParser::OPERATOR_LEFT], + 'not in' => ['precedence' => 20, 'class' => NotInBinary::class, 'associativity' => ExpressionParser::OPERATOR_LEFT], + 'in' => ['precedence' => 20, 'class' => InBinary::class, 'associativity' => ExpressionParser::OPERATOR_LEFT], + 'matches' => ['precedence' => 20, 'class' => MatchesBinary::class, 'associativity' => ExpressionParser::OPERATOR_LEFT], + 'starts with' => ['precedence' => 20, 'class' => StartsWithBinary::class, 'associativity' => ExpressionParser::OPERATOR_LEFT], + 'ends with' => ['precedence' => 20, 'class' => EndsWithBinary::class, 'associativity' => ExpressionParser::OPERATOR_LEFT], + '..' => ['precedence' => 25, 'class' => RangeBinary::class, 'associativity' => ExpressionParser::OPERATOR_LEFT], + '+' => ['precedence' => 30, 'class' => AddBinary::class, 'associativity' => ExpressionParser::OPERATOR_LEFT], + '-' => ['precedence' => 30, 'class' => SubBinary::class, 'associativity' => ExpressionParser::OPERATOR_LEFT], + '~' => ['precedence' => 40, 'class' => ConcatBinary::class, 'associativity' => ExpressionParser::OPERATOR_LEFT], + '*' => ['precedence' => 60, 'class' => MulBinary::class, 'associativity' => ExpressionParser::OPERATOR_LEFT], + '/' => ['precedence' => 60, 'class' => DivBinary::class, 'associativity' => ExpressionParser::OPERATOR_LEFT], + '//' => ['precedence' => 60, 'class' => FloorDivBinary::class, 'associativity' => ExpressionParser::OPERATOR_LEFT], + '%' => ['precedence' => 60, 'class' => ModBinary::class, 'associativity' => ExpressionParser::OPERATOR_LEFT], + 'is' => ['precedence' => 100, 'associativity' => ExpressionParser::OPERATOR_LEFT], + 'is not' => ['precedence' => 100, 'associativity' => ExpressionParser::OPERATOR_LEFT], + '**' => ['precedence' => 200, 'class' => PowerBinary::class, 'associativity' => ExpressionParser::OPERATOR_RIGHT], + '??' => ['precedence' => 300, 'class' => NullCoalesceExpression::class, 'associativity' => ExpressionParser::OPERATOR_RIGHT], + ], + ]; + } +} +} + +namespace { + use Twig\Environment; + use Twig\Error\LoaderError; + use Twig\Error\RuntimeError; + use Twig\Extension\CoreExtension; + use Twig\Extension\SandboxExtension; + use Twig\Markup; + use Twig\Source; + use Twig\Template; + use Twig\TemplateWrapper; + +/** + * Cycles over a value. + * + * @param \ArrayAccess|array $values + * @param int $position The cycle position + * + * @return string The next value in the cycle + */ +function twig_cycle($values, $position) +{ + if (!\is_array($values) && !$values instanceof \ArrayAccess) { + return $values; + } + + return $values[$position % \count($values)]; +} + +/** + * Returns a random value depending on the supplied parameter type: + * - a random item from a \Traversable or array + * - a random character from a string + * - a random integer between 0 and the integer parameter. + * + * @param \Traversable|array|int|float|string $values The values to pick a random item from + * @param int|null $max Maximum value used when $values is an int + * + * @throws RuntimeError when $values is an empty array (does not apply to an empty string which is returned as is) + * + * @return mixed A random value from the given sequence + */ +function twig_random(Environment $env, $values = null, $max = null) +{ + if (null === $values) { + return null === $max ? mt_rand() : mt_rand(0, $max); + } + + if (\is_int($values) || \is_float($values)) { + if (null === $max) { + if ($values < 0) { + $max = 0; + $min = $values; + } else { + $max = $values; + $min = 0; + } + } else { + $min = $values; + $max = $max; + } + + return mt_rand($min, $max); + } + + if (\is_string($values)) { + if ('' === $values) { + return ''; + } + + $charset = $env->getCharset(); + + if ('UTF-8' !== $charset) { + $values = twig_convert_encoding($values, 'UTF-8', $charset); + } + + // unicode version of str_split() + // split at all positions, but not after the start and not before the end + $values = preg_split('/(? $value) { + $values[$i] = twig_convert_encoding($value, $charset, 'UTF-8'); + } + } + } + + if (!twig_test_iterable($values)) { + return $values; + } + + $values = twig_to_array($values); + + if (0 === \count($values)) { + throw new RuntimeError('The random function cannot pick from an empty array.'); + } + + return $values[array_rand($values, 1)]; +} + +/** + * Converts a date to the given format. + * + * {{ post.published_at|date("m/d/Y") }} + * + * @param \DateTimeInterface|\DateInterval|string $date A date + * @param string|null $format The target format, null to use the default + * @param \DateTimeZone|string|false|null $timezone The target timezone, null to use the default, false to leave unchanged + * + * @return string The formatted date + */ +function twig_date_format_filter(Environment $env, $date, $format = null, $timezone = null) +{ + if (null === $format) { + $formats = $env->getExtension(CoreExtension::class)->getDateFormat(); + $format = $date instanceof \DateInterval ? $formats[1] : $formats[0]; + } + + if ($date instanceof \DateInterval) { + return $date->format($format); + } + + return twig_date_converter($env, $date, $timezone)->format($format); +} + +/** + * Returns a new date object modified. + * + * {{ post.published_at|date_modify("-1day")|date("m/d/Y") }} + * + * @param \DateTimeInterface|string $date A date + * @param string $modifier A modifier string + * + * @return \DateTimeInterface + */ +function twig_date_modify_filter(Environment $env, $date, $modifier) +{ + $date = twig_date_converter($env, $date, false); + + return $date->modify($modifier); +} + +/** + * Converts an input to a \DateTime instance. + * + * {% if date(user.created_at) < date('+2days') %} + * {# do something #} + * {% endif %} + * + * @param \DateTimeInterface|string|null $date A date or null to use the current time + * @param \DateTimeZone|string|false|null $timezone The target timezone, null to use the default, false to leave unchanged + * + * @return \DateTimeInterface + */ +function twig_date_converter(Environment $env, $date = null, $timezone = null) +{ + // determine the timezone + if (false !== $timezone) { + if (null === $timezone) { + $timezone = $env->getExtension(CoreExtension::class)->getTimezone(); + } elseif (!$timezone instanceof \DateTimeZone) { + $timezone = new \DateTimeZone($timezone); + } + } + + // immutable dates + if ($date instanceof \DateTimeImmutable) { + return false !== $timezone ? $date->setTimezone($timezone) : $date; + } + + if ($date instanceof \DateTimeInterface) { + $date = clone $date; + if (false !== $timezone) { + $date->setTimezone($timezone); + } + + return $date; + } + + if (null === $date || 'now' === $date) { + if (null === $date) { + $date = 'now'; + } + + return new \DateTime($date, false !== $timezone ? $timezone : $env->getExtension(CoreExtension::class)->getTimezone()); + } + + $asString = (string) $date; + if (ctype_digit($asString) || (!empty($asString) && '-' === $asString[0] && ctype_digit(substr($asString, 1)))) { + $date = new \DateTime('@'.$date); + } else { + $date = new \DateTime($date, $env->getExtension(CoreExtension::class)->getTimezone()); + } + + if (false !== $timezone) { + $date->setTimezone($timezone); + } + + return $date; +} + +/** + * Replaces strings within a string. + * + * @param string $str String to replace in + * @param array|\Traversable $from Replace values + * + * @return string + */ +function twig_replace_filter($str, $from) +{ + if (!twig_test_iterable($from)) { + throw new RuntimeError(sprintf('The "replace" filter expects an array or "Traversable" as replace values, got "%s".', \is_object($from) ? \get_class($from) : \gettype($from))); + } + + return strtr($str, twig_to_array($from)); +} + +/** + * Rounds a number. + * + * @param int|float $value The value to round + * @param int|float $precision The rounding precision + * @param string $method The method to use for rounding + * + * @return int|float The rounded number + */ +function twig_round($value, $precision = 0, $method = 'common') +{ + if ('common' === $method) { + return round($value, $precision); + } + + if ('ceil' !== $method && 'floor' !== $method) { + throw new RuntimeError('The round filter only supports the "common", "ceil", and "floor" methods.'); + } + + return $method($value * 10 ** $precision) / 10 ** $precision; +} + +/** + * Number format filter. + * + * All of the formatting options can be left null, in that case the defaults will + * be used. Supplying any of the parameters will override the defaults set in the + * environment object. + * + * @param mixed $number A float/int/string of the number to format + * @param int $decimal the number of decimal points to display + * @param string $decimalPoint the character(s) to use for the decimal point + * @param string $thousandSep the character(s) to use for the thousands separator + * + * @return string The formatted number + */ +function twig_number_format_filter(Environment $env, $number, $decimal = null, $decimalPoint = null, $thousandSep = null) +{ + $defaults = $env->getExtension(CoreExtension::class)->getNumberFormat(); + if (null === $decimal) { + $decimal = $defaults[0]; + } + + if (null === $decimalPoint) { + $decimalPoint = $defaults[1]; + } + + if (null === $thousandSep) { + $thousandSep = $defaults[2]; + } + + return number_format((float) $number, $decimal, $decimalPoint, $thousandSep); +} + +/** + * URL encodes (RFC 3986) a string as a path segment or an array as a query string. + * + * @param string|array $url A URL or an array of query parameters + * + * @return string The URL encoded value + */ +function twig_urlencode_filter($url) +{ + if (\is_array($url)) { + return http_build_query($url, '', '&', \PHP_QUERY_RFC3986); + } + + return rawurlencode($url); +} + +/** + * Merges an array with another one. + * + * {% set items = { 'apple': 'fruit', 'orange': 'fruit' } %} + * + * {% set items = items|merge({ 'peugeot': 'car' }) %} + * + * {# items now contains { 'apple': 'fruit', 'orange': 'fruit', 'peugeot': 'car' } #} + * + * @param array|\Traversable $arr1 An array + * @param array|\Traversable $arr2 An array + * + * @return array The merged array + */ +function twig_array_merge($arr1, $arr2) +{ + if (!twig_test_iterable($arr1)) { + throw new RuntimeError(sprintf('The merge filter only works with arrays or "Traversable", got "%s" as first argument.', \gettype($arr1))); + } + + if (!twig_test_iterable($arr2)) { + throw new RuntimeError(sprintf('The merge filter only works with arrays or "Traversable", got "%s" as second argument.', \gettype($arr2))); + } + + return array_merge(twig_to_array($arr1), twig_to_array($arr2)); +} + +/** + * Slices a variable. + * + * @param mixed $item A variable + * @param int $start Start of the slice + * @param int $length Size of the slice + * @param bool $preserveKeys Whether to preserve key or not (when the input is an array) + * + * @return mixed The sliced variable + */ +function twig_slice(Environment $env, $item, $start, $length = null, $preserveKeys = false) +{ + if ($item instanceof \Traversable) { + while ($item instanceof \IteratorAggregate) { + $item = $item->getIterator(); + } + + if ($start >= 0 && $length >= 0 && $item instanceof \Iterator) { + try { + return iterator_to_array(new \LimitIterator($item, $start, null === $length ? -1 : $length), $preserveKeys); + } catch (\OutOfBoundsException $e) { + return []; + } + } + + $item = iterator_to_array($item, $preserveKeys); + } + + if (\is_array($item)) { + return \array_slice($item, $start, $length, $preserveKeys); + } + + $item = (string) $item; + + return mb_substr($item, $start, $length, $env->getCharset()); +} + +/** + * Returns the first element of the item. + * + * @param mixed $item A variable + * + * @return mixed The first element of the item + */ +function twig_first(Environment $env, $item) +{ + $elements = twig_slice($env, $item, 0, 1, false); + + return \is_string($elements) ? $elements : current($elements); +} + +/** + * Returns the last element of the item. + * + * @param mixed $item A variable + * + * @return mixed The last element of the item + */ +function twig_last(Environment $env, $item) +{ + $elements = twig_slice($env, $item, -1, 1, false); + + return \is_string($elements) ? $elements : current($elements); +} + +/** + * Joins the values to a string. + * + * The separators between elements are empty strings per default, you can define them with the optional parameters. + * + * {{ [1, 2, 3]|join(', ', ' and ') }} + * {# returns 1, 2 and 3 #} + * + * {{ [1, 2, 3]|join('|') }} + * {# returns 1|2|3 #} + * + * {{ [1, 2, 3]|join }} + * {# returns 123 #} + * + * @param array $value An array + * @param string $glue The separator + * @param string|null $and The separator for the last pair + * + * @return string The concatenated string + */ +function twig_join_filter($value, $glue = '', $and = null) +{ + if (!twig_test_iterable($value)) { + $value = (array) $value; + } + + $value = twig_to_array($value, false); + + if (0 === \count($value)) { + return ''; + } + + if (null === $and || $and === $glue) { + return implode($glue, $value); + } + + if (1 === \count($value)) { + return $value[0]; + } + + return implode($glue, \array_slice($value, 0, -1)).$and.$value[\count($value) - 1]; +} + +/** + * Splits the string into an array. + * + * {{ "one,two,three"|split(',') }} + * {# returns [one, two, three] #} + * + * {{ "one,two,three,four,five"|split(',', 3) }} + * {# returns [one, two, "three,four,five"] #} + * + * {{ "123"|split('') }} + * {# returns [1, 2, 3] #} + * + * {{ "aabbcc"|split('', 2) }} + * {# returns [aa, bb, cc] #} + * + * @param string $value A string + * @param string $delimiter The delimiter + * @param int $limit The limit + * + * @return array The split string as an array + */ +function twig_split_filter(Environment $env, $value, $delimiter, $limit = null) +{ + if (\strlen($delimiter) > 0) { + return null === $limit ? explode($delimiter, $value) : explode($delimiter, $value, $limit); + } + + if ($limit <= 1) { + return preg_split('/(?getCharset()); + if ($length < $limit) { + return [$value]; + } + + $r = []; + for ($i = 0; $i < $length; $i += $limit) { + $r[] = mb_substr($value, $i, $limit, $env->getCharset()); + } + + return $r; +} + +// The '_default' filter is used internally to avoid using the ternary operator +// which costs a lot for big contexts (before PHP 5.4). So, on average, +// a function call is cheaper. +/** + * @internal + */ +function _twig_default_filter($value, $default = '') +{ + if (twig_test_empty($value)) { + return $default; + } + + return $value; +} + +/** + * Returns the keys for the given array. + * + * It is useful when you want to iterate over the keys of an array: + * + * {% for key in array|keys %} + * {# ... #} + * {% endfor %} + * + * @param array $array An array + * + * @return array The keys + */ +function twig_get_array_keys_filter($array) +{ + if ($array instanceof \Traversable) { + while ($array instanceof \IteratorAggregate) { + $array = $array->getIterator(); + } + + $keys = []; + if ($array instanceof \Iterator) { + $array->rewind(); + while ($array->valid()) { + $keys[] = $array->key(); + $array->next(); + } + + return $keys; + } + + foreach ($array as $key => $item) { + $keys[] = $key; + } + + return $keys; + } + + if (!\is_array($array)) { + return []; + } + + return array_keys($array); +} + +/** + * Reverses a variable. + * + * @param array|\Traversable|string $item An array, a \Traversable instance, or a string + * @param bool $preserveKeys Whether to preserve key or not + * + * @return mixed The reversed input + */ +function twig_reverse_filter(Environment $env, $item, $preserveKeys = false) +{ + if ($item instanceof \Traversable) { + return array_reverse(iterator_to_array($item), $preserveKeys); + } + + if (\is_array($item)) { + return array_reverse($item, $preserveKeys); + } + + $string = (string) $item; + + $charset = $env->getCharset(); + + if ('UTF-8' !== $charset) { + $item = twig_convert_encoding($string, 'UTF-8', $charset); + } + + preg_match_all('/./us', $item, $matches); + + $string = implode('', array_reverse($matches[0])); + + if ('UTF-8' !== $charset) { + $string = twig_convert_encoding($string, $charset, 'UTF-8'); + } + + return $string; +} + +/** + * Sorts an array. + * + * @param array|\Traversable $array + * + * @return array + */ +function twig_sort_filter($array, $arrow = null) +{ + if ($array instanceof \Traversable) { + $array = iterator_to_array($array); + } elseif (!\is_array($array)) { + throw new RuntimeError(sprintf('The sort filter only works with arrays or "Traversable", got "%s".', \gettype($array))); + } + + if (null !== $arrow) { + uasort($array, $arrow); + } else { + asort($array); + } + + return $array; +} + +/** + * @internal + */ +function twig_in_filter($value, $compare) +{ + if ($value instanceof Markup) { + $value = (string) $value; + } + if ($compare instanceof Markup) { + $compare = (string) $compare; + } + + if (\is_string($compare)) { + if (\is_string($value) || \is_int($value) || \is_float($value)) { + return '' === $value || false !== strpos($compare, (string) $value); + } + + return false; + } + + if (!is_iterable($compare)) { + return false; + } + + if (\is_object($value) || \is_resource($value)) { + if (!\is_array($compare)) { + foreach ($compare as $item) { + if ($item === $value) { + return true; + } + } + + return false; + } + + return \in_array($value, $compare, true); + } + + foreach ($compare as $item) { + if (0 === twig_compare($value, $item)) { + return true; + } + } + + return false; +} + +/** + * Compares two values using a more strict version of the PHP non-strict comparison operator. + * + * @see https://wiki.php.net/rfc/string_to_number_comparison + * @see https://wiki.php.net/rfc/trailing_whitespace_numerics + * + * @internal + */ +function twig_compare($a, $b) +{ + // int <=> string + if (\is_int($a) && \is_string($b)) { + $bTrim = trim($b, " \t\n\r\v\f"); + if (!is_numeric($bTrim)) { + return (string) $a <=> $b; + } + if ((int) $bTrim == $bTrim) { + return $a <=> (int) $bTrim; + } else { + return (float) $a <=> (float) $bTrim; + } + } + if (\is_string($a) && \is_int($b)) { + $aTrim = trim($a, " \t\n\r\v\f"); + if (!is_numeric($aTrim)) { + return $a <=> (string) $b; + } + if ((int) $aTrim == $aTrim) { + return (int) $aTrim <=> $b; + } else { + return (float) $aTrim <=> (float) $b; + } + } + + // float <=> string + if (\is_float($a) && \is_string($b)) { + if (is_nan($a)) { + return 1; + } + $bTrim = trim($b, " \t\n\r\v\f"); + if (!is_numeric($bTrim)) { + return (string) $a <=> $b; + } + + return $a <=> (float) $bTrim; + } + if (\is_string($a) && \is_float($b)) { + if (is_nan($b)) { + return 1; + } + $aTrim = trim($a, " \t\n\r\v\f"); + if (!is_numeric($aTrim)) { + return $a <=> (string) $b; + } + + return (float) $aTrim <=> $b; + } + + // fallback to <=> + return $a <=> $b; +} + +/** + * Returns a trimmed string. + * + * @return string + * + * @throws RuntimeError When an invalid trimming side is used (not a string or not 'left', 'right', or 'both') + */ +function twig_trim_filter($string, $characterMask = null, $side = 'both') +{ + if (null === $characterMask) { + $characterMask = " \t\n\r\0\x0B"; + } + + switch ($side) { + case 'both': + return trim($string, $characterMask); + case 'left': + return ltrim($string, $characterMask); + case 'right': + return rtrim($string, $characterMask); + default: + throw new RuntimeError('Trimming side must be "left", "right" or "both".'); + } +} + +/** + * Removes whitespaces between HTML tags. + * + * @return string + */ +function twig_spaceless($content) +{ + return trim(preg_replace('/>\s+<', $content)); +} + +function twig_convert_encoding($string, $to, $from) +{ + if (!\function_exists('iconv')) { + throw new RuntimeError('Unable to convert encoding: required function iconv() does not exist. You should install ext-iconv or symfony/polyfill-iconv.'); + } + + return iconv($from, $to, $string); +} + +/** + * Returns the length of a variable. + * + * @param mixed $thing A variable + * + * @return int The length of the value + */ +function twig_length_filter(Environment $env, $thing) +{ + if (null === $thing) { + return 0; + } + + if (is_scalar($thing)) { + return mb_strlen($thing, $env->getCharset()); + } + + if ($thing instanceof \Countable || \is_array($thing) || $thing instanceof \SimpleXMLElement) { + return \count($thing); + } + + if ($thing instanceof \Traversable) { + return iterator_count($thing); + } + + if (method_exists($thing, '__toString') && !$thing instanceof \Countable) { + return mb_strlen((string) $thing, $env->getCharset()); + } + + return 1; +} + +/** + * Converts a string to uppercase. + * + * @param string $string A string + * + * @return string The uppercased string + */ +function twig_upper_filter(Environment $env, $string) +{ + return mb_strtoupper($string, $env->getCharset()); +} + +/** + * Converts a string to lowercase. + * + * @param string $string A string + * + * @return string The lowercased string + */ +function twig_lower_filter(Environment $env, $string) +{ + return mb_strtolower($string, $env->getCharset()); +} + +/** + * Returns a titlecased string. + * + * @param string $string A string + * + * @return string The titlecased string + */ +function twig_title_string_filter(Environment $env, $string) +{ + if (null !== $charset = $env->getCharset()) { + return mb_convert_case($string, \MB_CASE_TITLE, $charset); + } + + return ucwords(strtolower($string)); +} + +/** + * Returns a capitalized string. + * + * @param string $string A string + * + * @return string The capitalized string + */ +function twig_capitalize_string_filter(Environment $env, $string) +{ + $charset = $env->getCharset(); + + return mb_strtoupper(mb_substr($string, 0, 1, $charset), $charset).mb_strtolower(mb_substr($string, 1, null, $charset), $charset); +} + +/** + * @internal + */ +function twig_call_macro(Template $template, string $method, array $args, int $lineno, array $context, Source $source) +{ + if (!method_exists($template, $method)) { + $parent = $template; + while ($parent = $parent->getParent($context)) { + if (method_exists($parent, $method)) { + return $parent->$method(...$args); + } + } + + throw new RuntimeError(sprintf('Macro "%s" is not defined in template "%s".', substr($method, \strlen('macro_')), $template->getTemplateName()), $lineno, $source); + } + + return $template->$method(...$args); +} + +/** + * @internal + */ +function twig_ensure_traversable($seq) +{ + if ($seq instanceof \Traversable || \is_array($seq)) { + return $seq; + } + + return []; +} + +/** + * @internal + */ +function twig_to_array($seq, $preserveKeys = true) +{ + if ($seq instanceof \Traversable) { + return iterator_to_array($seq, $preserveKeys); + } + + if (!\is_array($seq)) { + return $seq; + } + + return $preserveKeys ? $seq : array_values($seq); +} + +/** + * Checks if a variable is empty. + * + * {# evaluates to true if the foo variable is null, false, or the empty string #} + * {% if foo is empty %} + * {# ... #} + * {% endif %} + * + * @param mixed $value A variable + * + * @return bool true if the value is empty, false otherwise + */ +function twig_test_empty($value) +{ + if ($value instanceof \Countable) { + return 0 === \count($value); + } + + if ($value instanceof \Traversable) { + return !iterator_count($value); + } + + if (\is_object($value) && method_exists($value, '__toString')) { + return '' === (string) $value; + } + + return '' === $value || false === $value || null === $value || [] === $value; +} + +/** + * Checks if a variable is traversable. + * + * {# evaluates to true if the foo variable is an array or a traversable object #} + * {% if foo is iterable %} + * {# ... #} + * {% endif %} + * + * @param mixed $value A variable + * + * @return bool true if the value is traversable + */ +function twig_test_iterable($value) +{ + return $value instanceof \Traversable || \is_array($value); +} + +/** + * Renders a template. + * + * @param array $context + * @param string|array $template The template to render or an array of templates to try consecutively + * @param array $variables The variables to pass to the template + * @param bool $withContext + * @param bool $ignoreMissing Whether to ignore missing templates or not + * @param bool $sandboxed Whether to sandbox the template or not + * + * @return string The rendered template + */ +function twig_include(Environment $env, $context, $template, $variables = [], $withContext = true, $ignoreMissing = false, $sandboxed = false) +{ + $alreadySandboxed = false; + $sandbox = null; + if ($withContext) { + $variables = array_merge($context, $variables); + } + + if ($isSandboxed = $sandboxed && $env->hasExtension(SandboxExtension::class)) { + $sandbox = $env->getExtension(SandboxExtension::class); + if (!$alreadySandboxed = $sandbox->isSandboxed()) { + $sandbox->enableSandbox(); + } + + foreach ((\is_array($template) ? $template : [$template]) as $name) { + // if a Template instance is passed, it might have been instantiated outside of a sandbox, check security + if ($name instanceof TemplateWrapper || $name instanceof Template) { + $name->unwrap()->checkSecurity(); + } + } + } + + try { + $loaded = null; + try { + $loaded = $env->resolveTemplate($template); + } catch (LoaderError $e) { + if (!$ignoreMissing) { + throw $e; + } + } + + return $loaded ? $loaded->render($variables) : ''; + } finally { + if ($isSandboxed && !$alreadySandboxed) { + $sandbox->disableSandbox(); + } + } +} + +/** + * Returns a template content without rendering it. + * + * @param string $name The template name + * @param bool $ignoreMissing Whether to ignore missing templates or not + * + * @return string The template source + */ +function twig_source(Environment $env, $name, $ignoreMissing = false) +{ + $loader = $env->getLoader(); + try { + return $loader->getSourceContext($name)->getCode(); + } catch (LoaderError $e) { + if (!$ignoreMissing) { + throw $e; + } + } +} + +/** + * Provides the ability to get constants from instances as well as class/global constants. + * + * @param string $constant The name of the constant + * @param object|null $object The object to get the constant from + * + * @return string + */ +function twig_constant($constant, $object = null) +{ + if (null !== $object) { + $constant = \get_class($object).'::'.$constant; + } + + return \constant($constant); +} + +/** + * Checks if a constant exists. + * + * @param string $constant The name of the constant + * @param object|null $object The object to get the constant from + * + * @return bool + */ +function twig_constant_is_defined($constant, $object = null) +{ + if (null !== $object) { + $constant = \get_class($object).'::'.$constant; + } + + return \defined($constant); +} + +/** + * Batches item. + * + * @param array $items An array of items + * @param int $size The size of the batch + * @param mixed $fill A value used to fill missing items + * + * @return array + */ +function twig_array_batch($items, $size, $fill = null, $preserveKeys = true) +{ + if (!twig_test_iterable($items)) { + throw new RuntimeError(sprintf('The "batch" filter expects an array or "Traversable", got "%s".', \is_object($items) ? \get_class($items) : \gettype($items))); + } + + $size = ceil($size); + + $result = array_chunk(twig_to_array($items, $preserveKeys), $size, $preserveKeys); + + if (null !== $fill && $result) { + $last = \count($result) - 1; + if ($fillCount = $size - \count($result[$last])) { + for ($i = 0; $i < $fillCount; ++$i) { + $result[$last][] = $fill; + } + } + } + + return $result; +} + +/** + * Returns the attribute value for a given array/object. + * + * @param mixed $object The object or array from where to get the item + * @param mixed $item The item to get from the array or object + * @param array $arguments An array of arguments to pass if the item is an object method + * @param string $type The type of attribute (@see \Twig\Template constants) + * @param bool $isDefinedTest Whether this is only a defined check + * @param bool $ignoreStrictCheck Whether to ignore the strict attribute check or not + * @param int $lineno The template line where the attribute was called + * + * @return mixed The attribute value, or a Boolean when $isDefinedTest is true, or null when the attribute is not set and $ignoreStrictCheck is true + * + * @throws RuntimeError if the attribute does not exist and Twig is running in strict mode and $isDefinedTest is false + * + * @internal + */ +function twig_get_attribute(Environment $env, Source $source, $object, $item, array $arguments = [], $type = /* Template::ANY_CALL */ 'any', $isDefinedTest = false, $ignoreStrictCheck = false, $sandboxed = false, int $lineno = -1) +{ + // array + if (/* Template::METHOD_CALL */ 'method' !== $type) { + $arrayItem = \is_bool($item) || \is_float($item) ? (int) $item : $item; + + if (((\is_array($object) || $object instanceof \ArrayObject) && (isset($object[$arrayItem]) || \array_key_exists($arrayItem, (array) $object))) + || ($object instanceof ArrayAccess && isset($object[$arrayItem])) + ) { + if ($isDefinedTest) { + return true; + } + + return $object[$arrayItem]; + } + + if (/* Template::ARRAY_CALL */ 'array' === $type || !\is_object($object)) { + if ($isDefinedTest) { + return false; + } + + if ($ignoreStrictCheck || !$env->isStrictVariables()) { + return; + } + + if ($object instanceof ArrayAccess) { + $message = sprintf('Key "%s" in object with ArrayAccess of class "%s" does not exist.', $arrayItem, \get_class($object)); + } elseif (\is_object($object)) { + $message = sprintf('Impossible to access a key "%s" on an object of class "%s" that does not implement ArrayAccess interface.', $item, \get_class($object)); + } elseif (\is_array($object)) { + if (empty($object)) { + $message = sprintf('Key "%s" does not exist as the array is empty.', $arrayItem); + } else { + $message = sprintf('Key "%s" for array with keys "%s" does not exist.', $arrayItem, implode(', ', array_keys($object))); + } + } elseif (/* Template::ARRAY_CALL */ 'array' === $type) { + if (null === $object) { + $message = sprintf('Impossible to access a key ("%s") on a null variable.', $item); + } else { + $message = sprintf('Impossible to access a key ("%s") on a %s variable ("%s").', $item, \gettype($object), $object); + } + } elseif (null === $object) { + $message = sprintf('Impossible to access an attribute ("%s") on a null variable.', $item); + } else { + $message = sprintf('Impossible to access an attribute ("%s") on a %s variable ("%s").', $item, \gettype($object), $object); + } + + throw new RuntimeError($message, $lineno, $source); + } + } + + if (!\is_object($object)) { + if ($isDefinedTest) { + return false; + } + + if ($ignoreStrictCheck || !$env->isStrictVariables()) { + return; + } + + if (null === $object) { + $message = sprintf('Impossible to invoke a method ("%s") on a null variable.', $item); + } elseif (\is_array($object)) { + $message = sprintf('Impossible to invoke a method ("%s") on an array.', $item); + } else { + $message = sprintf('Impossible to invoke a method ("%s") on a %s variable ("%s").', $item, \gettype($object), $object); + } + + throw new RuntimeError($message, $lineno, $source); + } + + if ($object instanceof Template) { + throw new RuntimeError('Accessing \Twig\Template attributes is forbidden.', $lineno, $source); + } + + // object property + if (/* Template::METHOD_CALL */ 'method' !== $type) { + if (isset($object->$item) || \array_key_exists((string) $item, (array) $object)) { + if ($isDefinedTest) { + return true; + } + + if ($sandboxed) { + $env->getExtension(SandboxExtension::class)->checkPropertyAllowed($object, $item, $lineno, $source); + } + + return $object->$item; + } + } + + static $cache = []; + + $class = \get_class($object); + + // object method + // precedence: getXxx() > isXxx() > hasXxx() + if (!isset($cache[$class])) { + $methods = get_class_methods($object); + sort($methods); + $lcMethods = array_map(function ($value) { return strtr($value, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'); }, $methods); + $classCache = []; + foreach ($methods as $i => $method) { + $classCache[$method] = $method; + $classCache[$lcName = $lcMethods[$i]] = $method; + + if ('g' === $lcName[0] && 0 === strpos($lcName, 'get')) { + $name = substr($method, 3); + $lcName = substr($lcName, 3); + } elseif ('i' === $lcName[0] && 0 === strpos($lcName, 'is')) { + $name = substr($method, 2); + $lcName = substr($lcName, 2); + } elseif ('h' === $lcName[0] && 0 === strpos($lcName, 'has')) { + $name = substr($method, 3); + $lcName = substr($lcName, 3); + if (\in_array('is'.$lcName, $lcMethods)) { + continue; + } + } else { + continue; + } + + // skip get() and is() methods (in which case, $name is empty) + if ($name) { + if (!isset($classCache[$name])) { + $classCache[$name] = $method; + } + + if (!isset($classCache[$lcName])) { + $classCache[$lcName] = $method; + } + } + } + $cache[$class] = $classCache; + } + + $call = false; + if (isset($cache[$class][$item])) { + $method = $cache[$class][$item]; + } elseif (isset($cache[$class][$lcItem = strtr($item, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz')])) { + $method = $cache[$class][$lcItem]; + } elseif (isset($cache[$class]['__call'])) { + $method = $item; + $call = true; + } else { + if ($isDefinedTest) { + return false; + } + + if ($ignoreStrictCheck || !$env->isStrictVariables()) { + return; + } + + throw new RuntimeError(sprintf('Neither the property "%1$s" nor one of the methods "%1$s()", "get%1$s()"/"is%1$s()"/"has%1$s()" or "__call()" exist and have public access in class "%2$s".', $item, $class), $lineno, $source); + } + + if ($isDefinedTest) { + return true; + } + + if ($sandboxed) { + $env->getExtension(SandboxExtension::class)->checkMethodAllowed($object, $method, $lineno, $source); + } + + // Some objects throw exceptions when they have __call, and the method we try + // to call is not supported. If ignoreStrictCheck is true, we should return null. + try { + $ret = $object->$method(...$arguments); + } catch (\BadMethodCallException $e) { + if ($call && ($ignoreStrictCheck || !$env->isStrictVariables())) { + return; + } + throw $e; + } + + return $ret; +} + +/** + * Returns the values from a single column in the input array. + * + *
    + *  {% set items = [{ 'fruit' : 'apple'}, {'fruit' : 'orange' }] %}
    + *
    + *  {% set fruits = items|column('fruit') %}
    + *
    + *  {# fruits now contains ['apple', 'orange'] #}
    + * 
    + * + * @param array|Traversable $array An array + * @param mixed $name The column name + * @param mixed $index The column to use as the index/keys for the returned array + * + * @return array The array of values + */ +function twig_array_column($array, $name, $index = null): array +{ + if ($array instanceof Traversable) { + $array = iterator_to_array($array); + } elseif (!\is_array($array)) { + throw new RuntimeError(sprintf('The column filter only works with arrays or "Traversable", got "%s" as first argument.', \gettype($array))); + } + + return array_column($array, $name, $index); +} + +function twig_array_filter(Environment $env, $array, $arrow) +{ + if (!twig_test_iterable($array)) { + throw new RuntimeError(sprintf('The "filter" filter expects an array or "Traversable", got "%s".', \is_object($array) ? \get_class($array) : \gettype($array))); + } + + if (!$arrow instanceof Closure && $env->hasExtension('\Twig\Extension\SandboxExtension') && $env->getExtension('\Twig\Extension\SandboxExtension')->isSandboxed()) { + throw new RuntimeError('The callable passed to "filter" filter must be a Closure in sandbox mode.'); + } + + if (\is_array($array)) { + return array_filter($array, $arrow, \ARRAY_FILTER_USE_BOTH); + } + + // the IteratorIterator wrapping is needed as some internal PHP classes are \Traversable but do not implement \Iterator + return new \CallbackFilterIterator(new \IteratorIterator($array), $arrow); +} + +function twig_array_map(Environment $env, $array, $arrow) +{ + if (!$arrow instanceof Closure && $env->hasExtension('\Twig\Extension\SandboxExtension') && $env->getExtension('\Twig\Extension\SandboxExtension')->isSandboxed()) { + throw new RuntimeError('The callable passed to the "map" filter must be a Closure in sandbox mode.'); + } + + $r = []; + foreach ($array as $k => $v) { + $r[$k] = $arrow($v, $k); + } + + return $r; +} + +function twig_array_reduce(Environment $env, $array, $arrow, $initial = null) +{ + if (!$arrow instanceof Closure && $env->hasExtension('\Twig\Extension\SandboxExtension') && $env->getExtension('\Twig\Extension\SandboxExtension')->isSandboxed()) { + throw new RuntimeError('The callable passed to the "reduce" filter must be a Closure in sandbox mode.'); + } + + if (!\is_array($array)) { + if (!$array instanceof \Traversable) { + throw new RuntimeError(sprintf('The "reduce" filter only works with arrays or "Traversable", got "%s" as first argument.', \gettype($array))); + } + + $array = iterator_to_array($array); + } + + return array_reduce($array, $arrow, $initial); +} +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Extension/DebugExtension.php b/data/web/inc/lib/vendor/twig/twig/src/Extension/DebugExtension.php new file mode 100644 index 00000000..bfb23d7b --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Extension/DebugExtension.php @@ -0,0 +1,64 @@ + $isDumpOutputHtmlSafe ? ['html'] : [], 'needs_context' => true, 'needs_environment' => true, 'is_variadic' => true]), + ]; + } +} +} + +namespace { +use Twig\Environment; +use Twig\Template; +use Twig\TemplateWrapper; + +function twig_var_dump(Environment $env, $context, ...$vars) +{ + if (!$env->isDebug()) { + return; + } + + ob_start(); + + if (!$vars) { + $vars = []; + foreach ($context as $key => $value) { + if (!$value instanceof Template && !$value instanceof TemplateWrapper) { + $vars[$key] = $value; + } + } + + var_dump($vars); + } else { + var_dump(...$vars); + } + + return ob_get_clean(); +} +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Extension/EscaperExtension.php b/data/web/inc/lib/vendor/twig/twig/src/Extension/EscaperExtension.php new file mode 100644 index 00000000..372551f2 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Extension/EscaperExtension.php @@ -0,0 +1,421 @@ +setDefaultStrategy($defaultStrategy); + } + + public function getTokenParsers(): array + { + return [new AutoEscapeTokenParser()]; + } + + public function getNodeVisitors(): array + { + return [new EscaperNodeVisitor()]; + } + + public function getFilters(): array + { + return [ + new TwigFilter('escape', 'twig_escape_filter', ['needs_environment' => true, 'is_safe_callback' => 'twig_escape_filter_is_safe']), + new TwigFilter('e', 'twig_escape_filter', ['needs_environment' => true, 'is_safe_callback' => 'twig_escape_filter_is_safe']), + new TwigFilter('raw', 'twig_raw_filter', ['is_safe' => ['all']]), + ]; + } + + /** + * Sets the default strategy to use when not defined by the user. + * + * The strategy can be a valid PHP callback that takes the template + * name as an argument and returns the strategy to use. + * + * @param string|false|callable $defaultStrategy An escaping strategy + */ + public function setDefaultStrategy($defaultStrategy): void + { + if ('name' === $defaultStrategy) { + $defaultStrategy = [FileExtensionEscapingStrategy::class, 'guess']; + } + + $this->defaultStrategy = $defaultStrategy; + } + + /** + * Gets the default strategy to use when not defined by the user. + * + * @param string $name The template name + * + * @return string|false The default strategy to use for the template + */ + public function getDefaultStrategy(string $name) + { + // disable string callables to avoid calling a function named html or js, + // or any other upcoming escaping strategy + if (!\is_string($this->defaultStrategy) && false !== $this->defaultStrategy) { + return \call_user_func($this->defaultStrategy, $name); + } + + return $this->defaultStrategy; + } + + /** + * Defines a new escaper to be used via the escape filter. + * + * @param string $strategy The strategy name that should be used as a strategy in the escape call + * @param callable $callable A valid PHP callable + */ + public function setEscaper($strategy, callable $callable) + { + $this->escapers[$strategy] = $callable; + } + + /** + * Gets all defined escapers. + * + * @return callable[] An array of escapers + */ + public function getEscapers() + { + return $this->escapers; + } + + public function setSafeClasses(array $safeClasses = []) + { + $this->safeClasses = []; + $this->safeLookup = []; + foreach ($safeClasses as $class => $strategies) { + $this->addSafeClass($class, $strategies); + } + } + + public function addSafeClass(string $class, array $strategies) + { + $class = ltrim($class, '\\'); + if (!isset($this->safeClasses[$class])) { + $this->safeClasses[$class] = []; + } + $this->safeClasses[$class] = array_merge($this->safeClasses[$class], $strategies); + + foreach ($strategies as $strategy) { + $this->safeLookup[$strategy][$class] = true; + } + } +} +} + +namespace { +use Twig\Environment; +use Twig\Error\RuntimeError; +use Twig\Extension\EscaperExtension; +use Twig\Markup; +use Twig\Node\Expression\ConstantExpression; +use Twig\Node\Node; + +/** + * Marks a variable as being safe. + * + * @param string $string A PHP variable + */ +function twig_raw_filter($string) +{ + return $string; +} + +/** + * Escapes a string. + * + * @param mixed $string The value to be escaped + * @param string $strategy The escaping strategy + * @param string $charset The charset + * @param bool $autoescape Whether the function is called by the auto-escaping feature (true) or by the developer (false) + * + * @return string + */ +function twig_escape_filter(Environment $env, $string, $strategy = 'html', $charset = null, $autoescape = false) +{ + if ($autoescape && $string instanceof Markup) { + return $string; + } + + if (!\is_string($string)) { + if (\is_object($string) && method_exists($string, '__toString')) { + if ($autoescape) { + $c = \get_class($string); + $ext = $env->getExtension(EscaperExtension::class); + if (!isset($ext->safeClasses[$c])) { + $ext->safeClasses[$c] = []; + foreach (class_parents($string) + class_implements($string) as $class) { + if (isset($ext->safeClasses[$class])) { + $ext->safeClasses[$c] = array_unique(array_merge($ext->safeClasses[$c], $ext->safeClasses[$class])); + foreach ($ext->safeClasses[$class] as $s) { + $ext->safeLookup[$s][$c] = true; + } + } + } + } + if (isset($ext->safeLookup[$strategy][$c]) || isset($ext->safeLookup['all'][$c])) { + return (string) $string; + } + } + + $string = (string) $string; + } elseif (\in_array($strategy, ['html', 'js', 'css', 'html_attr', 'url'])) { + return $string; + } + } + + if ('' === $string) { + return ''; + } + + if (null === $charset) { + $charset = $env->getCharset(); + } + + switch ($strategy) { + case 'html': + // see https://secure.php.net/htmlspecialchars + + // Using a static variable to avoid initializing the array + // each time the function is called. Moving the declaration on the + // top of the function slow downs other escaping strategies. + static $htmlspecialcharsCharsets = [ + 'ISO-8859-1' => true, 'ISO8859-1' => true, + 'ISO-8859-15' => true, 'ISO8859-15' => true, + 'utf-8' => true, 'UTF-8' => true, + 'CP866' => true, 'IBM866' => true, '866' => true, + 'CP1251' => true, 'WINDOWS-1251' => true, 'WIN-1251' => true, + '1251' => true, + 'CP1252' => true, 'WINDOWS-1252' => true, '1252' => true, + 'KOI8-R' => true, 'KOI8-RU' => true, 'KOI8R' => true, + 'BIG5' => true, '950' => true, + 'GB2312' => true, '936' => true, + 'BIG5-HKSCS' => true, + 'SHIFT_JIS' => true, 'SJIS' => true, '932' => true, + 'EUC-JP' => true, 'EUCJP' => true, + 'ISO8859-5' => true, 'ISO-8859-5' => true, 'MACROMAN' => true, + ]; + + if (isset($htmlspecialcharsCharsets[$charset])) { + return htmlspecialchars($string, \ENT_QUOTES | \ENT_SUBSTITUTE, $charset); + } + + if (isset($htmlspecialcharsCharsets[strtoupper($charset)])) { + // cache the lowercase variant for future iterations + $htmlspecialcharsCharsets[$charset] = true; + + return htmlspecialchars($string, \ENT_QUOTES | \ENT_SUBSTITUTE, $charset); + } + + $string = twig_convert_encoding($string, 'UTF-8', $charset); + $string = htmlspecialchars($string, \ENT_QUOTES | \ENT_SUBSTITUTE, 'UTF-8'); + + return iconv('UTF-8', $charset, $string); + + case 'js': + // escape all non-alphanumeric characters + // into their \x or \uHHHH representations + if ('UTF-8' !== $charset) { + $string = twig_convert_encoding($string, 'UTF-8', $charset); + } + + if (!preg_match('//u', $string)) { + throw new RuntimeError('The string to escape is not a valid UTF-8 string.'); + } + + $string = preg_replace_callback('#[^a-zA-Z0-9,\._]#Su', function ($matches) { + $char = $matches[0]; + + /* + * A few characters have short escape sequences in JSON and JavaScript. + * Escape sequences supported only by JavaScript, not JSON, are omitted. + * \" is also supported but omitted, because the resulting string is not HTML safe. + */ + static $shortMap = [ + '\\' => '\\\\', + '/' => '\\/', + "\x08" => '\b', + "\x0C" => '\f', + "\x0A" => '\n', + "\x0D" => '\r', + "\x09" => '\t', + ]; + + if (isset($shortMap[$char])) { + return $shortMap[$char]; + } + + $codepoint = mb_ord($char); + if (0x10000 > $codepoint) { + return sprintf('\u%04X', $codepoint); + } + + // Split characters outside the BMP into surrogate pairs + // https://tools.ietf.org/html/rfc2781.html#section-2.1 + $u = $codepoint - 0x10000; + $high = 0xD800 | ($u >> 10); + $low = 0xDC00 | ($u & 0x3FF); + + return sprintf('\u%04X\u%04X', $high, $low); + }, $string); + + if ('UTF-8' !== $charset) { + $string = iconv('UTF-8', $charset, $string); + } + + return $string; + + case 'css': + if ('UTF-8' !== $charset) { + $string = twig_convert_encoding($string, 'UTF-8', $charset); + } + + if (!preg_match('//u', $string)) { + throw new RuntimeError('The string to escape is not a valid UTF-8 string.'); + } + + $string = preg_replace_callback('#[^a-zA-Z0-9]#Su', function ($matches) { + $char = $matches[0]; + + return sprintf('\\%X ', 1 === \strlen($char) ? \ord($char) : mb_ord($char, 'UTF-8')); + }, $string); + + if ('UTF-8' !== $charset) { + $string = iconv('UTF-8', $charset, $string); + } + + return $string; + + case 'html_attr': + if ('UTF-8' !== $charset) { + $string = twig_convert_encoding($string, 'UTF-8', $charset); + } + + if (!preg_match('//u', $string)) { + throw new RuntimeError('The string to escape is not a valid UTF-8 string.'); + } + + $string = preg_replace_callback('#[^a-zA-Z0-9,\.\-_]#Su', function ($matches) { + /** + * This function is adapted from code coming from Zend Framework. + * + * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (https://www.zend.com) + * @license https://framework.zend.com/license/new-bsd New BSD License + */ + $chr = $matches[0]; + $ord = \ord($chr); + + /* + * The following replaces characters undefined in HTML with the + * hex entity for the Unicode replacement character. + */ + if (($ord <= 0x1f && "\t" != $chr && "\n" != $chr && "\r" != $chr) || ($ord >= 0x7f && $ord <= 0x9f)) { + return '�'; + } + + /* + * Check if the current character to escape has a name entity we should + * replace it with while grabbing the hex value of the character. + */ + if (1 === \strlen($chr)) { + /* + * While HTML supports far more named entities, the lowest common denominator + * has become HTML5's XML Serialisation which is restricted to the those named + * entities that XML supports. Using HTML entities would result in this error: + * XML Parsing Error: undefined entity + */ + static $entityMap = [ + 34 => '"', /* quotation mark */ + 38 => '&', /* ampersand */ + 60 => '<', /* less-than sign */ + 62 => '>', /* greater-than sign */ + ]; + + if (isset($entityMap[$ord])) { + return $entityMap[$ord]; + } + + return sprintf('&#x%02X;', $ord); + } + + /* + * Per OWASP recommendations, we'll use hex entities for any other + * characters where a named entity does not exist. + */ + return sprintf('&#x%04X;', mb_ord($chr, 'UTF-8')); + }, $string); + + if ('UTF-8' !== $charset) { + $string = iconv('UTF-8', $charset, $string); + } + + return $string; + + case 'url': + return rawurlencode($string); + + default: + static $escapers; + + if (null === $escapers) { + $escapers = $env->getExtension(EscaperExtension::class)->getEscapers(); + } + + if (isset($escapers[$strategy])) { + return $escapers[$strategy]($env, $string, $charset); + } + + $validStrategies = implode(', ', array_merge(['html', 'js', 'url', 'css', 'html_attr'], array_keys($escapers))); + + throw new RuntimeError(sprintf('Invalid escaping strategy "%s" (valid ones: %s).', $strategy, $validStrategies)); + } +} + +/** + * @internal + */ +function twig_escape_filter_is_safe(Node $filterArgs) +{ + foreach ($filterArgs as $arg) { + if ($arg instanceof ConstantExpression) { + return [$arg->getAttribute('value')]; + } + + return []; + } + + return ['html']; +} +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Extension/ExtensionInterface.php b/data/web/inc/lib/vendor/twig/twig/src/Extension/ExtensionInterface.php new file mode 100644 index 00000000..75fa237e --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Extension/ExtensionInterface.php @@ -0,0 +1,68 @@ + + */ +interface ExtensionInterface +{ + /** + * Returns the token parser instances to add to the existing list. + * + * @return TokenParserInterface[] + */ + public function getTokenParsers(); + + /** + * Returns the node visitor instances to add to the existing list. + * + * @return NodeVisitorInterface[] + */ + public function getNodeVisitors(); + + /** + * Returns a list of filters to add to the existing list. + * + * @return TwigFilter[] + */ + public function getFilters(); + + /** + * Returns a list of tests to add to the existing list. + * + * @return TwigTest[] + */ + public function getTests(); + + /** + * Returns a list of functions to add to the existing list. + * + * @return TwigFunction[] + */ + public function getFunctions(); + + /** + * Returns a list of operators to add to the existing list. + * + * @return array First array of unary operators, second array of binary operators + */ + public function getOperators(); +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Extension/GlobalsInterface.php b/data/web/inc/lib/vendor/twig/twig/src/Extension/GlobalsInterface.php new file mode 100644 index 00000000..ec0c6829 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Extension/GlobalsInterface.php @@ -0,0 +1,25 @@ + + */ +interface GlobalsInterface +{ + public function getGlobals(): array; +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Extension/OptimizerExtension.php b/data/web/inc/lib/vendor/twig/twig/src/Extension/OptimizerExtension.php new file mode 100644 index 00000000..965bfdb0 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Extension/OptimizerExtension.php @@ -0,0 +1,29 @@ +optimizers = $optimizers; + } + + public function getNodeVisitors(): array + { + return [new OptimizerNodeVisitor($this->optimizers)]; + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Extension/ProfilerExtension.php b/data/web/inc/lib/vendor/twig/twig/src/Extension/ProfilerExtension.php new file mode 100644 index 00000000..43e4a449 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Extension/ProfilerExtension.php @@ -0,0 +1,52 @@ +actives[] = $profile; + } + + /** + * @return void + */ + public function enter(Profile $profile) + { + $this->actives[0]->addProfile($profile); + array_unshift($this->actives, $profile); + } + + /** + * @return void + */ + public function leave(Profile $profile) + { + $profile->leave(); + array_shift($this->actives); + + if (1 === \count($this->actives)) { + $this->actives[0]->leave(); + } + } + + public function getNodeVisitors(): array + { + return [new ProfilerNodeVisitor(static::class)]; + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Extension/RuntimeExtensionInterface.php b/data/web/inc/lib/vendor/twig/twig/src/Extension/RuntimeExtensionInterface.php new file mode 100644 index 00000000..63bc3b1a --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Extension/RuntimeExtensionInterface.php @@ -0,0 +1,19 @@ + + */ +interface RuntimeExtensionInterface +{ +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Extension/SandboxExtension.php b/data/web/inc/lib/vendor/twig/twig/src/Extension/SandboxExtension.php new file mode 100644 index 00000000..0a28cabf --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Extension/SandboxExtension.php @@ -0,0 +1,123 @@ +policy = $policy; + $this->sandboxedGlobally = $sandboxed; + } + + public function getTokenParsers(): array + { + return [new SandboxTokenParser()]; + } + + public function getNodeVisitors(): array + { + return [new SandboxNodeVisitor()]; + } + + public function enableSandbox(): void + { + $this->sandboxed = true; + } + + public function disableSandbox(): void + { + $this->sandboxed = false; + } + + public function isSandboxed(): bool + { + return $this->sandboxedGlobally || $this->sandboxed; + } + + public function isSandboxedGlobally(): bool + { + return $this->sandboxedGlobally; + } + + public function setSecurityPolicy(SecurityPolicyInterface $policy) + { + $this->policy = $policy; + } + + public function getSecurityPolicy(): SecurityPolicyInterface + { + return $this->policy; + } + + public function checkSecurity($tags, $filters, $functions): void + { + if ($this->isSandboxed()) { + $this->policy->checkSecurity($tags, $filters, $functions); + } + } + + public function checkMethodAllowed($obj, $method, int $lineno = -1, Source $source = null): void + { + if ($this->isSandboxed()) { + try { + $this->policy->checkMethodAllowed($obj, $method); + } catch (SecurityNotAllowedMethodError $e) { + $e->setSourceContext($source); + $e->setTemplateLine($lineno); + + throw $e; + } + } + } + + public function checkPropertyAllowed($obj, $method, int $lineno = -1, Source $source = null): void + { + if ($this->isSandboxed()) { + try { + $this->policy->checkPropertyAllowed($obj, $method); + } catch (SecurityNotAllowedPropertyError $e) { + $e->setSourceContext($source); + $e->setTemplateLine($lineno); + + throw $e; + } + } + } + + public function ensureToStringAllowed($obj, int $lineno = -1, Source $source = null) + { + if ($this->isSandboxed() && \is_object($obj) && method_exists($obj, '__toString')) { + try { + $this->policy->checkMethodAllowed($obj, '__toString'); + } catch (SecurityNotAllowedMethodError $e) { + $e->setSourceContext($source); + $e->setTemplateLine($lineno); + + throw $e; + } + } + + return $obj; + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Extension/StagingExtension.php b/data/web/inc/lib/vendor/twig/twig/src/Extension/StagingExtension.php new file mode 100644 index 00000000..0ea47f90 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Extension/StagingExtension.php @@ -0,0 +1,100 @@ + + * + * @internal + */ +final class StagingExtension extends AbstractExtension +{ + private $functions = []; + private $filters = []; + private $visitors = []; + private $tokenParsers = []; + private $tests = []; + + public function addFunction(TwigFunction $function): void + { + if (isset($this->functions[$function->getName()])) { + throw new \LogicException(sprintf('Function "%s" is already registered.', $function->getName())); + } + + $this->functions[$function->getName()] = $function; + } + + public function getFunctions(): array + { + return $this->functions; + } + + public function addFilter(TwigFilter $filter): void + { + if (isset($this->filters[$filter->getName()])) { + throw new \LogicException(sprintf('Filter "%s" is already registered.', $filter->getName())); + } + + $this->filters[$filter->getName()] = $filter; + } + + public function getFilters(): array + { + return $this->filters; + } + + public function addNodeVisitor(NodeVisitorInterface $visitor): void + { + $this->visitors[] = $visitor; + } + + public function getNodeVisitors(): array + { + return $this->visitors; + } + + public function addTokenParser(TokenParserInterface $parser): void + { + if (isset($this->tokenParsers[$parser->getTag()])) { + throw new \LogicException(sprintf('Tag "%s" is already registered.', $parser->getTag())); + } + + $this->tokenParsers[$parser->getTag()] = $parser; + } + + public function getTokenParsers(): array + { + return $this->tokenParsers; + } + + public function addTest(TwigTest $test): void + { + if (isset($this->tests[$test->getName()])) { + throw new \LogicException(sprintf('Test "%s" is already registered.', $test->getName())); + } + + $this->tests[$test->getName()] = $test; + } + + public function getTests(): array + { + return $this->tests; + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Extension/StringLoaderExtension.php b/data/web/inc/lib/vendor/twig/twig/src/Extension/StringLoaderExtension.php new file mode 100644 index 00000000..7b451471 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Extension/StringLoaderExtension.php @@ -0,0 +1,42 @@ + true]), + ]; + } +} +} + +namespace { +use Twig\Environment; +use Twig\TemplateWrapper; + +/** + * Loads a template from a string. + * + * {{ include(template_from_string("Hello {{ name }}")) }} + * + * @param string $template A template as a string or object implementing __toString() + * @param string $name An optional name of the template to be used in error messages + */ +function twig_template_from_string(Environment $env, $template, string $name = null): TemplateWrapper +{ + return $env->createTemplate((string) $template, $name); +} +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/ExtensionSet.php b/data/web/inc/lib/vendor/twig/twig/src/ExtensionSet.php new file mode 100644 index 00000000..36e5bbc5 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/ExtensionSet.php @@ -0,0 +1,463 @@ + + * + * @internal + */ +final class ExtensionSet +{ + private $extensions; + private $initialized = false; + private $runtimeInitialized = false; + private $staging; + private $parsers; + private $visitors; + private $filters; + private $tests; + private $functions; + private $unaryOperators; + private $binaryOperators; + private $globals; + private $functionCallbacks = []; + private $filterCallbacks = []; + private $parserCallbacks = []; + private $lastModified = 0; + + public function __construct() + { + $this->staging = new StagingExtension(); + } + + public function initRuntime() + { + $this->runtimeInitialized = true; + } + + public function hasExtension(string $class): bool + { + return isset($this->extensions[ltrim($class, '\\')]); + } + + public function getExtension(string $class): ExtensionInterface + { + $class = ltrim($class, '\\'); + + if (!isset($this->extensions[$class])) { + throw new RuntimeError(sprintf('The "%s" extension is not enabled.', $class)); + } + + return $this->extensions[$class]; + } + + /** + * @param ExtensionInterface[] $extensions + */ + public function setExtensions(array $extensions): void + { + foreach ($extensions as $extension) { + $this->addExtension($extension); + } + } + + /** + * @return ExtensionInterface[] + */ + public function getExtensions(): array + { + return $this->extensions; + } + + public function getSignature(): string + { + return json_encode(array_keys($this->extensions)); + } + + public function isInitialized(): bool + { + return $this->initialized || $this->runtimeInitialized; + } + + public function getLastModified(): int + { + if (0 !== $this->lastModified) { + return $this->lastModified; + } + + foreach ($this->extensions as $extension) { + $r = new \ReflectionObject($extension); + if (is_file($r->getFileName()) && ($extensionTime = filemtime($r->getFileName())) > $this->lastModified) { + $this->lastModified = $extensionTime; + } + } + + return $this->lastModified; + } + + public function addExtension(ExtensionInterface $extension): void + { + $class = \get_class($extension); + + if ($this->initialized) { + throw new \LogicException(sprintf('Unable to register extension "%s" as extensions have already been initialized.', $class)); + } + + if (isset($this->extensions[$class])) { + throw new \LogicException(sprintf('Unable to register extension "%s" as it is already registered.', $class)); + } + + $this->extensions[$class] = $extension; + } + + public function addFunction(TwigFunction $function): void + { + if ($this->initialized) { + throw new \LogicException(sprintf('Unable to add function "%s" as extensions have already been initialized.', $function->getName())); + } + + $this->staging->addFunction($function); + } + + /** + * @return TwigFunction[] + */ + public function getFunctions(): array + { + if (!$this->initialized) { + $this->initExtensions(); + } + + return $this->functions; + } + + public function getFunction(string $name): ?TwigFunction + { + if (!$this->initialized) { + $this->initExtensions(); + } + + if (isset($this->functions[$name])) { + return $this->functions[$name]; + } + + foreach ($this->functions as $pattern => $function) { + $pattern = str_replace('\\*', '(.*?)', preg_quote($pattern, '#'), $count); + + if ($count && preg_match('#^'.$pattern.'$#', $name, $matches)) { + array_shift($matches); + $function->setArguments($matches); + + return $function; + } + } + + foreach ($this->functionCallbacks as $callback) { + if (false !== $function = $callback($name)) { + return $function; + } + } + + return null; + } + + public function registerUndefinedFunctionCallback(callable $callable): void + { + $this->functionCallbacks[] = $callable; + } + + public function addFilter(TwigFilter $filter): void + { + if ($this->initialized) { + throw new \LogicException(sprintf('Unable to add filter "%s" as extensions have already been initialized.', $filter->getName())); + } + + $this->staging->addFilter($filter); + } + + /** + * @return TwigFilter[] + */ + public function getFilters(): array + { + if (!$this->initialized) { + $this->initExtensions(); + } + + return $this->filters; + } + + public function getFilter(string $name): ?TwigFilter + { + if (!$this->initialized) { + $this->initExtensions(); + } + + if (isset($this->filters[$name])) { + return $this->filters[$name]; + } + + foreach ($this->filters as $pattern => $filter) { + $pattern = str_replace('\\*', '(.*?)', preg_quote($pattern, '#'), $count); + + if ($count && preg_match('#^'.$pattern.'$#', $name, $matches)) { + array_shift($matches); + $filter->setArguments($matches); + + return $filter; + } + } + + foreach ($this->filterCallbacks as $callback) { + if (false !== $filter = $callback($name)) { + return $filter; + } + } + + return null; + } + + public function registerUndefinedFilterCallback(callable $callable): void + { + $this->filterCallbacks[] = $callable; + } + + public function addNodeVisitor(NodeVisitorInterface $visitor): void + { + if ($this->initialized) { + throw new \LogicException('Unable to add a node visitor as extensions have already been initialized.'); + } + + $this->staging->addNodeVisitor($visitor); + } + + /** + * @return NodeVisitorInterface[] + */ + public function getNodeVisitors(): array + { + if (!$this->initialized) { + $this->initExtensions(); + } + + return $this->visitors; + } + + public function addTokenParser(TokenParserInterface $parser): void + { + if ($this->initialized) { + throw new \LogicException('Unable to add a token parser as extensions have already been initialized.'); + } + + $this->staging->addTokenParser($parser); + } + + /** + * @return TokenParserInterface[] + */ + public function getTokenParsers(): array + { + if (!$this->initialized) { + $this->initExtensions(); + } + + return $this->parsers; + } + + public function getTokenParser(string $name): ?TokenParserInterface + { + if (!$this->initialized) { + $this->initExtensions(); + } + + if (isset($this->parsers[$name])) { + return $this->parsers[$name]; + } + + foreach ($this->parserCallbacks as $callback) { + if (false !== $parser = $callback($name)) { + return $parser; + } + } + + return null; + } + + public function registerUndefinedTokenParserCallback(callable $callable): void + { + $this->parserCallbacks[] = $callable; + } + + public function getGlobals(): array + { + if (null !== $this->globals) { + return $this->globals; + } + + $globals = []; + foreach ($this->extensions as $extension) { + if (!$extension instanceof GlobalsInterface) { + continue; + } + + $extGlobals = $extension->getGlobals(); + if (!\is_array($extGlobals)) { + throw new \UnexpectedValueException(sprintf('"%s::getGlobals()" must return an array of globals.', \get_class($extension))); + } + + $globals = array_merge($globals, $extGlobals); + } + + if ($this->initialized) { + $this->globals = $globals; + } + + return $globals; + } + + public function addTest(TwigTest $test): void + { + if ($this->initialized) { + throw new \LogicException(sprintf('Unable to add test "%s" as extensions have already been initialized.', $test->getName())); + } + + $this->staging->addTest($test); + } + + /** + * @return TwigTest[] + */ + public function getTests(): array + { + if (!$this->initialized) { + $this->initExtensions(); + } + + return $this->tests; + } + + public function getTest(string $name): ?TwigTest + { + if (!$this->initialized) { + $this->initExtensions(); + } + + if (isset($this->tests[$name])) { + return $this->tests[$name]; + } + + foreach ($this->tests as $pattern => $test) { + $pattern = str_replace('\\*', '(.*?)', preg_quote($pattern, '#'), $count); + + if ($count) { + if (preg_match('#^'.$pattern.'$#', $name, $matches)) { + array_shift($matches); + $test->setArguments($matches); + + return $test; + } + } + } + + return null; + } + + public function getUnaryOperators(): array + { + if (!$this->initialized) { + $this->initExtensions(); + } + + return $this->unaryOperators; + } + + public function getBinaryOperators(): array + { + if (!$this->initialized) { + $this->initExtensions(); + } + + return $this->binaryOperators; + } + + private function initExtensions(): void + { + $this->parsers = []; + $this->filters = []; + $this->functions = []; + $this->tests = []; + $this->visitors = []; + $this->unaryOperators = []; + $this->binaryOperators = []; + + foreach ($this->extensions as $extension) { + $this->initExtension($extension); + } + $this->initExtension($this->staging); + // Done at the end only, so that an exception during initialization does not mark the environment as initialized when catching the exception + $this->initialized = true; + } + + private function initExtension(ExtensionInterface $extension): void + { + // filters + foreach ($extension->getFilters() as $filter) { + $this->filters[$filter->getName()] = $filter; + } + + // functions + foreach ($extension->getFunctions() as $function) { + $this->functions[$function->getName()] = $function; + } + + // tests + foreach ($extension->getTests() as $test) { + $this->tests[$test->getName()] = $test; + } + + // token parsers + foreach ($extension->getTokenParsers() as $parser) { + if (!$parser instanceof TokenParserInterface) { + throw new \LogicException('getTokenParsers() must return an array of \Twig\TokenParser\TokenParserInterface.'); + } + + $this->parsers[$parser->getTag()] = $parser; + } + + // node visitors + foreach ($extension->getNodeVisitors() as $visitor) { + $this->visitors[] = $visitor; + } + + // operators + if ($operators = $extension->getOperators()) { + if (!\is_array($operators)) { + throw new \InvalidArgumentException(sprintf('"%s::getOperators()" must return an array with operators, got "%s".', \get_class($extension), \is_object($operators) ? \get_class($operators) : \gettype($operators).(\is_resource($operators) ? '' : '#'.$operators))); + } + + if (2 !== \count($operators)) { + throw new \InvalidArgumentException(sprintf('"%s::getOperators()" must return an array of 2 elements, got %d.', \get_class($extension), \count($operators))); + } + + $this->unaryOperators = array_merge($this->unaryOperators, $operators[0]); + $this->binaryOperators = array_merge($this->binaryOperators, $operators[1]); + } + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/FileExtensionEscapingStrategy.php b/data/web/inc/lib/vendor/twig/twig/src/FileExtensionEscapingStrategy.php new file mode 100644 index 00000000..65198bbb --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/FileExtensionEscapingStrategy.php @@ -0,0 +1,60 @@ + + */ +class FileExtensionEscapingStrategy +{ + /** + * Guesses the best autoescaping strategy based on the file name. + * + * @param string $name The template name + * + * @return string|false The escaping strategy name to use or false to disable + */ + public static function guess(string $name) + { + if (\in_array(substr($name, -1), ['/', '\\'])) { + return 'html'; // return html for directories + } + + if ('.twig' === substr($name, -5)) { + $name = substr($name, 0, -5); + } + + $extension = pathinfo($name, \PATHINFO_EXTENSION); + + switch ($extension) { + case 'js': + return 'js'; + + case 'css': + return 'css'; + + case 'txt': + return false; + + default: + return 'html'; + } + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Lexer.php b/data/web/inc/lib/vendor/twig/twig/src/Lexer.php new file mode 100644 index 00000000..9ff028c8 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Lexer.php @@ -0,0 +1,501 @@ + + */ +class Lexer +{ + private $tokens; + private $code; + private $cursor; + private $lineno; + private $end; + private $state; + private $states; + private $brackets; + private $env; + private $source; + private $options; + private $regexes; + private $position; + private $positions; + private $currentVarBlockLine; + + public const STATE_DATA = 0; + public const STATE_BLOCK = 1; + public const STATE_VAR = 2; + public const STATE_STRING = 3; + public const STATE_INTERPOLATION = 4; + + public const REGEX_NAME = '/[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/A'; + public const REGEX_NUMBER = '/[0-9]+(?:\.[0-9]+)?([Ee][\+\-][0-9]+)?/A'; + public const REGEX_STRING = '/"([^#"\\\\]*(?:\\\\.[^#"\\\\]*)*)"|\'([^\'\\\\]*(?:\\\\.[^\'\\\\]*)*)\'/As'; + public const REGEX_DQ_STRING_DELIM = '/"/A'; + public const REGEX_DQ_STRING_PART = '/[^#"\\\\]*(?:(?:\\\\.|#(?!\{))[^#"\\\\]*)*/As'; + public const PUNCTUATION = '()[]{}?:.,|'; + + public function __construct(Environment $env, array $options = []) + { + $this->env = $env; + + $this->options = array_merge([ + 'tag_comment' => ['{#', '#}'], + 'tag_block' => ['{%', '%}'], + 'tag_variable' => ['{{', '}}'], + 'whitespace_trim' => '-', + 'whitespace_line_trim' => '~', + 'whitespace_line_chars' => ' \t\0\x0B', + 'interpolation' => ['#{', '}'], + ], $options); + + // when PHP 7.3 is the min version, we will be able to remove the '#' part in preg_quote as it's part of the default + $this->regexes = [ + // }} + 'lex_var' => '{ + \s* + (?:'. + preg_quote($this->options['whitespace_trim'].$this->options['tag_variable'][1], '#').'\s*'. // -}}\s* + '|'. + preg_quote($this->options['whitespace_line_trim'].$this->options['tag_variable'][1], '#').'['.$this->options['whitespace_line_chars'].']*'. // ~}}[ \t\0\x0B]* + '|'. + preg_quote($this->options['tag_variable'][1], '#'). // }} + ') + }Ax', + + // %} + 'lex_block' => '{ + \s* + (?:'. + preg_quote($this->options['whitespace_trim'].$this->options['tag_block'][1], '#').'\s*\n?'. // -%}\s*\n? + '|'. + preg_quote($this->options['whitespace_line_trim'].$this->options['tag_block'][1], '#').'['.$this->options['whitespace_line_chars'].']*'. // ~%}[ \t\0\x0B]* + '|'. + preg_quote($this->options['tag_block'][1], '#').'\n?'. // %}\n? + ') + }Ax', + + // {% endverbatim %} + 'lex_raw_data' => '{'. + preg_quote($this->options['tag_block'][0], '#'). // {% + '('. + $this->options['whitespace_trim']. // - + '|'. + $this->options['whitespace_line_trim']. // ~ + ')?\s*endverbatim\s*'. + '(?:'. + preg_quote($this->options['whitespace_trim'].$this->options['tag_block'][1], '#').'\s*'. // -%} + '|'. + preg_quote($this->options['whitespace_line_trim'].$this->options['tag_block'][1], '#').'['.$this->options['whitespace_line_chars'].']*'. // ~%}[ \t\0\x0B]* + '|'. + preg_quote($this->options['tag_block'][1], '#'). // %} + ') + }sx', + + 'operator' => $this->getOperatorRegex(), + + // #} + 'lex_comment' => '{ + (?:'. + preg_quote($this->options['whitespace_trim'].$this->options['tag_comment'][1], '#').'\s*\n?'. // -#}\s*\n? + '|'. + preg_quote($this->options['whitespace_line_trim'].$this->options['tag_comment'][1], '#').'['.$this->options['whitespace_line_chars'].']*'. // ~#}[ \t\0\x0B]* + '|'. + preg_quote($this->options['tag_comment'][1], '#').'\n?'. // #}\n? + ') + }sx', + + // verbatim %} + 'lex_block_raw' => '{ + \s*verbatim\s* + (?:'. + preg_quote($this->options['whitespace_trim'].$this->options['tag_block'][1], '#').'\s*'. // -%}\s* + '|'. + preg_quote($this->options['whitespace_line_trim'].$this->options['tag_block'][1], '#').'['.$this->options['whitespace_line_chars'].']*'. // ~%}[ \t\0\x0B]* + '|'. + preg_quote($this->options['tag_block'][1], '#'). // %} + ') + }Asx', + + 'lex_block_line' => '{\s*line\s+(\d+)\s*'.preg_quote($this->options['tag_block'][1], '#').'}As', + + // {{ or {% or {# + 'lex_tokens_start' => '{ + ('. + preg_quote($this->options['tag_variable'][0], '#'). // {{ + '|'. + preg_quote($this->options['tag_block'][0], '#'). // {% + '|'. + preg_quote($this->options['tag_comment'][0], '#'). // {# + ')('. + preg_quote($this->options['whitespace_trim'], '#'). // - + '|'. + preg_quote($this->options['whitespace_line_trim'], '#'). // ~ + ')? + }sx', + 'interpolation_start' => '{'.preg_quote($this->options['interpolation'][0], '#').'\s*}A', + 'interpolation_end' => '{\s*'.preg_quote($this->options['interpolation'][1], '#').'}A', + ]; + } + + public function tokenize(Source $source): TokenStream + { + $this->source = $source; + $this->code = str_replace(["\r\n", "\r"], "\n", $source->getCode()); + $this->cursor = 0; + $this->lineno = 1; + $this->end = \strlen($this->code); + $this->tokens = []; + $this->state = self::STATE_DATA; + $this->states = []; + $this->brackets = []; + $this->position = -1; + + // find all token starts in one go + preg_match_all($this->regexes['lex_tokens_start'], $this->code, $matches, \PREG_OFFSET_CAPTURE); + $this->positions = $matches; + + while ($this->cursor < $this->end) { + // dispatch to the lexing functions depending + // on the current state + switch ($this->state) { + case self::STATE_DATA: + $this->lexData(); + break; + + case self::STATE_BLOCK: + $this->lexBlock(); + break; + + case self::STATE_VAR: + $this->lexVar(); + break; + + case self::STATE_STRING: + $this->lexString(); + break; + + case self::STATE_INTERPOLATION: + $this->lexInterpolation(); + break; + } + } + + $this->pushToken(/* Token::EOF_TYPE */ -1); + + if (!empty($this->brackets)) { + list($expect, $lineno) = array_pop($this->brackets); + throw new SyntaxError(sprintf('Unclosed "%s".', $expect), $lineno, $this->source); + } + + return new TokenStream($this->tokens, $this->source); + } + + private function lexData(): void + { + // if no matches are left we return the rest of the template as simple text token + if ($this->position == \count($this->positions[0]) - 1) { + $this->pushToken(/* Token::TEXT_TYPE */ 0, substr($this->code, $this->cursor)); + $this->cursor = $this->end; + + return; + } + + // Find the first token after the current cursor + $position = $this->positions[0][++$this->position]; + while ($position[1] < $this->cursor) { + if ($this->position == \count($this->positions[0]) - 1) { + return; + } + $position = $this->positions[0][++$this->position]; + } + + // push the template text first + $text = $textContent = substr($this->code, $this->cursor, $position[1] - $this->cursor); + + // trim? + if (isset($this->positions[2][$this->position][0])) { + if ($this->options['whitespace_trim'] === $this->positions[2][$this->position][0]) { + // whitespace_trim detected ({%-, {{- or {#-) + $text = rtrim($text); + } elseif ($this->options['whitespace_line_trim'] === $this->positions[2][$this->position][0]) { + // whitespace_line_trim detected ({%~, {{~ or {#~) + // don't trim \r and \n + $text = rtrim($text, " \t\0\x0B"); + } + } + $this->pushToken(/* Token::TEXT_TYPE */ 0, $text); + $this->moveCursor($textContent.$position[0]); + + switch ($this->positions[1][$this->position][0]) { + case $this->options['tag_comment'][0]: + $this->lexComment(); + break; + + case $this->options['tag_block'][0]: + // raw data? + if (preg_match($this->regexes['lex_block_raw'], $this->code, $match, 0, $this->cursor)) { + $this->moveCursor($match[0]); + $this->lexRawData(); + // {% line \d+ %} + } elseif (preg_match($this->regexes['lex_block_line'], $this->code, $match, 0, $this->cursor)) { + $this->moveCursor($match[0]); + $this->lineno = (int) $match[1]; + } else { + $this->pushToken(/* Token::BLOCK_START_TYPE */ 1); + $this->pushState(self::STATE_BLOCK); + $this->currentVarBlockLine = $this->lineno; + } + break; + + case $this->options['tag_variable'][0]: + $this->pushToken(/* Token::VAR_START_TYPE */ 2); + $this->pushState(self::STATE_VAR); + $this->currentVarBlockLine = $this->lineno; + break; + } + } + + private function lexBlock(): void + { + if (empty($this->brackets) && preg_match($this->regexes['lex_block'], $this->code, $match, 0, $this->cursor)) { + $this->pushToken(/* Token::BLOCK_END_TYPE */ 3); + $this->moveCursor($match[0]); + $this->popState(); + } else { + $this->lexExpression(); + } + } + + private function lexVar(): void + { + if (empty($this->brackets) && preg_match($this->regexes['lex_var'], $this->code, $match, 0, $this->cursor)) { + $this->pushToken(/* Token::VAR_END_TYPE */ 4); + $this->moveCursor($match[0]); + $this->popState(); + } else { + $this->lexExpression(); + } + } + + private function lexExpression(): void + { + // whitespace + if (preg_match('/\s+/A', $this->code, $match, 0, $this->cursor)) { + $this->moveCursor($match[0]); + + if ($this->cursor >= $this->end) { + throw new SyntaxError(sprintf('Unclosed "%s".', self::STATE_BLOCK === $this->state ? 'block' : 'variable'), $this->currentVarBlockLine, $this->source); + } + } + + // arrow function + if ('=' === $this->code[$this->cursor] && '>' === $this->code[$this->cursor + 1]) { + $this->pushToken(Token::ARROW_TYPE, '=>'); + $this->moveCursor('=>'); + } + // operators + elseif (preg_match($this->regexes['operator'], $this->code, $match, 0, $this->cursor)) { + $this->pushToken(/* Token::OPERATOR_TYPE */ 8, preg_replace('/\s+/', ' ', $match[0])); + $this->moveCursor($match[0]); + } + // names + elseif (preg_match(self::REGEX_NAME, $this->code, $match, 0, $this->cursor)) { + $this->pushToken(/* Token::NAME_TYPE */ 5, $match[0]); + $this->moveCursor($match[0]); + } + // numbers + elseif (preg_match(self::REGEX_NUMBER, $this->code, $match, 0, $this->cursor)) { + $number = (float) $match[0]; // floats + if (ctype_digit($match[0]) && $number <= \PHP_INT_MAX) { + $number = (int) $match[0]; // integers lower than the maximum + } + $this->pushToken(/* Token::NUMBER_TYPE */ 6, $number); + $this->moveCursor($match[0]); + } + // punctuation + elseif (false !== strpos(self::PUNCTUATION, $this->code[$this->cursor])) { + // opening bracket + if (false !== strpos('([{', $this->code[$this->cursor])) { + $this->brackets[] = [$this->code[$this->cursor], $this->lineno]; + } + // closing bracket + elseif (false !== strpos(')]}', $this->code[$this->cursor])) { + if (empty($this->brackets)) { + throw new SyntaxError(sprintf('Unexpected "%s".', $this->code[$this->cursor]), $this->lineno, $this->source); + } + + list($expect, $lineno) = array_pop($this->brackets); + if ($this->code[$this->cursor] != strtr($expect, '([{', ')]}')) { + throw new SyntaxError(sprintf('Unclosed "%s".', $expect), $lineno, $this->source); + } + } + + $this->pushToken(/* Token::PUNCTUATION_TYPE */ 9, $this->code[$this->cursor]); + ++$this->cursor; + } + // strings + elseif (preg_match(self::REGEX_STRING, $this->code, $match, 0, $this->cursor)) { + $this->pushToken(/* Token::STRING_TYPE */ 7, stripcslashes(substr($match[0], 1, -1))); + $this->moveCursor($match[0]); + } + // opening double quoted string + elseif (preg_match(self::REGEX_DQ_STRING_DELIM, $this->code, $match, 0, $this->cursor)) { + $this->brackets[] = ['"', $this->lineno]; + $this->pushState(self::STATE_STRING); + $this->moveCursor($match[0]); + } + // unlexable + else { + throw new SyntaxError(sprintf('Unexpected character "%s".', $this->code[$this->cursor]), $this->lineno, $this->source); + } + } + + private function lexRawData(): void + { + if (!preg_match($this->regexes['lex_raw_data'], $this->code, $match, \PREG_OFFSET_CAPTURE, $this->cursor)) { + throw new SyntaxError('Unexpected end of file: Unclosed "verbatim" block.', $this->lineno, $this->source); + } + + $text = substr($this->code, $this->cursor, $match[0][1] - $this->cursor); + $this->moveCursor($text.$match[0][0]); + + // trim? + if (isset($match[1][0])) { + if ($this->options['whitespace_trim'] === $match[1][0]) { + // whitespace_trim detected ({%-, {{- or {#-) + $text = rtrim($text); + } else { + // whitespace_line_trim detected ({%~, {{~ or {#~) + // don't trim \r and \n + $text = rtrim($text, " \t\0\x0B"); + } + } + + $this->pushToken(/* Token::TEXT_TYPE */ 0, $text); + } + + private function lexComment(): void + { + if (!preg_match($this->regexes['lex_comment'], $this->code, $match, \PREG_OFFSET_CAPTURE, $this->cursor)) { + throw new SyntaxError('Unclosed comment.', $this->lineno, $this->source); + } + + $this->moveCursor(substr($this->code, $this->cursor, $match[0][1] - $this->cursor).$match[0][0]); + } + + private function lexString(): void + { + if (preg_match($this->regexes['interpolation_start'], $this->code, $match, 0, $this->cursor)) { + $this->brackets[] = [$this->options['interpolation'][0], $this->lineno]; + $this->pushToken(/* Token::INTERPOLATION_START_TYPE */ 10); + $this->moveCursor($match[0]); + $this->pushState(self::STATE_INTERPOLATION); + } elseif (preg_match(self::REGEX_DQ_STRING_PART, $this->code, $match, 0, $this->cursor) && \strlen($match[0]) > 0) { + $this->pushToken(/* Token::STRING_TYPE */ 7, stripcslashes($match[0])); + $this->moveCursor($match[0]); + } elseif (preg_match(self::REGEX_DQ_STRING_DELIM, $this->code, $match, 0, $this->cursor)) { + list($expect, $lineno) = array_pop($this->brackets); + if ('"' != $this->code[$this->cursor]) { + throw new SyntaxError(sprintf('Unclosed "%s".', $expect), $lineno, $this->source); + } + + $this->popState(); + ++$this->cursor; + } else { + // unlexable + throw new SyntaxError(sprintf('Unexpected character "%s".', $this->code[$this->cursor]), $this->lineno, $this->source); + } + } + + private function lexInterpolation(): void + { + $bracket = end($this->brackets); + if ($this->options['interpolation'][0] === $bracket[0] && preg_match($this->regexes['interpolation_end'], $this->code, $match, 0, $this->cursor)) { + array_pop($this->brackets); + $this->pushToken(/* Token::INTERPOLATION_END_TYPE */ 11); + $this->moveCursor($match[0]); + $this->popState(); + } else { + $this->lexExpression(); + } + } + + private function pushToken($type, $value = ''): void + { + // do not push empty text tokens + if (/* Token::TEXT_TYPE */ 0 === $type && '' === $value) { + return; + } + + $this->tokens[] = new Token($type, $value, $this->lineno); + } + + private function moveCursor($text): void + { + $this->cursor += \strlen($text); + $this->lineno += substr_count($text, "\n"); + } + + private function getOperatorRegex(): string + { + $operators = array_merge( + ['='], + array_keys($this->env->getUnaryOperators()), + array_keys($this->env->getBinaryOperators()) + ); + + $operators = array_combine($operators, array_map('strlen', $operators)); + arsort($operators); + + $regex = []; + foreach ($operators as $operator => $length) { + // an operator that ends with a character must be followed by + // a whitespace, a parenthesis, an opening map [ or sequence { + $r = preg_quote($operator, '/'); + if (ctype_alpha($operator[$length - 1])) { + $r .= '(?=[\s()\[{])'; + } + + // an operator that begins with a character must not have a dot or pipe before + if (ctype_alpha($operator[0])) { + $r = '(?states[] = $this->state; + $this->state = $state; + } + + private function popState(): void + { + if (0 === \count($this->states)) { + throw new \LogicException('Cannot pop state without a previous state.'); + } + + $this->state = array_pop($this->states); + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Loader/ArrayLoader.php b/data/web/inc/lib/vendor/twig/twig/src/Loader/ArrayLoader.php new file mode 100644 index 00000000..5d726c35 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Loader/ArrayLoader.php @@ -0,0 +1,77 @@ + + */ +final class ArrayLoader implements LoaderInterface +{ + private $templates = []; + + /** + * @param array $templates An array of templates (keys are the names, and values are the source code) + */ + public function __construct(array $templates = []) + { + $this->templates = $templates; + } + + public function setTemplate(string $name, string $template): void + { + $this->templates[$name] = $template; + } + + public function getSourceContext(string $name): Source + { + if (!isset($this->templates[$name])) { + throw new LoaderError(sprintf('Template "%s" is not defined.', $name)); + } + + return new Source($this->templates[$name], $name); + } + + public function exists(string $name): bool + { + return isset($this->templates[$name]); + } + + public function getCacheKey(string $name): string + { + if (!isset($this->templates[$name])) { + throw new LoaderError(sprintf('Template "%s" is not defined.', $name)); + } + + return $name.':'.$this->templates[$name]; + } + + public function isFresh(string $name, int $time): bool + { + if (!isset($this->templates[$name])) { + throw new LoaderError(sprintf('Template "%s" is not defined.', $name)); + } + + return true; + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Loader/ChainLoader.php b/data/web/inc/lib/vendor/twig/twig/src/Loader/ChainLoader.php new file mode 100644 index 00000000..fbf4f3a0 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Loader/ChainLoader.php @@ -0,0 +1,119 @@ + + */ +final class ChainLoader implements LoaderInterface +{ + private $hasSourceCache = []; + private $loaders = []; + + /** + * @param LoaderInterface[] $loaders + */ + public function __construct(array $loaders = []) + { + foreach ($loaders as $loader) { + $this->addLoader($loader); + } + } + + public function addLoader(LoaderInterface $loader): void + { + $this->loaders[] = $loader; + $this->hasSourceCache = []; + } + + /** + * @return LoaderInterface[] + */ + public function getLoaders(): array + { + return $this->loaders; + } + + public function getSourceContext(string $name): Source + { + $exceptions = []; + foreach ($this->loaders as $loader) { + if (!$loader->exists($name)) { + continue; + } + + try { + return $loader->getSourceContext($name); + } catch (LoaderError $e) { + $exceptions[] = $e->getMessage(); + } + } + + throw new LoaderError(sprintf('Template "%s" is not defined%s.', $name, $exceptions ? ' ('.implode(', ', $exceptions).')' : '')); + } + + public function exists(string $name): bool + { + if (isset($this->hasSourceCache[$name])) { + return $this->hasSourceCache[$name]; + } + + foreach ($this->loaders as $loader) { + if ($loader->exists($name)) { + return $this->hasSourceCache[$name] = true; + } + } + + return $this->hasSourceCache[$name] = false; + } + + public function getCacheKey(string $name): string + { + $exceptions = []; + foreach ($this->loaders as $loader) { + if (!$loader->exists($name)) { + continue; + } + + try { + return $loader->getCacheKey($name); + } catch (LoaderError $e) { + $exceptions[] = \get_class($loader).': '.$e->getMessage(); + } + } + + throw new LoaderError(sprintf('Template "%s" is not defined%s.', $name, $exceptions ? ' ('.implode(', ', $exceptions).')' : '')); + } + + public function isFresh(string $name, int $time): bool + { + $exceptions = []; + foreach ($this->loaders as $loader) { + if (!$loader->exists($name)) { + continue; + } + + try { + return $loader->isFresh($name, $time); + } catch (LoaderError $e) { + $exceptions[] = \get_class($loader).': '.$e->getMessage(); + } + } + + throw new LoaderError(sprintf('Template "%s" is not defined%s.', $name, $exceptions ? ' ('.implode(', ', $exceptions).')' : '')); + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Loader/FilesystemLoader.php b/data/web/inc/lib/vendor/twig/twig/src/Loader/FilesystemLoader.php new file mode 100644 index 00000000..859a898c --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Loader/FilesystemLoader.php @@ -0,0 +1,283 @@ + + */ +class FilesystemLoader implements LoaderInterface +{ + /** Identifier of the main namespace. */ + public const MAIN_NAMESPACE = '__main__'; + + protected $paths = []; + protected $cache = []; + protected $errorCache = []; + + private $rootPath; + + /** + * @param string|array $paths A path or an array of paths where to look for templates + * @param string|null $rootPath The root path common to all relative paths (null for getcwd()) + */ + public function __construct($paths = [], string $rootPath = null) + { + $this->rootPath = (null === $rootPath ? getcwd() : $rootPath).\DIRECTORY_SEPARATOR; + if (null !== $rootPath && false !== ($realPath = realpath($rootPath))) { + $this->rootPath = $realPath.\DIRECTORY_SEPARATOR; + } + + if ($paths) { + $this->setPaths($paths); + } + } + + /** + * Returns the paths to the templates. + */ + public function getPaths(string $namespace = self::MAIN_NAMESPACE): array + { + return $this->paths[$namespace] ?? []; + } + + /** + * Returns the path namespaces. + * + * The main namespace is always defined. + */ + public function getNamespaces(): array + { + return array_keys($this->paths); + } + + /** + * @param string|array $paths A path or an array of paths where to look for templates + */ + public function setPaths($paths, string $namespace = self::MAIN_NAMESPACE): void + { + if (!\is_array($paths)) { + $paths = [$paths]; + } + + $this->paths[$namespace] = []; + foreach ($paths as $path) { + $this->addPath($path, $namespace); + } + } + + /** + * @throws LoaderError + */ + public function addPath(string $path, string $namespace = self::MAIN_NAMESPACE): void + { + // invalidate the cache + $this->cache = $this->errorCache = []; + + $checkPath = $this->isAbsolutePath($path) ? $path : $this->rootPath.$path; + if (!is_dir($checkPath)) { + throw new LoaderError(sprintf('The "%s" directory does not exist ("%s").', $path, $checkPath)); + } + + $this->paths[$namespace][] = rtrim($path, '/\\'); + } + + /** + * @throws LoaderError + */ + public function prependPath(string $path, string $namespace = self::MAIN_NAMESPACE): void + { + // invalidate the cache + $this->cache = $this->errorCache = []; + + $checkPath = $this->isAbsolutePath($path) ? $path : $this->rootPath.$path; + if (!is_dir($checkPath)) { + throw new LoaderError(sprintf('The "%s" directory does not exist ("%s").', $path, $checkPath)); + } + + $path = rtrim($path, '/\\'); + + if (!isset($this->paths[$namespace])) { + $this->paths[$namespace][] = $path; + } else { + array_unshift($this->paths[$namespace], $path); + } + } + + public function getSourceContext(string $name): Source + { + if (null === $path = $this->findTemplate($name)) { + return new Source('', $name, ''); + } + + return new Source(file_get_contents($path), $name, $path); + } + + public function getCacheKey(string $name): string + { + if (null === $path = $this->findTemplate($name)) { + return ''; + } + $len = \strlen($this->rootPath); + if (0 === strncmp($this->rootPath, $path, $len)) { + return substr($path, $len); + } + + return $path; + } + + /** + * @return bool + */ + public function exists(string $name) + { + $name = $this->normalizeName($name); + + if (isset($this->cache[$name])) { + return true; + } + + return null !== $this->findTemplate($name, false); + } + + public function isFresh(string $name, int $time): bool + { + // false support to be removed in 3.0 + if (null === $path = $this->findTemplate($name)) { + return false; + } + + return filemtime($path) < $time; + } + + /** + * @return string|null + */ + protected function findTemplate(string $name, bool $throw = true) + { + $name = $this->normalizeName($name); + + if (isset($this->cache[$name])) { + return $this->cache[$name]; + } + + if (isset($this->errorCache[$name])) { + if (!$throw) { + return null; + } + + throw new LoaderError($this->errorCache[$name]); + } + + try { + $this->validateName($name); + + list($namespace, $shortname) = $this->parseName($name); + } catch (LoaderError $e) { + if (!$throw) { + return null; + } + + throw $e; + } + + if (!isset($this->paths[$namespace])) { + $this->errorCache[$name] = sprintf('There are no registered paths for namespace "%s".', $namespace); + + if (!$throw) { + return null; + } + + throw new LoaderError($this->errorCache[$name]); + } + + foreach ($this->paths[$namespace] as $path) { + if (!$this->isAbsolutePath($path)) { + $path = $this->rootPath.$path; + } + + if (is_file($path.'/'.$shortname)) { + if (false !== $realpath = realpath($path.'/'.$shortname)) { + return $this->cache[$name] = $realpath; + } + + return $this->cache[$name] = $path.'/'.$shortname; + } + } + + $this->errorCache[$name] = sprintf('Unable to find template "%s" (looked into: %s).', $name, implode(', ', $this->paths[$namespace])); + + if (!$throw) { + return null; + } + + throw new LoaderError($this->errorCache[$name]); + } + + private function normalizeName(string $name): string + { + return preg_replace('#/{2,}#', '/', str_replace('\\', '/', $name)); + } + + private function parseName(string $name, string $default = self::MAIN_NAMESPACE): array + { + if (isset($name[0]) && '@' == $name[0]) { + if (false === $pos = strpos($name, '/')) { + throw new LoaderError(sprintf('Malformed namespaced template name "%s" (expecting "@namespace/template_name").', $name)); + } + + $namespace = substr($name, 1, $pos - 1); + $shortname = substr($name, $pos + 1); + + return [$namespace, $shortname]; + } + + return [$default, $name]; + } + + private function validateName(string $name): void + { + if (false !== strpos($name, "\0")) { + throw new LoaderError('A template name cannot contain NUL bytes.'); + } + + $name = ltrim($name, '/'); + $parts = explode('/', $name); + $level = 0; + foreach ($parts as $part) { + if ('..' === $part) { + --$level; + } elseif ('.' !== $part) { + ++$level; + } + + if ($level < 0) { + throw new LoaderError(sprintf('Looks like you try to load a template outside configured directories (%s).', $name)); + } + } + } + + private function isAbsolutePath(string $file): bool + { + return strspn($file, '/\\', 0, 1) + || (\strlen($file) > 3 && ctype_alpha($file[0]) + && ':' === $file[1] + && strspn($file, '/\\', 2, 1) + ) + || null !== parse_url($file, \PHP_URL_SCHEME) + ; + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Loader/LoaderInterface.php b/data/web/inc/lib/vendor/twig/twig/src/Loader/LoaderInterface.php new file mode 100644 index 00000000..fec7e85f --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Loader/LoaderInterface.php @@ -0,0 +1,49 @@ + + */ +interface LoaderInterface +{ + /** + * Returns the source context for a given template logical name. + * + * @throws LoaderError When $name is not found + */ + public function getSourceContext(string $name): Source; + + /** + * Gets the cache key to use for the cache for a given template name. + * + * @throws LoaderError When $name is not found + */ + public function getCacheKey(string $name): string; + + /** + * @param int $time Timestamp of the last modification time of the cached template + * + * @throws LoaderError When $name is not found + */ + public function isFresh(string $name, int $time): bool; + + /** + * @return bool + */ + public function exists(string $name); +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Markup.php b/data/web/inc/lib/vendor/twig/twig/src/Markup.php new file mode 100644 index 00000000..c8c5e1a1 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Markup.php @@ -0,0 +1,47 @@ + + */ +class Markup implements \Countable, \JsonSerializable +{ + private $content; + private $charset; + + public function __construct($content, $charset) + { + $this->content = (string) $content; + $this->charset = $charset; + } + + public function __toString() + { + return $this->content; + } + + /** + * @return int + */ + public function count() + { + return mb_strlen($this->content, $this->charset); + } + + public function jsonSerialize() + { + return $this->content; + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Node/AutoEscapeNode.php b/data/web/inc/lib/vendor/twig/twig/src/Node/AutoEscapeNode.php new file mode 100644 index 00000000..cd970411 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Node/AutoEscapeNode.php @@ -0,0 +1,38 @@ + + */ +class AutoEscapeNode extends Node +{ + public function __construct($value, Node $body, int $lineno, string $tag = 'autoescape') + { + parent::__construct(['body' => $body], ['value' => $value], $lineno, $tag); + } + + public function compile(Compiler $compiler): void + { + $compiler->subcompile($this->getNode('body')); + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Node/BlockNode.php b/data/web/inc/lib/vendor/twig/twig/src/Node/BlockNode.php new file mode 100644 index 00000000..0632ba74 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Node/BlockNode.php @@ -0,0 +1,44 @@ + + */ +class BlockNode extends Node +{ + public function __construct(string $name, Node $body, int $lineno, string $tag = null) + { + parent::__construct(['body' => $body], ['name' => $name], $lineno, $tag); + } + + public function compile(Compiler $compiler): void + { + $compiler + ->addDebugInfo($this) + ->write(sprintf("public function block_%s(\$context, array \$blocks = [])\n", $this->getAttribute('name')), "{\n") + ->indent() + ->write("\$macros = \$this->macros;\n") + ; + + $compiler + ->subcompile($this->getNode('body')) + ->outdent() + ->write("}\n\n") + ; + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Node/BlockReferenceNode.php b/data/web/inc/lib/vendor/twig/twig/src/Node/BlockReferenceNode.php new file mode 100644 index 00000000..cc8af5b5 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Node/BlockReferenceNode.php @@ -0,0 +1,36 @@ + + */ +class BlockReferenceNode extends Node implements NodeOutputInterface +{ + public function __construct(string $name, int $lineno, string $tag = null) + { + parent::__construct([], ['name' => $name], $lineno, $tag); + } + + public function compile(Compiler $compiler): void + { + $compiler + ->addDebugInfo($this) + ->write(sprintf("\$this->displayBlock('%s', \$context, \$blocks);\n", $this->getAttribute('name'))) + ; + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Node/BodyNode.php b/data/web/inc/lib/vendor/twig/twig/src/Node/BodyNode.php new file mode 100644 index 00000000..041cbf68 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Node/BodyNode.php @@ -0,0 +1,21 @@ + + */ +class BodyNode extends Node +{ +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Node/CheckSecurityCallNode.php b/data/web/inc/lib/vendor/twig/twig/src/Node/CheckSecurityCallNode.php new file mode 100644 index 00000000..a78a38d8 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Node/CheckSecurityCallNode.php @@ -0,0 +1,28 @@ + + */ +class CheckSecurityCallNode extends Node +{ + public function compile(Compiler $compiler) + { + $compiler + ->write("\$this->sandbox = \$this->env->getExtension('\Twig\Extension\SandboxExtension');\n") + ->write("\$this->checkSecurity();\n") + ; + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Node/CheckSecurityNode.php b/data/web/inc/lib/vendor/twig/twig/src/Node/CheckSecurityNode.php new file mode 100644 index 00000000..47273279 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Node/CheckSecurityNode.php @@ -0,0 +1,88 @@ + + */ +class CheckSecurityNode extends Node +{ + private $usedFilters; + private $usedTags; + private $usedFunctions; + + public function __construct(array $usedFilters, array $usedTags, array $usedFunctions) + { + $this->usedFilters = $usedFilters; + $this->usedTags = $usedTags; + $this->usedFunctions = $usedFunctions; + + parent::__construct(); + } + + public function compile(Compiler $compiler): void + { + $tags = $filters = $functions = []; + foreach (['tags', 'filters', 'functions'] as $type) { + foreach ($this->{'used'.ucfirst($type)} as $name => $node) { + if ($node instanceof Node) { + ${$type}[$name] = $node->getTemplateLine(); + } else { + ${$type}[$node] = null; + } + } + } + + $compiler + ->write("\n") + ->write("public function checkSecurity()\n") + ->write("{\n") + ->indent() + ->write('static $tags = ')->repr(array_filter($tags))->raw(";\n") + ->write('static $filters = ')->repr(array_filter($filters))->raw(";\n") + ->write('static $functions = ')->repr(array_filter($functions))->raw(";\n\n") + ->write("try {\n") + ->indent() + ->write("\$this->sandbox->checkSecurity(\n") + ->indent() + ->write(!$tags ? "[],\n" : "['".implode("', '", array_keys($tags))."'],\n") + ->write(!$filters ? "[],\n" : "['".implode("', '", array_keys($filters))."'],\n") + ->write(!$functions ? "[]\n" : "['".implode("', '", array_keys($functions))."']\n") + ->outdent() + ->write(");\n") + ->outdent() + ->write("} catch (SecurityError \$e) {\n") + ->indent() + ->write("\$e->setSourceContext(\$this->source);\n\n") + ->write("if (\$e instanceof SecurityNotAllowedTagError && isset(\$tags[\$e->getTagName()])) {\n") + ->indent() + ->write("\$e->setTemplateLine(\$tags[\$e->getTagName()]);\n") + ->outdent() + ->write("} elseif (\$e instanceof SecurityNotAllowedFilterError && isset(\$filters[\$e->getFilterName()])) {\n") + ->indent() + ->write("\$e->setTemplateLine(\$filters[\$e->getFilterName()]);\n") + ->outdent() + ->write("} elseif (\$e instanceof SecurityNotAllowedFunctionError && isset(\$functions[\$e->getFunctionName()])) {\n") + ->indent() + ->write("\$e->setTemplateLine(\$functions[\$e->getFunctionName()]);\n") + ->outdent() + ->write("}\n\n") + ->write("throw \$e;\n") + ->outdent() + ->write("}\n\n") + ->outdent() + ->write("}\n") + ; + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Node/CheckToStringNode.php b/data/web/inc/lib/vendor/twig/twig/src/Node/CheckToStringNode.php new file mode 100644 index 00000000..c7a9d698 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Node/CheckToStringNode.php @@ -0,0 +1,45 @@ + + */ +class CheckToStringNode extends AbstractExpression +{ + public function __construct(AbstractExpression $expr) + { + parent::__construct(['expr' => $expr], [], $expr->getTemplateLine(), $expr->getNodeTag()); + } + + public function compile(Compiler $compiler): void + { + $expr = $this->getNode('expr'); + $compiler + ->raw('$this->sandbox->ensureToStringAllowed(') + ->subcompile($expr) + ->raw(', ') + ->repr($expr->getTemplateLine()) + ->raw(', $this->source)') + ; + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Node/DeprecatedNode.php b/data/web/inc/lib/vendor/twig/twig/src/Node/DeprecatedNode.php new file mode 100644 index 00000000..5ff44307 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Node/DeprecatedNode.php @@ -0,0 +1,53 @@ + + */ +class DeprecatedNode extends Node +{ + public function __construct(AbstractExpression $expr, int $lineno, string $tag = null) + { + parent::__construct(['expr' => $expr], [], $lineno, $tag); + } + + public function compile(Compiler $compiler): void + { + $compiler->addDebugInfo($this); + + $expr = $this->getNode('expr'); + + if ($expr instanceof ConstantExpression) { + $compiler->write('@trigger_error(') + ->subcompile($expr); + } else { + $varName = $compiler->getVarName(); + $compiler->write(sprintf('$%s = ', $varName)) + ->subcompile($expr) + ->raw(";\n") + ->write(sprintf('@trigger_error($%s', $varName)); + } + + $compiler + ->raw('.') + ->string(sprintf(' ("%s" at line %d).', $this->getTemplateName(), $this->getTemplateLine())) + ->raw(", E_USER_DEPRECATED);\n") + ; + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Node/DoNode.php b/data/web/inc/lib/vendor/twig/twig/src/Node/DoNode.php new file mode 100644 index 00000000..f7783d19 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Node/DoNode.php @@ -0,0 +1,38 @@ + + */ +class DoNode extends Node +{ + public function __construct(AbstractExpression $expr, int $lineno, string $tag = null) + { + parent::__construct(['expr' => $expr], [], $lineno, $tag); + } + + public function compile(Compiler $compiler): void + { + $compiler + ->addDebugInfo($this) + ->write('') + ->subcompile($this->getNode('expr')) + ->raw(";\n") + ; + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Node/EmbedNode.php b/data/web/inc/lib/vendor/twig/twig/src/Node/EmbedNode.php new file mode 100644 index 00000000..903c3f6c --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Node/EmbedNode.php @@ -0,0 +1,48 @@ + + */ +class EmbedNode extends IncludeNode +{ + // we don't inject the module to avoid node visitors to traverse it twice (as it will be already visited in the main module) + public function __construct(string $name, int $index, ?AbstractExpression $variables, bool $only, bool $ignoreMissing, int $lineno, string $tag = null) + { + parent::__construct(new ConstantExpression('not_used', $lineno), $variables, $only, $ignoreMissing, $lineno, $tag); + + $this->setAttribute('name', $name); + $this->setAttribute('index', $index); + } + + protected function addGetTemplate(Compiler $compiler): void + { + $compiler + ->write('$this->loadTemplate(') + ->string($this->getAttribute('name')) + ->raw(', ') + ->repr($this->getTemplateName()) + ->raw(', ') + ->repr($this->getTemplateLine()) + ->raw(', ') + ->string($this->getAttribute('index')) + ->raw(')') + ; + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/AbstractExpression.php b/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/AbstractExpression.php new file mode 100644 index 00000000..42da0559 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/AbstractExpression.php @@ -0,0 +1,24 @@ + + */ +abstract class AbstractExpression extends Node +{ +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/ArrayExpression.php b/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/ArrayExpression.php new file mode 100644 index 00000000..0e25fe46 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/ArrayExpression.php @@ -0,0 +1,85 @@ +index = -1; + foreach ($this->getKeyValuePairs() as $pair) { + if ($pair['key'] instanceof ConstantExpression && ctype_digit((string) $pair['key']->getAttribute('value')) && $pair['key']->getAttribute('value') > $this->index) { + $this->index = $pair['key']->getAttribute('value'); + } + } + } + + public function getKeyValuePairs(): array + { + $pairs = []; + foreach (array_chunk($this->nodes, 2) as $pair) { + $pairs[] = [ + 'key' => $pair[0], + 'value' => $pair[1], + ]; + } + + return $pairs; + } + + public function hasElement(AbstractExpression $key): bool + { + foreach ($this->getKeyValuePairs() as $pair) { + // we compare the string representation of the keys + // to avoid comparing the line numbers which are not relevant here. + if ((string) $key === (string) $pair['key']) { + return true; + } + } + + return false; + } + + public function addElement(AbstractExpression $value, AbstractExpression $key = null): void + { + if (null === $key) { + $key = new ConstantExpression(++$this->index, $value->getTemplateLine()); + } + + array_push($this->nodes, $key, $value); + } + + public function compile(Compiler $compiler): void + { + $compiler->raw('['); + $first = true; + foreach ($this->getKeyValuePairs() as $pair) { + if (!$first) { + $compiler->raw(', '); + } + $first = false; + + $compiler + ->subcompile($pair['key']) + ->raw(' => ') + ->subcompile($pair['value']) + ; + } + $compiler->raw(']'); + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/ArrowFunctionExpression.php b/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/ArrowFunctionExpression.php new file mode 100644 index 00000000..eaad03c9 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/ArrowFunctionExpression.php @@ -0,0 +1,64 @@ + + */ +class ArrowFunctionExpression extends AbstractExpression +{ + public function __construct(AbstractExpression $expr, Node $names, $lineno, $tag = null) + { + parent::__construct(['expr' => $expr, 'names' => $names], [], $lineno, $tag); + } + + public function compile(Compiler $compiler): void + { + $compiler + ->addDebugInfo($this) + ->raw('function (') + ; + foreach ($this->getNode('names') as $i => $name) { + if ($i) { + $compiler->raw(', '); + } + + $compiler + ->raw('$__') + ->raw($name->getAttribute('name')) + ->raw('__') + ; + } + $compiler + ->raw(') use ($context, $macros) { ') + ; + foreach ($this->getNode('names') as $name) { + $compiler + ->raw('$context["') + ->raw($name->getAttribute('name')) + ->raw('"] = $__') + ->raw($name->getAttribute('name')) + ->raw('__; ') + ; + } + $compiler + ->raw('return ') + ->subcompile($this->getNode('expr')) + ->raw('; }') + ; + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/AssignNameExpression.php b/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/AssignNameExpression.php new file mode 100644 index 00000000..7dd1bc4a --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/AssignNameExpression.php @@ -0,0 +1,27 @@ +raw('$context[') + ->string($this->getAttribute('name')) + ->raw(']') + ; + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/Binary/AbstractBinary.php b/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/Binary/AbstractBinary.php new file mode 100644 index 00000000..c424e5cc --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/Binary/AbstractBinary.php @@ -0,0 +1,42 @@ + $left, 'right' => $right], [], $lineno); + } + + public function compile(Compiler $compiler): void + { + $compiler + ->raw('(') + ->subcompile($this->getNode('left')) + ->raw(' ') + ; + $this->operator($compiler); + $compiler + ->raw(' ') + ->subcompile($this->getNode('right')) + ->raw(')') + ; + } + + abstract public function operator(Compiler $compiler): Compiler; +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/Binary/AddBinary.php b/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/Binary/AddBinary.php new file mode 100644 index 00000000..ee4307e3 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/Binary/AddBinary.php @@ -0,0 +1,23 @@ +raw('+'); + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/Binary/AndBinary.php b/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/Binary/AndBinary.php new file mode 100644 index 00000000..5f2380da --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/Binary/AndBinary.php @@ -0,0 +1,23 @@ +raw('&&'); + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/Binary/BitwiseAndBinary.php b/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/Binary/BitwiseAndBinary.php new file mode 100644 index 00000000..db7d6d61 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/Binary/BitwiseAndBinary.php @@ -0,0 +1,23 @@ +raw('&'); + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/Binary/BitwiseOrBinary.php b/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/Binary/BitwiseOrBinary.php new file mode 100644 index 00000000..ce803dd9 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/Binary/BitwiseOrBinary.php @@ -0,0 +1,23 @@ +raw('|'); + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/Binary/BitwiseXorBinary.php b/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/Binary/BitwiseXorBinary.php new file mode 100644 index 00000000..5c297850 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/Binary/BitwiseXorBinary.php @@ -0,0 +1,23 @@ +raw('^'); + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/Binary/ConcatBinary.php b/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/Binary/ConcatBinary.php new file mode 100644 index 00000000..f825ab87 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/Binary/ConcatBinary.php @@ -0,0 +1,23 @@ +raw('.'); + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/Binary/DivBinary.php b/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/Binary/DivBinary.php new file mode 100644 index 00000000..e3817d1c --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/Binary/DivBinary.php @@ -0,0 +1,23 @@ +raw('/'); + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/Binary/EndsWithBinary.php b/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/Binary/EndsWithBinary.php new file mode 100644 index 00000000..c3516b85 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/Binary/EndsWithBinary.php @@ -0,0 +1,35 @@ +getVarName(); + $right = $compiler->getVarName(); + $compiler + ->raw(sprintf('(is_string($%s = ', $left)) + ->subcompile($this->getNode('left')) + ->raw(sprintf(') && is_string($%s = ', $right)) + ->subcompile($this->getNode('right')) + ->raw(sprintf(') && (\'\' === $%2$s || $%2$s === substr($%1$s, -strlen($%2$s))))', $left, $right)) + ; + } + + public function operator(Compiler $compiler): Compiler + { + return $compiler->raw(''); + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/Binary/EqualBinary.php b/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/Binary/EqualBinary.php new file mode 100644 index 00000000..6b48549e --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/Binary/EqualBinary.php @@ -0,0 +1,39 @@ += 80000) { + parent::compile($compiler); + + return; + } + + $compiler + ->raw('(0 === twig_compare(') + ->subcompile($this->getNode('left')) + ->raw(', ') + ->subcompile($this->getNode('right')) + ->raw('))') + ; + } + + public function operator(Compiler $compiler): Compiler + { + return $compiler->raw('=='); + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/Binary/FloorDivBinary.php b/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/Binary/FloorDivBinary.php new file mode 100644 index 00000000..d7e7980e --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/Binary/FloorDivBinary.php @@ -0,0 +1,29 @@ +raw('(int) floor('); + parent::compile($compiler); + $compiler->raw(')'); + } + + public function operator(Compiler $compiler): Compiler + { + return $compiler->raw('/'); + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/Binary/GreaterBinary.php b/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/Binary/GreaterBinary.php new file mode 100644 index 00000000..e1dd0678 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/Binary/GreaterBinary.php @@ -0,0 +1,39 @@ += 80000) { + parent::compile($compiler); + + return; + } + + $compiler + ->raw('(1 === twig_compare(') + ->subcompile($this->getNode('left')) + ->raw(', ') + ->subcompile($this->getNode('right')) + ->raw('))') + ; + } + + public function operator(Compiler $compiler): Compiler + { + return $compiler->raw('>'); + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/Binary/GreaterEqualBinary.php b/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/Binary/GreaterEqualBinary.php new file mode 100644 index 00000000..df9bfcfb --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/Binary/GreaterEqualBinary.php @@ -0,0 +1,39 @@ += 80000) { + parent::compile($compiler); + + return; + } + + $compiler + ->raw('(0 <= twig_compare(') + ->subcompile($this->getNode('left')) + ->raw(', ') + ->subcompile($this->getNode('right')) + ->raw('))') + ; + } + + public function operator(Compiler $compiler): Compiler + { + return $compiler->raw('>='); + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/Binary/InBinary.php b/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/Binary/InBinary.php new file mode 100644 index 00000000..6dbfa97f --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/Binary/InBinary.php @@ -0,0 +1,33 @@ +raw('twig_in_filter(') + ->subcompile($this->getNode('left')) + ->raw(', ') + ->subcompile($this->getNode('right')) + ->raw(')') + ; + } + + public function operator(Compiler $compiler): Compiler + { + return $compiler->raw('in'); + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/Binary/LessBinary.php b/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/Binary/LessBinary.php new file mode 100644 index 00000000..598e6291 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/Binary/LessBinary.php @@ -0,0 +1,39 @@ += 80000) { + parent::compile($compiler); + + return; + } + + $compiler + ->raw('(-1 === twig_compare(') + ->subcompile($this->getNode('left')) + ->raw(', ') + ->subcompile($this->getNode('right')) + ->raw('))') + ; + } + + public function operator(Compiler $compiler): Compiler + { + return $compiler->raw('<'); + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/Binary/LessEqualBinary.php b/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/Binary/LessEqualBinary.php new file mode 100644 index 00000000..e3c4af58 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/Binary/LessEqualBinary.php @@ -0,0 +1,39 @@ += 80000) { + parent::compile($compiler); + + return; + } + + $compiler + ->raw('(0 >= twig_compare(') + ->subcompile($this->getNode('left')) + ->raw(', ') + ->subcompile($this->getNode('right')) + ->raw('))') + ; + } + + public function operator(Compiler $compiler): Compiler + { + return $compiler->raw('<='); + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/Binary/MatchesBinary.php b/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/Binary/MatchesBinary.php new file mode 100644 index 00000000..bc97292c --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/Binary/MatchesBinary.php @@ -0,0 +1,33 @@ +raw('preg_match(') + ->subcompile($this->getNode('right')) + ->raw(', ') + ->subcompile($this->getNode('left')) + ->raw(')') + ; + } + + public function operator(Compiler $compiler): Compiler + { + return $compiler->raw(''); + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/Binary/ModBinary.php b/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/Binary/ModBinary.php new file mode 100644 index 00000000..271b45ca --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/Binary/ModBinary.php @@ -0,0 +1,23 @@ +raw('%'); + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/Binary/MulBinary.php b/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/Binary/MulBinary.php new file mode 100644 index 00000000..6d4c1e0b --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/Binary/MulBinary.php @@ -0,0 +1,23 @@ +raw('*'); + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/Binary/NotEqualBinary.php b/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/Binary/NotEqualBinary.php new file mode 100644 index 00000000..db47a289 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/Binary/NotEqualBinary.php @@ -0,0 +1,39 @@ += 80000) { + parent::compile($compiler); + + return; + } + + $compiler + ->raw('(0 !== twig_compare(') + ->subcompile($this->getNode('left')) + ->raw(', ') + ->subcompile($this->getNode('right')) + ->raw('))') + ; + } + + public function operator(Compiler $compiler): Compiler + { + return $compiler->raw('!='); + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/Binary/NotInBinary.php b/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/Binary/NotInBinary.php new file mode 100644 index 00000000..fcba6cca --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/Binary/NotInBinary.php @@ -0,0 +1,33 @@ +raw('!twig_in_filter(') + ->subcompile($this->getNode('left')) + ->raw(', ') + ->subcompile($this->getNode('right')) + ->raw(')') + ; + } + + public function operator(Compiler $compiler): Compiler + { + return $compiler->raw('not in'); + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/Binary/OrBinary.php b/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/Binary/OrBinary.php new file mode 100644 index 00000000..21f87c91 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/Binary/OrBinary.php @@ -0,0 +1,23 @@ +raw('||'); + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/Binary/PowerBinary.php b/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/Binary/PowerBinary.php new file mode 100644 index 00000000..c9f4c669 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/Binary/PowerBinary.php @@ -0,0 +1,22 @@ +raw('**'); + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/Binary/RangeBinary.php b/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/Binary/RangeBinary.php new file mode 100644 index 00000000..55982c81 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/Binary/RangeBinary.php @@ -0,0 +1,33 @@ +raw('range(') + ->subcompile($this->getNode('left')) + ->raw(', ') + ->subcompile($this->getNode('right')) + ->raw(')') + ; + } + + public function operator(Compiler $compiler): Compiler + { + return $compiler->raw('..'); + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/Binary/SpaceshipBinary.php b/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/Binary/SpaceshipBinary.php new file mode 100644 index 00000000..ae5a4a49 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/Binary/SpaceshipBinary.php @@ -0,0 +1,22 @@ +raw('<=>'); + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/Binary/StartsWithBinary.php b/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/Binary/StartsWithBinary.php new file mode 100644 index 00000000..d0df1c4b --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/Binary/StartsWithBinary.php @@ -0,0 +1,35 @@ +getVarName(); + $right = $compiler->getVarName(); + $compiler + ->raw(sprintf('(is_string($%s = ', $left)) + ->subcompile($this->getNode('left')) + ->raw(sprintf(') && is_string($%s = ', $right)) + ->subcompile($this->getNode('right')) + ->raw(sprintf(') && (\'\' === $%2$s || 0 === strpos($%1$s, $%2$s)))', $left, $right)) + ; + } + + public function operator(Compiler $compiler): Compiler + { + return $compiler->raw(''); + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/Binary/SubBinary.php b/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/Binary/SubBinary.php new file mode 100644 index 00000000..eeb87fac --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/Binary/SubBinary.php @@ -0,0 +1,23 @@ +raw('-'); + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/BlockReferenceExpression.php b/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/BlockReferenceExpression.php new file mode 100644 index 00000000..b1e2a8f7 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/BlockReferenceExpression.php @@ -0,0 +1,86 @@ + + */ +class BlockReferenceExpression extends AbstractExpression +{ + public function __construct(Node $name, ?Node $template, int $lineno, string $tag = null) + { + $nodes = ['name' => $name]; + if (null !== $template) { + $nodes['template'] = $template; + } + + parent::__construct($nodes, ['is_defined_test' => false, 'output' => false], $lineno, $tag); + } + + public function compile(Compiler $compiler): void + { + if ($this->getAttribute('is_defined_test')) { + $this->compileTemplateCall($compiler, 'hasBlock'); + } else { + if ($this->getAttribute('output')) { + $compiler->addDebugInfo($this); + + $this + ->compileTemplateCall($compiler, 'displayBlock') + ->raw(";\n"); + } else { + $this->compileTemplateCall($compiler, 'renderBlock'); + } + } + } + + private function compileTemplateCall(Compiler $compiler, string $method): Compiler + { + if (!$this->hasNode('template')) { + $compiler->write('$this'); + } else { + $compiler + ->write('$this->loadTemplate(') + ->subcompile($this->getNode('template')) + ->raw(', ') + ->repr($this->getTemplateName()) + ->raw(', ') + ->repr($this->getTemplateLine()) + ->raw(')') + ; + } + + $compiler->raw(sprintf('->%s', $method)); + + return $this->compileBlockArguments($compiler); + } + + private function compileBlockArguments(Compiler $compiler): Compiler + { + $compiler + ->raw('(') + ->subcompile($this->getNode('name')) + ->raw(', $context'); + + if (!$this->hasNode('template')) { + $compiler->raw(', $blocks'); + } + + return $compiler->raw(')'); + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/CallExpression.php b/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/CallExpression.php new file mode 100644 index 00000000..fdf92a8e --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/CallExpression.php @@ -0,0 +1,320 @@ +getAttribute('callable'); + + $closingParenthesis = false; + $isArray = false; + if (\is_string($callable) && false === strpos($callable, '::')) { + $compiler->raw($callable); + } else { + list($r, $callable) = $this->reflectCallable($callable); + if ($r instanceof \ReflectionMethod && \is_string($callable[0])) { + if ($r->isStatic()) { + $compiler->raw(sprintf('%s::%s', $callable[0], $callable[1])); + } else { + $compiler->raw(sprintf('$this->env->getRuntime(\'%s\')->%s', $callable[0], $callable[1])); + } + } elseif ($r instanceof \ReflectionMethod && $callable[0] instanceof ExtensionInterface) { + $class = \get_class($callable[0]); + if (!$compiler->getEnvironment()->hasExtension($class)) { + // Compile a non-optimized call to trigger a \Twig\Error\RuntimeError, which cannot be a compile-time error + $compiler->raw(sprintf('$this->env->getExtension(\'%s\')', $class)); + } else { + $compiler->raw(sprintf('$this->extensions[\'%s\']', ltrim($class, '\\'))); + } + + $compiler->raw(sprintf('->%s', $callable[1])); + } else { + $closingParenthesis = true; + $isArray = true; + $compiler->raw(sprintf('call_user_func_array($this->env->get%s(\'%s\')->getCallable(), ', ucfirst($this->getAttribute('type')), $this->getAttribute('name'))); + } + } + + $this->compileArguments($compiler, $isArray); + + if ($closingParenthesis) { + $compiler->raw(')'); + } + } + + protected function compileArguments(Compiler $compiler, $isArray = false): void + { + $compiler->raw($isArray ? '[' : '('); + + $first = true; + + if ($this->hasAttribute('needs_environment') && $this->getAttribute('needs_environment')) { + $compiler->raw('$this->env'); + $first = false; + } + + if ($this->hasAttribute('needs_context') && $this->getAttribute('needs_context')) { + if (!$first) { + $compiler->raw(', '); + } + $compiler->raw('$context'); + $first = false; + } + + if ($this->hasAttribute('arguments')) { + foreach ($this->getAttribute('arguments') as $argument) { + if (!$first) { + $compiler->raw(', '); + } + $compiler->string($argument); + $first = false; + } + } + + if ($this->hasNode('node')) { + if (!$first) { + $compiler->raw(', '); + } + $compiler->subcompile($this->getNode('node')); + $first = false; + } + + if ($this->hasNode('arguments')) { + $callable = $this->getAttribute('callable'); + $arguments = $this->getArguments($callable, $this->getNode('arguments')); + foreach ($arguments as $node) { + if (!$first) { + $compiler->raw(', '); + } + $compiler->subcompile($node); + $first = false; + } + } + + $compiler->raw($isArray ? ']' : ')'); + } + + protected function getArguments($callable, $arguments) + { + $callType = $this->getAttribute('type'); + $callName = $this->getAttribute('name'); + + $parameters = []; + $named = false; + foreach ($arguments as $name => $node) { + if (!\is_int($name)) { + $named = true; + $name = $this->normalizeName($name); + } elseif ($named) { + throw new SyntaxError(sprintf('Positional arguments cannot be used after named arguments for %s "%s".', $callType, $callName), $this->getTemplateLine(), $this->getSourceContext()); + } + + $parameters[$name] = $node; + } + + $isVariadic = $this->hasAttribute('is_variadic') && $this->getAttribute('is_variadic'); + if (!$named && !$isVariadic) { + return $parameters; + } + + if (!$callable) { + if ($named) { + $message = sprintf('Named arguments are not supported for %s "%s".', $callType, $callName); + } else { + $message = sprintf('Arbitrary positional arguments are not supported for %s "%s".', $callType, $callName); + } + + throw new \LogicException($message); + } + + list($callableParameters, $isPhpVariadic) = $this->getCallableParameters($callable, $isVariadic); + $arguments = []; + $names = []; + $missingArguments = []; + $optionalArguments = []; + $pos = 0; + foreach ($callableParameters as $callableParameter) { + $name = $this->normalizeName($callableParameter->name); + if (\PHP_VERSION_ID >= 80000 && 'range' === $callable) { + if ('start' === $name) { + $name = 'low'; + } elseif ('end' === $name) { + $name = 'high'; + } + } + + $names[] = $name; + + if (\array_key_exists($name, $parameters)) { + if (\array_key_exists($pos, $parameters)) { + throw new SyntaxError(sprintf('Argument "%s" is defined twice for %s "%s".', $name, $callType, $callName), $this->getTemplateLine(), $this->getSourceContext()); + } + + if (\count($missingArguments)) { + throw new SyntaxError(sprintf( + 'Argument "%s" could not be assigned for %s "%s(%s)" because it is mapped to an internal PHP function which cannot determine default value for optional argument%s "%s".', + $name, $callType, $callName, implode(', ', $names), \count($missingArguments) > 1 ? 's' : '', implode('", "', $missingArguments) + ), $this->getTemplateLine(), $this->getSourceContext()); + } + + $arguments = array_merge($arguments, $optionalArguments); + $arguments[] = $parameters[$name]; + unset($parameters[$name]); + $optionalArguments = []; + } elseif (\array_key_exists($pos, $parameters)) { + $arguments = array_merge($arguments, $optionalArguments); + $arguments[] = $parameters[$pos]; + unset($parameters[$pos]); + $optionalArguments = []; + ++$pos; + } elseif ($callableParameter->isDefaultValueAvailable()) { + $optionalArguments[] = new ConstantExpression($callableParameter->getDefaultValue(), -1); + } elseif ($callableParameter->isOptional()) { + if (empty($parameters)) { + break; + } else { + $missingArguments[] = $name; + } + } else { + throw new SyntaxError(sprintf('Value for argument "%s" is required for %s "%s".', $name, $callType, $callName), $this->getTemplateLine(), $this->getSourceContext()); + } + } + + if ($isVariadic) { + $arbitraryArguments = $isPhpVariadic ? new VariadicExpression([], -1) : new ArrayExpression([], -1); + foreach ($parameters as $key => $value) { + if (\is_int($key)) { + $arbitraryArguments->addElement($value); + } else { + $arbitraryArguments->addElement($value, new ConstantExpression($key, -1)); + } + unset($parameters[$key]); + } + + if ($arbitraryArguments->count()) { + $arguments = array_merge($arguments, $optionalArguments); + $arguments[] = $arbitraryArguments; + } + } + + if (!empty($parameters)) { + $unknownParameter = null; + foreach ($parameters as $parameter) { + if ($parameter instanceof Node) { + $unknownParameter = $parameter; + break; + } + } + + throw new SyntaxError( + sprintf( + 'Unknown argument%s "%s" for %s "%s(%s)".', + \count($parameters) > 1 ? 's' : '', implode('", "', array_keys($parameters)), $callType, $callName, implode(', ', $names) + ), + $unknownParameter ? $unknownParameter->getTemplateLine() : $this->getTemplateLine(), + $unknownParameter ? $unknownParameter->getSourceContext() : $this->getSourceContext() + ); + } + + return $arguments; + } + + protected function normalizeName(string $name): string + { + return strtolower(preg_replace(['/([A-Z]+)([A-Z][a-z])/', '/([a-z\d])([A-Z])/'], ['\\1_\\2', '\\1_\\2'], $name)); + } + + private function getCallableParameters($callable, bool $isVariadic): array + { + list($r) = $this->reflectCallable($callable); + if (null === $r) { + return [[], false]; + } + + $parameters = $r->getParameters(); + if ($this->hasNode('node')) { + array_shift($parameters); + } + if ($this->hasAttribute('needs_environment') && $this->getAttribute('needs_environment')) { + array_shift($parameters); + } + if ($this->hasAttribute('needs_context') && $this->getAttribute('needs_context')) { + array_shift($parameters); + } + if ($this->hasAttribute('arguments') && null !== $this->getAttribute('arguments')) { + foreach ($this->getAttribute('arguments') as $argument) { + array_shift($parameters); + } + } + $isPhpVariadic = false; + if ($isVariadic) { + $argument = end($parameters); + $isArray = $argument && $argument->hasType() && 'array' === $argument->getType()->getName(); + if ($isArray && $argument->isDefaultValueAvailable() && [] === $argument->getDefaultValue()) { + array_pop($parameters); + } elseif ($argument && $argument->isVariadic()) { + array_pop($parameters); + $isPhpVariadic = true; + } else { + $callableName = $r->name; + if ($r instanceof \ReflectionMethod) { + $callableName = $r->getDeclaringClass()->name.'::'.$callableName; + } + + throw new \LogicException(sprintf('The last parameter of "%s" for %s "%s" must be an array with default value, eg. "array $arg = []".', $callableName, $this->getAttribute('type'), $this->getAttribute('name'))); + } + } + + return [$parameters, $isPhpVariadic]; + } + + private function reflectCallable($callable) + { + if (null !== $this->reflector) { + return $this->reflector; + } + + if (\is_array($callable)) { + if (!method_exists($callable[0], $callable[1])) { + // __call() + return [null, []]; + } + $r = new \ReflectionMethod($callable[0], $callable[1]); + } elseif (\is_object($callable) && !$callable instanceof \Closure) { + $r = new \ReflectionObject($callable); + $r = $r->getMethod('__invoke'); + $callable = [$callable, '__invoke']; + } elseif (\is_string($callable) && false !== $pos = strpos($callable, '::')) { + $class = substr($callable, 0, $pos); + $method = substr($callable, $pos + 2); + if (!method_exists($class, $method)) { + // __staticCall() + return [null, []]; + } + $r = new \ReflectionMethod($callable); + $callable = [$class, $method]; + } else { + $r = new \ReflectionFunction($callable); + } + + return $this->reflector = [$r, $callable]; + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/ConditionalExpression.php b/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/ConditionalExpression.php new file mode 100644 index 00000000..2c7bd0a2 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/ConditionalExpression.php @@ -0,0 +1,36 @@ + $expr1, 'expr2' => $expr2, 'expr3' => $expr3], [], $lineno); + } + + public function compile(Compiler $compiler): void + { + $compiler + ->raw('((') + ->subcompile($this->getNode('expr1')) + ->raw(') ? (') + ->subcompile($this->getNode('expr2')) + ->raw(') : (') + ->subcompile($this->getNode('expr3')) + ->raw('))') + ; + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/ConstantExpression.php b/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/ConstantExpression.php new file mode 100644 index 00000000..7ddbcc6f --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/ConstantExpression.php @@ -0,0 +1,28 @@ + $value], $lineno); + } + + public function compile(Compiler $compiler): void + { + $compiler->repr($this->getAttribute('value')); + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/Filter/DefaultFilter.php b/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/Filter/DefaultFilter.php new file mode 100644 index 00000000..6a572d48 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/Filter/DefaultFilter.php @@ -0,0 +1,52 @@ + + */ +class DefaultFilter extends FilterExpression +{ + public function __construct(Node $node, ConstantExpression $filterName, Node $arguments, int $lineno, string $tag = null) + { + $default = new FilterExpression($node, new ConstantExpression('default', $node->getTemplateLine()), $arguments, $node->getTemplateLine()); + + if ('default' === $filterName->getAttribute('value') && ($node instanceof NameExpression || $node instanceof GetAttrExpression)) { + $test = new DefinedTest(clone $node, 'defined', new Node(), $node->getTemplateLine()); + $false = \count($arguments) ? $arguments->getNode(0) : new ConstantExpression('', $node->getTemplateLine()); + + $node = new ConditionalExpression($test, $default, $false, $node->getTemplateLine()); + } else { + $node = $default; + } + + parent::__construct($node, $filterName, $arguments, $lineno, $tag); + } + + public function compile(Compiler $compiler): void + { + $compiler->subcompile($this->getNode('node')); + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/FilterExpression.php b/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/FilterExpression.php new file mode 100644 index 00000000..0fc15886 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/FilterExpression.php @@ -0,0 +1,40 @@ + $node, 'filter' => $filterName, 'arguments' => $arguments], [], $lineno, $tag); + } + + public function compile(Compiler $compiler): void + { + $name = $this->getNode('filter')->getAttribute('value'); + $filter = $compiler->getEnvironment()->getFilter($name); + + $this->setAttribute('name', $name); + $this->setAttribute('type', 'filter'); + $this->setAttribute('needs_environment', $filter->needsEnvironment()); + $this->setAttribute('needs_context', $filter->needsContext()); + $this->setAttribute('arguments', $filter->getArguments()); + $this->setAttribute('callable', $filter->getCallable()); + $this->setAttribute('is_variadic', $filter->isVariadic()); + + $this->compileCallable($compiler); + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/FunctionExpression.php b/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/FunctionExpression.php new file mode 100644 index 00000000..71269775 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/FunctionExpression.php @@ -0,0 +1,43 @@ + $arguments], ['name' => $name, 'is_defined_test' => false], $lineno); + } + + public function compile(Compiler $compiler) + { + $name = $this->getAttribute('name'); + $function = $compiler->getEnvironment()->getFunction($name); + + $this->setAttribute('name', $name); + $this->setAttribute('type', 'function'); + $this->setAttribute('needs_environment', $function->needsEnvironment()); + $this->setAttribute('needs_context', $function->needsContext()); + $this->setAttribute('arguments', $function->getArguments()); + $callable = $function->getCallable(); + if ('constant' === $name && $this->getAttribute('is_defined_test')) { + $callable = 'twig_constant_is_defined'; + } + $this->setAttribute('callable', $callable); + $this->setAttribute('is_variadic', $function->isVariadic()); + + $this->compileCallable($compiler); + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/GetAttrExpression.php b/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/GetAttrExpression.php new file mode 100644 index 00000000..e6a75ce9 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/GetAttrExpression.php @@ -0,0 +1,87 @@ + $node, 'attribute' => $attribute]; + if (null !== $arguments) { + $nodes['arguments'] = $arguments; + } + + parent::__construct($nodes, ['type' => $type, 'is_defined_test' => false, 'ignore_strict_check' => false, 'optimizable' => true], $lineno); + } + + public function compile(Compiler $compiler): void + { + $env = $compiler->getEnvironment(); + + // optimize array calls + if ( + $this->getAttribute('optimizable') + && (!$env->isStrictVariables() || $this->getAttribute('ignore_strict_check')) + && !$this->getAttribute('is_defined_test') + && Template::ARRAY_CALL === $this->getAttribute('type') + ) { + $var = '$'.$compiler->getVarName(); + $compiler + ->raw('(('.$var.' = ') + ->subcompile($this->getNode('node')) + ->raw(') && is_array(') + ->raw($var) + ->raw(') || ') + ->raw($var) + ->raw(' instanceof ArrayAccess ? (') + ->raw($var) + ->raw('[') + ->subcompile($this->getNode('attribute')) + ->raw('] ?? null) : null)') + ; + + return; + } + + $compiler->raw('twig_get_attribute($this->env, $this->source, '); + + if ($this->getAttribute('ignore_strict_check')) { + $this->getNode('node')->setAttribute('ignore_strict_check', true); + } + + $compiler + ->subcompile($this->getNode('node')) + ->raw(', ') + ->subcompile($this->getNode('attribute')) + ; + + if ($this->hasNode('arguments')) { + $compiler->raw(', ')->subcompile($this->getNode('arguments')); + } else { + $compiler->raw(', []'); + } + + $compiler->raw(', ') + ->repr($this->getAttribute('type')) + ->raw(', ')->repr($this->getAttribute('is_defined_test')) + ->raw(', ')->repr($this->getAttribute('ignore_strict_check')) + ->raw(', ')->repr($env->hasExtension(SandboxExtension::class)) + ->raw(', ')->repr($this->getNode('node')->getTemplateLine()) + ->raw(')') + ; + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/InlinePrint.php b/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/InlinePrint.php new file mode 100644 index 00000000..1ad4751e --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/InlinePrint.php @@ -0,0 +1,35 @@ + $node], [], $lineno); + } + + public function compile(Compiler $compiler): void + { + $compiler + ->raw('print (') + ->subcompile($this->getNode('node')) + ->raw(')') + ; + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/MethodCallExpression.php b/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/MethodCallExpression.php new file mode 100644 index 00000000..d5ec0b6e --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/MethodCallExpression.php @@ -0,0 +1,62 @@ + $node, 'arguments' => $arguments], ['method' => $method, 'safe' => false, 'is_defined_test' => false], $lineno); + + if ($node instanceof NameExpression) { + $node->setAttribute('always_defined', true); + } + } + + public function compile(Compiler $compiler): void + { + if ($this->getAttribute('is_defined_test')) { + $compiler + ->raw('method_exists($macros[') + ->repr($this->getNode('node')->getAttribute('name')) + ->raw('], ') + ->repr($this->getAttribute('method')) + ->raw(')') + ; + + return; + } + + $compiler + ->raw('twig_call_macro($macros[') + ->repr($this->getNode('node')->getAttribute('name')) + ->raw('], ') + ->repr($this->getAttribute('method')) + ->raw(', [') + ; + $first = true; + foreach ($this->getNode('arguments')->getKeyValuePairs() as $pair) { + if (!$first) { + $compiler->raw(', '); + } + $first = false; + + $compiler->subcompile($pair['value']); + } + $compiler + ->raw('], ') + ->repr($this->getTemplateLine()) + ->raw(', $context, $this->getSourceContext())'); + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/NameExpression.php b/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/NameExpression.php new file mode 100644 index 00000000..c3563f01 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/NameExpression.php @@ -0,0 +1,97 @@ + '$this->getTemplateName()', + '_context' => '$context', + '_charset' => '$this->env->getCharset()', + ]; + + public function __construct(string $name, int $lineno) + { + parent::__construct([], ['name' => $name, 'is_defined_test' => false, 'ignore_strict_check' => false, 'always_defined' => false], $lineno); + } + + public function compile(Compiler $compiler): void + { + $name = $this->getAttribute('name'); + + $compiler->addDebugInfo($this); + + if ($this->getAttribute('is_defined_test')) { + if ($this->isSpecial()) { + $compiler->repr(true); + } elseif (\PHP_VERSION_ID >= 70400) { + $compiler + ->raw('array_key_exists(') + ->string($name) + ->raw(', $context)') + ; + } else { + $compiler + ->raw('(isset($context[') + ->string($name) + ->raw(']) || array_key_exists(') + ->string($name) + ->raw(', $context))') + ; + } + } elseif ($this->isSpecial()) { + $compiler->raw($this->specialVars[$name]); + } elseif ($this->getAttribute('always_defined')) { + $compiler + ->raw('$context[') + ->string($name) + ->raw(']') + ; + } else { + if ($this->getAttribute('ignore_strict_check') || !$compiler->getEnvironment()->isStrictVariables()) { + $compiler + ->raw('($context[') + ->string($name) + ->raw('] ?? null)') + ; + } else { + $compiler + ->raw('(isset($context[') + ->string($name) + ->raw(']) || array_key_exists(') + ->string($name) + ->raw(', $context) ? $context[') + ->string($name) + ->raw('] : (function () { throw new RuntimeError(\'Variable ') + ->string($name) + ->raw(' does not exist.\', ') + ->repr($this->lineno) + ->raw(', $this->source); })()') + ->raw(')') + ; + } + } + } + + public function isSpecial() + { + return isset($this->specialVars[$this->getAttribute('name')]); + } + + public function isSimple() + { + return !$this->isSpecial() && !$this->getAttribute('is_defined_test'); + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/NullCoalesceExpression.php b/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/NullCoalesceExpression.php new file mode 100644 index 00000000..a72bc4fc --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/NullCoalesceExpression.php @@ -0,0 +1,60 @@ +getTemplateLine()); + // for "block()", we don't need the null test as the return value is always a string + if (!$left instanceof BlockReferenceExpression) { + $test = new AndBinary( + $test, + new NotUnary(new NullTest($left, 'null', new Node(), $left->getTemplateLine()), $left->getTemplateLine()), + $left->getTemplateLine() + ); + } + + parent::__construct($test, $left, $right, $lineno); + } + + public function compile(Compiler $compiler): void + { + /* + * This optimizes only one case. PHP 7 also supports more complex expressions + * that can return null. So, for instance, if log is defined, log("foo") ?? "..." works, + * but log($a["foo"]) ?? "..." does not if $a["foo"] is not defined. More advanced + * cases might be implemented as an optimizer node visitor, but has not been done + * as benefits are probably not worth the added complexity. + */ + if ($this->getNode('expr2') instanceof NameExpression) { + $this->getNode('expr2')->setAttribute('always_defined', true); + $compiler + ->raw('((') + ->subcompile($this->getNode('expr2')) + ->raw(') ?? (') + ->subcompile($this->getNode('expr3')) + ->raw('))') + ; + } else { + parent::compile($compiler); + } + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/ParentExpression.php b/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/ParentExpression.php new file mode 100644 index 00000000..25491971 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/ParentExpression.php @@ -0,0 +1,46 @@ + + */ +class ParentExpression extends AbstractExpression +{ + public function __construct(string $name, int $lineno, string $tag = null) + { + parent::__construct([], ['output' => false, 'name' => $name], $lineno, $tag); + } + + public function compile(Compiler $compiler): void + { + if ($this->getAttribute('output')) { + $compiler + ->addDebugInfo($this) + ->write('$this->displayParentBlock(') + ->string($this->getAttribute('name')) + ->raw(", \$context, \$blocks);\n") + ; + } else { + $compiler + ->raw('$this->renderParentBlock(') + ->string($this->getAttribute('name')) + ->raw(', $context, $blocks)') + ; + } + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/TempNameExpression.php b/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/TempNameExpression.php new file mode 100644 index 00000000..004c704a --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/TempNameExpression.php @@ -0,0 +1,31 @@ + $name], $lineno); + } + + public function compile(Compiler $compiler): void + { + $compiler + ->raw('$_') + ->raw($this->getAttribute('name')) + ->raw('_') + ; + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/Test/ConstantTest.php b/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/Test/ConstantTest.php new file mode 100644 index 00000000..57e9319d --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/Test/ConstantTest.php @@ -0,0 +1,49 @@ + + */ +class ConstantTest extends TestExpression +{ + public function compile(Compiler $compiler): void + { + $compiler + ->raw('(') + ->subcompile($this->getNode('node')) + ->raw(' === constant(') + ; + + if ($this->getNode('arguments')->hasNode(1)) { + $compiler + ->raw('get_class(') + ->subcompile($this->getNode('arguments')->getNode(1)) + ->raw(')."::".') + ; + } + + $compiler + ->subcompile($this->getNode('arguments')->getNode(0)) + ->raw('))') + ; + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/Test/DefinedTest.php b/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/Test/DefinedTest.php new file mode 100644 index 00000000..3953bbbe --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/Test/DefinedTest.php @@ -0,0 +1,74 @@ + + */ +class DefinedTest extends TestExpression +{ + public function __construct(Node $node, string $name, ?Node $arguments, int $lineno) + { + if ($node instanceof NameExpression) { + $node->setAttribute('is_defined_test', true); + } elseif ($node instanceof GetAttrExpression) { + $node->setAttribute('is_defined_test', true); + $this->changeIgnoreStrictCheck($node); + } elseif ($node instanceof BlockReferenceExpression) { + $node->setAttribute('is_defined_test', true); + } elseif ($node instanceof FunctionExpression && 'constant' === $node->getAttribute('name')) { + $node->setAttribute('is_defined_test', true); + } elseif ($node instanceof ConstantExpression || $node instanceof ArrayExpression) { + $node = new ConstantExpression(true, $node->getTemplateLine()); + } elseif ($node instanceof MethodCallExpression) { + $node->setAttribute('is_defined_test', true); + } else { + throw new SyntaxError('The "defined" test only works with simple variables.', $lineno); + } + + parent::__construct($node, $name, $arguments, $lineno); + } + + private function changeIgnoreStrictCheck(GetAttrExpression $node) + { + $node->setAttribute('optimizable', false); + $node->setAttribute('ignore_strict_check', true); + + if ($node->getNode('node') instanceof GetAttrExpression) { + $this->changeIgnoreStrictCheck($node->getNode('node')); + } + } + + public function compile(Compiler $compiler): void + { + $compiler->subcompile($this->getNode('node')); + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/Test/DivisiblebyTest.php b/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/Test/DivisiblebyTest.php new file mode 100644 index 00000000..4cb3ee09 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/Test/DivisiblebyTest.php @@ -0,0 +1,36 @@ + + */ +class DivisiblebyTest extends TestExpression +{ + public function compile(Compiler $compiler): void + { + $compiler + ->raw('(0 == ') + ->subcompile($this->getNode('node')) + ->raw(' % ') + ->subcompile($this->getNode('arguments')->getNode(0)) + ->raw(')') + ; + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/Test/EvenTest.php b/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/Test/EvenTest.php new file mode 100644 index 00000000..a0e3ed62 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/Test/EvenTest.php @@ -0,0 +1,35 @@ + + */ +class EvenTest extends TestExpression +{ + public function compile(Compiler $compiler): void + { + $compiler + ->raw('(') + ->subcompile($this->getNode('node')) + ->raw(' % 2 == 0') + ->raw(')') + ; + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/Test/NullTest.php b/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/Test/NullTest.php new file mode 100644 index 00000000..45b54ae3 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/Test/NullTest.php @@ -0,0 +1,34 @@ + + */ +class NullTest extends TestExpression +{ + public function compile(Compiler $compiler): void + { + $compiler + ->raw('(null === ') + ->subcompile($this->getNode('node')) + ->raw(')') + ; + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/Test/OddTest.php b/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/Test/OddTest.php new file mode 100644 index 00000000..d56c7111 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/Test/OddTest.php @@ -0,0 +1,35 @@ + + */ +class OddTest extends TestExpression +{ + public function compile(Compiler $compiler): void + { + $compiler + ->raw('(') + ->subcompile($this->getNode('node')) + ->raw(' % 2 != 0') + ->raw(')') + ; + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/Test/SameasTest.php b/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/Test/SameasTest.php new file mode 100644 index 00000000..c96d2bc0 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/Test/SameasTest.php @@ -0,0 +1,34 @@ + + */ +class SameasTest extends TestExpression +{ + public function compile(Compiler $compiler): void + { + $compiler + ->raw('(') + ->subcompile($this->getNode('node')) + ->raw(' === ') + ->subcompile($this->getNode('arguments')->getNode(0)) + ->raw(')') + ; + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/TestExpression.php b/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/TestExpression.php new file mode 100644 index 00000000..e518bd8f --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/TestExpression.php @@ -0,0 +1,42 @@ + $node]; + if (null !== $arguments) { + $nodes['arguments'] = $arguments; + } + + parent::__construct($nodes, ['name' => $name], $lineno); + } + + public function compile(Compiler $compiler): void + { + $name = $this->getAttribute('name'); + $test = $compiler->getEnvironment()->getTest($name); + + $this->setAttribute('name', $name); + $this->setAttribute('type', 'test'); + $this->setAttribute('arguments', $test->getArguments()); + $this->setAttribute('callable', $test->getCallable()); + $this->setAttribute('is_variadic', $test->isVariadic()); + + $this->compileCallable($compiler); + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/Unary/AbstractUnary.php b/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/Unary/AbstractUnary.php new file mode 100644 index 00000000..e31e3f84 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/Unary/AbstractUnary.php @@ -0,0 +1,34 @@ + $node], [], $lineno); + } + + public function compile(Compiler $compiler): void + { + $compiler->raw(' '); + $this->operator($compiler); + $compiler->subcompile($this->getNode('node')); + } + + abstract public function operator(Compiler $compiler): Compiler; +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/Unary/NegUnary.php b/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/Unary/NegUnary.php new file mode 100644 index 00000000..dc2f2350 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/Unary/NegUnary.php @@ -0,0 +1,23 @@ +raw('-'); + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/Unary/NotUnary.php b/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/Unary/NotUnary.php new file mode 100644 index 00000000..55c11bac --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/Unary/NotUnary.php @@ -0,0 +1,23 @@ +raw('!'); + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/Unary/PosUnary.php b/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/Unary/PosUnary.php new file mode 100644 index 00000000..4b0a0620 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/Unary/PosUnary.php @@ -0,0 +1,23 @@ +raw('+'); + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/VariadicExpression.php b/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/VariadicExpression.php new file mode 100644 index 00000000..a1bdb48c --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Node/Expression/VariadicExpression.php @@ -0,0 +1,24 @@ +raw('...'); + + parent::compile($compiler); + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Node/FlushNode.php b/data/web/inc/lib/vendor/twig/twig/src/Node/FlushNode.php new file mode 100644 index 00000000..fa50a88e --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Node/FlushNode.php @@ -0,0 +1,35 @@ + + */ +class FlushNode extends Node +{ + public function __construct(int $lineno, string $tag) + { + parent::__construct([], [], $lineno, $tag); + } + + public function compile(Compiler $compiler): void + { + $compiler + ->addDebugInfo($this) + ->write("flush();\n") + ; + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Node/ForLoopNode.php b/data/web/inc/lib/vendor/twig/twig/src/Node/ForLoopNode.php new file mode 100644 index 00000000..d5ce845a --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Node/ForLoopNode.php @@ -0,0 +1,49 @@ + + */ +class ForLoopNode extends Node +{ + public function __construct(int $lineno, string $tag = null) + { + parent::__construct([], ['with_loop' => false, 'ifexpr' => false, 'else' => false], $lineno, $tag); + } + + public function compile(Compiler $compiler): void + { + if ($this->getAttribute('else')) { + $compiler->write("\$context['_iterated'] = true;\n"); + } + + if ($this->getAttribute('with_loop')) { + $compiler + ->write("++\$context['loop']['index0'];\n") + ->write("++\$context['loop']['index'];\n") + ->write("\$context['loop']['first'] = false;\n") + ->write("if (isset(\$context['loop']['length'])) {\n") + ->indent() + ->write("--\$context['loop']['revindex0'];\n") + ->write("--\$context['loop']['revindex'];\n") + ->write("\$context['loop']['last'] = 0 === \$context['loop']['revindex0'];\n") + ->outdent() + ->write("}\n") + ; + } + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Node/ForNode.php b/data/web/inc/lib/vendor/twig/twig/src/Node/ForNode.php new file mode 100644 index 00000000..04addfbf --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Node/ForNode.php @@ -0,0 +1,107 @@ + + */ +class ForNode extends Node +{ + private $loop; + + public function __construct(AssignNameExpression $keyTarget, AssignNameExpression $valueTarget, AbstractExpression $seq, ?Node $ifexpr, Node $body, ?Node $else, int $lineno, string $tag = null) + { + $body = new Node([$body, $this->loop = new ForLoopNode($lineno, $tag)]); + + $nodes = ['key_target' => $keyTarget, 'value_target' => $valueTarget, 'seq' => $seq, 'body' => $body]; + if (null !== $else) { + $nodes['else'] = $else; + } + + parent::__construct($nodes, ['with_loop' => true], $lineno, $tag); + } + + public function compile(Compiler $compiler): void + { + $compiler + ->addDebugInfo($this) + ->write("\$context['_parent'] = \$context;\n") + ->write("\$context['_seq'] = twig_ensure_traversable(") + ->subcompile($this->getNode('seq')) + ->raw(");\n") + ; + + if ($this->hasNode('else')) { + $compiler->write("\$context['_iterated'] = false;\n"); + } + + if ($this->getAttribute('with_loop')) { + $compiler + ->write("\$context['loop'] = [\n") + ->write(" 'parent' => \$context['_parent'],\n") + ->write(" 'index0' => 0,\n") + ->write(" 'index' => 1,\n") + ->write(" 'first' => true,\n") + ->write("];\n") + ->write("if (is_array(\$context['_seq']) || (is_object(\$context['_seq']) && \$context['_seq'] instanceof \Countable)) {\n") + ->indent() + ->write("\$length = count(\$context['_seq']);\n") + ->write("\$context['loop']['revindex0'] = \$length - 1;\n") + ->write("\$context['loop']['revindex'] = \$length;\n") + ->write("\$context['loop']['length'] = \$length;\n") + ->write("\$context['loop']['last'] = 1 === \$length;\n") + ->outdent() + ->write("}\n") + ; + } + + $this->loop->setAttribute('else', $this->hasNode('else')); + $this->loop->setAttribute('with_loop', $this->getAttribute('with_loop')); + + $compiler + ->write("foreach (\$context['_seq'] as ") + ->subcompile($this->getNode('key_target')) + ->raw(' => ') + ->subcompile($this->getNode('value_target')) + ->raw(") {\n") + ->indent() + ->subcompile($this->getNode('body')) + ->outdent() + ->write("}\n") + ; + + if ($this->hasNode('else')) { + $compiler + ->write("if (!\$context['_iterated']) {\n") + ->indent() + ->subcompile($this->getNode('else')) + ->outdent() + ->write("}\n") + ; + } + + $compiler->write("\$_parent = \$context['_parent'];\n"); + + // remove some "private" loop variables (needed for nested loops) + $compiler->write('unset($context[\'_seq\'], $context[\'_iterated\'], $context[\''.$this->getNode('key_target')->getAttribute('name').'\'], $context[\''.$this->getNode('value_target')->getAttribute('name').'\'], $context[\'_parent\'], $context[\'loop\']);'."\n"); + + // keep the values set in the inner context for variables defined in the outer context + $compiler->write("\$context = array_intersect_key(\$context, \$_parent) + \$_parent;\n"); + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Node/IfNode.php b/data/web/inc/lib/vendor/twig/twig/src/Node/IfNode.php new file mode 100644 index 00000000..5fa20082 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Node/IfNode.php @@ -0,0 +1,70 @@ + + */ +class IfNode extends Node +{ + public function __construct(Node $tests, ?Node $else, int $lineno, string $tag = null) + { + $nodes = ['tests' => $tests]; + if (null !== $else) { + $nodes['else'] = $else; + } + + parent::__construct($nodes, [], $lineno, $tag); + } + + public function compile(Compiler $compiler): void + { + $compiler->addDebugInfo($this); + for ($i = 0, $count = \count($this->getNode('tests')); $i < $count; $i += 2) { + if ($i > 0) { + $compiler + ->outdent() + ->write('} elseif (') + ; + } else { + $compiler + ->write('if (') + ; + } + + $compiler + ->subcompile($this->getNode('tests')->getNode($i)) + ->raw(") {\n") + ->indent() + ->subcompile($this->getNode('tests')->getNode($i + 1)) + ; + } + + if ($this->hasNode('else')) { + $compiler + ->outdent() + ->write("} else {\n") + ->indent() + ->subcompile($this->getNode('else')) + ; + } + + $compiler + ->outdent() + ->write("}\n"); + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Node/ImportNode.php b/data/web/inc/lib/vendor/twig/twig/src/Node/ImportNode.php new file mode 100644 index 00000000..5378d799 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Node/ImportNode.php @@ -0,0 +1,63 @@ + + */ +class ImportNode extends Node +{ + public function __construct(AbstractExpression $expr, AbstractExpression $var, int $lineno, string $tag = null, bool $global = true) + { + parent::__construct(['expr' => $expr, 'var' => $var], ['global' => $global], $lineno, $tag); + } + + public function compile(Compiler $compiler): void + { + $compiler + ->addDebugInfo($this) + ->write('$macros[') + ->repr($this->getNode('var')->getAttribute('name')) + ->raw('] = ') + ; + + if ($this->getAttribute('global')) { + $compiler + ->raw('$this->macros[') + ->repr($this->getNode('var')->getAttribute('name')) + ->raw('] = ') + ; + } + + if ($this->getNode('expr') instanceof NameExpression && '_self' === $this->getNode('expr')->getAttribute('name')) { + $compiler->raw('$this'); + } else { + $compiler + ->raw('$this->loadTemplate(') + ->subcompile($this->getNode('expr')) + ->raw(', ') + ->repr($this->getTemplateName()) + ->raw(', ') + ->repr($this->getTemplateLine()) + ->raw(')->unwrap()') + ; + } + + $compiler->raw(";\n"); + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Node/IncludeNode.php b/data/web/inc/lib/vendor/twig/twig/src/Node/IncludeNode.php new file mode 100644 index 00000000..d540d6b2 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Node/IncludeNode.php @@ -0,0 +1,106 @@ + + */ +class IncludeNode extends Node implements NodeOutputInterface +{ + public function __construct(AbstractExpression $expr, ?AbstractExpression $variables, bool $only, bool $ignoreMissing, int $lineno, string $tag = null) + { + $nodes = ['expr' => $expr]; + if (null !== $variables) { + $nodes['variables'] = $variables; + } + + parent::__construct($nodes, ['only' => $only, 'ignore_missing' => $ignoreMissing], $lineno, $tag); + } + + public function compile(Compiler $compiler): void + { + $compiler->addDebugInfo($this); + + if ($this->getAttribute('ignore_missing')) { + $template = $compiler->getVarName(); + + $compiler + ->write(sprintf("$%s = null;\n", $template)) + ->write("try {\n") + ->indent() + ->write(sprintf('$%s = ', $template)) + ; + + $this->addGetTemplate($compiler); + + $compiler + ->raw(";\n") + ->outdent() + ->write("} catch (LoaderError \$e) {\n") + ->indent() + ->write("// ignore missing template\n") + ->outdent() + ->write("}\n") + ->write(sprintf("if ($%s) {\n", $template)) + ->indent() + ->write(sprintf('$%s->display(', $template)) + ; + $this->addTemplateArguments($compiler); + $compiler + ->raw(");\n") + ->outdent() + ->write("}\n") + ; + } else { + $this->addGetTemplate($compiler); + $compiler->raw('->display('); + $this->addTemplateArguments($compiler); + $compiler->raw(");\n"); + } + } + + protected function addGetTemplate(Compiler $compiler) + { + $compiler + ->write('$this->loadTemplate(') + ->subcompile($this->getNode('expr')) + ->raw(', ') + ->repr($this->getTemplateName()) + ->raw(', ') + ->repr($this->getTemplateLine()) + ->raw(')') + ; + } + + protected function addTemplateArguments(Compiler $compiler) + { + if (!$this->hasNode('variables')) { + $compiler->raw(false === $this->getAttribute('only') ? '$context' : '[]'); + } elseif (false === $this->getAttribute('only')) { + $compiler + ->raw('twig_array_merge($context, ') + ->subcompile($this->getNode('variables')) + ->raw(')') + ; + } else { + $compiler->raw('twig_to_array('); + $compiler->subcompile($this->getNode('variables')); + $compiler->raw(')'); + } + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Node/MacroNode.php b/data/web/inc/lib/vendor/twig/twig/src/Node/MacroNode.php new file mode 100644 index 00000000..7f1b24d5 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Node/MacroNode.php @@ -0,0 +1,113 @@ + + */ +class MacroNode extends Node +{ + public const VARARGS_NAME = 'varargs'; + + public function __construct(string $name, Node $body, Node $arguments, int $lineno, string $tag = null) + { + foreach ($arguments as $argumentName => $argument) { + if (self::VARARGS_NAME === $argumentName) { + throw new SyntaxError(sprintf('The argument "%s" in macro "%s" cannot be defined because the variable "%s" is reserved for arbitrary arguments.', self::VARARGS_NAME, $name, self::VARARGS_NAME), $argument->getTemplateLine(), $argument->getSourceContext()); + } + } + + parent::__construct(['body' => $body, 'arguments' => $arguments], ['name' => $name], $lineno, $tag); + } + + public function compile(Compiler $compiler): void + { + $compiler + ->addDebugInfo($this) + ->write(sprintf('public function macro_%s(', $this->getAttribute('name'))) + ; + + $count = \count($this->getNode('arguments')); + $pos = 0; + foreach ($this->getNode('arguments') as $name => $default) { + $compiler + ->raw('$__'.$name.'__ = ') + ->subcompile($default) + ; + + if (++$pos < $count) { + $compiler->raw(', '); + } + } + + if ($count) { + $compiler->raw(', '); + } + + $compiler + ->raw('...$__varargs__') + ->raw(")\n") + ->write("{\n") + ->indent() + ->write("\$macros = \$this->macros;\n") + ->write("\$context = \$this->env->mergeGlobals([\n") + ->indent() + ; + + foreach ($this->getNode('arguments') as $name => $default) { + $compiler + ->write('') + ->string($name) + ->raw(' => $__'.$name.'__') + ->raw(",\n") + ; + } + + $compiler + ->write('') + ->string(self::VARARGS_NAME) + ->raw(' => ') + ; + + $compiler + ->raw("\$__varargs__,\n") + ->outdent() + ->write("]);\n\n") + ->write("\$blocks = [];\n\n") + ; + if ($compiler->getEnvironment()->isDebug()) { + $compiler->write("ob_start();\n"); + } else { + $compiler->write("ob_start(function () { return ''; });\n"); + } + $compiler + ->write("try {\n") + ->indent() + ->subcompile($this->getNode('body')) + ->raw("\n") + ->write("return ('' === \$tmp = ob_get_contents()) ? '' : new Markup(\$tmp, \$this->env->getCharset());\n") + ->outdent() + ->write("} finally {\n") + ->indent() + ->write("ob_end_clean();\n") + ->outdent() + ->write("}\n") + ->outdent() + ->write("}\n\n") + ; + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Node/ModuleNode.php b/data/web/inc/lib/vendor/twig/twig/src/Node/ModuleNode.php new file mode 100644 index 00000000..e972b6ba --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Node/ModuleNode.php @@ -0,0 +1,464 @@ + + */ +final class ModuleNode extends Node +{ + public function __construct(Node $body, ?AbstractExpression $parent, Node $blocks, Node $macros, Node $traits, $embeddedTemplates, Source $source) + { + $nodes = [ + 'body' => $body, + 'blocks' => $blocks, + 'macros' => $macros, + 'traits' => $traits, + 'display_start' => new Node(), + 'display_end' => new Node(), + 'constructor_start' => new Node(), + 'constructor_end' => new Node(), + 'class_end' => new Node(), + ]; + if (null !== $parent) { + $nodes['parent'] = $parent; + } + + // embedded templates are set as attributes so that they are only visited once by the visitors + parent::__construct($nodes, [ + 'index' => null, + 'embedded_templates' => $embeddedTemplates, + ], 1); + + // populate the template name of all node children + $this->setSourceContext($source); + } + + public function setIndex($index) + { + $this->setAttribute('index', $index); + } + + public function compile(Compiler $compiler): void + { + $this->compileTemplate($compiler); + + foreach ($this->getAttribute('embedded_templates') as $template) { + $compiler->subcompile($template); + } + } + + protected function compileTemplate(Compiler $compiler) + { + if (!$this->getAttribute('index')) { + $compiler->write('compileClassHeader($compiler); + + $this->compileConstructor($compiler); + + $this->compileGetParent($compiler); + + $this->compileDisplay($compiler); + + $compiler->subcompile($this->getNode('blocks')); + + $this->compileMacros($compiler); + + $this->compileGetTemplateName($compiler); + + $this->compileIsTraitable($compiler); + + $this->compileDebugInfo($compiler); + + $this->compileGetSourceContext($compiler); + + $this->compileClassFooter($compiler); + } + + protected function compileGetParent(Compiler $compiler) + { + if (!$this->hasNode('parent')) { + return; + } + $parent = $this->getNode('parent'); + + $compiler + ->write("protected function doGetParent(array \$context)\n", "{\n") + ->indent() + ->addDebugInfo($parent) + ->write('return ') + ; + + if ($parent instanceof ConstantExpression) { + $compiler->subcompile($parent); + } else { + $compiler + ->raw('$this->loadTemplate(') + ->subcompile($parent) + ->raw(', ') + ->repr($this->getSourceContext()->getName()) + ->raw(', ') + ->repr($parent->getTemplateLine()) + ->raw(')') + ; + } + + $compiler + ->raw(";\n") + ->outdent() + ->write("}\n\n") + ; + } + + protected function compileClassHeader(Compiler $compiler) + { + $compiler + ->write("\n\n") + ; + if (!$this->getAttribute('index')) { + $compiler + ->write("use Twig\Environment;\n") + ->write("use Twig\Error\LoaderError;\n") + ->write("use Twig\Error\RuntimeError;\n") + ->write("use Twig\Extension\SandboxExtension;\n") + ->write("use Twig\Markup;\n") + ->write("use Twig\Sandbox\SecurityError;\n") + ->write("use Twig\Sandbox\SecurityNotAllowedTagError;\n") + ->write("use Twig\Sandbox\SecurityNotAllowedFilterError;\n") + ->write("use Twig\Sandbox\SecurityNotAllowedFunctionError;\n") + ->write("use Twig\Source;\n") + ->write("use Twig\Template;\n\n") + ; + } + $compiler + // if the template name contains */, add a blank to avoid a PHP parse error + ->write('/* '.str_replace('*/', '* /', $this->getSourceContext()->getName())." */\n") + ->write('class '.$compiler->getEnvironment()->getTemplateClass($this->getSourceContext()->getName(), $this->getAttribute('index'))) + ->raw(" extends Template\n") + ->write("{\n") + ->indent() + ->write("private \$source;\n") + ->write("private \$macros = [];\n\n") + ; + } + + protected function compileConstructor(Compiler $compiler) + { + $compiler + ->write("public function __construct(Environment \$env)\n", "{\n") + ->indent() + ->subcompile($this->getNode('constructor_start')) + ->write("parent::__construct(\$env);\n\n") + ->write("\$this->source = \$this->getSourceContext();\n\n") + ; + + // parent + if (!$this->hasNode('parent')) { + $compiler->write("\$this->parent = false;\n\n"); + } + + $countTraits = \count($this->getNode('traits')); + if ($countTraits) { + // traits + foreach ($this->getNode('traits') as $i => $trait) { + $node = $trait->getNode('template'); + + $compiler + ->addDebugInfo($node) + ->write(sprintf('$_trait_%s = $this->loadTemplate(', $i)) + ->subcompile($node) + ->raw(', ') + ->repr($node->getTemplateName()) + ->raw(', ') + ->repr($node->getTemplateLine()) + ->raw(");\n") + ->write(sprintf("if (!\$_trait_%s->isTraitable()) {\n", $i)) + ->indent() + ->write("throw new RuntimeError('Template \"'.") + ->subcompile($trait->getNode('template')) + ->raw(".'\" cannot be used as a trait.', ") + ->repr($node->getTemplateLine()) + ->raw(", \$this->source);\n") + ->outdent() + ->write("}\n") + ->write(sprintf("\$_trait_%s_blocks = \$_trait_%s->getBlocks();\n\n", $i, $i)) + ; + + foreach ($trait->getNode('targets') as $key => $value) { + $compiler + ->write(sprintf('if (!isset($_trait_%s_blocks[', $i)) + ->string($key) + ->raw("])) {\n") + ->indent() + ->write("throw new RuntimeError('Block ") + ->string($key) + ->raw(' is not defined in trait ') + ->subcompile($trait->getNode('template')) + ->raw(".', ") + ->repr($node->getTemplateLine()) + ->raw(", \$this->source);\n") + ->outdent() + ->write("}\n\n") + + ->write(sprintf('$_trait_%s_blocks[', $i)) + ->subcompile($value) + ->raw(sprintf('] = $_trait_%s_blocks[', $i)) + ->string($key) + ->raw(sprintf(']; unset($_trait_%s_blocks[', $i)) + ->string($key) + ->raw("]);\n\n") + ; + } + } + + if ($countTraits > 1) { + $compiler + ->write("\$this->traits = array_merge(\n") + ->indent() + ; + + for ($i = 0; $i < $countTraits; ++$i) { + $compiler + ->write(sprintf('$_trait_%s_blocks'.($i == $countTraits - 1 ? '' : ',')."\n", $i)) + ; + } + + $compiler + ->outdent() + ->write(");\n\n") + ; + } else { + $compiler + ->write("\$this->traits = \$_trait_0_blocks;\n\n") + ; + } + + $compiler + ->write("\$this->blocks = array_merge(\n") + ->indent() + ->write("\$this->traits,\n") + ->write("[\n") + ; + } else { + $compiler + ->write("\$this->blocks = [\n") + ; + } + + // blocks + $compiler + ->indent() + ; + + foreach ($this->getNode('blocks') as $name => $node) { + $compiler + ->write(sprintf("'%s' => [\$this, 'block_%s'],\n", $name, $name)) + ; + } + + if ($countTraits) { + $compiler + ->outdent() + ->write("]\n") + ->outdent() + ->write(");\n") + ; + } else { + $compiler + ->outdent() + ->write("];\n") + ; + } + + $compiler + ->subcompile($this->getNode('constructor_end')) + ->outdent() + ->write("}\n\n") + ; + } + + protected function compileDisplay(Compiler $compiler) + { + $compiler + ->write("protected function doDisplay(array \$context, array \$blocks = [])\n", "{\n") + ->indent() + ->write("\$macros = \$this->macros;\n") + ->subcompile($this->getNode('display_start')) + ->subcompile($this->getNode('body')) + ; + + if ($this->hasNode('parent')) { + $parent = $this->getNode('parent'); + + $compiler->addDebugInfo($parent); + if ($parent instanceof ConstantExpression) { + $compiler + ->write('$this->parent = $this->loadTemplate(') + ->subcompile($parent) + ->raw(', ') + ->repr($this->getSourceContext()->getName()) + ->raw(', ') + ->repr($parent->getTemplateLine()) + ->raw(");\n") + ; + $compiler->write('$this->parent'); + } else { + $compiler->write('$this->getParent($context)'); + } + $compiler->raw("->display(\$context, array_merge(\$this->blocks, \$blocks));\n"); + } + + $compiler + ->subcompile($this->getNode('display_end')) + ->outdent() + ->write("}\n\n") + ; + } + + protected function compileClassFooter(Compiler $compiler) + { + $compiler + ->subcompile($this->getNode('class_end')) + ->outdent() + ->write("}\n") + ; + } + + protected function compileMacros(Compiler $compiler) + { + $compiler->subcompile($this->getNode('macros')); + } + + protected function compileGetTemplateName(Compiler $compiler) + { + $compiler + ->write("public function getTemplateName()\n", "{\n") + ->indent() + ->write('return ') + ->repr($this->getSourceContext()->getName()) + ->raw(";\n") + ->outdent() + ->write("}\n\n") + ; + } + + protected function compileIsTraitable(Compiler $compiler) + { + // A template can be used as a trait if: + // * it has no parent + // * it has no macros + // * it has no body + // + // Put another way, a template can be used as a trait if it + // only contains blocks and use statements. + $traitable = !$this->hasNode('parent') && 0 === \count($this->getNode('macros')); + if ($traitable) { + if ($this->getNode('body') instanceof BodyNode) { + $nodes = $this->getNode('body')->getNode(0); + } else { + $nodes = $this->getNode('body'); + } + + if (!\count($nodes)) { + $nodes = new Node([$nodes]); + } + + foreach ($nodes as $node) { + if (!\count($node)) { + continue; + } + + if ($node instanceof TextNode && ctype_space($node->getAttribute('data'))) { + continue; + } + + if ($node instanceof BlockReferenceNode) { + continue; + } + + $traitable = false; + break; + } + } + + if ($traitable) { + return; + } + + $compiler + ->write("public function isTraitable()\n", "{\n") + ->indent() + ->write(sprintf("return %s;\n", $traitable ? 'true' : 'false')) + ->outdent() + ->write("}\n\n") + ; + } + + protected function compileDebugInfo(Compiler $compiler) + { + $compiler + ->write("public function getDebugInfo()\n", "{\n") + ->indent() + ->write(sprintf("return %s;\n", str_replace("\n", '', var_export(array_reverse($compiler->getDebugInfo(), true), true)))) + ->outdent() + ->write("}\n\n") + ; + } + + protected function compileGetSourceContext(Compiler $compiler) + { + $compiler + ->write("public function getSourceContext()\n", "{\n") + ->indent() + ->write('return new Source(') + ->string($compiler->getEnvironment()->isDebug() ? $this->getSourceContext()->getCode() : '') + ->raw(', ') + ->string($this->getSourceContext()->getName()) + ->raw(', ') + ->string($this->getSourceContext()->getPath()) + ->raw(");\n") + ->outdent() + ->write("}\n") + ; + } + + protected function compileLoadTemplate(Compiler $compiler, $node, $var) + { + if ($node instanceof ConstantExpression) { + $compiler + ->write(sprintf('%s = $this->loadTemplate(', $var)) + ->subcompile($node) + ->raw(', ') + ->repr($node->getTemplateName()) + ->raw(', ') + ->repr($node->getTemplateLine()) + ->raw(");\n") + ; + } else { + throw new \LogicException('Trait templates can only be constant nodes.'); + } + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Node/Node.php b/data/web/inc/lib/vendor/twig/twig/src/Node/Node.php new file mode 100644 index 00000000..e974b497 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Node/Node.php @@ -0,0 +1,178 @@ + + */ +class Node implements \Countable, \IteratorAggregate +{ + protected $nodes; + protected $attributes; + protected $lineno; + protected $tag; + + private $name; + private $sourceContext; + + /** + * @param array $nodes An array of named nodes + * @param array $attributes An array of attributes (should not be nodes) + * @param int $lineno The line number + * @param string $tag The tag name associated with the Node + */ + public function __construct(array $nodes = [], array $attributes = [], int $lineno = 0, string $tag = null) + { + foreach ($nodes as $name => $node) { + if (!$node instanceof self) { + throw new \InvalidArgumentException(sprintf('Using "%s" for the value of node "%s" of "%s" is not supported. You must pass a \Twig\Node\Node instance.', \is_object($node) ? \get_class($node) : (null === $node ? 'null' : \gettype($node)), $name, static::class)); + } + } + $this->nodes = $nodes; + $this->attributes = $attributes; + $this->lineno = $lineno; + $this->tag = $tag; + } + + public function __toString() + { + $attributes = []; + foreach ($this->attributes as $name => $value) { + $attributes[] = sprintf('%s: %s', $name, str_replace("\n", '', var_export($value, true))); + } + + $repr = [static::class.'('.implode(', ', $attributes)]; + + if (\count($this->nodes)) { + foreach ($this->nodes as $name => $node) { + $len = \strlen($name) + 4; + $noderepr = []; + foreach (explode("\n", (string) $node) as $line) { + $noderepr[] = str_repeat(' ', $len).$line; + } + + $repr[] = sprintf(' %s: %s', $name, ltrim(implode("\n", $noderepr))); + } + + $repr[] = ')'; + } else { + $repr[0] .= ')'; + } + + return implode("\n", $repr); + } + + /** + * @return void + */ + public function compile(Compiler $compiler) + { + foreach ($this->nodes as $node) { + $node->compile($compiler); + } + } + + public function getTemplateLine(): int + { + return $this->lineno; + } + + public function getNodeTag(): ?string + { + return $this->tag; + } + + public function hasAttribute(string $name): bool + { + return \array_key_exists($name, $this->attributes); + } + + public function getAttribute(string $name) + { + if (!\array_key_exists($name, $this->attributes)) { + throw new \LogicException(sprintf('Attribute "%s" does not exist for Node "%s".', $name, static::class)); + } + + return $this->attributes[$name]; + } + + public function setAttribute(string $name, $value): void + { + $this->attributes[$name] = $value; + } + + public function removeAttribute(string $name): void + { + unset($this->attributes[$name]); + } + + public function hasNode(string $name): bool + { + return isset($this->nodes[$name]); + } + + public function getNode(string $name): self + { + if (!isset($this->nodes[$name])) { + throw new \LogicException(sprintf('Node "%s" does not exist for Node "%s".', $name, static::class)); + } + + return $this->nodes[$name]; + } + + public function setNode(string $name, self $node): void + { + $this->nodes[$name] = $node; + } + + public function removeNode(string $name): void + { + unset($this->nodes[$name]); + } + + /** + * @return int + */ + public function count() + { + return \count($this->nodes); + } + + public function getIterator(): \Traversable + { + return new \ArrayIterator($this->nodes); + } + + public function getTemplateName(): ?string + { + return $this->sourceContext ? $this->sourceContext->getName() : null; + } + + public function setSourceContext(Source $source): void + { + $this->sourceContext = $source; + foreach ($this->nodes as $node) { + $node->setSourceContext($source); + } + } + + public function getSourceContext(): ?Source + { + return $this->sourceContext; + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Node/NodeCaptureInterface.php b/data/web/inc/lib/vendor/twig/twig/src/Node/NodeCaptureInterface.php new file mode 100644 index 00000000..9fb6a0ca --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Node/NodeCaptureInterface.php @@ -0,0 +1,21 @@ + + */ +interface NodeCaptureInterface +{ +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Node/NodeOutputInterface.php b/data/web/inc/lib/vendor/twig/twig/src/Node/NodeOutputInterface.php new file mode 100644 index 00000000..5e35b406 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Node/NodeOutputInterface.php @@ -0,0 +1,21 @@ + + */ +interface NodeOutputInterface +{ +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Node/PrintNode.php b/data/web/inc/lib/vendor/twig/twig/src/Node/PrintNode.php new file mode 100644 index 00000000..60386d29 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Node/PrintNode.php @@ -0,0 +1,39 @@ + + */ +class PrintNode extends Node implements NodeOutputInterface +{ + public function __construct(AbstractExpression $expr, int $lineno, string $tag = null) + { + parent::__construct(['expr' => $expr], [], $lineno, $tag); + } + + public function compile(Compiler $compiler): void + { + $compiler + ->addDebugInfo($this) + ->write('echo ') + ->subcompile($this->getNode('expr')) + ->raw(";\n") + ; + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Node/SandboxNode.php b/data/web/inc/lib/vendor/twig/twig/src/Node/SandboxNode.php new file mode 100644 index 00000000..4d5666bf --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Node/SandboxNode.php @@ -0,0 +1,52 @@ + + */ +class SandboxNode extends Node +{ + public function __construct(Node $body, int $lineno, string $tag = null) + { + parent::__construct(['body' => $body], [], $lineno, $tag); + } + + public function compile(Compiler $compiler): void + { + $compiler + ->addDebugInfo($this) + ->write("if (!\$alreadySandboxed = \$this->sandbox->isSandboxed()) {\n") + ->indent() + ->write("\$this->sandbox->enableSandbox();\n") + ->outdent() + ->write("}\n") + ->write("try {\n") + ->indent() + ->subcompile($this->getNode('body')) + ->outdent() + ->write("} finally {\n") + ->indent() + ->write("if (!\$alreadySandboxed) {\n") + ->indent() + ->write("\$this->sandbox->disableSandbox();\n") + ->outdent() + ->write("}\n") + ->outdent() + ->write("}\n") + ; + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Node/SetNode.php b/data/web/inc/lib/vendor/twig/twig/src/Node/SetNode.php new file mode 100644 index 00000000..96b6bd8b --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Node/SetNode.php @@ -0,0 +1,105 @@ + + */ +class SetNode extends Node implements NodeCaptureInterface +{ + public function __construct(bool $capture, Node $names, Node $values, int $lineno, string $tag = null) + { + parent::__construct(['names' => $names, 'values' => $values], ['capture' => $capture, 'safe' => false], $lineno, $tag); + + /* + * Optimizes the node when capture is used for a large block of text. + * + * {% set foo %}foo{% endset %} is compiled to $context['foo'] = new Twig\Markup("foo"); + */ + if ($this->getAttribute('capture')) { + $this->setAttribute('safe', true); + + $values = $this->getNode('values'); + if ($values instanceof TextNode) { + $this->setNode('values', new ConstantExpression($values->getAttribute('data'), $values->getTemplateLine())); + $this->setAttribute('capture', false); + } + } + } + + public function compile(Compiler $compiler): void + { + $compiler->addDebugInfo($this); + + if (\count($this->getNode('names')) > 1) { + $compiler->write('list('); + foreach ($this->getNode('names') as $idx => $node) { + if ($idx) { + $compiler->raw(', '); + } + + $compiler->subcompile($node); + } + $compiler->raw(')'); + } else { + if ($this->getAttribute('capture')) { + if ($compiler->getEnvironment()->isDebug()) { + $compiler->write("ob_start();\n"); + } else { + $compiler->write("ob_start(function () { return ''; });\n"); + } + $compiler + ->subcompile($this->getNode('values')) + ; + } + + $compiler->subcompile($this->getNode('names'), false); + + if ($this->getAttribute('capture')) { + $compiler->raw(" = ('' === \$tmp = ob_get_clean()) ? '' : new Markup(\$tmp, \$this->env->getCharset())"); + } + } + + if (!$this->getAttribute('capture')) { + $compiler->raw(' = '); + + if (\count($this->getNode('names')) > 1) { + $compiler->write('['); + foreach ($this->getNode('values') as $idx => $value) { + if ($idx) { + $compiler->raw(', '); + } + + $compiler->subcompile($value); + } + $compiler->raw(']'); + } else { + if ($this->getAttribute('safe')) { + $compiler + ->raw("('' === \$tmp = ") + ->subcompile($this->getNode('values')) + ->raw(") ? '' : new Markup(\$tmp, \$this->env->getCharset())") + ; + } else { + $compiler->subcompile($this->getNode('values')); + } + } + } + + $compiler->raw(";\n"); + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Node/TextNode.php b/data/web/inc/lib/vendor/twig/twig/src/Node/TextNode.php new file mode 100644 index 00000000..d74ebe63 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Node/TextNode.php @@ -0,0 +1,38 @@ + + */ +class TextNode extends Node implements NodeOutputInterface +{ + public function __construct(string $data, int $lineno) + { + parent::__construct([], ['data' => $data], $lineno); + } + + public function compile(Compiler $compiler): void + { + $compiler + ->addDebugInfo($this) + ->write('echo ') + ->string($this->getAttribute('data')) + ->raw(";\n") + ; + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Node/WithNode.php b/data/web/inc/lib/vendor/twig/twig/src/Node/WithNode.php new file mode 100644 index 00000000..56a33449 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Node/WithNode.php @@ -0,0 +1,70 @@ + + */ +class WithNode extends Node +{ + public function __construct(Node $body, ?Node $variables, bool $only, int $lineno, string $tag = null) + { + $nodes = ['body' => $body]; + if (null !== $variables) { + $nodes['variables'] = $variables; + } + + parent::__construct($nodes, ['only' => $only], $lineno, $tag); + } + + public function compile(Compiler $compiler): void + { + $compiler->addDebugInfo($this); + + $parentContextName = $compiler->getVarName(); + + $compiler->write(sprintf("\$%s = \$context;\n", $parentContextName)); + + if ($this->hasNode('variables')) { + $node = $this->getNode('variables'); + $varsName = $compiler->getVarName(); + $compiler + ->write(sprintf('$%s = ', $varsName)) + ->subcompile($node) + ->raw(";\n") + ->write(sprintf("if (!twig_test_iterable(\$%s)) {\n", $varsName)) + ->indent() + ->write("throw new RuntimeError('Variables passed to the \"with\" tag must be a hash.', ") + ->repr($node->getTemplateLine()) + ->raw(", \$this->getSourceContext());\n") + ->outdent() + ->write("}\n") + ->write(sprintf("\$%s = twig_to_array(\$%s);\n", $varsName, $varsName)) + ; + + if ($this->getAttribute('only')) { + $compiler->write("\$context = [];\n"); + } + + $compiler->write(sprintf("\$context = \$this->env->mergeGlobals(array_merge(\$context, \$%s));\n", $varsName)); + } + + $compiler + ->subcompile($this->getNode('body')) + ->write(sprintf("\$context = \$%s;\n", $parentContextName)) + ; + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/NodeTraverser.php b/data/web/inc/lib/vendor/twig/twig/src/NodeTraverser.php new file mode 100644 index 00000000..47a2d5ca --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/NodeTraverser.php @@ -0,0 +1,76 @@ + + */ +final class NodeTraverser +{ + private $env; + private $visitors = []; + + /** + * @param NodeVisitorInterface[] $visitors + */ + public function __construct(Environment $env, array $visitors = []) + { + $this->env = $env; + foreach ($visitors as $visitor) { + $this->addVisitor($visitor); + } + } + + public function addVisitor(NodeVisitorInterface $visitor): void + { + $this->visitors[$visitor->getPriority()][] = $visitor; + } + + /** + * Traverses a node and calls the registered visitors. + */ + public function traverse(Node $node): Node + { + ksort($this->visitors); + foreach ($this->visitors as $visitors) { + foreach ($visitors as $visitor) { + $node = $this->traverseForVisitor($visitor, $node); + } + } + + return $node; + } + + private function traverseForVisitor(NodeVisitorInterface $visitor, Node $node): ?Node + { + $node = $visitor->enterNode($node, $this->env); + + foreach ($node as $k => $n) { + if (null !== $m = $this->traverseForVisitor($visitor, $n)) { + if ($m !== $n) { + $node->setNode($k, $m); + } + } else { + $node->removeNode($k); + } + } + + return $visitor->leaveNode($node, $this->env); + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/NodeVisitor/AbstractNodeVisitor.php b/data/web/inc/lib/vendor/twig/twig/src/NodeVisitor/AbstractNodeVisitor.php new file mode 100644 index 00000000..d7036ae5 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/NodeVisitor/AbstractNodeVisitor.php @@ -0,0 +1,49 @@ + + */ +abstract class AbstractNodeVisitor implements NodeVisitorInterface +{ + final public function enterNode(Node $node, Environment $env): Node + { + return $this->doEnterNode($node, $env); + } + + final public function leaveNode(Node $node, Environment $env): ?Node + { + return $this->doLeaveNode($node, $env); + } + + /** + * Called before child nodes are visited. + * + * @return Node The modified node + */ + abstract protected function doEnterNode(Node $node, Environment $env); + + /** + * Called after child nodes are visited. + * + * @return Node|null The modified node or null if the node must be removed + */ + abstract protected function doLeaveNode(Node $node, Environment $env); +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/NodeVisitor/EscaperNodeVisitor.php b/data/web/inc/lib/vendor/twig/twig/src/NodeVisitor/EscaperNodeVisitor.php new file mode 100644 index 00000000..fe56ea30 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/NodeVisitor/EscaperNodeVisitor.php @@ -0,0 +1,208 @@ + + * + * @internal + */ +final class EscaperNodeVisitor implements NodeVisitorInterface +{ + private $statusStack = []; + private $blocks = []; + private $safeAnalysis; + private $traverser; + private $defaultStrategy = false; + private $safeVars = []; + + public function __construct() + { + $this->safeAnalysis = new SafeAnalysisNodeVisitor(); + } + + public function enterNode(Node $node, Environment $env): Node + { + if ($node instanceof ModuleNode) { + if ($env->hasExtension(EscaperExtension::class) && $defaultStrategy = $env->getExtension(EscaperExtension::class)->getDefaultStrategy($node->getTemplateName())) { + $this->defaultStrategy = $defaultStrategy; + } + $this->safeVars = []; + $this->blocks = []; + } elseif ($node instanceof AutoEscapeNode) { + $this->statusStack[] = $node->getAttribute('value'); + } elseif ($node instanceof BlockNode) { + $this->statusStack[] = isset($this->blocks[$node->getAttribute('name')]) ? $this->blocks[$node->getAttribute('name')] : $this->needEscaping($env); + } elseif ($node instanceof ImportNode) { + $this->safeVars[] = $node->getNode('var')->getAttribute('name'); + } + + return $node; + } + + public function leaveNode(Node $node, Environment $env): ?Node + { + if ($node instanceof ModuleNode) { + $this->defaultStrategy = false; + $this->safeVars = []; + $this->blocks = []; + } elseif ($node instanceof FilterExpression) { + return $this->preEscapeFilterNode($node, $env); + } elseif ($node instanceof PrintNode && false !== $type = $this->needEscaping($env)) { + $expression = $node->getNode('expr'); + if ($expression instanceof ConditionalExpression && $this->shouldUnwrapConditional($expression, $env, $type)) { + return new DoNode($this->unwrapConditional($expression, $env, $type), $expression->getTemplateLine()); + } + + return $this->escapePrintNode($node, $env, $type); + } + + if ($node instanceof AutoEscapeNode || $node instanceof BlockNode) { + array_pop($this->statusStack); + } elseif ($node instanceof BlockReferenceNode) { + $this->blocks[$node->getAttribute('name')] = $this->needEscaping($env); + } + + return $node; + } + + private function shouldUnwrapConditional(ConditionalExpression $expression, Environment $env, string $type): bool + { + $expr2Safe = $this->isSafeFor($type, $expression->getNode('expr2'), $env); + $expr3Safe = $this->isSafeFor($type, $expression->getNode('expr3'), $env); + + return $expr2Safe !== $expr3Safe; + } + + private function unwrapConditional(ConditionalExpression $expression, Environment $env, string $type): ConditionalExpression + { + // convert "echo a ? b : c" to "a ? echo b : echo c" recursively + $expr2 = $expression->getNode('expr2'); + if ($expr2 instanceof ConditionalExpression && $this->shouldUnwrapConditional($expr2, $env, $type)) { + $expr2 = $this->unwrapConditional($expr2, $env, $type); + } else { + $expr2 = $this->escapeInlinePrintNode(new InlinePrint($expr2, $expr2->getTemplateLine()), $env, $type); + } + $expr3 = $expression->getNode('expr3'); + if ($expr3 instanceof ConditionalExpression && $this->shouldUnwrapConditional($expr3, $env, $type)) { + $expr3 = $this->unwrapConditional($expr3, $env, $type); + } else { + $expr3 = $this->escapeInlinePrintNode(new InlinePrint($expr3, $expr3->getTemplateLine()), $env, $type); + } + + return new ConditionalExpression($expression->getNode('expr1'), $expr2, $expr3, $expression->getTemplateLine()); + } + + private function escapeInlinePrintNode(InlinePrint $node, Environment $env, string $type): Node + { + $expression = $node->getNode('node'); + + if ($this->isSafeFor($type, $expression, $env)) { + return $node; + } + + return new InlinePrint($this->getEscaperFilter($type, $expression), $node->getTemplateLine()); + } + + private function escapePrintNode(PrintNode $node, Environment $env, string $type): Node + { + if (false === $type) { + return $node; + } + + $expression = $node->getNode('expr'); + + if ($this->isSafeFor($type, $expression, $env)) { + return $node; + } + + $class = \get_class($node); + + return new $class($this->getEscaperFilter($type, $expression), $node->getTemplateLine()); + } + + private function preEscapeFilterNode(FilterExpression $filter, Environment $env): FilterExpression + { + $name = $filter->getNode('filter')->getAttribute('value'); + + $type = $env->getFilter($name)->getPreEscape(); + if (null === $type) { + return $filter; + } + + $node = $filter->getNode('node'); + if ($this->isSafeFor($type, $node, $env)) { + return $filter; + } + + $filter->setNode('node', $this->getEscaperFilter($type, $node)); + + return $filter; + } + + private function isSafeFor(string $type, Node $expression, Environment $env): bool + { + $safe = $this->safeAnalysis->getSafe($expression); + + if (null === $safe) { + if (null === $this->traverser) { + $this->traverser = new NodeTraverser($env, [$this->safeAnalysis]); + } + + $this->safeAnalysis->setSafeVars($this->safeVars); + + $this->traverser->traverse($expression); + $safe = $this->safeAnalysis->getSafe($expression); + } + + return \in_array($type, $safe) || \in_array('all', $safe); + } + + private function needEscaping(Environment $env) + { + if (\count($this->statusStack)) { + return $this->statusStack[\count($this->statusStack) - 1]; + } + + return $this->defaultStrategy ? $this->defaultStrategy : false; + } + + private function getEscaperFilter(string $type, Node $node): FilterExpression + { + $line = $node->getTemplateLine(); + $name = new ConstantExpression('escape', $line); + $args = new Node([new ConstantExpression($type, $line), new ConstantExpression(null, $line), new ConstantExpression(true, $line)]); + + return new FilterExpression($node, $name, $args, $line); + } + + public function getPriority(): int + { + return 0; + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/NodeVisitor/MacroAutoImportNodeVisitor.php b/data/web/inc/lib/vendor/twig/twig/src/NodeVisitor/MacroAutoImportNodeVisitor.php new file mode 100644 index 00000000..af477e65 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/NodeVisitor/MacroAutoImportNodeVisitor.php @@ -0,0 +1,74 @@ + + * + * @internal + */ +final class MacroAutoImportNodeVisitor implements NodeVisitorInterface +{ + private $inAModule = false; + private $hasMacroCalls = false; + + public function enterNode(Node $node, Environment $env): Node + { + if ($node instanceof ModuleNode) { + $this->inAModule = true; + $this->hasMacroCalls = false; + } + + return $node; + } + + public function leaveNode(Node $node, Environment $env): Node + { + if ($node instanceof ModuleNode) { + $this->inAModule = false; + if ($this->hasMacroCalls) { + $node->getNode('constructor_end')->setNode('_auto_macro_import', new ImportNode(new NameExpression('_self', 0), new AssignNameExpression('_self', 0), 0, 'import', true)); + } + } elseif ($this->inAModule) { + if ( + $node instanceof GetAttrExpression && + $node->getNode('node') instanceof NameExpression && + '_self' === $node->getNode('node')->getAttribute('name') && + $node->getNode('attribute') instanceof ConstantExpression + ) { + $this->hasMacroCalls = true; + + $name = $node->getNode('attribute')->getAttribute('value'); + $node = new MethodCallExpression($node->getNode('node'), 'macro_'.$name, $node->getNode('arguments'), $node->getTemplateLine()); + $node->setAttribute('safe', true); + } + } + + return $node; + } + + public function getPriority(): int + { + // we must be ran before auto-escaping + return -10; + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/NodeVisitor/NodeVisitorInterface.php b/data/web/inc/lib/vendor/twig/twig/src/NodeVisitor/NodeVisitorInterface.php new file mode 100644 index 00000000..59e836db --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/NodeVisitor/NodeVisitorInterface.php @@ -0,0 +1,46 @@ + + */ +interface NodeVisitorInterface +{ + /** + * Called before child nodes are visited. + * + * @return Node The modified node + */ + public function enterNode(Node $node, Environment $env): Node; + + /** + * Called after child nodes are visited. + * + * @return Node|null The modified node or null if the node must be removed + */ + public function leaveNode(Node $node, Environment $env): ?Node; + + /** + * Returns the priority for this visitor. + * + * Priority should be between -10 and 10 (0 is the default). + * + * @return int The priority level + */ + public function getPriority(); +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/NodeVisitor/OptimizerNodeVisitor.php b/data/web/inc/lib/vendor/twig/twig/src/NodeVisitor/OptimizerNodeVisitor.php new file mode 100644 index 00000000..7ac75e41 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/NodeVisitor/OptimizerNodeVisitor.php @@ -0,0 +1,217 @@ + + * + * @internal + */ +final class OptimizerNodeVisitor implements NodeVisitorInterface +{ + public const OPTIMIZE_ALL = -1; + public const OPTIMIZE_NONE = 0; + public const OPTIMIZE_FOR = 2; + public const OPTIMIZE_RAW_FILTER = 4; + + private $loops = []; + private $loopsTargets = []; + private $optimizers; + + /** + * @param int $optimizers The optimizer mode + */ + public function __construct(int $optimizers = -1) + { + if ($optimizers > (self::OPTIMIZE_FOR | self::OPTIMIZE_RAW_FILTER)) { + throw new \InvalidArgumentException(sprintf('Optimizer mode "%s" is not valid.', $optimizers)); + } + + $this->optimizers = $optimizers; + } + + public function enterNode(Node $node, Environment $env): Node + { + if (self::OPTIMIZE_FOR === (self::OPTIMIZE_FOR & $this->optimizers)) { + $this->enterOptimizeFor($node, $env); + } + + return $node; + } + + public function leaveNode(Node $node, Environment $env): ?Node + { + if (self::OPTIMIZE_FOR === (self::OPTIMIZE_FOR & $this->optimizers)) { + $this->leaveOptimizeFor($node, $env); + } + + if (self::OPTIMIZE_RAW_FILTER === (self::OPTIMIZE_RAW_FILTER & $this->optimizers)) { + $node = $this->optimizeRawFilter($node, $env); + } + + $node = $this->optimizePrintNode($node, $env); + + return $node; + } + + /** + * Optimizes print nodes. + * + * It replaces: + * + * * "echo $this->render(Parent)Block()" with "$this->display(Parent)Block()" + */ + private function optimizePrintNode(Node $node, Environment $env): Node + { + if (!$node instanceof PrintNode) { + return $node; + } + + $exprNode = $node->getNode('expr'); + if ( + $exprNode instanceof BlockReferenceExpression || + $exprNode instanceof ParentExpression + ) { + $exprNode->setAttribute('output', true); + + return $exprNode; + } + + return $node; + } + + /** + * Removes "raw" filters. + */ + private function optimizeRawFilter(Node $node, Environment $env): Node + { + if ($node instanceof FilterExpression && 'raw' == $node->getNode('filter')->getAttribute('value')) { + return $node->getNode('node'); + } + + return $node; + } + + /** + * Optimizes "for" tag by removing the "loop" variable creation whenever possible. + */ + private function enterOptimizeFor(Node $node, Environment $env): void + { + if ($node instanceof ForNode) { + // disable the loop variable by default + $node->setAttribute('with_loop', false); + array_unshift($this->loops, $node); + array_unshift($this->loopsTargets, $node->getNode('value_target')->getAttribute('name')); + array_unshift($this->loopsTargets, $node->getNode('key_target')->getAttribute('name')); + } elseif (!$this->loops) { + // we are outside a loop + return; + } + + // when do we need to add the loop variable back? + + // the loop variable is referenced for the current loop + elseif ($node instanceof NameExpression && 'loop' === $node->getAttribute('name')) { + $node->setAttribute('always_defined', true); + $this->addLoopToCurrent(); + } + + // optimize access to loop targets + elseif ($node instanceof NameExpression && \in_array($node->getAttribute('name'), $this->loopsTargets)) { + $node->setAttribute('always_defined', true); + } + + // block reference + elseif ($node instanceof BlockReferenceNode || $node instanceof BlockReferenceExpression) { + $this->addLoopToCurrent(); + } + + // include without the only attribute + elseif ($node instanceof IncludeNode && !$node->getAttribute('only')) { + $this->addLoopToAll(); + } + + // include function without the with_context=false parameter + elseif ($node instanceof FunctionExpression + && 'include' === $node->getAttribute('name') + && (!$node->getNode('arguments')->hasNode('with_context') + || false !== $node->getNode('arguments')->getNode('with_context')->getAttribute('value') + ) + ) { + $this->addLoopToAll(); + } + + // the loop variable is referenced via an attribute + elseif ($node instanceof GetAttrExpression + && (!$node->getNode('attribute') instanceof ConstantExpression + || 'parent' === $node->getNode('attribute')->getAttribute('value') + ) + && (true === $this->loops[0]->getAttribute('with_loop') + || ($node->getNode('node') instanceof NameExpression + && 'loop' === $node->getNode('node')->getAttribute('name') + ) + ) + ) { + $this->addLoopToAll(); + } + } + + /** + * Optimizes "for" tag by removing the "loop" variable creation whenever possible. + */ + private function leaveOptimizeFor(Node $node, Environment $env): void + { + if ($node instanceof ForNode) { + array_shift($this->loops); + array_shift($this->loopsTargets); + array_shift($this->loopsTargets); + } + } + + private function addLoopToCurrent(): void + { + $this->loops[0]->setAttribute('with_loop', true); + } + + private function addLoopToAll(): void + { + foreach ($this->loops as $loop) { + $loop->setAttribute('with_loop', true); + } + } + + public function getPriority(): int + { + return 255; + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/NodeVisitor/SafeAnalysisNodeVisitor.php b/data/web/inc/lib/vendor/twig/twig/src/NodeVisitor/SafeAnalysisNodeVisitor.php new file mode 100644 index 00000000..90d6f2e0 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/NodeVisitor/SafeAnalysisNodeVisitor.php @@ -0,0 +1,160 @@ +safeVars = $safeVars; + } + + public function getSafe(Node $node) + { + $hash = spl_object_hash($node); + if (!isset($this->data[$hash])) { + return; + } + + foreach ($this->data[$hash] as $bucket) { + if ($bucket['key'] !== $node) { + continue; + } + + if (\in_array('html_attr', $bucket['value'])) { + $bucket['value'][] = 'html'; + } + + return $bucket['value']; + } + } + + private function setSafe(Node $node, array $safe): void + { + $hash = spl_object_hash($node); + if (isset($this->data[$hash])) { + foreach ($this->data[$hash] as &$bucket) { + if ($bucket['key'] === $node) { + $bucket['value'] = $safe; + + return; + } + } + } + $this->data[$hash][] = [ + 'key' => $node, + 'value' => $safe, + ]; + } + + public function enterNode(Node $node, Environment $env): Node + { + return $node; + } + + public function leaveNode(Node $node, Environment $env): ?Node + { + if ($node instanceof ConstantExpression) { + // constants are marked safe for all + $this->setSafe($node, ['all']); + } elseif ($node instanceof BlockReferenceExpression) { + // blocks are safe by definition + $this->setSafe($node, ['all']); + } elseif ($node instanceof ParentExpression) { + // parent block is safe by definition + $this->setSafe($node, ['all']); + } elseif ($node instanceof ConditionalExpression) { + // intersect safeness of both operands + $safe = $this->intersectSafe($this->getSafe($node->getNode('expr2')), $this->getSafe($node->getNode('expr3'))); + $this->setSafe($node, $safe); + } elseif ($node instanceof FilterExpression) { + // filter expression is safe when the filter is safe + $name = $node->getNode('filter')->getAttribute('value'); + $args = $node->getNode('arguments'); + if ($filter = $env->getFilter($name)) { + $safe = $filter->getSafe($args); + if (null === $safe) { + $safe = $this->intersectSafe($this->getSafe($node->getNode('node')), $filter->getPreservesSafety()); + } + $this->setSafe($node, $safe); + } else { + $this->setSafe($node, []); + } + } elseif ($node instanceof FunctionExpression) { + // function expression is safe when the function is safe + $name = $node->getAttribute('name'); + $args = $node->getNode('arguments'); + if ($function = $env->getFunction($name)) { + $this->setSafe($node, $function->getSafe($args)); + } else { + $this->setSafe($node, []); + } + } elseif ($node instanceof MethodCallExpression) { + if ($node->getAttribute('safe')) { + $this->setSafe($node, ['all']); + } else { + $this->setSafe($node, []); + } + } elseif ($node instanceof GetAttrExpression && $node->getNode('node') instanceof NameExpression) { + $name = $node->getNode('node')->getAttribute('name'); + if (\in_array($name, $this->safeVars)) { + $this->setSafe($node, ['all']); + } else { + $this->setSafe($node, []); + } + } else { + $this->setSafe($node, []); + } + + return $node; + } + + private function intersectSafe(array $a = null, array $b = null): array + { + if (null === $a || null === $b) { + return []; + } + + if (\in_array('all', $a)) { + return $b; + } + + if (\in_array('all', $b)) { + return $a; + } + + return array_intersect($a, $b); + } + + public function getPriority(): int + { + return 0; + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/NodeVisitor/SandboxNodeVisitor.php b/data/web/inc/lib/vendor/twig/twig/src/NodeVisitor/SandboxNodeVisitor.php new file mode 100644 index 00000000..1446cee6 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/NodeVisitor/SandboxNodeVisitor.php @@ -0,0 +1,136 @@ + + * + * @internal + */ +final class SandboxNodeVisitor implements NodeVisitorInterface +{ + private $inAModule = false; + private $tags; + private $filters; + private $functions; + private $needsToStringWrap = false; + + public function enterNode(Node $node, Environment $env): Node + { + if ($node instanceof ModuleNode) { + $this->inAModule = true; + $this->tags = []; + $this->filters = []; + $this->functions = []; + + return $node; + } elseif ($this->inAModule) { + // look for tags + if ($node->getNodeTag() && !isset($this->tags[$node->getNodeTag()])) { + $this->tags[$node->getNodeTag()] = $node; + } + + // look for filters + if ($node instanceof FilterExpression && !isset($this->filters[$node->getNode('filter')->getAttribute('value')])) { + $this->filters[$node->getNode('filter')->getAttribute('value')] = $node; + } + + // look for functions + if ($node instanceof FunctionExpression && !isset($this->functions[$node->getAttribute('name')])) { + $this->functions[$node->getAttribute('name')] = $node; + } + + // the .. operator is equivalent to the range() function + if ($node instanceof RangeBinary && !isset($this->functions['range'])) { + $this->functions['range'] = $node; + } + + if ($node instanceof PrintNode) { + $this->needsToStringWrap = true; + $this->wrapNode($node, 'expr'); + } + + if ($node instanceof SetNode && !$node->getAttribute('capture')) { + $this->needsToStringWrap = true; + } + + // wrap outer nodes that can implicitly call __toString() + if ($this->needsToStringWrap) { + if ($node instanceof ConcatBinary) { + $this->wrapNode($node, 'left'); + $this->wrapNode($node, 'right'); + } + if ($node instanceof FilterExpression) { + $this->wrapNode($node, 'node'); + $this->wrapArrayNode($node, 'arguments'); + } + if ($node instanceof FunctionExpression) { + $this->wrapArrayNode($node, 'arguments'); + } + } + } + + return $node; + } + + public function leaveNode(Node $node, Environment $env): ?Node + { + if ($node instanceof ModuleNode) { + $this->inAModule = false; + + $node->setNode('constructor_end', new Node([new CheckSecurityCallNode(), $node->getNode('constructor_end')])); + $node->setNode('class_end', new Node([new CheckSecurityNode($this->filters, $this->tags, $this->functions), $node->getNode('class_end')])); + } elseif ($this->inAModule) { + if ($node instanceof PrintNode || $node instanceof SetNode) { + $this->needsToStringWrap = false; + } + } + + return $node; + } + + private function wrapNode(Node $node, string $name): void + { + $expr = $node->getNode($name); + if ($expr instanceof NameExpression || $expr instanceof GetAttrExpression) { + $node->setNode($name, new CheckToStringNode($expr)); + } + } + + private function wrapArrayNode(Node $node, string $name): void + { + $args = $node->getNode($name); + foreach ($args as $name => $_) { + $this->wrapNode($args, $name); + } + } + + public function getPriority(): int + { + return 0; + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Parser.php b/data/web/inc/lib/vendor/twig/twig/src/Parser.php new file mode 100644 index 00000000..6103695e --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Parser.php @@ -0,0 +1,349 @@ + + */ +class Parser +{ + private $stack = []; + private $stream; + private $parent; + private $visitors; + private $expressionParser; + private $blocks; + private $blockStack; + private $macros; + private $env; + private $importedSymbols; + private $traits; + private $embeddedTemplates = []; + private $varNameSalt = 0; + + public function __construct(Environment $env) + { + $this->env = $env; + } + + public function getVarName(): string + { + return sprintf('__internal_%s', hash('sha256', __METHOD__.$this->stream->getSourceContext()->getCode().$this->varNameSalt++)); + } + + public function parse(TokenStream $stream, $test = null, bool $dropNeedle = false): ModuleNode + { + $vars = get_object_vars($this); + unset($vars['stack'], $vars['env'], $vars['handlers'], $vars['visitors'], $vars['expressionParser'], $vars['reservedMacroNames']); + $this->stack[] = $vars; + + // node visitors + if (null === $this->visitors) { + $this->visitors = $this->env->getNodeVisitors(); + } + + if (null === $this->expressionParser) { + $this->expressionParser = new ExpressionParser($this, $this->env); + } + + $this->stream = $stream; + $this->parent = null; + $this->blocks = []; + $this->macros = []; + $this->traits = []; + $this->blockStack = []; + $this->importedSymbols = [[]]; + $this->embeddedTemplates = []; + $this->varNameSalt = 0; + + try { + $body = $this->subparse($test, $dropNeedle); + + if (null !== $this->parent && null === $body = $this->filterBodyNodes($body)) { + $body = new Node(); + } + } catch (SyntaxError $e) { + if (!$e->getSourceContext()) { + $e->setSourceContext($this->stream->getSourceContext()); + } + + if (!$e->getTemplateLine()) { + $e->setTemplateLine($this->stream->getCurrent()->getLine()); + } + + throw $e; + } + + $node = new ModuleNode(new BodyNode([$body]), $this->parent, new Node($this->blocks), new Node($this->macros), new Node($this->traits), $this->embeddedTemplates, $stream->getSourceContext()); + + $traverser = new NodeTraverser($this->env, $this->visitors); + + $node = $traverser->traverse($node); + + // restore previous stack so previous parse() call can resume working + foreach (array_pop($this->stack) as $key => $val) { + $this->$key = $val; + } + + return $node; + } + + public function subparse($test, bool $dropNeedle = false): Node + { + $lineno = $this->getCurrentToken()->getLine(); + $rv = []; + while (!$this->stream->isEOF()) { + switch ($this->getCurrentToken()->getType()) { + case /* Token::TEXT_TYPE */ 0: + $token = $this->stream->next(); + $rv[] = new TextNode($token->getValue(), $token->getLine()); + break; + + case /* Token::VAR_START_TYPE */ 2: + $token = $this->stream->next(); + $expr = $this->expressionParser->parseExpression(); + $this->stream->expect(/* Token::VAR_END_TYPE */ 4); + $rv[] = new PrintNode($expr, $token->getLine()); + break; + + case /* Token::BLOCK_START_TYPE */ 1: + $this->stream->next(); + $token = $this->getCurrentToken(); + + if (/* Token::NAME_TYPE */ 5 !== $token->getType()) { + throw new SyntaxError('A block must start with a tag name.', $token->getLine(), $this->stream->getSourceContext()); + } + + if (null !== $test && $test($token)) { + if ($dropNeedle) { + $this->stream->next(); + } + + if (1 === \count($rv)) { + return $rv[0]; + } + + return new Node($rv, [], $lineno); + } + + if (!$subparser = $this->env->getTokenParser($token->getValue())) { + if (null !== $test) { + $e = new SyntaxError(sprintf('Unexpected "%s" tag', $token->getValue()), $token->getLine(), $this->stream->getSourceContext()); + + if (\is_array($test) && isset($test[0]) && $test[0] instanceof TokenParserInterface) { + $e->appendMessage(sprintf(' (expecting closing tag for the "%s" tag defined near line %s).', $test[0]->getTag(), $lineno)); + } + } else { + $e = new SyntaxError(sprintf('Unknown "%s" tag.', $token->getValue()), $token->getLine(), $this->stream->getSourceContext()); + $e->addSuggestions($token->getValue(), array_keys($this->env->getTokenParsers())); + } + + throw $e; + } + + $this->stream->next(); + + $subparser->setParser($this); + $node = $subparser->parse($token); + if (null !== $node) { + $rv[] = $node; + } + break; + + default: + throw new SyntaxError('Lexer or parser ended up in unsupported state.', $this->getCurrentToken()->getLine(), $this->stream->getSourceContext()); + } + } + + if (1 === \count($rv)) { + return $rv[0]; + } + + return new Node($rv, [], $lineno); + } + + public function getBlockStack(): array + { + return $this->blockStack; + } + + public function peekBlockStack() + { + return $this->blockStack[\count($this->blockStack) - 1] ?? null; + } + + public function popBlockStack(): void + { + array_pop($this->blockStack); + } + + public function pushBlockStack($name): void + { + $this->blockStack[] = $name; + } + + public function hasBlock(string $name): bool + { + return isset($this->blocks[$name]); + } + + public function getBlock(string $name): Node + { + return $this->blocks[$name]; + } + + public function setBlock(string $name, BlockNode $value): void + { + $this->blocks[$name] = new BodyNode([$value], [], $value->getTemplateLine()); + } + + public function hasMacro(string $name): bool + { + return isset($this->macros[$name]); + } + + public function setMacro(string $name, MacroNode $node): void + { + $this->macros[$name] = $node; + } + + public function addTrait($trait): void + { + $this->traits[] = $trait; + } + + public function hasTraits(): bool + { + return \count($this->traits) > 0; + } + + public function embedTemplate(ModuleNode $template) + { + $template->setIndex(mt_rand()); + + $this->embeddedTemplates[] = $template; + } + + public function addImportedSymbol(string $type, string $alias, string $name = null, AbstractExpression $node = null): void + { + $this->importedSymbols[0][$type][$alias] = ['name' => $name, 'node' => $node]; + } + + public function getImportedSymbol(string $type, string $alias) + { + // if the symbol does not exist in the current scope (0), try in the main/global scope (last index) + return $this->importedSymbols[0][$type][$alias] ?? ($this->importedSymbols[\count($this->importedSymbols) - 1][$type][$alias] ?? null); + } + + public function isMainScope(): bool + { + return 1 === \count($this->importedSymbols); + } + + public function pushLocalScope(): void + { + array_unshift($this->importedSymbols, []); + } + + public function popLocalScope(): void + { + array_shift($this->importedSymbols); + } + + public function getExpressionParser(): ExpressionParser + { + return $this->expressionParser; + } + + public function getParent(): ?Node + { + return $this->parent; + } + + public function setParent(?Node $parent): void + { + $this->parent = $parent; + } + + public function getStream(): TokenStream + { + return $this->stream; + } + + public function getCurrentToken(): Token + { + return $this->stream->getCurrent(); + } + + private function filterBodyNodes(Node $node, bool $nested = false): ?Node + { + // check that the body does not contain non-empty output nodes + if ( + ($node instanceof TextNode && !ctype_space($node->getAttribute('data'))) + || + (!$node instanceof TextNode && !$node instanceof BlockReferenceNode && $node instanceof NodeOutputInterface) + ) { + if (false !== strpos((string) $node, \chr(0xEF).\chr(0xBB).\chr(0xBF))) { + $t = substr($node->getAttribute('data'), 3); + if ('' === $t || ctype_space($t)) { + // bypass empty nodes starting with a BOM + return null; + } + } + + throw new SyntaxError('A template that extends another one cannot include content outside Twig blocks. Did you forget to put the content inside a {% block %} tag?', $node->getTemplateLine(), $this->stream->getSourceContext()); + } + + // bypass nodes that "capture" the output + if ($node instanceof NodeCaptureInterface) { + // a "block" tag in such a node will serve as a block definition AND be displayed in place as well + return $node; + } + + // "block" tags that are not captured (see above) are only used for defining + // the content of the block. In such a case, nesting it does not work as + // expected as the definition is not part of the default template code flow. + if ($nested && $node instanceof BlockReferenceNode) { + throw new SyntaxError('A block definition cannot be nested under non-capturing nodes.', $node->getTemplateLine(), $this->stream->getSourceContext()); + } + + if ($node instanceof NodeOutputInterface) { + return null; + } + + // here, $nested means "being at the root level of a child template" + // we need to discard the wrapping "Node" for the "body" node + $nested = $nested || Node::class !== \get_class($node); + foreach ($node as $k => $n) { + if (null !== $n && null === $this->filterBodyNodes($n, $nested)) { + $node->removeNode($k); + } + } + + return $node; + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Profiler/Dumper/BaseDumper.php b/data/web/inc/lib/vendor/twig/twig/src/Profiler/Dumper/BaseDumper.php new file mode 100644 index 00000000..4da43e47 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Profiler/Dumper/BaseDumper.php @@ -0,0 +1,63 @@ + + */ +abstract class BaseDumper +{ + private $root; + + public function dump(Profile $profile): string + { + return $this->dumpProfile($profile); + } + + abstract protected function formatTemplate(Profile $profile, $prefix): string; + + abstract protected function formatNonTemplate(Profile $profile, $prefix): string; + + abstract protected function formatTime(Profile $profile, $percent): string; + + private function dumpProfile(Profile $profile, $prefix = '', $sibling = false): string + { + if ($profile->isRoot()) { + $this->root = $profile->getDuration(); + $start = $profile->getName(); + } else { + if ($profile->isTemplate()) { + $start = $this->formatTemplate($profile, $prefix); + } else { + $start = $this->formatNonTemplate($profile, $prefix); + } + $prefix .= $sibling ? '│ ' : ' '; + } + + $percent = $this->root ? $profile->getDuration() / $this->root * 100 : 0; + + if ($profile->getDuration() * 1000 < 1) { + $str = $start."\n"; + } else { + $str = sprintf("%s %s\n", $start, $this->formatTime($profile, $percent)); + } + + $nCount = \count($profile->getProfiles()); + foreach ($profile as $i => $p) { + $str .= $this->dumpProfile($p, $prefix, $i + 1 !== $nCount); + } + + return $str; + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Profiler/Dumper/BlackfireDumper.php b/data/web/inc/lib/vendor/twig/twig/src/Profiler/Dumper/BlackfireDumper.php new file mode 100644 index 00000000..03abe0fa --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Profiler/Dumper/BlackfireDumper.php @@ -0,0 +1,72 @@ + + */ +final class BlackfireDumper +{ + public function dump(Profile $profile): string + { + $data = []; + $this->dumpProfile('main()', $profile, $data); + $this->dumpChildren('main()', $profile, $data); + + $start = sprintf('%f', microtime(true)); + $str = << $values) { + $str .= "$name//{$values['ct']} {$values['wt']} {$values['mu']} {$values['pmu']}\n"; + } + + return $str; + } + + private function dumpChildren(string $parent, Profile $profile, &$data) + { + foreach ($profile as $p) { + if ($p->isTemplate()) { + $name = $p->getTemplate(); + } else { + $name = sprintf('%s::%s(%s)', $p->getTemplate(), $p->getType(), $p->getName()); + } + $this->dumpProfile(sprintf('%s==>%s', $parent, $name), $p, $data); + $this->dumpChildren($name, $p, $data); + } + } + + private function dumpProfile(string $edge, Profile $profile, &$data) + { + if (isset($data[$edge])) { + ++$data[$edge]['ct']; + $data[$edge]['wt'] += floor($profile->getDuration() * 1000000); + $data[$edge]['mu'] += $profile->getMemoryUsage(); + $data[$edge]['pmu'] += $profile->getPeakMemoryUsage(); + } else { + $data[$edge] = [ + 'ct' => 1, + 'wt' => floor($profile->getDuration() * 1000000), + 'mu' => $profile->getMemoryUsage(), + 'pmu' => $profile->getPeakMemoryUsage(), + ]; + } + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Profiler/Dumper/HtmlDumper.php b/data/web/inc/lib/vendor/twig/twig/src/Profiler/Dumper/HtmlDumper.php new file mode 100644 index 00000000..1f2433b4 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Profiler/Dumper/HtmlDumper.php @@ -0,0 +1,47 @@ + + */ +final class HtmlDumper extends BaseDumper +{ + private static $colors = [ + 'block' => '#dfd', + 'macro' => '#ddf', + 'template' => '#ffd', + 'big' => '#d44', + ]; + + public function dump(Profile $profile): string + { + return '
    '.parent::dump($profile).'
    '; + } + + protected function formatTemplate(Profile $profile, $prefix): string + { + return sprintf('%s└ %s', $prefix, self::$colors['template'], $profile->getTemplate()); + } + + protected function formatNonTemplate(Profile $profile, $prefix): string + { + return sprintf('%s└ %s::%s(%s)', $prefix, $profile->getTemplate(), $profile->getType(), isset(self::$colors[$profile->getType()]) ? self::$colors[$profile->getType()] : 'auto', $profile->getName()); + } + + protected function formatTime(Profile $profile, $percent): string + { + return sprintf('%.2fms/%.0f%%', $percent > 20 ? self::$colors['big'] : 'auto', $profile->getDuration() * 1000, $percent); + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Profiler/Dumper/TextDumper.php b/data/web/inc/lib/vendor/twig/twig/src/Profiler/Dumper/TextDumper.php new file mode 100644 index 00000000..31561c46 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Profiler/Dumper/TextDumper.php @@ -0,0 +1,35 @@ + + */ +final class TextDumper extends BaseDumper +{ + protected function formatTemplate(Profile $profile, $prefix): string + { + return sprintf('%s└ %s', $prefix, $profile->getTemplate()); + } + + protected function formatNonTemplate(Profile $profile, $prefix): string + { + return sprintf('%s└ %s::%s(%s)', $prefix, $profile->getTemplate(), $profile->getType(), $profile->getName()); + } + + protected function formatTime(Profile $profile, $percent): string + { + return sprintf('%.2fms/%.0f%%', $profile->getDuration() * 1000, $percent); + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Profiler/Node/EnterProfileNode.php b/data/web/inc/lib/vendor/twig/twig/src/Profiler/Node/EnterProfileNode.php new file mode 100644 index 00000000..1494baf4 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Profiler/Node/EnterProfileNode.php @@ -0,0 +1,42 @@ + + */ +class EnterProfileNode extends Node +{ + public function __construct(string $extensionName, string $type, string $name, string $varName) + { + parent::__construct([], ['extension_name' => $extensionName, 'name' => $name, 'type' => $type, 'var_name' => $varName]); + } + + public function compile(Compiler $compiler): void + { + $compiler + ->write(sprintf('$%s = $this->extensions[', $this->getAttribute('var_name'))) + ->repr($this->getAttribute('extension_name')) + ->raw("];\n") + ->write(sprintf('$%s->enter($%s = new \Twig\Profiler\Profile($this->getTemplateName(), ', $this->getAttribute('var_name'), $this->getAttribute('var_name').'_prof')) + ->repr($this->getAttribute('type')) + ->raw(', ') + ->repr($this->getAttribute('name')) + ->raw("));\n\n") + ; + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Profiler/Node/LeaveProfileNode.php b/data/web/inc/lib/vendor/twig/twig/src/Profiler/Node/LeaveProfileNode.php new file mode 100644 index 00000000..94cebbaa --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Profiler/Node/LeaveProfileNode.php @@ -0,0 +1,36 @@ + + */ +class LeaveProfileNode extends Node +{ + public function __construct(string $varName) + { + parent::__construct([], ['var_name' => $varName]); + } + + public function compile(Compiler $compiler): void + { + $compiler + ->write("\n") + ->write(sprintf("\$%s->leave(\$%s);\n\n", $this->getAttribute('var_name'), $this->getAttribute('var_name').'_prof')) + ; + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Profiler/NodeVisitor/ProfilerNodeVisitor.php b/data/web/inc/lib/vendor/twig/twig/src/Profiler/NodeVisitor/ProfilerNodeVisitor.php new file mode 100644 index 00000000..bd23b208 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Profiler/NodeVisitor/ProfilerNodeVisitor.php @@ -0,0 +1,76 @@ + + */ +final class ProfilerNodeVisitor implements NodeVisitorInterface +{ + private $extensionName; + + public function __construct(string $extensionName) + { + $this->extensionName = $extensionName; + } + + public function enterNode(Node $node, Environment $env): Node + { + return $node; + } + + public function leaveNode(Node $node, Environment $env): ?Node + { + if ($node instanceof ModuleNode) { + $varName = $this->getVarName(); + $node->setNode('display_start', new Node([new EnterProfileNode($this->extensionName, Profile::TEMPLATE, $node->getTemplateName(), $varName), $node->getNode('display_start')])); + $node->setNode('display_end', new Node([new LeaveProfileNode($varName), $node->getNode('display_end')])); + } elseif ($node instanceof BlockNode) { + $varName = $this->getVarName(); + $node->setNode('body', new BodyNode([ + new EnterProfileNode($this->extensionName, Profile::BLOCK, $node->getAttribute('name'), $varName), + $node->getNode('body'), + new LeaveProfileNode($varName), + ])); + } elseif ($node instanceof MacroNode) { + $varName = $this->getVarName(); + $node->setNode('body', new BodyNode([ + new EnterProfileNode($this->extensionName, Profile::MACRO, $node->getAttribute('name'), $varName), + $node->getNode('body'), + new LeaveProfileNode($varName), + ])); + } + + return $node; + } + + private function getVarName(): string + { + return sprintf('__internal_%s', hash('sha256', $this->extensionName)); + } + + public function getPriority(): int + { + return 0; + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Profiler/Profile.php b/data/web/inc/lib/vendor/twig/twig/src/Profiler/Profile.php new file mode 100644 index 00000000..252ca9b0 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Profiler/Profile.php @@ -0,0 +1,181 @@ + + */ +final class Profile implements \IteratorAggregate, \Serializable +{ + public const ROOT = 'ROOT'; + public const BLOCK = 'block'; + public const TEMPLATE = 'template'; + public const MACRO = 'macro'; + + private $template; + private $name; + private $type; + private $starts = []; + private $ends = []; + private $profiles = []; + + public function __construct(string $template = 'main', string $type = self::ROOT, string $name = 'main') + { + $this->template = $template; + $this->type = $type; + $this->name = 0 === strpos($name, '__internal_') ? 'INTERNAL' : $name; + $this->enter(); + } + + public function getTemplate(): string + { + return $this->template; + } + + public function getType(): string + { + return $this->type; + } + + public function getName(): string + { + return $this->name; + } + + public function isRoot(): bool + { + return self::ROOT === $this->type; + } + + public function isTemplate(): bool + { + return self::TEMPLATE === $this->type; + } + + public function isBlock(): bool + { + return self::BLOCK === $this->type; + } + + public function isMacro(): bool + { + return self::MACRO === $this->type; + } + + /** + * @return Profile[] + */ + public function getProfiles(): array + { + return $this->profiles; + } + + public function addProfile(self $profile): void + { + $this->profiles[] = $profile; + } + + /** + * Returns the duration in microseconds. + */ + public function getDuration(): float + { + if ($this->isRoot() && $this->profiles) { + // for the root node with children, duration is the sum of all child durations + $duration = 0; + foreach ($this->profiles as $profile) { + $duration += $profile->getDuration(); + } + + return $duration; + } + + return isset($this->ends['wt']) && isset($this->starts['wt']) ? $this->ends['wt'] - $this->starts['wt'] : 0; + } + + /** + * Returns the memory usage in bytes. + */ + public function getMemoryUsage(): int + { + return isset($this->ends['mu']) && isset($this->starts['mu']) ? $this->ends['mu'] - $this->starts['mu'] : 0; + } + + /** + * Returns the peak memory usage in bytes. + */ + public function getPeakMemoryUsage(): int + { + return isset($this->ends['pmu']) && isset($this->starts['pmu']) ? $this->ends['pmu'] - $this->starts['pmu'] : 0; + } + + /** + * Starts the profiling. + */ + public function enter(): void + { + $this->starts = [ + 'wt' => microtime(true), + 'mu' => memory_get_usage(), + 'pmu' => memory_get_peak_usage(), + ]; + } + + /** + * Stops the profiling. + */ + public function leave(): void + { + $this->ends = [ + 'wt' => microtime(true), + 'mu' => memory_get_usage(), + 'pmu' => memory_get_peak_usage(), + ]; + } + + public function reset(): void + { + $this->starts = $this->ends = $this->profiles = []; + $this->enter(); + } + + public function getIterator(): \Traversable + { + return new \ArrayIterator($this->profiles); + } + + public function serialize(): string + { + return serialize($this->__serialize()); + } + + public function unserialize($data): void + { + $this->__unserialize(unserialize($data)); + } + + /** + * @internal + */ + public function __serialize(): array + { + return [$this->template, $this->name, $this->type, $this->starts, $this->ends, $this->profiles]; + } + + /** + * @internal + */ + public function __unserialize(array $data): void + { + list($this->template, $this->name, $this->type, $this->starts, $this->ends, $this->profiles) = $data; + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/RuntimeLoader/ContainerRuntimeLoader.php b/data/web/inc/lib/vendor/twig/twig/src/RuntimeLoader/ContainerRuntimeLoader.php new file mode 100644 index 00000000..b360d7be --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/RuntimeLoader/ContainerRuntimeLoader.php @@ -0,0 +1,37 @@ + + * @author Robin Chalas + */ +class ContainerRuntimeLoader implements RuntimeLoaderInterface +{ + private $container; + + public function __construct(ContainerInterface $container) + { + $this->container = $container; + } + + public function load(string $class) + { + return $this->container->has($class) ? $this->container->get($class) : null; + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/RuntimeLoader/FactoryRuntimeLoader.php b/data/web/inc/lib/vendor/twig/twig/src/RuntimeLoader/FactoryRuntimeLoader.php new file mode 100644 index 00000000..13064839 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/RuntimeLoader/FactoryRuntimeLoader.php @@ -0,0 +1,41 @@ + + */ +class FactoryRuntimeLoader implements RuntimeLoaderInterface +{ + private $map; + + /** + * @param array $map An array where keys are class names and values factory callables + */ + public function __construct(array $map = []) + { + $this->map = $map; + } + + public function load(string $class) + { + if (!isset($this->map[$class])) { + return null; + } + + $runtimeFactory = $this->map[$class]; + + return $runtimeFactory(); + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/RuntimeLoader/RuntimeLoaderInterface.php b/data/web/inc/lib/vendor/twig/twig/src/RuntimeLoader/RuntimeLoaderInterface.php new file mode 100644 index 00000000..9e5b2048 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/RuntimeLoader/RuntimeLoaderInterface.php @@ -0,0 +1,27 @@ + + */ +interface RuntimeLoaderInterface +{ + /** + * Creates the runtime implementation of a Twig element (filter/function/test). + * + * @return object|null The runtime instance or null if the loader does not know how to create the runtime for this class + */ + public function load(string $class); +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Sandbox/SecurityError.php b/data/web/inc/lib/vendor/twig/twig/src/Sandbox/SecurityError.php new file mode 100644 index 00000000..30a404f2 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Sandbox/SecurityError.php @@ -0,0 +1,23 @@ + + */ +class SecurityError extends Error +{ +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Sandbox/SecurityNotAllowedFilterError.php b/data/web/inc/lib/vendor/twig/twig/src/Sandbox/SecurityNotAllowedFilterError.php new file mode 100644 index 00000000..02d30636 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Sandbox/SecurityNotAllowedFilterError.php @@ -0,0 +1,33 @@ + + */ +final class SecurityNotAllowedFilterError extends SecurityError +{ + private $filterName; + + public function __construct(string $message, string $functionName) + { + parent::__construct($message); + $this->filterName = $functionName; + } + + public function getFilterName(): string + { + return $this->filterName; + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Sandbox/SecurityNotAllowedFunctionError.php b/data/web/inc/lib/vendor/twig/twig/src/Sandbox/SecurityNotAllowedFunctionError.php new file mode 100644 index 00000000..4f76dc6e --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Sandbox/SecurityNotAllowedFunctionError.php @@ -0,0 +1,33 @@ + + */ +final class SecurityNotAllowedFunctionError extends SecurityError +{ + private $functionName; + + public function __construct(string $message, string $functionName) + { + parent::__construct($message); + $this->functionName = $functionName; + } + + public function getFunctionName(): string + { + return $this->functionName; + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Sandbox/SecurityNotAllowedMethodError.php b/data/web/inc/lib/vendor/twig/twig/src/Sandbox/SecurityNotAllowedMethodError.php new file mode 100644 index 00000000..8df9d0ba --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Sandbox/SecurityNotAllowedMethodError.php @@ -0,0 +1,40 @@ + + */ +final class SecurityNotAllowedMethodError extends SecurityError +{ + private $className; + private $methodName; + + public function __construct(string $message, string $className, string $methodName) + { + parent::__construct($message); + $this->className = $className; + $this->methodName = $methodName; + } + + public function getClassName(): string + { + return $this->className; + } + + public function getMethodName() + { + return $this->methodName; + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Sandbox/SecurityNotAllowedPropertyError.php b/data/web/inc/lib/vendor/twig/twig/src/Sandbox/SecurityNotAllowedPropertyError.php new file mode 100644 index 00000000..42ec4f38 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Sandbox/SecurityNotAllowedPropertyError.php @@ -0,0 +1,40 @@ + + */ +final class SecurityNotAllowedPropertyError extends SecurityError +{ + private $className; + private $propertyName; + + public function __construct(string $message, string $className, string $propertyName) + { + parent::__construct($message); + $this->className = $className; + $this->propertyName = $propertyName; + } + + public function getClassName(): string + { + return $this->className; + } + + public function getPropertyName() + { + return $this->propertyName; + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Sandbox/SecurityNotAllowedTagError.php b/data/web/inc/lib/vendor/twig/twig/src/Sandbox/SecurityNotAllowedTagError.php new file mode 100644 index 00000000..4522150e --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Sandbox/SecurityNotAllowedTagError.php @@ -0,0 +1,33 @@ + + */ +final class SecurityNotAllowedTagError extends SecurityError +{ + private $tagName; + + public function __construct(string $message, string $tagName) + { + parent::__construct($message); + $this->tagName = $tagName; + } + + public function getTagName(): string + { + return $this->tagName; + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Sandbox/SecurityPolicy.php b/data/web/inc/lib/vendor/twig/twig/src/Sandbox/SecurityPolicy.php new file mode 100644 index 00000000..2fc0d013 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Sandbox/SecurityPolicy.php @@ -0,0 +1,126 @@ + + */ +final class SecurityPolicy implements SecurityPolicyInterface +{ + private $allowedTags; + private $allowedFilters; + private $allowedMethods; + private $allowedProperties; + private $allowedFunctions; + + public function __construct(array $allowedTags = [], array $allowedFilters = [], array $allowedMethods = [], array $allowedProperties = [], array $allowedFunctions = []) + { + $this->allowedTags = $allowedTags; + $this->allowedFilters = $allowedFilters; + $this->setAllowedMethods($allowedMethods); + $this->allowedProperties = $allowedProperties; + $this->allowedFunctions = $allowedFunctions; + } + + public function setAllowedTags(array $tags): void + { + $this->allowedTags = $tags; + } + + public function setAllowedFilters(array $filters): void + { + $this->allowedFilters = $filters; + } + + public function setAllowedMethods(array $methods): void + { + $this->allowedMethods = []; + foreach ($methods as $class => $m) { + $this->allowedMethods[$class] = array_map(function ($value) { return strtr($value, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'); }, \is_array($m) ? $m : [$m]); + } + } + + public function setAllowedProperties(array $properties): void + { + $this->allowedProperties = $properties; + } + + public function setAllowedFunctions(array $functions): void + { + $this->allowedFunctions = $functions; + } + + public function checkSecurity($tags, $filters, $functions): void + { + foreach ($tags as $tag) { + if (!\in_array($tag, $this->allowedTags)) { + throw new SecurityNotAllowedTagError(sprintf('Tag "%s" is not allowed.', $tag), $tag); + } + } + + foreach ($filters as $filter) { + if (!\in_array($filter, $this->allowedFilters)) { + throw new SecurityNotAllowedFilterError(sprintf('Filter "%s" is not allowed.', $filter), $filter); + } + } + + foreach ($functions as $function) { + if (!\in_array($function, $this->allowedFunctions)) { + throw new SecurityNotAllowedFunctionError(sprintf('Function "%s" is not allowed.', $function), $function); + } + } + } + + public function checkMethodAllowed($obj, $method): void + { + if ($obj instanceof Template || $obj instanceof Markup) { + return; + } + + $allowed = false; + $method = strtr($method, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'); + foreach ($this->allowedMethods as $class => $methods) { + if ($obj instanceof $class) { + $allowed = \in_array($method, $methods); + + break; + } + } + + if (!$allowed) { + $class = \get_class($obj); + throw new SecurityNotAllowedMethodError(sprintf('Calling "%s" method on a "%s" object is not allowed.', $method, $class), $class, $method); + } + } + + public function checkPropertyAllowed($obj, $property): void + { + $allowed = false; + foreach ($this->allowedProperties as $class => $properties) { + if ($obj instanceof $class) { + $allowed = \in_array($property, \is_array($properties) ? $properties : [$properties]); + + break; + } + } + + if (!$allowed) { + $class = \get_class($obj); + throw new SecurityNotAllowedPropertyError(sprintf('Calling "%s" property on a "%s" object is not allowed.', $property, $class), $class, $property); + } + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Sandbox/SecurityPolicyInterface.php b/data/web/inc/lib/vendor/twig/twig/src/Sandbox/SecurityPolicyInterface.php new file mode 100644 index 00000000..4cb479d5 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Sandbox/SecurityPolicyInterface.php @@ -0,0 +1,35 @@ + + */ +interface SecurityPolicyInterface +{ + /** + * @throws SecurityError + */ + public function checkSecurity($tags, $filters, $functions): void; + + /** + * @throws SecurityNotAllowedMethodError + */ + public function checkMethodAllowed($obj, $method): void; + + /** + * @throws SecurityNotAllowedPropertyError + */ + public function checkPropertyAllowed($obj, $method): void; +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Source.php b/data/web/inc/lib/vendor/twig/twig/src/Source.php new file mode 100644 index 00000000..3cb02403 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Source.php @@ -0,0 +1,51 @@ + + */ +final class Source +{ + private $code; + private $name; + private $path; + + /** + * @param string $code The template source code + * @param string $name The template logical name + * @param string $path The filesystem path of the template if any + */ + public function __construct(string $code, string $name, string $path = '') + { + $this->code = $code; + $this->name = $name; + $this->path = $path; + } + + public function getCode(): string + { + return $this->code; + } + + public function getName(): string + { + return $this->name; + } + + public function getPath(): string + { + return $this->path; + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Template.php b/data/web/inc/lib/vendor/twig/twig/src/Template.php new file mode 100644 index 00000000..e04bd04a --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Template.php @@ -0,0 +1,422 @@ +load() + * instead, which returns an instance of \Twig\TemplateWrapper. + * + * @author Fabien Potencier + * + * @internal + */ +abstract class Template +{ + public const ANY_CALL = 'any'; + public const ARRAY_CALL = 'array'; + public const METHOD_CALL = 'method'; + + protected $parent; + protected $parents = []; + protected $env; + protected $blocks = []; + protected $traits = []; + protected $extensions = []; + protected $sandbox; + + public function __construct(Environment $env) + { + $this->env = $env; + $this->extensions = $env->getExtensions(); + } + + /** + * Returns the template name. + * + * @return string The template name + */ + abstract public function getTemplateName(); + + /** + * Returns debug information about the template. + * + * @return array Debug information + */ + abstract public function getDebugInfo(); + + /** + * Returns information about the original template source code. + * + * @return Source + */ + abstract public function getSourceContext(); + + /** + * Returns the parent template. + * + * This method is for internal use only and should never be called + * directly. + * + * @return Template|TemplateWrapper|false The parent template or false if there is no parent + */ + public function getParent(array $context) + { + if (null !== $this->parent) { + return $this->parent; + } + + try { + $parent = $this->doGetParent($context); + + if (false === $parent) { + return false; + } + + if ($parent instanceof self || $parent instanceof TemplateWrapper) { + return $this->parents[$parent->getSourceContext()->getName()] = $parent; + } + + if (!isset($this->parents[$parent])) { + $this->parents[$parent] = $this->loadTemplate($parent); + } + } catch (LoaderError $e) { + $e->setSourceContext(null); + $e->guess(); + + throw $e; + } + + return $this->parents[$parent]; + } + + protected function doGetParent(array $context) + { + return false; + } + + public function isTraitable() + { + return true; + } + + /** + * Displays a parent block. + * + * This method is for internal use only and should never be called + * directly. + * + * @param string $name The block name to display from the parent + * @param array $context The context + * @param array $blocks The current set of blocks + */ + public function displayParentBlock($name, array $context, array $blocks = []) + { + if (isset($this->traits[$name])) { + $this->traits[$name][0]->displayBlock($name, $context, $blocks, false); + } elseif (false !== $parent = $this->getParent($context)) { + $parent->displayBlock($name, $context, $blocks, false); + } else { + throw new RuntimeError(sprintf('The template has no parent and no traits defining the "%s" block.', $name), -1, $this->getSourceContext()); + } + } + + /** + * Displays a block. + * + * This method is for internal use only and should never be called + * directly. + * + * @param string $name The block name to display + * @param array $context The context + * @param array $blocks The current set of blocks + * @param bool $useBlocks Whether to use the current set of blocks + */ + public function displayBlock($name, array $context, array $blocks = [], $useBlocks = true, self $templateContext = null) + { + if ($useBlocks && isset($blocks[$name])) { + $template = $blocks[$name][0]; + $block = $blocks[$name][1]; + } elseif (isset($this->blocks[$name])) { + $template = $this->blocks[$name][0]; + $block = $this->blocks[$name][1]; + } else { + $template = null; + $block = null; + } + + // avoid RCEs when sandbox is enabled + if (null !== $template && !$template instanceof self) { + throw new \LogicException('A block must be a method on a \Twig\Template instance.'); + } + + if (null !== $template) { + try { + $template->$block($context, $blocks); + } catch (Error $e) { + if (!$e->getSourceContext()) { + $e->setSourceContext($template->getSourceContext()); + } + + // this is mostly useful for \Twig\Error\LoaderError exceptions + // see \Twig\Error\LoaderError + if (-1 === $e->getTemplateLine()) { + $e->guess(); + } + + throw $e; + } catch (\Exception $e) { + $e = new RuntimeError(sprintf('An exception has been thrown during the rendering of a template ("%s").', $e->getMessage()), -1, $template->getSourceContext(), $e); + $e->guess(); + + throw $e; + } + } elseif (false !== $parent = $this->getParent($context)) { + $parent->displayBlock($name, $context, array_merge($this->blocks, $blocks), false, $templateContext ?? $this); + } elseif (isset($blocks[$name])) { + throw new RuntimeError(sprintf('Block "%s" should not call parent() in "%s" as the block does not exist in the parent template "%s".', $name, $blocks[$name][0]->getTemplateName(), $this->getTemplateName()), -1, $blocks[$name][0]->getSourceContext()); + } else { + throw new RuntimeError(sprintf('Block "%s" on template "%s" does not exist.', $name, $this->getTemplateName()), -1, ($templateContext ?? $this)->getSourceContext()); + } + } + + /** + * Renders a parent block. + * + * This method is for internal use only and should never be called + * directly. + * + * @param string $name The block name to render from the parent + * @param array $context The context + * @param array $blocks The current set of blocks + * + * @return string The rendered block + */ + public function renderParentBlock($name, array $context, array $blocks = []) + { + if ($this->env->isDebug()) { + ob_start(); + } else { + ob_start(function () { return ''; }); + } + $this->displayParentBlock($name, $context, $blocks); + + return ob_get_clean(); + } + + /** + * Renders a block. + * + * This method is for internal use only and should never be called + * directly. + * + * @param string $name The block name to render + * @param array $context The context + * @param array $blocks The current set of blocks + * @param bool $useBlocks Whether to use the current set of blocks + * + * @return string The rendered block + */ + public function renderBlock($name, array $context, array $blocks = [], $useBlocks = true) + { + if ($this->env->isDebug()) { + ob_start(); + } else { + ob_start(function () { return ''; }); + } + $this->displayBlock($name, $context, $blocks, $useBlocks); + + return ob_get_clean(); + } + + /** + * Returns whether a block exists or not in the current context of the template. + * + * This method checks blocks defined in the current template + * or defined in "used" traits or defined in parent templates. + * + * @param string $name The block name + * @param array $context The context + * @param array $blocks The current set of blocks + * + * @return bool true if the block exists, false otherwise + */ + public function hasBlock($name, array $context, array $blocks = []) + { + if (isset($blocks[$name])) { + return $blocks[$name][0] instanceof self; + } + + if (isset($this->blocks[$name])) { + return true; + } + + if (false !== $parent = $this->getParent($context)) { + return $parent->hasBlock($name, $context); + } + + return false; + } + + /** + * Returns all block names in the current context of the template. + * + * This method checks blocks defined in the current template + * or defined in "used" traits or defined in parent templates. + * + * @param array $context The context + * @param array $blocks The current set of blocks + * + * @return array An array of block names + */ + public function getBlockNames(array $context, array $blocks = []) + { + $names = array_merge(array_keys($blocks), array_keys($this->blocks)); + + if (false !== $parent = $this->getParent($context)) { + $names = array_merge($names, $parent->getBlockNames($context)); + } + + return array_unique($names); + } + + /** + * @return Template|TemplateWrapper + */ + protected function loadTemplate($template, $templateName = null, $line = null, $index = null) + { + try { + if (\is_array($template)) { + return $this->env->resolveTemplate($template); + } + + if ($template instanceof self || $template instanceof TemplateWrapper) { + return $template; + } + + if ($template === $this->getTemplateName()) { + $class = static::class; + if (false !== $pos = strrpos($class, '___', -1)) { + $class = substr($class, 0, $pos); + } + } else { + $class = $this->env->getTemplateClass($template); + } + + return $this->env->loadTemplate($class, $template, $index); + } catch (Error $e) { + if (!$e->getSourceContext()) { + $e->setSourceContext($templateName ? new Source('', $templateName) : $this->getSourceContext()); + } + + if ($e->getTemplateLine() > 0) { + throw $e; + } + + if (!$line) { + $e->guess(); + } else { + $e->setTemplateLine($line); + } + + throw $e; + } + } + + /** + * @internal + * + * @return Template + */ + public function unwrap() + { + return $this; + } + + /** + * Returns all blocks. + * + * This method is for internal use only and should never be called + * directly. + * + * @return array An array of blocks + */ + public function getBlocks() + { + return $this->blocks; + } + + public function display(array $context, array $blocks = []) + { + $this->displayWithErrorHandling($this->env->mergeGlobals($context), array_merge($this->blocks, $blocks)); + } + + public function render(array $context) + { + $level = ob_get_level(); + if ($this->env->isDebug()) { + ob_start(); + } else { + ob_start(function () { return ''; }); + } + try { + $this->display($context); + } catch (\Throwable $e) { + while (ob_get_level() > $level) { + ob_end_clean(); + } + + throw $e; + } + + return ob_get_clean(); + } + + protected function displayWithErrorHandling(array $context, array $blocks = []) + { + try { + $this->doDisplay($context, $blocks); + } catch (Error $e) { + if (!$e->getSourceContext()) { + $e->setSourceContext($this->getSourceContext()); + } + + // this is mostly useful for \Twig\Error\LoaderError exceptions + // see \Twig\Error\LoaderError + if (-1 === $e->getTemplateLine()) { + $e->guess(); + } + + throw $e; + } catch (\Exception $e) { + $e = new RuntimeError(sprintf('An exception has been thrown during the rendering of a template ("%s").', $e->getMessage()), -1, $this->getSourceContext(), $e); + $e->guess(); + + throw $e; + } + } + + /** + * Auto-generated method to display the template with the given context. + * + * @param array $context An array of parameters to pass to the template + * @param array $blocks An array of blocks to pass to the template + */ + abstract protected function doDisplay(array $context, array $blocks = []); +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/TemplateWrapper.php b/data/web/inc/lib/vendor/twig/twig/src/TemplateWrapper.php new file mode 100644 index 00000000..c9c6b07c --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/TemplateWrapper.php @@ -0,0 +1,109 @@ + + */ +final class TemplateWrapper +{ + private $env; + private $template; + + /** + * This method is for internal use only and should never be called + * directly (use Twig\Environment::load() instead). + * + * @internal + */ + public function __construct(Environment $env, Template $template) + { + $this->env = $env; + $this->template = $template; + } + + public function render(array $context = []): string + { + // using func_get_args() allows to not expose the blocks argument + // as it should only be used by internal code + return $this->template->render($context, \func_get_args()[1] ?? []); + } + + public function display(array $context = []) + { + // using func_get_args() allows to not expose the blocks argument + // as it should only be used by internal code + $this->template->display($context, \func_get_args()[1] ?? []); + } + + public function hasBlock(string $name, array $context = []): bool + { + return $this->template->hasBlock($name, $context); + } + + /** + * @return string[] An array of defined template block names + */ + public function getBlockNames(array $context = []): array + { + return $this->template->getBlockNames($context); + } + + public function renderBlock(string $name, array $context = []): string + { + $context = $this->env->mergeGlobals($context); + $level = ob_get_level(); + if ($this->env->isDebug()) { + ob_start(); + } else { + ob_start(function () { return ''; }); + } + try { + $this->template->displayBlock($name, $context); + } catch (\Throwable $e) { + while (ob_get_level() > $level) { + ob_end_clean(); + } + + throw $e; + } + + return ob_get_clean(); + } + + public function displayBlock(string $name, array $context = []) + { + $this->template->displayBlock($name, $this->env->mergeGlobals($context)); + } + + public function getSourceContext(): Source + { + return $this->template->getSourceContext(); + } + + public function getTemplateName(): string + { + return $this->template->getTemplateName(); + } + + /** + * @internal + * + * @return Template + */ + public function unwrap() + { + return $this->template; + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Test/IntegrationTestCase.php b/data/web/inc/lib/vendor/twig/twig/src/Test/IntegrationTestCase.php new file mode 100644 index 00000000..7d7d5909 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Test/IntegrationTestCase.php @@ -0,0 +1,265 @@ + + * @author Karma Dordrak + */ +abstract class IntegrationTestCase extends TestCase +{ + /** + * @return string + */ + abstract protected function getFixturesDir(); + + /** + * @return RuntimeLoaderInterface[] + */ + protected function getRuntimeLoaders() + { + return []; + } + + /** + * @return ExtensionInterface[] + */ + protected function getExtensions() + { + return []; + } + + /** + * @return TwigFilter[] + */ + protected function getTwigFilters() + { + return []; + } + + /** + * @return TwigFunction[] + */ + protected function getTwigFunctions() + { + return []; + } + + /** + * @return TwigTest[] + */ + protected function getTwigTests() + { + return []; + } + + /** + * @dataProvider getTests + */ + public function testIntegration($file, $message, $condition, $templates, $exception, $outputs, $deprecation = '') + { + $this->doIntegrationTest($file, $message, $condition, $templates, $exception, $outputs, $deprecation); + } + + /** + * @dataProvider getLegacyTests + * @group legacy + */ + public function testLegacyIntegration($file, $message, $condition, $templates, $exception, $outputs, $deprecation = '') + { + $this->doIntegrationTest($file, $message, $condition, $templates, $exception, $outputs, $deprecation); + } + + public function getTests($name, $legacyTests = false) + { + $fixturesDir = realpath($this->getFixturesDir()); + $tests = []; + + foreach (new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($fixturesDir), \RecursiveIteratorIterator::LEAVES_ONLY) as $file) { + if (!preg_match('/\.test$/', $file)) { + continue; + } + + if ($legacyTests xor false !== strpos($file->getRealpath(), '.legacy.test')) { + continue; + } + + $test = file_get_contents($file->getRealpath()); + + if (preg_match('/--TEST--\s*(.*?)\s*(?:--CONDITION--\s*(.*))?\s*(?:--DEPRECATION--\s*(.*?))?\s*((?:--TEMPLATE(?:\(.*?\))?--(?:.*?))+)\s*(?:--DATA--\s*(.*))?\s*--EXCEPTION--\s*(.*)/sx', $test, $match)) { + $message = $match[1]; + $condition = $match[2]; + $deprecation = $match[3]; + $templates = self::parseTemplates($match[4]); + $exception = $match[6]; + $outputs = [[null, $match[5], null, '']]; + } elseif (preg_match('/--TEST--\s*(.*?)\s*(?:--CONDITION--\s*(.*))?\s*(?:--DEPRECATION--\s*(.*?))?\s*((?:--TEMPLATE(?:\(.*?\))?--(?:.*?))+)--DATA--.*?--EXPECT--.*/s', $test, $match)) { + $message = $match[1]; + $condition = $match[2]; + $deprecation = $match[3]; + $templates = self::parseTemplates($match[4]); + $exception = false; + preg_match_all('/--DATA--(.*?)(?:--CONFIG--(.*?))?--EXPECT--(.*?)(?=\-\-DATA\-\-|$)/s', $test, $outputs, \PREG_SET_ORDER); + } else { + throw new \InvalidArgumentException(sprintf('Test "%s" is not valid.', str_replace($fixturesDir.'/', '', $file))); + } + + $tests[] = [str_replace($fixturesDir.'/', '', $file), $message, $condition, $templates, $exception, $outputs, $deprecation]; + } + + if ($legacyTests && empty($tests)) { + // add a dummy test to avoid a PHPUnit message + return [['not', '-', '', [], '', []]]; + } + + return $tests; + } + + public function getLegacyTests() + { + return $this->getTests('testLegacyIntegration', true); + } + + protected function doIntegrationTest($file, $message, $condition, $templates, $exception, $outputs, $deprecation = '') + { + if (!$outputs) { + $this->markTestSkipped('no tests to run'); + } + + if ($condition) { + eval('$ret = '.$condition.';'); + if (!$ret) { + $this->markTestSkipped($condition); + } + } + + $loader = new ArrayLoader($templates); + + foreach ($outputs as $i => $match) { + $config = array_merge([ + 'cache' => false, + 'strict_variables' => true, + ], $match[2] ? eval($match[2].';') : []); + $twig = new Environment($loader, $config); + $twig->addGlobal('global', 'global'); + foreach ($this->getRuntimeLoaders() as $runtimeLoader) { + $twig->addRuntimeLoader($runtimeLoader); + } + + foreach ($this->getExtensions() as $extension) { + $twig->addExtension($extension); + } + + foreach ($this->getTwigFilters() as $filter) { + $twig->addFilter($filter); + } + + foreach ($this->getTwigTests() as $test) { + $twig->addTest($test); + } + + foreach ($this->getTwigFunctions() as $function) { + $twig->addFunction($function); + } + + // avoid using the same PHP class name for different cases + $p = new \ReflectionProperty($twig, 'templateClassPrefix'); + $p->setAccessible(true); + $p->setValue($twig, '__TwigTemplate_'.hash('sha256', uniqid(mt_rand(), true), false).'_'); + + $deprecations = []; + try { + $prevHandler = set_error_handler(function ($type, $msg, $file, $line, $context = []) use (&$deprecations, &$prevHandler) { + if (\E_USER_DEPRECATED === $type) { + $deprecations[] = $msg; + + return true; + } + + return $prevHandler ? $prevHandler($type, $msg, $file, $line, $context) : false; + }); + + $template = $twig->load('index.twig'); + } catch (\Exception $e) { + if (false !== $exception) { + $message = $e->getMessage(); + $this->assertSame(trim($exception), trim(sprintf('%s: %s', \get_class($e), $message))); + $last = substr($message, \strlen($message) - 1); + $this->assertTrue('.' === $last || '?' === $last, 'Exception message must end with a dot or a question mark.'); + + return; + } + + throw new Error(sprintf('%s: %s', \get_class($e), $e->getMessage()), -1, null, $e); + } finally { + restore_error_handler(); + } + + $this->assertSame($deprecation, implode("\n", $deprecations)); + + try { + $output = trim($template->render(eval($match[1].';')), "\n "); + } catch (\Exception $e) { + if (false !== $exception) { + $this->assertSame(trim($exception), trim(sprintf('%s: %s', \get_class($e), $e->getMessage()))); + + return; + } + + $e = new Error(sprintf('%s: %s', \get_class($e), $e->getMessage()), -1, null, $e); + + $output = trim(sprintf('%s: %s', \get_class($e), $e->getMessage())); + } + + if (false !== $exception) { + list($class) = explode(':', $exception); + $constraintClass = class_exists('PHPUnit\Framework\Constraint\Exception') ? 'PHPUnit\Framework\Constraint\Exception' : 'PHPUnit_Framework_Constraint_Exception'; + $this->assertThat(null, new $constraintClass($class)); + } + + $expected = trim($match[3], "\n "); + + if ($expected !== $output) { + printf("Compiled templates that failed on case %d:\n", $i + 1); + + foreach (array_keys($templates) as $name) { + echo "Template: $name\n"; + echo $twig->compile($twig->parse($twig->tokenize($twig->getLoader()->getSourceContext($name)))); + } + } + $this->assertEquals($expected, $output, $message.' (in '.$file.')'); + } + } + + protected static function parseTemplates($test) + { + $templates = []; + preg_match_all('/--TEMPLATE(?:\((.*?)\))?--(.*?)(?=\-\-TEMPLATE|$)/s', $test, $matches, \PREG_SET_ORDER); + foreach ($matches as $match) { + $templates[($match[1] ?: 'index.twig')] = $match[2]; + } + + return $templates; + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Test/NodeTestCase.php b/data/web/inc/lib/vendor/twig/twig/src/Test/NodeTestCase.php new file mode 100644 index 00000000..3b8b2c86 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Test/NodeTestCase.php @@ -0,0 +1,65 @@ +assertNodeCompilation($source, $node, $environment, $isPattern); + } + + public function assertNodeCompilation($source, Node $node, Environment $environment = null, $isPattern = false) + { + $compiler = $this->getCompiler($environment); + $compiler->compile($node); + + if ($isPattern) { + $this->assertStringMatchesFormat($source, trim($compiler->getSource())); + } else { + $this->assertEquals($source, trim($compiler->getSource())); + } + } + + protected function getCompiler(Environment $environment = null) + { + return new Compiler(null === $environment ? $this->getEnvironment() : $environment); + } + + protected function getEnvironment() + { + return new Environment(new ArrayLoader([])); + } + + protected function getVariableGetter($name, $line = false) + { + $line = $line > 0 ? "// line $line\n" : ''; + + return sprintf('%s($context["%s"] ?? null)', $line, $name); + } + + protected function getAttributeGetter() + { + return 'twig_get_attribute($this->env, $this->source, '; + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Token.php b/data/web/inc/lib/vendor/twig/twig/src/Token.php new file mode 100644 index 00000000..53a6cafc --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Token.php @@ -0,0 +1,178 @@ + + */ +final class Token +{ + private $value; + private $type; + private $lineno; + + public const EOF_TYPE = -1; + public const TEXT_TYPE = 0; + public const BLOCK_START_TYPE = 1; + public const VAR_START_TYPE = 2; + public const BLOCK_END_TYPE = 3; + public const VAR_END_TYPE = 4; + public const NAME_TYPE = 5; + public const NUMBER_TYPE = 6; + public const STRING_TYPE = 7; + public const OPERATOR_TYPE = 8; + public const PUNCTUATION_TYPE = 9; + public const INTERPOLATION_START_TYPE = 10; + public const INTERPOLATION_END_TYPE = 11; + public const ARROW_TYPE = 12; + + public function __construct(int $type, $value, int $lineno) + { + $this->type = $type; + $this->value = $value; + $this->lineno = $lineno; + } + + public function __toString() + { + return sprintf('%s(%s)', self::typeToString($this->type, true), $this->value); + } + + /** + * Tests the current token for a type and/or a value. + * + * Parameters may be: + * * just type + * * type and value (or array of possible values) + * * just value (or array of possible values) (NAME_TYPE is used as type) + * + * @param array|string|int $type The type to test + * @param array|string|null $values The token value + */ + public function test($type, $values = null): bool + { + if (null === $values && !\is_int($type)) { + $values = $type; + $type = self::NAME_TYPE; + } + + return ($this->type === $type) && ( + null === $values || + (\is_array($values) && \in_array($this->value, $values)) || + $this->value == $values + ); + } + + public function getLine(): int + { + return $this->lineno; + } + + public function getType(): int + { + return $this->type; + } + + public function getValue() + { + return $this->value; + } + + public static function typeToString(int $type, bool $short = false): string + { + switch ($type) { + case self::EOF_TYPE: + $name = 'EOF_TYPE'; + break; + case self::TEXT_TYPE: + $name = 'TEXT_TYPE'; + break; + case self::BLOCK_START_TYPE: + $name = 'BLOCK_START_TYPE'; + break; + case self::VAR_START_TYPE: + $name = 'VAR_START_TYPE'; + break; + case self::BLOCK_END_TYPE: + $name = 'BLOCK_END_TYPE'; + break; + case self::VAR_END_TYPE: + $name = 'VAR_END_TYPE'; + break; + case self::NAME_TYPE: + $name = 'NAME_TYPE'; + break; + case self::NUMBER_TYPE: + $name = 'NUMBER_TYPE'; + break; + case self::STRING_TYPE: + $name = 'STRING_TYPE'; + break; + case self::OPERATOR_TYPE: + $name = 'OPERATOR_TYPE'; + break; + case self::PUNCTUATION_TYPE: + $name = 'PUNCTUATION_TYPE'; + break; + case self::INTERPOLATION_START_TYPE: + $name = 'INTERPOLATION_START_TYPE'; + break; + case self::INTERPOLATION_END_TYPE: + $name = 'INTERPOLATION_END_TYPE'; + break; + case self::ARROW_TYPE: + $name = 'ARROW_TYPE'; + break; + default: + throw new \LogicException(sprintf('Token of type "%s" does not exist.', $type)); + } + + return $short ? $name : 'Twig\Token::'.$name; + } + + public static function typeToEnglish(int $type): string + { + switch ($type) { + case self::EOF_TYPE: + return 'end of template'; + case self::TEXT_TYPE: + return 'text'; + case self::BLOCK_START_TYPE: + return 'begin of statement block'; + case self::VAR_START_TYPE: + return 'begin of print statement'; + case self::BLOCK_END_TYPE: + return 'end of statement block'; + case self::VAR_END_TYPE: + return 'end of print statement'; + case self::NAME_TYPE: + return 'name'; + case self::NUMBER_TYPE: + return 'number'; + case self::STRING_TYPE: + return 'string'; + case self::OPERATOR_TYPE: + return 'operator'; + case self::PUNCTUATION_TYPE: + return 'punctuation'; + case self::INTERPOLATION_START_TYPE: + return 'begin of string interpolation'; + case self::INTERPOLATION_END_TYPE: + return 'end of string interpolation'; + case self::ARROW_TYPE: + return 'arrow function'; + default: + throw new \LogicException(sprintf('Token of type "%s" does not exist.', $type)); + } + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/TokenParser/AbstractTokenParser.php b/data/web/inc/lib/vendor/twig/twig/src/TokenParser/AbstractTokenParser.php new file mode 100644 index 00000000..720ea676 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/TokenParser/AbstractTokenParser.php @@ -0,0 +1,32 @@ + + */ +abstract class AbstractTokenParser implements TokenParserInterface +{ + /** + * @var Parser + */ + protected $parser; + + public function setParser(Parser $parser): void + { + $this->parser = $parser; + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/TokenParser/ApplyTokenParser.php b/data/web/inc/lib/vendor/twig/twig/src/TokenParser/ApplyTokenParser.php new file mode 100644 index 00000000..4dbf3040 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/TokenParser/ApplyTokenParser.php @@ -0,0 +1,60 @@ +getLine(); + $name = $this->parser->getVarName(); + + $ref = new TempNameExpression($name, $lineno); + $ref->setAttribute('always_defined', true); + + $filter = $this->parser->getExpressionParser()->parseFilterExpressionRaw($ref, $this->getTag()); + + $this->parser->getStream()->expect(Token::BLOCK_END_TYPE); + $body = $this->parser->subparse([$this, 'decideApplyEnd'], true); + $this->parser->getStream()->expect(Token::BLOCK_END_TYPE); + + return new Node([ + new SetNode(true, $ref, $body, $lineno, $this->getTag()), + new PrintNode($filter, $lineno, $this->getTag()), + ]); + } + + public function decideApplyEnd(Token $token): bool + { + return $token->test('endapply'); + } + + public function getTag(): string + { + return 'apply'; + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/TokenParser/AutoEscapeTokenParser.php b/data/web/inc/lib/vendor/twig/twig/src/TokenParser/AutoEscapeTokenParser.php new file mode 100644 index 00000000..b674bea4 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/TokenParser/AutoEscapeTokenParser.php @@ -0,0 +1,58 @@ +getLine(); + $stream = $this->parser->getStream(); + + if ($stream->test(/* Token::BLOCK_END_TYPE */ 3)) { + $value = 'html'; + } else { + $expr = $this->parser->getExpressionParser()->parseExpression(); + if (!$expr instanceof ConstantExpression) { + throw new SyntaxError('An escaping strategy must be a string or false.', $stream->getCurrent()->getLine(), $stream->getSourceContext()); + } + $value = $expr->getAttribute('value'); + } + + $stream->expect(/* Token::BLOCK_END_TYPE */ 3); + $body = $this->parser->subparse([$this, 'decideBlockEnd'], true); + $stream->expect(/* Token::BLOCK_END_TYPE */ 3); + + return new AutoEscapeNode($value, $body, $lineno, $this->getTag()); + } + + public function decideBlockEnd(Token $token): bool + { + return $token->test('endautoescape'); + } + + public function getTag(): string + { + return 'autoescape'; + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/TokenParser/BlockTokenParser.php b/data/web/inc/lib/vendor/twig/twig/src/TokenParser/BlockTokenParser.php new file mode 100644 index 00000000..5878131b --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/TokenParser/BlockTokenParser.php @@ -0,0 +1,78 @@ + + * {% block title %}{% endblock %} - My Webpage + * {% endblock %} + * + * @internal + */ +final class BlockTokenParser extends AbstractTokenParser +{ + public function parse(Token $token): Node + { + $lineno = $token->getLine(); + $stream = $this->parser->getStream(); + $name = $stream->expect(/* Token::NAME_TYPE */ 5)->getValue(); + if ($this->parser->hasBlock($name)) { + throw new SyntaxError(sprintf("The block '%s' has already been defined line %d.", $name, $this->parser->getBlock($name)->getTemplateLine()), $stream->getCurrent()->getLine(), $stream->getSourceContext()); + } + $this->parser->setBlock($name, $block = new BlockNode($name, new Node([]), $lineno)); + $this->parser->pushLocalScope(); + $this->parser->pushBlockStack($name); + + if ($stream->nextIf(/* Token::BLOCK_END_TYPE */ 3)) { + $body = $this->parser->subparse([$this, 'decideBlockEnd'], true); + if ($token = $stream->nextIf(/* Token::NAME_TYPE */ 5)) { + $value = $token->getValue(); + + if ($value != $name) { + throw new SyntaxError(sprintf('Expected endblock for block "%s" (but "%s" given).', $name, $value), $stream->getCurrent()->getLine(), $stream->getSourceContext()); + } + } + } else { + $body = new Node([ + new PrintNode($this->parser->getExpressionParser()->parseExpression(), $lineno), + ]); + } + $stream->expect(/* Token::BLOCK_END_TYPE */ 3); + + $block->setNode('body', $body); + $this->parser->popBlockStack(); + $this->parser->popLocalScope(); + + return new BlockReferenceNode($name, $lineno, $this->getTag()); + } + + public function decideBlockEnd(Token $token): bool + { + return $token->test('endblock'); + } + + public function getTag(): string + { + return 'block'; + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/TokenParser/DeprecatedTokenParser.php b/data/web/inc/lib/vendor/twig/twig/src/TokenParser/DeprecatedTokenParser.php new file mode 100644 index 00000000..31416c79 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/TokenParser/DeprecatedTokenParser.php @@ -0,0 +1,43 @@ + + * + * @internal + */ +final class DeprecatedTokenParser extends AbstractTokenParser +{ + public function parse(Token $token): Node + { + $expr = $this->parser->getExpressionParser()->parseExpression(); + + $this->parser->getStream()->expect(Token::BLOCK_END_TYPE); + + return new DeprecatedNode($expr, $token->getLine(), $this->getTag()); + } + + public function getTag(): string + { + return 'deprecated'; + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/TokenParser/DoTokenParser.php b/data/web/inc/lib/vendor/twig/twig/src/TokenParser/DoTokenParser.php new file mode 100644 index 00000000..32c8f12f --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/TokenParser/DoTokenParser.php @@ -0,0 +1,38 @@ +parser->getExpressionParser()->parseExpression(); + + $this->parser->getStream()->expect(/* Token::BLOCK_END_TYPE */ 3); + + return new DoNode($expr, $token->getLine(), $this->getTag()); + } + + public function getTag(): string + { + return 'do'; + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/TokenParser/EmbedTokenParser.php b/data/web/inc/lib/vendor/twig/twig/src/TokenParser/EmbedTokenParser.php new file mode 100644 index 00000000..64b4f296 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/TokenParser/EmbedTokenParser.php @@ -0,0 +1,73 @@ +parser->getStream(); + + $parent = $this->parser->getExpressionParser()->parseExpression(); + + list($variables, $only, $ignoreMissing) = $this->parseArguments(); + + $parentToken = $fakeParentToken = new Token(/* Token::STRING_TYPE */ 7, '__parent__', $token->getLine()); + if ($parent instanceof ConstantExpression) { + $parentToken = new Token(/* Token::STRING_TYPE */ 7, $parent->getAttribute('value'), $token->getLine()); + } elseif ($parent instanceof NameExpression) { + $parentToken = new Token(/* Token::NAME_TYPE */ 5, $parent->getAttribute('name'), $token->getLine()); + } + + // inject a fake parent to make the parent() function work + $stream->injectTokens([ + new Token(/* Token::BLOCK_START_TYPE */ 1, '', $token->getLine()), + new Token(/* Token::NAME_TYPE */ 5, 'extends', $token->getLine()), + $parentToken, + new Token(/* Token::BLOCK_END_TYPE */ 3, '', $token->getLine()), + ]); + + $module = $this->parser->parse($stream, [$this, 'decideBlockEnd'], true); + + // override the parent with the correct one + if ($fakeParentToken === $parentToken) { + $module->setNode('parent', $parent); + } + + $this->parser->embedTemplate($module); + + $stream->expect(/* Token::BLOCK_END_TYPE */ 3); + + return new EmbedNode($module->getTemplateName(), $module->getAttribute('index'), $variables, $only, $ignoreMissing, $token->getLine(), $this->getTag()); + } + + public function decideBlockEnd(Token $token): bool + { + return $token->test('endembed'); + } + + public function getTag(): string + { + return 'embed'; + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/TokenParser/ExtendsTokenParser.php b/data/web/inc/lib/vendor/twig/twig/src/TokenParser/ExtendsTokenParser.php new file mode 100644 index 00000000..0ca46dd2 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/TokenParser/ExtendsTokenParser.php @@ -0,0 +1,52 @@ +parser->getStream(); + + if ($this->parser->peekBlockStack()) { + throw new SyntaxError('Cannot use "extend" in a block.', $token->getLine(), $stream->getSourceContext()); + } elseif (!$this->parser->isMainScope()) { + throw new SyntaxError('Cannot use "extend" in a macro.', $token->getLine(), $stream->getSourceContext()); + } + + if (null !== $this->parser->getParent()) { + throw new SyntaxError('Multiple extends tags are forbidden.', $token->getLine(), $stream->getSourceContext()); + } + $this->parser->setParent($this->parser->getExpressionParser()->parseExpression()); + + $stream->expect(/* Token::BLOCK_END_TYPE */ 3); + + return new Node(); + } + + public function getTag(): string + { + return 'extends'; + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/TokenParser/FlushTokenParser.php b/data/web/inc/lib/vendor/twig/twig/src/TokenParser/FlushTokenParser.php new file mode 100644 index 00000000..02c74aa1 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/TokenParser/FlushTokenParser.php @@ -0,0 +1,38 @@ +parser->getStream()->expect(/* Token::BLOCK_END_TYPE */ 3); + + return new FlushNode($token->getLine(), $this->getTag()); + } + + public function getTag(): string + { + return 'flush'; + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/TokenParser/ForTokenParser.php b/data/web/inc/lib/vendor/twig/twig/src/TokenParser/ForTokenParser.php new file mode 100644 index 00000000..bac8ba2d --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/TokenParser/ForTokenParser.php @@ -0,0 +1,78 @@ + + * {% for user in users %} + *
  • {{ user.username|e }}
  • + * {% endfor %} + * + * + * @internal + */ +final class ForTokenParser extends AbstractTokenParser +{ + public function parse(Token $token): Node + { + $lineno = $token->getLine(); + $stream = $this->parser->getStream(); + $targets = $this->parser->getExpressionParser()->parseAssignmentExpression(); + $stream->expect(/* Token::OPERATOR_TYPE */ 8, 'in'); + $seq = $this->parser->getExpressionParser()->parseExpression(); + + $stream->expect(/* Token::BLOCK_END_TYPE */ 3); + $body = $this->parser->subparse([$this, 'decideForFork']); + if ('else' == $stream->next()->getValue()) { + $stream->expect(/* Token::BLOCK_END_TYPE */ 3); + $else = $this->parser->subparse([$this, 'decideForEnd'], true); + } else { + $else = null; + } + $stream->expect(/* Token::BLOCK_END_TYPE */ 3); + + if (\count($targets) > 1) { + $keyTarget = $targets->getNode(0); + $keyTarget = new AssignNameExpression($keyTarget->getAttribute('name'), $keyTarget->getTemplateLine()); + $valueTarget = $targets->getNode(1); + } else { + $keyTarget = new AssignNameExpression('_key', $lineno); + $valueTarget = $targets->getNode(0); + } + $valueTarget = new AssignNameExpression($valueTarget->getAttribute('name'), $valueTarget->getTemplateLine()); + + return new ForNode($keyTarget, $valueTarget, $seq, null, $body, $else, $lineno, $this->getTag()); + } + + public function decideForFork(Token $token): bool + { + return $token->test(['else', 'endfor']); + } + + public function decideForEnd(Token $token): bool + { + return $token->test('endfor'); + } + + public function getTag(): string + { + return 'for'; + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/TokenParser/FromTokenParser.php b/data/web/inc/lib/vendor/twig/twig/src/TokenParser/FromTokenParser.php new file mode 100644 index 00000000..35098c26 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/TokenParser/FromTokenParser.php @@ -0,0 +1,66 @@ +parser->getExpressionParser()->parseExpression(); + $stream = $this->parser->getStream(); + $stream->expect(/* Token::NAME_TYPE */ 5, 'import'); + + $targets = []; + do { + $name = $stream->expect(/* Token::NAME_TYPE */ 5)->getValue(); + + $alias = $name; + if ($stream->nextIf('as')) { + $alias = $stream->expect(/* Token::NAME_TYPE */ 5)->getValue(); + } + + $targets[$name] = $alias; + + if (!$stream->nextIf(/* Token::PUNCTUATION_TYPE */ 9, ',')) { + break; + } + } while (true); + + $stream->expect(/* Token::BLOCK_END_TYPE */ 3); + + $var = new AssignNameExpression($this->parser->getVarName(), $token->getLine()); + $node = new ImportNode($macro, $var, $token->getLine(), $this->getTag(), $this->parser->isMainScope()); + + foreach ($targets as $name => $alias) { + $this->parser->addImportedSymbol('function', $alias, 'macro_'.$name, $var); + } + + return $node; + } + + public function getTag(): string + { + return 'from'; + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/TokenParser/IfTokenParser.php b/data/web/inc/lib/vendor/twig/twig/src/TokenParser/IfTokenParser.php new file mode 100644 index 00000000..c0fe6df0 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/TokenParser/IfTokenParser.php @@ -0,0 +1,89 @@ + + * {% for user in users %} + *
  • {{ user.username|e }}
  • + * {% endfor %} + * + * {% endif %} + * + * @internal + */ +final class IfTokenParser extends AbstractTokenParser +{ + public function parse(Token $token): Node + { + $lineno = $token->getLine(); + $expr = $this->parser->getExpressionParser()->parseExpression(); + $stream = $this->parser->getStream(); + $stream->expect(/* Token::BLOCK_END_TYPE */ 3); + $body = $this->parser->subparse([$this, 'decideIfFork']); + $tests = [$expr, $body]; + $else = null; + + $end = false; + while (!$end) { + switch ($stream->next()->getValue()) { + case 'else': + $stream->expect(/* Token::BLOCK_END_TYPE */ 3); + $else = $this->parser->subparse([$this, 'decideIfEnd']); + break; + + case 'elseif': + $expr = $this->parser->getExpressionParser()->parseExpression(); + $stream->expect(/* Token::BLOCK_END_TYPE */ 3); + $body = $this->parser->subparse([$this, 'decideIfFork']); + $tests[] = $expr; + $tests[] = $body; + break; + + case 'endif': + $end = true; + break; + + default: + throw new SyntaxError(sprintf('Unexpected end of template. Twig was looking for the following tags "else", "elseif", or "endif" to close the "if" block started at line %d).', $lineno), $stream->getCurrent()->getLine(), $stream->getSourceContext()); + } + } + + $stream->expect(/* Token::BLOCK_END_TYPE */ 3); + + return new IfNode(new Node($tests), $else, $lineno, $this->getTag()); + } + + public function decideIfFork(Token $token): bool + { + return $token->test(['elseif', 'else', 'endif']); + } + + public function decideIfEnd(Token $token): bool + { + return $token->test(['endif']); + } + + public function getTag(): string + { + return 'if'; + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/TokenParser/ImportTokenParser.php b/data/web/inc/lib/vendor/twig/twig/src/TokenParser/ImportTokenParser.php new file mode 100644 index 00000000..44cb4dad --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/TokenParser/ImportTokenParser.php @@ -0,0 +1,44 @@ +parser->getExpressionParser()->parseExpression(); + $this->parser->getStream()->expect(/* Token::NAME_TYPE */ 5, 'as'); + $var = new AssignNameExpression($this->parser->getStream()->expect(/* Token::NAME_TYPE */ 5)->getValue(), $token->getLine()); + $this->parser->getStream()->expect(/* Token::BLOCK_END_TYPE */ 3); + + $this->parser->addImportedSymbol('template', $var->getAttribute('name')); + + return new ImportNode($macro, $var, $token->getLine(), $this->getTag(), $this->parser->isMainScope()); + } + + public function getTag(): string + { + return 'import'; + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/TokenParser/IncludeTokenParser.php b/data/web/inc/lib/vendor/twig/twig/src/TokenParser/IncludeTokenParser.php new file mode 100644 index 00000000..28beb8ae --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/TokenParser/IncludeTokenParser.php @@ -0,0 +1,69 @@ +parser->getExpressionParser()->parseExpression(); + + list($variables, $only, $ignoreMissing) = $this->parseArguments(); + + return new IncludeNode($expr, $variables, $only, $ignoreMissing, $token->getLine(), $this->getTag()); + } + + protected function parseArguments() + { + $stream = $this->parser->getStream(); + + $ignoreMissing = false; + if ($stream->nextIf(/* Token::NAME_TYPE */ 5, 'ignore')) { + $stream->expect(/* Token::NAME_TYPE */ 5, 'missing'); + + $ignoreMissing = true; + } + + $variables = null; + if ($stream->nextIf(/* Token::NAME_TYPE */ 5, 'with')) { + $variables = $this->parser->getExpressionParser()->parseExpression(); + } + + $only = false; + if ($stream->nextIf(/* Token::NAME_TYPE */ 5, 'only')) { + $only = true; + } + + $stream->expect(/* Token::BLOCK_END_TYPE */ 3); + + return [$variables, $only, $ignoreMissing]; + } + + public function getTag(): string + { + return 'include'; + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/TokenParser/MacroTokenParser.php b/data/web/inc/lib/vendor/twig/twig/src/TokenParser/MacroTokenParser.php new file mode 100644 index 00000000..f584927e --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/TokenParser/MacroTokenParser.php @@ -0,0 +1,66 @@ + + * {% endmacro %} + * + * @internal + */ +final class MacroTokenParser extends AbstractTokenParser +{ + public function parse(Token $token): Node + { + $lineno = $token->getLine(); + $stream = $this->parser->getStream(); + $name = $stream->expect(/* Token::NAME_TYPE */ 5)->getValue(); + + $arguments = $this->parser->getExpressionParser()->parseArguments(true, true); + + $stream->expect(/* Token::BLOCK_END_TYPE */ 3); + $this->parser->pushLocalScope(); + $body = $this->parser->subparse([$this, 'decideBlockEnd'], true); + if ($token = $stream->nextIf(/* Token::NAME_TYPE */ 5)) { + $value = $token->getValue(); + + if ($value != $name) { + throw new SyntaxError(sprintf('Expected endmacro for macro "%s" (but "%s" given).', $name, $value), $stream->getCurrent()->getLine(), $stream->getSourceContext()); + } + } + $this->parser->popLocalScope(); + $stream->expect(/* Token::BLOCK_END_TYPE */ 3); + + $this->parser->setMacro($name, new MacroNode($name, new BodyNode([$body]), $arguments, $lineno, $this->getTag())); + + return new Node(); + } + + public function decideBlockEnd(Token $token): bool + { + return $token->test('endmacro'); + } + + public function getTag(): string + { + return 'macro'; + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/TokenParser/SandboxTokenParser.php b/data/web/inc/lib/vendor/twig/twig/src/TokenParser/SandboxTokenParser.php new file mode 100644 index 00000000..c919556e --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/TokenParser/SandboxTokenParser.php @@ -0,0 +1,66 @@ +parser->getStream(); + $stream->expect(/* Token::BLOCK_END_TYPE */ 3); + $body = $this->parser->subparse([$this, 'decideBlockEnd'], true); + $stream->expect(/* Token::BLOCK_END_TYPE */ 3); + + // in a sandbox tag, only include tags are allowed + if (!$body instanceof IncludeNode) { + foreach ($body as $node) { + if ($node instanceof TextNode && ctype_space($node->getAttribute('data'))) { + continue; + } + + if (!$node instanceof IncludeNode) { + throw new SyntaxError('Only "include" tags are allowed within a "sandbox" section.', $node->getTemplateLine(), $stream->getSourceContext()); + } + } + } + + return new SandboxNode($body, $token->getLine(), $this->getTag()); + } + + public function decideBlockEnd(Token $token): bool + { + return $token->test('endsandbox'); + } + + public function getTag(): string + { + return 'sandbox'; + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/TokenParser/SetTokenParser.php b/data/web/inc/lib/vendor/twig/twig/src/TokenParser/SetTokenParser.php new file mode 100644 index 00000000..2fbdfe09 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/TokenParser/SetTokenParser.php @@ -0,0 +1,73 @@ +getLine(); + $stream = $this->parser->getStream(); + $names = $this->parser->getExpressionParser()->parseAssignmentExpression(); + + $capture = false; + if ($stream->nextIf(/* Token::OPERATOR_TYPE */ 8, '=')) { + $values = $this->parser->getExpressionParser()->parseMultitargetExpression(); + + $stream->expect(/* Token::BLOCK_END_TYPE */ 3); + + if (\count($names) !== \count($values)) { + throw new SyntaxError('When using set, you must have the same number of variables and assignments.', $stream->getCurrent()->getLine(), $stream->getSourceContext()); + } + } else { + $capture = true; + + if (\count($names) > 1) { + throw new SyntaxError('When using set with a block, you cannot have a multi-target.', $stream->getCurrent()->getLine(), $stream->getSourceContext()); + } + + $stream->expect(/* Token::BLOCK_END_TYPE */ 3); + + $values = $this->parser->subparse([$this, 'decideBlockEnd'], true); + $stream->expect(/* Token::BLOCK_END_TYPE */ 3); + } + + return new SetNode($capture, $names, $values, $lineno, $this->getTag()); + } + + public function decideBlockEnd(Token $token): bool + { + return $token->test('endset'); + } + + public function getTag(): string + { + return 'set'; + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/TokenParser/TokenParserInterface.php b/data/web/inc/lib/vendor/twig/twig/src/TokenParser/TokenParserInterface.php new file mode 100644 index 00000000..bb8db3e5 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/TokenParser/TokenParserInterface.php @@ -0,0 +1,46 @@ + + */ +interface TokenParserInterface +{ + /** + * Sets the parser associated with this token parser. + */ + public function setParser(Parser $parser): void; + + /** + * Parses a token and returns a node. + * + * @return Node + * + * @throws SyntaxError + */ + public function parse(Token $token); + + /** + * Gets the tag name associated with this token parser. + * + * @return string + */ + public function getTag(); +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/TokenParser/UseTokenParser.php b/data/web/inc/lib/vendor/twig/twig/src/TokenParser/UseTokenParser.php new file mode 100644 index 00000000..d0a2de41 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/TokenParser/UseTokenParser.php @@ -0,0 +1,73 @@ +parser->getExpressionParser()->parseExpression(); + $stream = $this->parser->getStream(); + + if (!$template instanceof ConstantExpression) { + throw new SyntaxError('The template references in a "use" statement must be a string.', $stream->getCurrent()->getLine(), $stream->getSourceContext()); + } + + $targets = []; + if ($stream->nextIf('with')) { + do { + $name = $stream->expect(/* Token::NAME_TYPE */ 5)->getValue(); + + $alias = $name; + if ($stream->nextIf('as')) { + $alias = $stream->expect(/* Token::NAME_TYPE */ 5)->getValue(); + } + + $targets[$name] = new ConstantExpression($alias, -1); + + if (!$stream->nextIf(/* Token::PUNCTUATION_TYPE */ 9, ',')) { + break; + } + } while (true); + } + + $stream->expect(/* Token::BLOCK_END_TYPE */ 3); + + $this->parser->addTrait(new Node(['template' => $template, 'targets' => new Node($targets)])); + + return new Node(); + } + + public function getTag(): string + { + return 'use'; + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/TokenParser/WithTokenParser.php b/data/web/inc/lib/vendor/twig/twig/src/TokenParser/WithTokenParser.php new file mode 100644 index 00000000..7d8cbe26 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/TokenParser/WithTokenParser.php @@ -0,0 +1,56 @@ + + * + * @internal + */ +final class WithTokenParser extends AbstractTokenParser +{ + public function parse(Token $token): Node + { + $stream = $this->parser->getStream(); + + $variables = null; + $only = false; + if (!$stream->test(/* Token::BLOCK_END_TYPE */ 3)) { + $variables = $this->parser->getExpressionParser()->parseExpression(); + $only = (bool) $stream->nextIf(/* Token::NAME_TYPE */ 5, 'only'); + } + + $stream->expect(/* Token::BLOCK_END_TYPE */ 3); + + $body = $this->parser->subparse([$this, 'decideWithEnd'], true); + + $stream->expect(/* Token::BLOCK_END_TYPE */ 3); + + return new WithNode($body, $variables, $only, $token->getLine(), $this->getTag()); + } + + public function decideWithEnd(Token $token): bool + { + return $token->test('endwith'); + } + + public function getTag(): string + { + return 'with'; + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/TokenStream.php b/data/web/inc/lib/vendor/twig/twig/src/TokenStream.php new file mode 100644 index 00000000..1eac11a0 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/TokenStream.php @@ -0,0 +1,132 @@ + + */ +final class TokenStream +{ + private $tokens; + private $current = 0; + private $source; + + public function __construct(array $tokens, Source $source = null) + { + $this->tokens = $tokens; + $this->source = $source ?: new Source('', ''); + } + + public function __toString() + { + return implode("\n", $this->tokens); + } + + public function injectTokens(array $tokens) + { + $this->tokens = array_merge(\array_slice($this->tokens, 0, $this->current), $tokens, \array_slice($this->tokens, $this->current)); + } + + /** + * Sets the pointer to the next token and returns the old one. + */ + public function next(): Token + { + if (!isset($this->tokens[++$this->current])) { + throw new SyntaxError('Unexpected end of template.', $this->tokens[$this->current - 1]->getLine(), $this->source); + } + + return $this->tokens[$this->current - 1]; + } + + /** + * Tests a token, sets the pointer to the next one and returns it or throws a syntax error. + * + * @return Token|null The next token if the condition is true, null otherwise + */ + public function nextIf($primary, $secondary = null) + { + if ($this->tokens[$this->current]->test($primary, $secondary)) { + return $this->next(); + } + } + + /** + * Tests a token and returns it or throws a syntax error. + */ + public function expect($type, $value = null, string $message = null): Token + { + $token = $this->tokens[$this->current]; + if (!$token->test($type, $value)) { + $line = $token->getLine(); + throw new SyntaxError(sprintf('%sUnexpected token "%s"%s ("%s" expected%s).', + $message ? $message.'. ' : '', + Token::typeToEnglish($token->getType()), + $token->getValue() ? sprintf(' of value "%s"', $token->getValue()) : '', + Token::typeToEnglish($type), $value ? sprintf(' with value "%s"', $value) : ''), + $line, + $this->source + ); + } + $this->next(); + + return $token; + } + + /** + * Looks at the next token. + */ + public function look(int $number = 1): Token + { + if (!isset($this->tokens[$this->current + $number])) { + throw new SyntaxError('Unexpected end of template.', $this->tokens[$this->current + $number - 1]->getLine(), $this->source); + } + + return $this->tokens[$this->current + $number]; + } + + /** + * Tests the current token. + */ + public function test($primary, $secondary = null): bool + { + return $this->tokens[$this->current]->test($primary, $secondary); + } + + /** + * Checks if end of stream was reached. + */ + public function isEOF(): bool + { + return /* Token::EOF_TYPE */ -1 === $this->tokens[$this->current]->getType(); + } + + public function getCurrent(): Token + { + return $this->tokens[$this->current]; + } + + /** + * Gets the source associated with this stream. + * + * @internal + */ + public function getSourceContext(): Source + { + return $this->source; + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/TwigFilter.php b/data/web/inc/lib/vendor/twig/twig/src/TwigFilter.php new file mode 100644 index 00000000..94e5f9b0 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/TwigFilter.php @@ -0,0 +1,134 @@ + + * + * @see https://twig.symfony.com/doc/templates.html#filters + */ +final class TwigFilter +{ + private $name; + private $callable; + private $options; + private $arguments = []; + + /** + * @param callable|null $callable A callable implementing the filter. If null, you need to overwrite the "node_class" option to customize compilation. + */ + public function __construct(string $name, $callable = null, array $options = []) + { + $this->name = $name; + $this->callable = $callable; + $this->options = array_merge([ + 'needs_environment' => false, + 'needs_context' => false, + 'is_variadic' => false, + 'is_safe' => null, + 'is_safe_callback' => null, + 'pre_escape' => null, + 'preserves_safety' => null, + 'node_class' => FilterExpression::class, + 'deprecated' => false, + 'alternative' => null, + ], $options); + } + + public function getName(): string + { + return $this->name; + } + + /** + * Returns the callable to execute for this filter. + * + * @return callable|null + */ + public function getCallable() + { + return $this->callable; + } + + public function getNodeClass(): string + { + return $this->options['node_class']; + } + + public function setArguments(array $arguments): void + { + $this->arguments = $arguments; + } + + public function getArguments(): array + { + return $this->arguments; + } + + public function needsEnvironment(): bool + { + return $this->options['needs_environment']; + } + + public function needsContext(): bool + { + return $this->options['needs_context']; + } + + public function getSafe(Node $filterArgs): ?array + { + if (null !== $this->options['is_safe']) { + return $this->options['is_safe']; + } + + if (null !== $this->options['is_safe_callback']) { + return $this->options['is_safe_callback']($filterArgs); + } + + return null; + } + + public function getPreservesSafety(): ?array + { + return $this->options['preserves_safety']; + } + + public function getPreEscape(): ?string + { + return $this->options['pre_escape']; + } + + public function isVariadic(): bool + { + return $this->options['is_variadic']; + } + + public function isDeprecated(): bool + { + return (bool) $this->options['deprecated']; + } + + public function getDeprecatedVersion(): string + { + return \is_bool($this->options['deprecated']) ? '' : $this->options['deprecated']; + } + + public function getAlternative(): ?string + { + return $this->options['alternative']; + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/TwigFunction.php b/data/web/inc/lib/vendor/twig/twig/src/TwigFunction.php new file mode 100644 index 00000000..494d45b0 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/TwigFunction.php @@ -0,0 +1,122 @@ + + * + * @see https://twig.symfony.com/doc/templates.html#functions + */ +final class TwigFunction +{ + private $name; + private $callable; + private $options; + private $arguments = []; + + /** + * @param callable|null $callable A callable implementing the function. If null, you need to overwrite the "node_class" option to customize compilation. + */ + public function __construct(string $name, $callable = null, array $options = []) + { + $this->name = $name; + $this->callable = $callable; + $this->options = array_merge([ + 'needs_environment' => false, + 'needs_context' => false, + 'is_variadic' => false, + 'is_safe' => null, + 'is_safe_callback' => null, + 'node_class' => FunctionExpression::class, + 'deprecated' => false, + 'alternative' => null, + ], $options); + } + + public function getName(): string + { + return $this->name; + } + + /** + * Returns the callable to execute for this function. + * + * @return callable|null + */ + public function getCallable() + { + return $this->callable; + } + + public function getNodeClass(): string + { + return $this->options['node_class']; + } + + public function setArguments(array $arguments): void + { + $this->arguments = $arguments; + } + + public function getArguments(): array + { + return $this->arguments; + } + + public function needsEnvironment(): bool + { + return $this->options['needs_environment']; + } + + public function needsContext(): bool + { + return $this->options['needs_context']; + } + + public function getSafe(Node $functionArgs): ?array + { + if (null !== $this->options['is_safe']) { + return $this->options['is_safe']; + } + + if (null !== $this->options['is_safe_callback']) { + return $this->options['is_safe_callback']($functionArgs); + } + + return []; + } + + public function isVariadic(): bool + { + return (bool) $this->options['is_variadic']; + } + + public function isDeprecated(): bool + { + return (bool) $this->options['deprecated']; + } + + public function getDeprecatedVersion(): string + { + return \is_bool($this->options['deprecated']) ? '' : $this->options['deprecated']; + } + + public function getAlternative(): ?string + { + return $this->options['alternative']; + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/TwigTest.php b/data/web/inc/lib/vendor/twig/twig/src/TwigTest.php new file mode 100644 index 00000000..4c18632f --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/TwigTest.php @@ -0,0 +1,100 @@ + + * + * @see https://twig.symfony.com/doc/templates.html#test-operator + */ +final class TwigTest +{ + private $name; + private $callable; + private $options; + private $arguments = []; + + /** + * @param callable|null $callable A callable implementing the test. If null, you need to overwrite the "node_class" option to customize compilation. + */ + public function __construct(string $name, $callable = null, array $options = []) + { + $this->name = $name; + $this->callable = $callable; + $this->options = array_merge([ + 'is_variadic' => false, + 'node_class' => TestExpression::class, + 'deprecated' => false, + 'alternative' => null, + 'one_mandatory_argument' => false, + ], $options); + } + + public function getName(): string + { + return $this->name; + } + + /** + * Returns the callable to execute for this test. + * + * @return callable|null + */ + public function getCallable() + { + return $this->callable; + } + + public function getNodeClass(): string + { + return $this->options['node_class']; + } + + public function setArguments(array $arguments): void + { + $this->arguments = $arguments; + } + + public function getArguments(): array + { + return $this->arguments; + } + + public function isVariadic(): bool + { + return (bool) $this->options['is_variadic']; + } + + public function isDeprecated(): bool + { + return (bool) $this->options['deprecated']; + } + + public function getDeprecatedVersion(): string + { + return \is_bool($this->options['deprecated']) ? '' : $this->options['deprecated']; + } + + public function getAlternative(): ?string + { + return $this->options['alternative']; + } + + public function hasOneMandatoryArgument(): bool + { + return (bool) $this->options['one_mandatory_argument']; + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Util/DeprecationCollector.php b/data/web/inc/lib/vendor/twig/twig/src/Util/DeprecationCollector.php new file mode 100644 index 00000000..378b666b --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Util/DeprecationCollector.php @@ -0,0 +1,77 @@ + + */ +final class DeprecationCollector +{ + private $twig; + + public function __construct(Environment $twig) + { + $this->twig = $twig; + } + + /** + * Returns deprecations for templates contained in a directory. + * + * @param string $dir A directory where templates are stored + * @param string $ext Limit the loaded templates by extension + * + * @return array An array of deprecations + */ + public function collectDir(string $dir, string $ext = '.twig'): array + { + $iterator = new \RegexIterator( + new \RecursiveIteratorIterator( + new \RecursiveDirectoryIterator($dir), \RecursiveIteratorIterator::LEAVES_ONLY + ), '{'.preg_quote($ext).'$}' + ); + + return $this->collect(new TemplateDirIterator($iterator)); + } + + /** + * Returns deprecations for passed templates. + * + * @param \Traversable $iterator An iterator of templates (where keys are template names and values the contents of the template) + * + * @return array An array of deprecations + */ + public function collect(\Traversable $iterator): array + { + $deprecations = []; + set_error_handler(function ($type, $msg) use (&$deprecations) { + if (\E_USER_DEPRECATED === $type) { + $deprecations[] = $msg; + } + }); + + foreach ($iterator as $name => $contents) { + try { + $this->twig->parse($this->twig->tokenize(new Source($contents, $name))); + } catch (SyntaxError $e) { + // ignore templates containing syntax errors + } + } + + restore_error_handler(); + + return $deprecations; + } +} diff --git a/data/web/inc/lib/vendor/twig/twig/src/Util/TemplateDirIterator.php b/data/web/inc/lib/vendor/twig/twig/src/Util/TemplateDirIterator.php new file mode 100644 index 00000000..c7339fd7 --- /dev/null +++ b/data/web/inc/lib/vendor/twig/twig/src/Util/TemplateDirIterator.php @@ -0,0 +1,28 @@ + + */ +class TemplateDirIterator extends \IteratorIterator +{ + public function current() + { + return file_get_contents(parent::current()); + } + + public function key() + { + return (string) parent::key(); + } +} diff --git a/data/web/inc/prerequisites.inc.php b/data/web/inc/prerequisites.inc.php index 0cbd05a0..a5eb2c80 100644 --- a/data/web/inc/prerequisites.inc.php +++ b/data/web/inc/prerequisites.inc.php @@ -1,5 +1,8 @@ $DEV_MODE, + 'cache' => $_SERVER['DOCUMENT_ROOT'].'/templates/cache', +]); + +// functions +$twig->addFunction(new TwigFunction('query_string', function (array $params = []) { + return http_build_query(array_merge($_GET, $params)); +})); + +$twig->addFunction(new TwigFunction('is_uri', function (string $uri, string $where = null) { + if (is_null($where)) $where = $_SERVER['REQUEST_URI']; + return preg_match('/'.$uri.'/i', $where); +})); + +// filters +$twig->addFilter(new TwigFilter('rot13', 'str_rot13')); +$twig->addFilter(new TwigFilter('base64_encode', 'base64_encode')); +$twig->addFilter(new TwigFilter('formatBytes', 'formatBytes')); diff --git a/data/web/index.php b/data/web/index.php index 93e72a77..c319d5ef 100644 --- a/data/web/index.php +++ b/data/web/index.php @@ -24,128 +24,12 @@ require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/header.inc.php'; $_SESSION['return_to'] = $_SERVER['REQUEST_URI']; $_SESSION['index_query_string'] = $_SERVER['QUERY_STRING']; -?> -
    -
    -
    - -
    - -
    -
    -
    - -
    -
    -
    - -

    - -

    -

    -

    -

    - -
    -
    -
    -
    - -
    -
    - @$_SESSION['oauth2_request'], + 'is_mobileconfig' => str_contains($_SESSION['index_query_string'], 'mobileconfig'), + 'login_delay' => @$_SESSION['ldelay'], +]; + $js_minifier->add('/web/js/site/index.js'); require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/footer.inc.php'; diff --git a/data/web/js/build/014-mailcow.js b/data/web/js/build/014-mailcow.js index 90d83504..7468310f 100644 --- a/data/web/js/build/014-mailcow.js +++ b/data/web/js/build/014-mailcow.js @@ -159,8 +159,8 @@ $(document).ready(function() { } if ($(this).is("select")) { $(this).selectpicker('destroy'); - $(this).replaceWith(function() { - return ''; + $(this).replaceWith(function() { + return ''; }); } if ($(this).hasClass('btn-group')) { diff --git a/data/web/js/site/debug.js b/data/web/js/site/debug.js index 6b08113e..8f2aa663 100644 --- a/data/web/js/site/debug.js +++ b/data/web/js/site/debug.js @@ -78,6 +78,7 @@ jQuery(function($){ {"name":"time","formatter":function unix_time_format(tm) { var date = new Date(tm ? tm * 1000 : 0); return date.toLocaleDateString(undefined, {year: "numeric", month: "2-digit", day: "2-digit", hour: "2-digit", minute: "2-digit", second: "2-digit"});},"title":lang.time,"style":{"width":"170px"}}, {"name":"ua","title":"User-Agent","style":{"min-width":"200px"}}, {"name":"user","title":"Username","style":{"min-width":"200px"}}, + {"name":"ip","title":"IP","style":{"min-width":"200px"}}, {"name":"service","title":"Service"}, ], "rows": $.ajax({ @@ -706,9 +707,7 @@ jQuery(function($){ $.each(data, function (i, item) { if (item === null) { return true; } item.username = escapeHtml(item.username); - if (item.service == "smtp") { item.service = '
    ' + item.service.toUpperCase() + '
    '; } - else if (item.service == "imap") { item.service = '
    ' + item.service.toUpperCase() + '
    '; } - else { item.service = '
    ' + item.service.toUpperCase() + '
    '; } + item.service = '
    ' + item.service.toUpperCase() + '
    '; }); } else if (table == 'general_syslog') { $.each(data, function (i, item) { diff --git a/data/web/js/site/index.js b/data/web/js/site/index.js index 02de2068..1b3e56ad 100644 --- a/data/web/js/site/index.js +++ b/data/web/js/site/index.js @@ -1,4 +1,3 @@ -$(document).ready(function() { - $('nav').hide(); - localStorage.clear(); -}); \ No newline at end of file +$(document).ready(function() { + localStorage.clear(); +}); diff --git a/data/web/js/site/mailbox.js b/data/web/js/site/mailbox.js index fec23821..745c4f21 100644 --- a/data/web/js/site/mailbox.js +++ b/data/web/js/site/mailbox.js @@ -988,6 +988,7 @@ jQuery(function($){ {"name":"exclude","title":lang.excludes,"breakpoints":"all"}, {"name":"mins_interval","title":lang.mins_interval,"breakpoints":"all"}, {"name":"last_run","title":lang.last_run,"breakpoints":"xs sm md"}, + {"name":"exit_status","filterable": false,"title":lang.syncjob_last_run_result}, {"name":"log","title":"Log"}, {"name":"active","filterable": false,"style":{"min-width":"70px","width":"70px"},"title":lang.active,"formatter": function(value){return 1==value?'':0==value&&'';}}, {"name":"is_running","filterable": false,"style":{"min-width":"120px","width":"100px"},"title":lang.status}, @@ -1024,6 +1025,18 @@ jQuery(function($){ if (!item.last_run > 0) { item.last_run = lang.waiting; } + if (item.success == null) { + item.success = '-'; + item.exit_status = ''; + } else { + item.success = ''; + } + if (lang['syncjob_'+item.exit_status]) { + item.exit_status = lang['syncjob_'+item.exit_status]; + } else if (item.success != '-') { + item.exit_status = lang.syncjob_check_log; + } + item.exit_status = item.success + ' ' + item.exit_status; }); } }), diff --git a/data/web/js/site/user.js b/data/web/js/site/user.js index 83aedba4..8fd7b47f 100644 --- a/data/web/js/site/user.js +++ b/data/web/js/site/user.js @@ -79,7 +79,7 @@ jQuery(function($){ $('.clear-last-logins').on('click', function () {if (confirm(lang.delete_ays)) {last_logins('reset');}}) $(".login-history").on('click', function(e) {e.preventDefault(); last_logins('get', $(this).data('days'));$(this).addClass('active').siblings().removeClass('active');}); - function last_logins(action, days = 1) { + function last_logins(action, days = 7) { if (action == 'get') { $('.last-login').html('' + lang.waiting); $.ajax({ @@ -101,10 +101,11 @@ jQuery(function($){ $.each(data.sasl, function (i, item) { var datetime = new Date(item.datetime.replace(/-/g, "/")); var local_datetime = datetime.toLocaleDateString(undefined, {year: "numeric", month: "2-digit", day: "2-digit", hour: "2-digit", minute: "2-digit", second: "2-digit"}); - item.app_password ? app_password = ' (App)' : app_password = "", item.location ? ip_location = ' ' : ip_location = ""; - "smtp" == item.service ? service = '
    ' + item.service.toUpperCase() + '
    ' : "imap" == item.service ? service = '
    ' + item.service.toUpperCase() + "
    " : service = '
    ' + item.service.toUpperCase() + "
    "; - item.real_rip.startsWith("Web") ? real_rip = item.real_rip : real_rip = '' + item.real_rip + ""; - ip_data = real_rip + ip_location + app_password; + var service = '
    ' + item.service.toUpperCase() + '
    '; + var app_password = item.app_password ? ' ' + escapeHtml(item.app_password_name || "App") + '' : ''; + var real_rip = item.real_rip.startsWith("Web") ? item.real_rip : '' + item.real_rip + ""; + var ip_location = item.location ? ' ' : ''; + var ip_data = real_rip + ip_location + app_password; $(".last-login").append('
  • ' + local_datetime + " " + service + " " + lang.from + " " + ip_data + "
  • "); }) $('.last-login').append(''); @@ -133,7 +134,7 @@ jQuery(function($){ {"name":"address","title":lang.alias}, {"name":"validity","formatter":function unix_time_format(tm) { var date = new Date(tm ? tm * 1000 : 0); return date.toLocaleDateString(undefined, {year: "numeric", month: "2-digit", day: "2-digit", hour: "2-digit", minute: "2-digit", second: "2-digit"});},"title":lang.alias_valid_until,"style":{"width":"170px"}}, {"sorted": true,"sortValue": function(value){res = new Date(value);return res.getTime();},"direction":"DESC","name":"created","formatter":function date_format(datetime) { var date = new Date(datetime.replace(/-/g, "/")); return date.toLocaleDateString(undefined, {year: "numeric", month: "2-digit", day: "2-digit", hour: "2-digit", minute: "2-digit", second: "2-digit"});},"title":lang.created_on,"style":{"width":"170px"}}, - {"name":"action","filterable": false,"sortable": false,"style":{"text-align":"right","maxWidth":"180px","width":"180px"},"type":"html","title":lang.action,"breakpoints":"xs sm"} + {"name":"action","filterable": false,"sortable": false,"style":{"text-align":"right","min-width":"220px","width":"220px"},"type":"html","title":lang.action,"breakpoints":"xs sm"} ], "empty": lang.empty, "rows": $.ajax({ @@ -176,12 +177,13 @@ jQuery(function($){ "columns": [ {"name":"chkbox","title":"","style":{"min-width":"60px","width":"60px","text-align":"center"},"filterable": false,"sortable": false,"type":"html"}, {"sorted": true,"name":"id","title":"ID","style":{"maxWidth":"60px","width":"60px","text-align":"center"}}, - {"name":"server_w_port","title":"Server"}, + {"name":"server_w_port","title":"Server","breakpoints":"xs sm md","style":{"word-break":"break-all"}}, {"name":"enc1","title":lang.encryption,"breakpoints":"all"}, {"name":"user1","title":lang.username}, {"name":"exclude","title":lang.excludes,"breakpoints":"all"}, {"name":"mins_interval","title":lang.interval + " (min)","breakpoints":"all"}, - {"name":"last_run","title":lang.last_run,"breakpoints":"all"}, + {"name":"last_run","title":lang.last_run,"breakpoints":"xs sm md"}, + {"name":"exit_status","filterable": false,"title":lang.syncjob_last_run_result}, {"name":"log","title":"Log"}, {"name":"active","filterable": false,"style":{"maxWidth":"70px","width":"70px"},"title":lang.active,"formatter": function(value){return 1==value?'':0==value&&'';}}, {"name":"is_running","filterable": false,"style":{"maxWidth":"120px","width":"100px"},"title":lang.status}, @@ -224,6 +226,18 @@ jQuery(function($){ if (!item.last_run > 0) { item.last_run = lang.waiting; } + if (item.success == null) { + item.success = '-'; + item.exit_status = ''; + } else { + item.success = ''; + } + if (lang['syncjob_'+item.exit_status]) { + item.exit_status = lang['syncjob_'+item.exit_status]; + } else if (item.success != '-') { + item.exit_status = lang.syncjob_check_log; + } + item.exit_status = item.success + ' ' + item.exit_status; }); } }), @@ -245,8 +259,9 @@ jQuery(function($){ {"name":"chkbox","title":"","style":{"maxWidth":"60px","width":"60px","text-align":"center"},"filterable": false,"sortable": false,"type":"html"}, {"sorted": true,"name":"id","title":"ID","style":{"maxWidth":"60px","width":"60px","text-align":"center"}}, {"name":"name","title":lang.app_name}, + {"name":"protocols","title":lang.allowed_protocols}, {"name":"active","filterable": false,"style":{"maxWidth":"70px","width":"70px"},"title":lang.active,"formatter": function(value){return 1==value?'':0==value&&'';}}, - {"name":"action","filterable": false,"sortable": false,"style":{"text-align":"right","maxWidth":"180px","width":"180px"},"type":"html","title":lang.action,"breakpoints":"xs sm"} + {"name":"action","filterable": false,"sortable": false,"style":{"text-align":"right","min-width":"220px","width":"220px"},"type":"html","title":lang.action,"breakpoints":"xs sm"} ], "empty": lang.empty, "rows": $.ajax({ @@ -258,7 +273,15 @@ jQuery(function($){ }, success: function (data) { $.each(data, function (i, item) { - item.name = escapeHtml(item.name); + item.name = escapeHtml(item.name) + item.protocols = [] + if (item.imap_access == 1) { item.protocols.push("IMAP"); } + if (item.smtp_access == 1) { item.protocols.push("SMTP"); } + if (item.eas_access == 1) { item.protocols.push("EAS/ActiveSync"); } + if (item.dav_access == 1) { item.protocols.push("DAV"); } + if (item.pop3_access == 1) { item.protocols.push("POP3"); } + if (item.sieve_access == 1) { item.protocols.push("Sieve"); } + item.protocols = item.protocols.join(" ") if (acl_data.app_passwds === 1) { item.action = '
    ' + ' ' + lang.edit + '' + diff --git a/data/web/json_api.php b/data/web/json_api.php index bc90ed4d..595bd8f9 100644 --- a/data/web/json_api.php +++ b/data/web/json_api.php @@ -485,7 +485,7 @@ if (isset($_GET['query'])) { } if (!empty($app_passwds)) { foreach ($app_passwds as $app_passwd) { - $details = app_passwd('details', array('id' => $app_passwd['id'])); + $details = app_passwd('details', $app_passwd['id']); if ($details !== false) { $data[] = $details; } diff --git a/data/web/lang/lang.cs.json b/data/web/lang/lang.cs.json index 5299f10d..06e61353 100644 --- a/data/web/lang/lang.cs.json +++ b/data/web/lang/lang.cs.json @@ -28,7 +28,7 @@ "spam_score": "Skóre spamu", "syncjobs": "Synchronizační úlohy", "tls_policy": "Pravidla TLS", - "unlimited_quota": "Neomezené kvóty pro poštovní schránky" + "unlimited_quota": "Neomezené kvóty pro mailové schránky" }, "add": { "activate_filter_warn": "Pokud je zaškrtlá volba \"Aktivní\", budou všechny ostatní filtry deaktivovány.", @@ -70,10 +70,10 @@ "inactive": "Neaktivní", "kind": "Druh", "mailbox_quota_def": "Výchozí kvóta schránky", - "mailbox_quota_m": "Max. kvóta poštovní schránky (MiB)", + "mailbox_quota_m": "Max. kvóta mailové schránky (MiB)", "mailbox_username": "Uživatelské jméno (levá část email adresy)", "max_aliases": "Max. počet aliasů", - "max_mailboxes": "Max. počet poštovních schránek", + "max_mailboxes": "Max. počet mailových schránek", "mins_interval": "Interval kontroly (minuty)", "multiple_bookings": "Vícenásobné rezervace", "nexthop": "Další skok", @@ -85,7 +85,7 @@ "public_comment": "Veřejný komentář", "quota_mb": "Kvóta (MiB)", "relay_all": "Předávání všech příjemců", - "relay_all_info": "Pokud se rozhodnete nepředávat všechny příjemce, musíte přidat prázdnou poštovní schránku pro každého příjemce, který se má předávat.", + "relay_all_info": "Pokud se rozhodnete nepředávat všechny příjemce, musíte přidat prázdnou mailovou schránku pro každého příjemce, který se má předávat.", "relay_domain": "Předávání domény", "relay_transport_info": "
    Info
    U této domény lze pro konkrétní cíl nastavit transportní mapu. Není-li nastavena, použije se MX záznam.", "relay_unknown_only": "Předávat jen neexistující schránky. Doručení do existujících proběhne lokálně.", @@ -190,7 +190,7 @@ "flush_queue": "Vyprázdnit frontu (opětovně doručit)", "forwarding_hosts": "Předávající servery", "forwarding_hosts_add_hint": "Lze zadat IPv4/IPv6 adresy, sítě ve formátu CIDR, názvy serverů (budou převedeny na IP adresy) nebo názvy domén (budou převedeny na IP pomocí SPF záznamů, příp. MX záznamů).", - "forwarding_hosts_hint": "Příchozí zprávy od zde uvedených serverů jsou bezpodmínečně přijaty. U těchto serverů se nekontroluje DNSBL a nepoužije greylisting. Spam od těchto serverů se nikdy neodmítá, ale občas může skončit ve složce se spamem. Nejčastěji se zde uvádějí poštovní servery, jež předávají příchozí e-maily na tento poštovní server.", + "forwarding_hosts_hint": "Příchozí zprávy od zde uvedených serverů jsou bezpodmínečně přijaty. U těchto serverů se nekontroluje DNSBL a nepoužije greylisting. Spam od těchto serverů se nikdy neodmítá, ale občas může skončit ve složce se spamem. Nejčastěji se zde uvádějí mailové servery, jež předávají příchozí e-maily na tento mailový server.", "from": "Od", "generate": "generovat", "guid": "GUID - unikátní ID licence", @@ -204,7 +204,7 @@ "in_use_by": "Používáno", "inactive": "Neaktivní", "include_exclude": "Zahrnout/Vyloučit", - "include_exclude_info": "Ve výchozím nastavení (bez výběru), jsou adresovány všechny poštovní schránky", + "include_exclude_info": "Ve výchozím nastavení (bez výběru), jsou adresovány všechny mailové schránky", "includes": "Zahrnout tyto přijemce", "is_mx_based": "Na základě MX", "last_applied": "Naposledy použité", @@ -227,7 +227,7 @@ "oauth2_apps": "OAuth2 Aplikace", "oauth2_client_id": "ID klienta", "oauth2_client_secret": "Tajný klíč klienta", - "oauth2_info": "Implementace OAuth2 podporuje přidělení typu \"Authorization Code\" a vydává tokeny k obnovení.
    \r\nServer vydává tokeny k obnovení automaticky, jakmile byl předchozí token použit.

    \r\n→ Výchozím rozsahem je profil. Ověření přes OAuth2 mohou využít jen uživatelé poštovních schránek. Je-li rozsah vynechán, použije se profil.
    \r\n→ Klient je povinen uvést parametr state spolu s požadavkem na ověření.

    \r\nCesty API pro požadavky na ověření OAuth2:
    \r\n
      \r\n
    • Koncový bod pro ověření: /oauth/authorize
    • \r\n
    • Koncový bod pro token: /oauth/token
    • \r\n
    • Stránka zdroje: /oauth/profile
    • \r\n
    \r\nDojde-li ke znovuvytvoření tajného klíče klienta, nedojde ke zneplatnění stávajícíh ověřovacích kódů, nebude však už možné obnovit jejich token.

    \r\nOdvoláním klientského tokenů okamžitě ukončíte všechny aktivní relace a klienti se budou muset znovu přihlásit.", + "oauth2_info": "Implementace OAuth2 podporuje přidělení typu \"Authorization Code\" a vydává tokeny k obnovení.
    \r\nServer vydává tokeny k obnovení automaticky, jakmile byl předchozí token použit.

    \r\n→ Výchozím rozsahem je profil. Ověření přes OAuth2 mohou využít jen uživatelé mailových schránek. Je-li rozsah vynechán, použije se profil.
    \r\n→ Klient je povinen uvést parametr state spolu s požadavkem na ověření.

    \r\nCesty API pro požadavky na ověření OAuth2:
    \r\n
      \r\n
    • Koncový bod pro ověření: /oauth/authorize
    • \r\n
    • Koncový bod pro token: /oauth/token
    • \r\n
    • Stránka zdroje: /oauth/profile
    • \r\n
    \r\nDojde-li ke znovuvytvoření tajného klíče klienta, nedojde ke zneplatnění stávajícíh ověřovacích kódů, nebude však už možné obnovit jejich token.

    \r\nOdvoláním klientského tokenů okamžitě ukončíte všechny aktivní relace a klienti se budou muset znovu přihlásit.", "oauth2_redirect_uri": "URI přesměrování", "oauth2_renew_secret": "Vytvořit nový tajný klíč", "oauth2_revoke_tokens": "Odvolat všechny klientské tokeny", @@ -256,7 +256,7 @@ "quarantine_release_format": "Formát propuštěných položek", "quarantine_release_format_att": "Jako příloha", "quarantine_release_format_raw": "Nezměněný originál", - "quarantine_retention_size": "Počet zadržených zpráv na poštovní schránku
    0 znamená neaktivní.", + "quarantine_retention_size": "Počet zadržených zpráv na mailovou schránku
    0 znamená neaktivní.", "queue_ays": "Potvrďte prosím, že chcete odstranit všechny položky z aktuální fronty.", "queue_deliver_mail": "Doručit", "queue_hold_mail": "Zadržet", @@ -269,7 +269,7 @@ "quota_notification_subject": "Předmět upozornění", "quota_notifications": "Upozornění na kvóty", "quota_notifications_info": "Upozornění na kvótu se uživateli odesílají při překročení 80 % a 95 % limitu.", - "quota_notifications_vars": "{{percent}} se rovná aktuální kvótě
    {{username}} je jméno poštovní schránky", + "quota_notifications_vars": "{{percent}} se rovná aktuální kvótě
    {{username}} je jméno mailové schránky", "r_active": "Aktivní omezení", "r_inactive": "Neaktivní omezení", "r_info": "Šedé/vypnuté položky v seznamu aktivních omezení neuznává mailcow jako platná a nelze je přesouvat. Neznámá omezení budou však budou stejně seřazena tak, jak jdou za sebou.
    Nové prvky lze přidat do inc/vars.local.inc.php a pak je zde přepínat.", @@ -394,22 +394,22 @@ "invalid_recipient_map_old": "Neplatný původní příjemce: %s", "ip_list_empty": "Seznam povolených IP nesmí být prázdný", "is_alias": "%s je již známa jako adresa aliasu", - "is_alias_or_mailbox": "%s je již známa jako adresa aliasu, poštovní schránky nebo aliasu rozvedeného z aliasu domény.", + "is_alias_or_mailbox": "%s je již známa jako adresa aliasu, mailové schránky nebo aliasu rozvedeného z aliasu domény.", "is_spam_alias": "%s je již známa jako adresa spamového aliasu", "last_key": "Nelze smazat poslední klíč", "login_failed": "Přihlášení selhalo", "mailbox_defquota_exceeds_mailbox_maxquota": "Výchozí kvóta překračuje maximální kvótu schránky\"", - "mailbox_invalid": "Název poštovní chránky je neplatný", + "mailbox_invalid": "Název mailové schránky je neplatný", "mailbox_quota_exceeded": "Kvóta překročila limit domény (max. %d MiB)", "mailbox_quota_exceeds_domain_quota": "Max. kvóta překročila limit domény", "mailbox_quota_left_exceeded": "Není dost volného místa (zbývá: %d MiB)", - "mailboxes_in_use": "Max. počet poštovních schránek musí být větší nebo roven %d", + "mailboxes_in_use": "Max. počet mailových schránek musí být větší nebo roven %d", "malformed_username": "Neplatné uživatelské jméno", "map_content_empty": "Obsah mapování nesmí být prázdný", "max_alias_exceeded": "Překročeno max. množství aliasů", - "max_mailbox_exceeded": "Max. počet poštovních schránek překročen (%d z %d)", - "max_quota_in_use": "Kvóta poštovní schránky musí být větší nebo rovna %d MiB", - "maxquota_empty": "Max. kvóta poštovní schránky nesmí být 0.", + "max_mailbox_exceeded": "Max. počet mailových schránek překročen (%d z %d)", + "max_quota_in_use": "Kvóta mailové schránky musí být větší nebo rovna %d MiB", + "maxquota_empty": "Max. kvóta mailové schránky nesmí být 0.", "mysql_error": "Chyba MySQL: %s", "network_host_invalid": "Neplatná síť nebo hostitel: %s", "next_hop_interferes": "%s koliduje se skokem %s", @@ -544,15 +544,15 @@ "inactive": "Neaktivní", "kind": "Druh", "lookup_mx": "Cíl je regulární výraz který se shoduje s MX záznamem (.*google\\.com směřuje veškerou poštu na MX které jsou cílem pro google.com přes tento skok)", - "mailbox": "Úprava poštovní schránky", + "mailbox": "Úprava mailové schránky", "mailbox_quota_def": "Výchozí kvóta schránky", "mailbox_relayhost_info": "Aplikované jen na uživatelskou schránku a přímé aliasy, přepisuje předávající server domény.", "max_aliases": "Max. počet aliasů", - "max_mailboxes": "Max. počet poštovních schránek", - "max_quota": "Max. kvóta poštovní schránky (MiB)", + "max_mailboxes": "Max. počet mailových schránek", + "max_quota": "Max. kvóta mailové schránky (MiB)", "maxage": "Maximální stáří stahovaných zpráv, ve dnech
    (0 = ignorovat stáří)", "maxbytespersecond": "Max. bajtů za sekundu
    (0 = neomezeno)", - "mbox_rl_info": "Toto omezení provozu se vyhodnocuje podle přihlašovacího jména SASL, porovnává se s jakoukoliv adresou \"od\" použitou přihlášeným uživatelem. Omezení provozu poštovní schránku má prioritu před omezením provozu domény.", + "mbox_rl_info": "Toto omezení provozu se vyhodnocuje podle přihlašovacího jména SASL, porovnává se s jakoukoliv adresou \"od\" použitou přihlášeným uživatelem. Omezení provozu mailové schránky má prioritu před omezením provozu domény.", "mins_interval": "Interval (min)", "multiple_bookings": "Vícenásobné rezervace", "nexthop": "Další skok", @@ -577,7 +577,7 @@ "ratelimit": "Omezení přenosu", "redirect_uri": "URL přesměrování/odvolání", "relay_all": "Předávání všech příjemců", - "relay_all_info": "Pokud se rozhodnete nepředávat všechny příjemce, musíte přidat prázdnou poštovní schránku pro každého příjemce, který se má předávat.", + "relay_all_info": "Pokud se rozhodnete nepředávat všechny příjemce, musíte přidat prázdnou mailovou schránku pro každého příjemce, který se má předávat.", "relay_domain": "Předávání domény", "relay_transport_info": "
    Info
    U této domény lze pro konkrétní cíl nastavit transportní mapu. Není-li nastavena, použije se MX záznam.", "relay_unknown_only": "Předávat jen neexistující schránky. Doručení do existujících proběhne lokálně.", @@ -592,8 +592,6 @@ "sieve_desc": "Krátký popis", "sieve_type": "Typ filtru", "skipcrossduplicates": "Přeskočit duplicitní zprávy (\"první přijde, první mele\")", - "sogo_access": "Udělit přístup k SOGo", - "sogo_access_info": "Toto nastavení neovlivňuje přístup k ostatním službám, ani nezmění existující profil uživatele SOGo.", "sogo_visible": "Alias dostupný v SOGo", "sogo_visible_info": "Tato volba určuje objekty, jež lze zobrazit v SOGo (sdílené nebo nesdílené aliasy, jež ukazuje alespoň na jednu schránku).", "spam_alias": "Vytvořit nebo změnit dočasné aliasy", @@ -622,6 +620,7 @@ "register_status": "Stav registrace", "rename": "Přejmenovat", "set_fido2": "Registrovat FIDO2 zařízení", + "set_fido2_touchid": "Registrovat Touch ID na Apple M1", "set_fn": "Nastavi uživatelsky přívětivý název", "start_fido2_validation": "Spustit FIDO2 ověření" }, @@ -644,7 +643,7 @@ "administration": "Hlavní nastavení", "apps": "Aplikace", "debug": "Systémové informace", - "mailboxes": "Nastavení pošty", + "mailboxes": "Nastavení mailů", "mailcow_settings": "Nastavení", "quarantine": "Karanténa", "restart_netfilter": "Restartovat netfilter", @@ -677,7 +676,7 @@ "add_domain_alias": "Přidat doménový alias", "add_domain_record_first": "Prosím nejdříve vytvořte doménu", "add_filter": "Přidat filtr", - "add_mailbox": "Přidat poštovní schránku", + "add_mailbox": "Přidat mailovou schránku", "add_recipient_map_entry": "Přidat mapu příjemce", "add_resource": "Přidat zdroj", "add_tls_policy_map": "Přidat mapu TLS pravidel", @@ -739,12 +738,12 @@ "last_pw_change": "Naposledy změněno heslo", "last_run": "Naposledy spuštěno", "last_run_reset": "Znovu naplánovat", - "mailbox": "Poštovní schránka", + "mailbox": "Mailová schránka", "mailbox_defaults": "Výchozí nastavení", "mailbox_defaults_info": "Definuje výchozí nastavení pro nové schránky", "mailbox_defquota": "Výchozí velikost schránky", "mailbox_quota": "Max. velikost schránky", - "mailboxes": "Poštovní schránky", + "mailboxes": "Mailové schránky", "mins_interval": "Interval (min)", "msg_num": "Počet zpráv", "multiple_bookings": "Vícenásobné rezervace", @@ -793,6 +792,15 @@ "stats": "Statistika", "status": "Stav", "sync_jobs": "Synchronizační úlohy", + "syncjob_check_log": "Zkontrolujte záznam", + "syncjob_last_run_result": "Výsledek posledního spuštění", + "syncjob_EX_OK": "Úspěch", + "syncjob_EXIT_CONNECTION_FAILURE": "Problém se spojením", + "syncjob_EXIT_TLS_FAILURE": "Problém se šifrovaným spojením", + "syncjob_EXIT_AUTHENTICATION_FAILURE": "Problém s autentifikací", + "syncjob_EXIT_OVERQUOTA": "Cílová schránka je plná", + "syncjob_EXIT_CONNECTION_FAILURE_HOST1": "Nelze se připojit ke vzdálenému serveru", + "syncjob_EXIT_AUTHENTICATION_FAILURE_USER1": "Chybné uživatelské jméno nebo heslo", "table_size": "Velikost tabulky", "table_size_show_n": "Zobrazit %s položek", "target_address": "Cílová adresa", @@ -815,7 +823,7 @@ "yes": "✓" }, "oauth2": { - "access_denied": "K udělení přístupu se přihlašte jako vlastník poštovních schránky.", + "access_denied": "K udělení přístupu se přihlašte jako vlastník mailové schránky.", "authorize_app": "Ověřit aplikaci", "deny": "Zamítnout", "permit": "Ověřit aplikaci", @@ -935,9 +943,9 @@ "learned_ham": "Úspěšně naučeno ID %s jako 'ham'", "license_modified": "Změny licence uloženy", "logged_in_as": "Přihlášen jako %s", - "mailbox_added": "Poštovní schránka %s přidána", - "mailbox_modified": "Změny poštovní schránky %s uloženy", - "mailbox_removed": "Poštovní schránka %s odebrána", + "mailbox_added": "Mailová schránka %s přidána", + "mailbox_modified": "Změny mailové schránky %s uloženy", + "mailbox_removed": "Mailová schránka %s odebrána", "nginx_reloaded": "Nginx reload byl úspěšný", "object_modified": "Změny objektu %s uloženy", "password_policy_saved": "Politika hesel byla úspěšně uložena", @@ -950,7 +958,7 @@ "relayhost_removed": "Položka %s odebrána", "reset_main_logo": "Obnovit výchozí logo", "resource_added": "Zdroj %s přidán", - "resource_modified": "Změny poštovní schránky %s uloženy", + "resource_modified": "Změny mailové schránky %s uloženy", "resource_removed": "Zdroj %s odebrán", "rl_saved": "Omezení provozu pro objekt %s uloženo", "rspamd_ui_pw_set": "Heslo k Rspamd UI nastaveno", @@ -1007,7 +1015,7 @@ "alias_valid_until": "Platný do", "aliases_also_send_as": "Smí odesílat také jako uživatel", "aliases_send_as_all": "Nekontrolovat přístup odesílatele pro následující doménu(y) a jejich aliasy domény:", - "app_hint": "Hesla aplikací jsou alternativní heslo pro přihlášení k IMAP a SMTP. Uživatelské jméno zůstává stejné.
    SOGo (včetně ActiveSync) však nelze s heslem aplikace použít.", + "app_hint": "Hesla aplikací jsou alternativní heslo pro přihlášení k IMAP, SMTP, CalDAV, CardDAV a EAS. Uživatelské jméno zůstává stejné.
    SOGo však nelze s heslem aplikace použít.", "app_name": "Název aplikace", "app_passwds": "Hesla aplikací", "apple_connection_profile": "Profil připojení Apple", @@ -1028,8 +1036,8 @@ "eas_reset_help": "Obnovení mezipaměti zařízení pomůže zpravidla obnovit poškozený profil služby ActiveSync.
    Upozornění: Všechna data budou opětovně stažena!", "eas_reset_now": "Smazat", "edit": "Upravit", - "email": "Pošta", - "email_and_dav": "Pošta, kalendáře a kontakty", + "email": "Mail", + "email_and_dav": "Mail, kalendáře a kontakty", "empty": "Nejsou k dispozici žádné záznamy", "encryption": "Šifrování", "excludes": "Vyloučené", @@ -1050,8 +1058,8 @@ "last_ui_login": "Poslední přihlášení do web rozhraní", "loading": "Načítá se...", "login_history": "Historie přihlášení", - "mailbox": "Poštová schránka", - "mailbox_details": "Podrobnosti poštovní schránky", + "mailbox": "Mailová schránka", + "mailbox_details": "Podrobnosti mailové schránky", "mailbox_general": "Obecné", "mailbox_settings": "Nastavení", "messages": "zpráv", @@ -1102,7 +1110,7 @@ "spamfilter": "Filtr spamu", "spamfilter_behavior": "Hodnocení", "spamfilter_bl": "Seznam zakázaných adres (blacklist)", - "spamfilter_bl_desc": "Zakázané emailové adresy budou vždy klasifikovány jako spam a odmítnuty. Lze použít zástupné znaky (*). Filtr se použije pouze na přímé aliasy (s jednou cílovou poštovní schránkou), s výjimkou doménových košů a samotné poštovní schránky.", + "spamfilter_bl_desc": "Zakázané emailové adresy budou vždy klasifikovány jako spam a odmítnuty. Lze použít zástupné znaky (*). Filtr se použije pouze na přímé aliasy (s jednou cílovou mailovou schránkou), s výjimkou doménových košů a samotné mailové schránky.", "spamfilter_default_score": "Výchozí hodnoty:", "spamfilter_green": "Zelená: tato zpráva není spam", "spamfilter_hint": "První hodnota představuje \"nízké spam skóre\" a druhá \"vysoké spam skóre\".", @@ -1114,10 +1122,19 @@ "spamfilter_table_remove": "smazat", "spamfilter_table_rule": "Pravidlo", "spamfilter_wl": "Seznam povolených adres (whitelist)", - "spamfilter_wl_desc": "Povolené emailové adresy nebudou nikdy klasifikovány jako spam. Lze použít zástupné znaky (*). Filtr se použije pouze na přímé aliasy (s jednou cílovou poštovní schránkou), s výjimkou doménových košů a samotné poštovní schránky.", + "spamfilter_wl_desc": "Povolené emailové adresy nebudou nikdy klasifikovány jako spam. Lze použít zástupné znaky (*). Filtr se použije pouze na přímé aliasy (s jednou cílovou mailovou schránkou), s výjimkou doménových košů a samotné mailové schránky.", "spamfilter_yellow": "Žlutá: tato zpráva může být spam, bude označena jako spam a přesunuta do složky nevyžádané pošty", "status": "Stav", "sync_jobs": "Synchronizační úlohy", + "syncjob_check_log": "Zkontrolujte záznam", + "syncjob_last_run_result": "Výsledek posledního spuštění", + "syncjob_EX_OK": "Úspěch", + "syncjob_EXIT_CONNECTION_FAILURE": "Problém se spojením", + "syncjob_EXIT_TLS_FAILURE": "Problém se šifrovaným spojením", + "syncjob_EXIT_AUTHENTICATION_FAILURE": "Problém s autentifikací", + "syncjob_EXIT_OVERQUOTA": "Cílová schránka je plná", + "syncjob_EXIT_CONNECTION_FAILURE_HOST1": "Nelze se připojit ke vzdálenému serveru", + "syncjob_EXIT_AUTHENTICATION_FAILURE_USER1": "Chybné uživatelské jméno nebo heslo", "tag_handling": "Zacházení s označkovanou poštou", "tag_help_example": "Příklad e-mailové adresy se značkou: me+Facebook@example.org", "tag_help_explain": "V podsložce: v doručené poště bude vytvořena nová podsložka pojmenovaná po značce zprávy (\"INBOX / Facebook\").
    \r\nV předmětu: název značky bude přidáván k předmětu mailu, například: \"[Facebook] Moje zprávy\".", @@ -1129,7 +1146,7 @@ "tls_enforce_in": "Vynutit TLS pro příchozí poštu ", "tls_enforce_out": "Vynutit TLS pro odchozí poštu", "tls_policy": "Politika šifrování", - "tls_policy_warning": "Varování: Pokud se rozhodnete vynutit šifrovaný přenos pošty, může dojít ke ztrátě e-mailů.
    Zprávy, které nesplňují tuto politiku, budou poštovním systémem odmítnuty.
    Tato volba ovlivňuje primární e-mailovou adresu (přihlašovací jméno), všechny adresy odvozené z doménových aliasů i aliasy, jež mají tuto poštovní chránku jako cíl.", + "tls_policy_warning": "Varování: Pokud se rozhodnete vynutit šifrovaný přenos pošty, může dojít ke ztrátě e-mailů.
    Zprávy, které nesplňují tuto politiku, budou mailovým systémem odmítnuty.
    Tato volba ovlivňuje primární e-mailovou adresu (přihlašovací jméno), všechny adresy odvozené z doménových aliasů i aliasy, jež mají tuto mailovou schránku jako cíl.", "user_settings": "Uživatelské nastavení", "username": "Uživatelské jméno", "verify": "Ověřit", diff --git a/data/web/lang/lang.da.json b/data/web/lang/lang.da.json index 3b467a35..95169179 100644 --- a/data/web/lang/lang.da.json +++ b/data/web/lang/lang.da.json @@ -25,11 +25,7 @@ "syncjobs": "Synkroniser job", "tls_policy": "TLS politik", "unlimited_quota": "Ubegrænset quote for mailbokse", - "domain_desc": "Skift domæne beskrivelse", - "xmpp_admin": "Promover XMPP-bruger til administrator", - "xmpp_domain_access": "Konfigurer XMPP-domæneadgang", - "xmpp_mailbox_access": "Konfigurer XMPP-brugeradgang", - "xmpp_prefix": "Skift XMPP-underdomæne (præfiks)" + "domain_desc": "Skift domæne beskrivelse" }, "add": { "activate_filter_warn": "Alle andre filtre deaktiveres, når aktiv er markeret.", @@ -557,8 +553,6 @@ "sieve_desc": "Kort beskrivelse", "sieve_type": "Filtertype", "skipcrossduplicates": "Spring duplikatbeskeder over mapper (først til mølle)", - "sogo_access": "Giv adgang til SOGo", - "sogo_access_info": "Giv eller tillad adgang til SOGo. Denne indstilling påvirker hverken adgang til alle andre tjenester eller sletter eller ændrer en eksisterende SOGo-profil for brugere.", "sogo_visible": "Alias er synligt i SOGo", "sogo_visible_info": "Denne indstilling påvirker kun objekter, der kan vises i SOGo (delte eller ikke-delte aliasadresser, der peger på mindst en lokal postkasse). Hvis skjult, vises et alias ikke som valgbar afsender i SOGo.", "spam_alias": "Opret eller skift tidsbegrænsede aliasadresser", @@ -950,7 +944,7 @@ "alias_valid_until": "Gyldig indtil", "aliases_also_send_as": "Også tilladt at sende som bruger", "aliases_send_as_all": "Do not check sender access for the following domain(s) and its alias domains", - "app_hint": "App adgangskoder er alternative adgangskoder til din IMAP og SMTP login. Brugernavnet forbliver uændret.
    SOGo (inklusive AktivSync) er ikke tilgængelig via app-adgangskoder.", + "app_hint": "App adgangskoder er alternative adgangskoder til din IMAP, SMTP, CalDAV, CardDAV og EAS login. Brugernavnet forbliver uændret.
    SOGo er ikke tilgængelig via app-adgangskoder.", "app_name": "App navn", "app_passwds": "App kodeord", "apple_connection_profile": "Apple forbindelses profil", diff --git a/data/web/lang/lang.de.json b/data/web/lang/lang.de.json index 193df904..6aa28f23 100644 --- a/data/web/lang/lang.de.json +++ b/data/web/lang/lang.de.json @@ -28,14 +28,10 @@ "spam_score": "Spam-Bewertung", "syncjobs": "Sync Jobs", "tls_policy": "Verschlüsselungsrichtlinie", - "unlimited_quota": "Unendliche Quota für Mailboxen", - "xmpp_admin": "Benutzer zum XMPP-Administrator ernennen", - "xmpp_domain_access": "XMPP-Zugang einer Domain konfigurieren", - "xmpp_mailbox_access": "XMPP-Zugang eines Benutzers einstellen", - "xmpp_prefix": "XMPP-Subdomain/Präfix ändern" + "unlimited_quota": "Unendliche Quota für Mailboxen" }, "add": { - "activate_filter_warn": "Alle anderen Filter dieses Typs werden deaktiviert, falls dieses Script aktiv markiert wird.", + "activate_filter_warn": "Alle anderen Filter dieses Typs werden deaktiviert, falls dieses Script aktiviert wird.", "active": "Aktiv", "add": "Hinzufügen", "add_domain_only": "Nur Domain hinzufügen", @@ -46,6 +42,7 @@ "alias_domain_info": "Nur gültige Domains. Getrennt durch Komma.", "app_name": "App-Name", "app_password": "App-Passwort hinzufügen", + "app_passwd_protocols": "Zugelassene Protokolle für App-Passwort", "automap": "Ordner automatisch mappen (\"Sent items\", \"Sent\" => \"Sent\" etc.)", "backup_mx_options": "Relay-Optionen", "bcc_dest_format": "BCC-Ziel muss eine gültige E-Mail-Adresse sein.", @@ -84,14 +81,14 @@ "password": "Passwort", "password_repeat": "Passwort wiederholen", "port": "Port", - "post_domain_add": "Der SOGo-Container - \"sogo-mailcow\" - muss nach dem Hinzufügen einer Domain neugestartet werden!

    Im Anschluss sollte die DNS-Konfiguration der Domain überprüft- und \"acme-mailcow\" gegebenenfalls neugestartet werden, um Änderungen am Zertifikat zu übernehmen (autoconfig.<domain>, autodiscover.<domain>).
    Dieser Schritt ist optional und wird alle 24 Stunden automatisch ausgeführt.", + "post_domain_add": "Der SOGo-Container - \"sogo-mailcow\" - muss nach dem Hinzufügen einer Domain neugestartet werden!

    Im Anschluss sollte die DNS-Konfiguration der Domain überprüft und \"acme-mailcow\" gegebenenfalls neugestartet werden, um Änderungen am Zertifikat zu übernehmen (autoconfig.<domain>, autodiscover.<domain>).
    Dieser Schritt ist optional und wird alle 24 Stunden automatisch ausgeführt.", "private_comment": "Privater Kommentar", "public_comment": "Öffentlicher Kommentar", "quota_mb": "Speicherplatz (MiB)", "relay_all": "Alle Empfänger-Adressen relayen", "relay_all_info": "↪ Wenn nicht alle Empfänger-Adressen relayt werden sollen, müssen \"blinde\" Mailboxen für jede Adresse, die relayt werden soll, erstellen werden.", "relay_domain": "Diese Domain relayen", - "relay_transport_info": "
    Info
    Transport-Maps können erstellt werden, um individuelle Ziele für eine Relay-Domain zu definieren.", + "relay_transport_info": "
    Info
    Transport-Maps können erstellt werden, um individuelle Ziele für eine Relay-Domain zu definieren.", "relay_unknown_only": "Nur nicht-lokale Mailboxen relayen. Existente Mailboxen werden weiterhin lokal zugestellt.", "relayhost_wrapped_tls_info": "Bitte keine \"TLS-wrapped Ports\" verwenden (etwa SMTPS via Port 465/tcp).
    \r\nDer Transport wird stattdessen STARTTLS anfordern, um TLS zu verwenden. TLS kann unter \"TLS Policy Maps\" erzwungen werden.", "select": "Bitte auswählen", @@ -109,15 +106,7 @@ "timeout2": "Timeout für Verbindung zum lokalen Host", "username": "Benutzername", "validate": "Validieren", - "validation_success": "Erfolgreich validiert", - "xmpp": "XMPP für diese Domain aktivieren", - "xmpp_access": "XMPP-Zugang", - "xmpp_access_info": "XMPP muss für diese Domain aktiviert sein.", - "xmpp_admin": "XMPP-Administrator", - "xmpp_admin_info": "Vorsicht: Ernennt den Benutzer zum Administrator der jeweiligen XMPP-Domain.", - "xmpp_info": "Diese Funktion stellt eine Chat-Funktionalität für die Domain bereit.", - "xmpp_prefix": "XMPP-Präfix für Domain (\"im\" für im.example.org)", - "xmpp_prefix_info": "Für die Bereitstellung eines Zertifikates sollte vorab ein DNS-Eintrag, etwa in Form eines CNAMEs, für im.example.org sowie *.im.example.org auf %s zeigend angelegt werden. Im Anschluss an die Aktivierung sollte der DNS-Check für diese Domain ausgeführt werden." + "validation_success": "Erfolgreich validiert" }, "admin": { "access": "Zugang", @@ -235,7 +224,7 @@ "no_record": "Kein Eintrag", "oauth2_client_id": "Client ID", "oauth2_client_secret": "Client Secret", - "oauth2_info": "Die OAuth2 Implementierung unterstützt den Grant Type \"Authorization Code\" mit Refresh Tokens.
    \r\nDer Server wird automatisch einen neuen Refresh Token ausstellen, sobald ein vorheriger Token gegen einen Access Token eingetauscht wurde.

    \r\n• Der Standard Scope lautet profile. Nur Mailbox-Benutzer können sich gegen OAuth2 authentifizieren. Wird kein Scope angegeben, verwendet das System per Standard profile.
    \r\n• Der state Parameter wird im Zuge des Autorisierungsprozesses benötigt.

    \r\nDie Pfade für die OAuth2 API lauten wie folgt:
    \r\n
      \r\n
    • Authorization Endpoint: /oauth/authorize
    • \r\n
    • Token Endpoint: /oauth/token
    • \r\n
    • Resource Page: /oauth/profile
    • \r\n
    \r\nDie Regenerierung des Client Secrets wird vorhandene Authorization Codes nicht invalidieren, dennoch wird der Renew des Access Tokens durch einen Refresh Token nicht mehr gelingen.

    \r\nDas Entfernen aller Client Tokens verursacht die umgehende Terminierung aller aktiven OAuth2 Sessions. Clients müssen sich erneut gegen die OAuth2 Anwendung authentifizieren.", + "oauth2_info": "Die OAuth2-Implementierung unterstützt den Grant Type \"Authorization Code\" mit Refresh Tokens.
    \r\nDer Server wird automatisch einen neuen Refresh Token ausstellen, sobald ein vorheriger Token gegen einen Access Token eingetauscht wurde.

    \r\n• Der Standard Scope lautet profile. Nur Mailbox-Benutzer können sich gegen OAuth2 authentifizieren. Wird kein Scope angegeben, verwendet das System per Standard profile.
    \r\n• Der state Parameter wird im Zuge des Autorisierungsprozesses benötigt.

    \r\nDie Pfade für die OAuth2 API lauten wie folgt:
    \r\n
      \r\n
    • Authorization Endpoint: /oauth/authorize
    • \r\n
    • Token Endpoint: /oauth/token
    • \r\n
    • Resource Page: /oauth/profile
    • \r\n
    \r\nDie Regenerierung des Client Secrets wird vorhandene Authorization Codes nicht invalidieren, dennoch wird der Renew des Access Tokens durch einen Refresh Token nicht mehr gelingen.

    \r\nDas Entfernen aller Client Tokens verursacht die umgehende Terminierung aller aktiven OAuth2 Sessions. Clients müssen sich erneut gegen die OAuth2-Anwendung authentifizieren.", "oauth2_redirect_uri": "Redirect-URI", "oauth2_renew_secret": "Neues Client Secret generieren", "oauth2_revoke_tokens": "Alle Client Tokens entfernen", @@ -310,7 +299,7 @@ "rspamd_global_filters": "Globale Filter-Maps", "rspamd_global_filters_agree": "Ich werde vorsichtig sein!", "rspamd_global_filters_info": "Globale Filter-Maps steuern globales White- und Blacklisting dieses Servers.", - "rspamd_global_filters_regex": "Die akzeptierte Form für Einträge sind ausschließlich Regular Expressions.\r\n Trotz rudimentärer Überprüfung der Map, kann es zu fehlerhaften Einträgen kommen, die Rspamd im schlechtesten Fall mit unvorhersehbarer Funktionalität bestraft.
    \r\n Das korrekte Format lautet \"/pattern/options\" (Beispiel: /.+@domain\\.tld/i).
    \r\n Der Name der Map beschreibt die jeweilige Funktion.
    \r\n Rspamd versucht die Maps umgehend aufzulösen. Bei Problemen sollte Rspamd manuell neugestartet werden
    Elemente auf Blacklists sind von der Quarantäne ausgeschlossen.", + "rspamd_global_filters_regex": "Die akzeptierte Form für Einträge sind ausschließlich Regular Expressions.\r\n Trotz rudimentärer Überprüfung der Map, kann es zu fehlerhaften Einträgen kommen, die Rspamd im schlechtesten Fall mit unvorhersehbarer Funktionalität bestraft.
    \r\n Das korrekte Format lautet \"/pattern/options\" (Beispiel: /.+@domain\\.tld/i).
    \r\n Der Name der Map beschreibt die jeweilige Funktion.
    \r\n Rspamd versucht die Maps umgehend aufzulösen. Bei Problemen sollte Rspamd manuell neugestartet werden.
    Elemente auf Blacklists sind von der Quarantäne ausgeschlossen.", "rspamd_settings_map": "Rspamd-Settings-Map", "sal_level": "Moo-Level", "save": "Änderungen speichern", @@ -332,7 +321,7 @@ "transport_dest_format": "Regex oder Syntax: example.org, .example.org, *, box@example.org (getrennt durch Komma einzugeben)", "transport_maps": "Transport-Maps", "transport_test_rcpt_info": "• Die Verwendung von null@hosted.mailcow.de testet das Relay gegen ein fremdes Ziel.", - "transports_hint": "• Transport-Maps überwiegen senderabhängige Transport Maps.
    \r\n• MX-basierte Transporte werden bevorzugt.
    \r\n• Transport-Maps ignorieren Mailbox-Einstellungen für ausgehende Verschlüsselung. Eine serverweite TLS-Richtlinie wird jedoch angewendet.
    \r\n• Der Transport erfolgt immer via \"smtp:\", verwendet TLS wenn angeboten und unterstützt kein wrapped TLS (SMTPS).
    \r\n• Adressen, die mit \"/localhost$/\" übereinstimmen, werden immer via \"local:\" transportiert, daher sind sie von einer Zieldefinition \"*\" ausgeschlossen.
    \r\n• Die Authentifizierung wird anhand des \"Next hop\" Parameters ermittelt. Hierbei würde bei einem beispielhaften Wert \"[host]:25\" immer zuerst \"host\" abfragt und erst im Anschluss \"[host]:25\". Dieses Verhalten schließt die gleichzeitige Verwendung von Einträgen der Art \"host\" sowie \"[host]:25\" aus.", + "transports_hint": "• Transport-Maps überwiegen senderabhängige Transport-Maps.
    \r\n• MX-basierte Transporte werden bevorzugt.
    \r\n• Transport-Maps ignorieren Mailbox-Einstellungen für ausgehende Verschlüsselung. Eine serverweite TLS-Richtlinie wird jedoch angewendet.
    \r\n• Der Transport erfolgt immer via \"smtp:\", verwendet TLS wenn angeboten und unterstützt kein wrapped TLS (SMTPS).
    \r\n• Adressen, die mit \"/localhost$/\" übereinstimmen, werden immer via \"local:\" transportiert, daher sind sie von einer Zieldefinition \"*\" ausgeschlossen.
    \r\n• Die Authentifizierung wird anhand des \"Next hop\" Parameters ermittelt. Hierbei würde bei einem beispielhaften Wert \"[host]:25\" immer zuerst \"host\" abgefragt und erst im Anschluss \"[host]:25\". Dieses Verhalten schließt die gleichzeitige Verwendung von Einträgen der Art \"host\" sowie \"[host]:25\" aus.", "ui_footer": "Footer (HTML zulässig)", "ui_header_announcement": "Ankündigungen", "ui_header_announcement_active": "Ankündigung aktivieren", @@ -440,7 +429,7 @@ "redis_error": "Redis Fehler: %s", "relayhost_invalid": "Map-Eintrag %s ist ungültig", "release_send_failed": "Die Nachricht konnte nicht versendet werden: %s", - "reset_f2b_regex": "Regex Filter konnten nicht in vorgegebener Zeit zurückgesetzt werden, bitte erneut versuchen oder die Webseite neu laden.", + "reset_f2b_regex": "Regex-Filter konnten nicht in vorgegebener Zeit zurückgesetzt werden, bitte erneut versuchen oder die Webseite neu laden.", "resource_invalid": "Ressourcenname %s ist ungültig", "rl_timeframe": "Ratelimit-Zeitraum ist inkorrekt", "rspamd_ui_pw_length": "Rspamd UI-Passwort muss mindestens 6 Zeichen lang sein", @@ -456,7 +445,7 @@ "targetd_relay_domain": "Ziel-Domain %s ist eine Relay-Domain", "temp_error": "Temporärer Fehler", "text_empty": "Text darf nicht leer sein", - "tfa_token_invalid": "TFA Token ungültig", + "tfa_token_invalid": "TFA-Token ungültig", "tls_policy_map_dest_invalid": "Ziel ist ungültig", "tls_policy_map_entry_exists": "Eine TLS-Richtlinie \"%s\" existiert bereits", "tls_policy_map_parameter_invalid": "Parameter ist ungültig", @@ -469,9 +458,6 @@ "username_invalid": "Benutzername %s kann nicht verwendet werden", "validity_missing": "Bitte geben Sie eine Gültigkeitsdauer an", "value_missing": "Bitte alle Felder ausfüllen", - "xmpp_map_write_error": "Kann XMPP-Map nicht schreiben: %s", - "xmpp_reload_failed": "XMPP konnte nicht neu geladen werden", - "xmpp_restart_failed": "XMPP konnte nicht neu gestartet werden", "yotp_verification_failed": "Yubico OTP-Verifizierung fehlgeschlagen: %s" }, "debug": { @@ -499,9 +485,7 @@ "success": "Erfolg", "system_containers": "System & Container", "uptime": "Uptime", - "username": "Benutzername", - "xmpp_dead": "XMPP startet, ist deaktiviert oder temporär nicht erreichbar.", - "xmpp_status": "XMPP Status" + "username": "Benutzername" }, "diagnostics": { "cname_from_a": "Wert abgeleitet von A/AAAA-Eintrag. Wird unterstützt, sofern der Eintrag auf die korrekte Ressource zeigt.", @@ -522,9 +506,10 @@ "alias": "Alias bearbeiten", "allow_from_smtp": "Nur folgende IPs für SMTP erlauben", "allow_from_smtp_info": "Leer lassen, um keine Prüfung durchzuführen.
    IPv4- sowie IPv6-Adressen und Subnetzwerke.", - "allowed_protocols": "Erlaubte Protokolle", + "allowed_protocols": "Erlaubte Protokolle für direkten Zugriff (hat keinen Einfluss auf App-Passwort Protokolle)", "app_name": "App-Name", "app_passwd": "App-Passwörter", + "app_passwd_protocols": "Zugelassene Protokolle für App-Passwort", "automap": "Ordner automatisch mappen (\"Sent items\", \"Sent\" => \"Sent\" etc.)", "backup_mx_options": "Relay-Optionen", "bcc_dest_format": "BCC-Ziel muss eine gültige E-Mail-Adresse sein.", @@ -548,7 +533,7 @@ "extended_sender_acl": "Externe Absenderadressen", "extended_sender_acl_info": "Der DKIM-Domainkey der externen Absenderdomain sollte in diesen Server importiert werden, falls vorhanden.
    \r\n Wird SPF verwendet, muss diesem Server der Versand gestattet werden.
    \r\n Wird eine Domain oder Alias-Domain zu diesem Server hinzugefügt, die sich mit der externen Absenderadresse überschneidet, wird der externe Absender hier entfernt.
    \r\n Ein Eintrag @domain.tld erlaubt den Versand als *@domain.tld", "force_pw_update": "Erzwinge Passwortänderung bei nächstem Login", - "force_pw_update_info": "Dem Benutzer wird lediglich der Zugang zur %s ermöglicht.", + "force_pw_update_info": "Dem Benutzer wird lediglich der Zugang zur %s ermöglicht, App Passwörter funktionieren weiterhin.", "full_name": "Voller Name", "gal": "Globales Adressbuch", "gal_info": "Das globale Adressbuch enthält alle Objekte einer Domain und kann durch keinen Benutzer geändert werden. Die Verfügbarkeitsinformation in SOGo ist nur bei eingeschaltetem globalen Adressbuch ersichtlich Zum Anwenden einer Änderung muss SOGo neugestartet werden.", @@ -578,8 +563,8 @@ "public_comment": "Öffentlicher Kommentar", "pushover": "Pushover", "pushover_evaluate_x_prio": "Hohe Priorität eskalieren [X-Priority: 1]", - "pushover_info": "Push-Benachrichtigungen werden angewendet auf alle nicht-Spam Nachrichten zugestellt an %s, einschließlich Alias-Adressen (shared, non-shared, tagged).", - "pushover_only_x_prio": "Nur Mail mit hoher Priorität berücksichtigen [X-Priority: 1]", + "pushover_info": "Push-Benachrichtigungen werden angewendet auf alle nicht-Spam-Nachrichten zugestellt an %s, einschließlich Alias-Adressen (shared, non-shared, tagged).", + "pushover_only_x_prio": "Nur E-Mail mit hoher Priorität berücksichtigen [X-Priority: 1]", "pushover_sender_array": "Folgende Sender E-Mail-Adressen berücksichtigen (getrennt durch Komma)", "pushover_sender_regex": "Sender mit folgendem regulären Ausdruck auswählen", "pushover_text": "Notification-Text", @@ -607,8 +592,8 @@ "sieve_desc": "Kurze Beschreibung", "sieve_type": "Filtertyp", "skipcrossduplicates": "Duplikate auch über Ordner hinweg überspringen (\"first come, first serve\")", - "sogo_access": "SOGo-Zugriffsrecht", - "sogo_access_info": "Zugriff auf SOGo erlauben oder verbieten. Diese Einstellung hat weder Einfluss auf den Zugang sonstiger Dienste noch entfernt sie ein vorhandenes SOGo-Benutzerprofil.", + "sogo_access": "Direktes Einloggen an SOGo erlauben", + "sogo_access_info": "Single-Sign-On Zugriff über die UI wird hierdurch NICHT deaktiviert. Diese Einstellung hat weder Einfluss auf den Zugang sonstiger Dienste noch entfernt sie ein vorhandenes SOGo-Benutzerprofil.", "sogo_visible": "Alias in SOGo sichtbar", "sogo_visible_info": "Diese Option hat lediglich Einfluss auf Objekte, die in SOGo darstellbar sind (geteilte oder nicht-geteilte Alias-Adressen mit dem Ziel mindestens einer lokalen Mailbox).", "spam_alias": "Anpassen temporärer Alias-Adressen", @@ -624,16 +609,7 @@ "title": "Objekt bearbeiten", "unchanged_if_empty": "Unverändert, wenn leer", "username": "Benutzername", - "validate_save": "Validieren und speichern", - "xmpp": "XMPP für diese Domain aktivieren", - "xmpp_access": "XMPP-Zugang", - "xmpp_access_info": "XMPP muss für diese Domain aktiviert sein.", - "xmpp_admin": "XMPP-Administrator", - "xmpp_admin_info": "Vorsicht: Ernennt den Benutzer zum Administrator der jeweiligen XMPP Domain.", - "xmpp_example_jid": "Beispiel JID (Passwort entspricht Mailbox-Passwort)", - "xmpp_info": "Diese Funktion stellt eine Chat-Funktionalität für die Domain bereit.", - "xmpp_prefix": "XMPP-Präfix für Domain (\"im\" für im.example.org)", - "xmpp_prefix_info": "Für die Bereitstellung eines Zertifikates sollte vorab ein DNS-Eintrag, etwa in Form eines CNAMEs, für im.example.org sowie *.im.example.org auf %s zeigend angelegt werden. Im Anschluss an die Aktivierung sollte der DNS-Check für diese Domain ausgeführt werden." + "validate_save": "Validieren und speichern" }, "fido2": { "confirm": "Bestätigen", @@ -646,6 +622,7 @@ "register_status": "Registrierungsstatus", "rename": "Umbenennen", "set_fido2": "Registriere FIDO2-Gerät", + "set_fido2_touchid": "Registriere Touch ID auf Apple M1", "set_fn": "Benutzerfreundlichen Namen konfigurieren", "start_fido2_validation": "Starte FIDO2-Validierung" }, @@ -712,7 +689,7 @@ "allow_from_smtp": "Nur folgende IPs für SMTP erlauben", "allow_from_smtp_info": "Leer lassen, um keine Prüfung durchzuführen.
    IPv4- sowie IPv6-Adressen und Subnetzwerke.", "allowed_protocols": "Erlaubte Protokolle", - "backup_mx": "Relay Domain", + "backup_mx": "Relay-Domain", "bcc": "BCC", "bcc_destination": "BCC-Ziel", "bcc_destinations": "BCC-Ziel", @@ -974,10 +951,7 @@ "verified_fido2_login": "FIDO2-Anmeldung verifiziert", "verified_totp_login": "TOTP-Anmeldung verifiziert", "verified_u2f_login": "U2F-Anmeldung verifiziert", - "verified_yotp_login": "Yubico-OTP-Anmeldung verifiziert", - "xmpp_maps_updated": "XMPP-Maps wurden aktualisiert", - "xmpp_reloaded": "XMPP-Dienst wurde neu geladen", - "xmpp_restarted": "XMPP-Dienst wurde neu gestartet" + "verified_yotp_login": "Yubico-OTP-Anmeldung verifiziert" }, "tfa": { "api_register": "%s verwendet die Yubico-Cloud-API. Ein API-Key für den Yubico-Stick kann hier bezogen werden.", @@ -1019,7 +993,8 @@ "alias_valid_until": "Gültig bis", "aliases_also_send_as": "Darf außerdem versenden als Benutzer", "aliases_send_as_all": "Absender für folgende Domains und zugehörige Alias-Domains nicht prüfen", - "app_hint": "App-Passwörter sind alternative Passwörter für den IMAP- und SMTP-Login am Mailserver. Der Benutzername bleibt unverändert.
    SOGo (und damit ActiveSync) ist mit diesem Kennwort nicht verwendbar.", + "app_hint": "App-Passwörter sind alternative Passwörter für den IMAP-, SMTP-, CalDAV-, CardDAV- und EAS-Login am Mailserver. Der Benutzername bleibt unverändert.
    SOGo Webmail ist mit diesem Kennwort nicht verwendbar.", + "allowed_protocols": "Erlaubte Protokolle", "app_name": "App-Name", "app_passwds": "App-Passwörter", "apple_connection_profile": "Apple-Verbindungsprofil", @@ -1036,6 +1011,7 @@ "delete_ays": "Soll der Löschvorgang wirklich ausgeführt werden?", "direct_aliases": "Direkte Alias-Adressen", "direct_aliases_desc": "Nur direkte Alias-Adressen werden für benutzerdefinierte Einstellungen berücksichtigt.", + "direct_protocol_access": "Der Hauptbenutzer hat direkten, externen Zugriff auf folgende Protokolle und Anwendungen. Diese Einstellung wird vom Administrator gesteuert. App-Passwörter können verwendet werden, um individuelle Zugänge für Protokolle und Anwendungen zu erstellen.
    Der Button \"In Webmail einloggen\" kann unabhängig der Einstellung immer verwendet werden.", "eas_reset": "ActiveSync-Geräte-Cache zurücksetzen", "eas_reset_help": "In vielen Fällen kann ein ActiveSync-Profil durch das Zurücksetzen des Caches repariert werden.
    Vorsicht: Alle Elemente werden erneut heruntergeladen!", "eas_reset_now": "Jetzt zurücksetzen", diff --git a/data/web/lang/lang.en.json b/data/web/lang/lang.en.json index b24ac6b9..e2d4779a 100644 --- a/data/web/lang/lang.en.json +++ b/data/web/lang/lang.en.json @@ -28,11 +28,7 @@ "spam_score": "Spam score", "syncjobs": "Sync jobs", "tls_policy": "TLS policy", - "unlimited_quota": "Unlimited quota for mailboxes", - "xmpp_admin": "Promote XMPP user to administrator", - "xmpp_domain_access": "Configure XMPP domain access", - "xmpp_mailbox_access": "Configure XMPP user access", - "xmpp_prefix": "Change XMPP subdomain (prefix)" + "unlimited_quota": "Unlimited quota for mailboxes" }, "add": { "activate_filter_warn": "All other filters will be deactivated, when active is checked.", @@ -46,6 +42,7 @@ "alias_domain_info": "Valid domain names only (comma-separated).", "app_name": "App name", "app_password": "Add app password", + "app_passwd_protocols": "Allowed protocols for app password", "automap": "Try to automap folders (\"Sent items\", \"Sent\" => \"Sent\" etc.)", "backup_mx_options": "Relay options", "bcc_dest_format": "BCC destination must be a single valid email address.
    If you need to send a copy to multiple addresses, create an alias and use it here.", @@ -109,13 +106,7 @@ "timeout2": "Timeout for connection to local host", "username": "Username", "validate": "Validate", - "validation_success": "Validated successfully", - "xmpp": "Activate XMPP for this domain", - "xmpp_access": "XMPP access", - "xmpp_access_info": "XMPP must be enabled for this domain.", - "xmpp_admin": "XMPP administrator", - "xmpp_admin_info": "Danger: Promotes a user to an XMPP administrator of this domain.", - "xmpp_info": "This function will enable chat functionality for this domain." + "validation_success": "Validated successfully" }, "admin": { "access": "Access", @@ -471,9 +462,6 @@ "username_invalid": "Username %s cannot be used", "validity_missing": "Please assign a period of validity", "value_missing": "Please provide all values", - "xmpp_map_write_error": "Could not write XMPP map: %s", - "xmpp_reload_failed": "XMPP could not be reloaded", - "xmpp_restart_failed": "XMPP could not be restarted", "yotp_verification_failed": "Yubico OTP verification failed: %s" }, "debug": { @@ -527,6 +515,7 @@ "allowed_protocols": "Allowed protocols", "app_name": "App name", "app_passwd": "App password", + "app_passwd_protocols": "Allowed protocols for app password", "automap": "Try to automap folders (\"Sent items\", \"Sent\" => \"Sent\" etc.)", "backup_mx_options": "Relay options", "bcc_dest_format": "BCC destination must be a single valid email address.
    If you need to send a copy to multiple addresses, create an alias and use it here.", @@ -550,7 +539,7 @@ "extended_sender_acl": "External sender addresses", "extended_sender_acl_info": "A DKIM domain key should be imported, if available.
    \r\n Remember to add this server to the corresponding SPF TXT record.
    \r\n Whenever a domain or alias domain is added to this server, that overlaps with an external address, the external address is removed.
    \r\n Use @domain.tld to allow to send as *@domain.tld.", "force_pw_update": "Force password update at next login", - "force_pw_update_info": "This user will only be able to login to %s.", + "force_pw_update_info": "This user will only be able to login to %s. App passwords remain useable.", "full_name": "Full name", "gal": "Global Address List", "gal_info": "The GAL contains all objects of a domain and cannot be edited by any user. Free/busy information in SOGo is missing, if disabled! Restart SOGo to apply changes.", @@ -609,8 +598,8 @@ "sieve_desc": "Short description", "sieve_type": "Filter type", "skipcrossduplicates": "Skip duplicate messages across folders (first come, first serve)", - "sogo_access": "Grant access to SOGo", - "sogo_access_info": "Grant or permit access to SOGo. This setting does neither affect access to all other services nor does it delete or change a user's existing SOGo profile.", + "sogo_access": "Grant direct login access to SOGo", + "sogo_access_info": "Single-sign-on from within the mail UI remains working. This setting does neither affect access to all other services nor does it delete or change a user's existing SOGo profile.", "sogo_visible": "Alias is visible in SOGo", "sogo_visible_info": "This option only affects objects, that can be displayed in SOGo (shared or non-shared alias addresses pointing to at least one local mailbox). If hidden, an alias will not appear as selectable sender in SOGo.", "spam_alias": "Create or change time limited alias addresses", @@ -648,6 +637,7 @@ "register_status": "Registration status", "rename": "Rename", "set_fido2": "Register FIDO2 device", + "set_fido2_touchid": "Register Touch ID on Apple M1", "set_fn": "Set friendly name", "start_fido2_validation": "Start FIDO2 validation" }, @@ -715,7 +705,7 @@ "all_domains": "All Domains", "allow_from_smtp": "Only allow these IPs to use SMTP", "allow_from_smtp_info": "Leave empty to allow all senders.
    IPv4/IPv6 addresses and networks.", - "allowed_protocols": "Allowed protocols", + "allowed_protocols": "Allowed protocols for direct user access (does not affect app password protocols)", "backup_mx": "Relay domain", "bcc": "BCC", "bcc_destination": "BCC destination", @@ -819,6 +809,15 @@ "stats": "Statistics", "status": "Status", "sync_jobs": "Sync jobs", + "syncjob_check_log": "Check log", + "syncjob_last_run_result": "Last run result", + "syncjob_EX_OK": "Success", + "syncjob_EXIT_CONNECTION_FAILURE": "Connection problem", + "syncjob_EXIT_TLS_FAILURE": "Problem with encrypted connection", + "syncjob_EXIT_AUTHENTICATION_FAILURE": "Authentication problem", + "syncjob_EXIT_OVERQUOTA": "Target mailbox is over quota", + "syncjob_EXIT_CONNECTION_FAILURE_HOST1": "Can't connect to remote server", + "syncjob_EXIT_AUTHENTICATION_FAILURE_USER1": "Wrong username or password", "table_size": "Table size", "table_size_show_n": "Show %s items", "target_address": "Goto address", @@ -1036,7 +1035,8 @@ "alias_valid_until": "Valid until", "aliases_also_send_as": "Also allowed to send as user", "aliases_send_as_all": "Do not check sender access for the following domain(s) and its alias domains", - "app_hint": "App passwords are alternative passwords for your IMAP and SMTP login. The username remains unchanged.
    SOGo (including ActiveSync) is not available through app passwords.", + "app_hint": "App passwords are alternative passwords for your IMAP, SMTP, CalDAV, CardDAV and EAS login. The username remains unchanged. SOGo webmail is not available through app passwords.", + "allowed_protocols": "Allowed protocols", "app_name": "App name", "app_passwds": "App passwords", "apple_connection_profile": "Apple connection profile", @@ -1053,6 +1053,7 @@ "delete_ays": "Please confirm the deletion process.", "direct_aliases": "Direct alias addresses", "direct_aliases_desc": "Direct alias addresses are affected by spam filter and TLS policy settings.", + "direct_protocol_access": "This mailbox user has direct, external access to the following protocols and applications. This setting is controlled by your administrator. App passwords can be created to grant access to individual protocols and applications.
    The \"Login to webmail\" button provides single-sign-on to SOGo and is always available.", "eas_reset": "Reset ActiveSync device cache", "eas_reset_help": "In many cases a device cache reset will help to recover a broken ActiveSync profile.
    Attention: All elements will be redownloaded!", "eas_reset_now": "Reset now", @@ -1146,6 +1147,15 @@ "spamfilter_yellow": "Yellow: this message may be spam, will be tagged as spam and moved to your junk folder", "status": "Status", "sync_jobs": "Sync jobs", + "syncjob_check_log": "Check log", + "syncjob_last_run_result": "Last run result", + "syncjob_EX_OK": "Success", + "syncjob_EXIT_CONNECTION_FAILURE": "Connection problem", + "syncjob_EXIT_TLS_FAILURE": "Problem with encrypted connection", + "syncjob_EXIT_AUTHENTICATION_FAILURE": "Authentication problem", + "syncjob_EXIT_OVERQUOTA": "Target mailbox is over quota", + "syncjob_EXIT_CONNECTION_FAILURE_HOST1": "Can't connect to remote server", + "syncjob_EXIT_AUTHENTICATION_FAILURE_USER1": "Wrong username or password", "tag_handling": "Set handling for tagged mail", "tag_help_example": "Example for a tagged email address: me+Facebook@example.org", "tag_help_explain": "In subfolder: a new subfolder named after the tag will be created below INBOX (\"INBOX/Facebook\").
    \r\nIn subject: the tags name will be prepended to the mails subject, example: \"[Facebook] My News\".", diff --git a/data/web/lang/lang.es.json b/data/web/lang/lang.es.json index eac99a5b..824147c9 100644 --- a/data/web/lang/lang.es.json +++ b/data/web/lang/lang.es.json @@ -419,8 +419,6 @@ "sieve_desc": "Descripción", "sieve_type": "Tipo de filtro", "skipcrossduplicates": "Omitir mensajes duplicados en carpetas (orden de llegada)", - "sogo_access": "Permitir acceso a SOGo", - "sogo_access_info": "Permitir acceso a SOGo. Este ajuste no afecta el acceso a todos los demás servicios ni elimina o cambia el perfil de SOGo existente de un usuario.", "subfolder2": "Sincronizar en subcarpeta en destino
    (vacío = no usar subcarpeta)", "syncjob": "Editar trabajo de sincronización", "target_address": "Dirección/es destino (separadas por coma):", diff --git a/data/web/lang/lang.fi.json b/data/web/lang/lang.fi.json index 3410ccc7..138f1644 100644 --- a/data/web/lang/lang.fi.json +++ b/data/web/lang/lang.fi.json @@ -473,8 +473,6 @@ "sieve_desc": "Lyhyt kuvaus", "sieve_type": "Suodattimen tyyppi", "skipcrossduplicates": "Ohita päällekkäiset viestit kansioiden välillä (ensimmäinen tulee, ensimmäinen palvella)", - "sogo_access": "Myönnä pääsy SOGo-kohteeseen", - "sogo_access_info": "Myönnä tai salli pääsy SOGo-palveluun. Tämä asetus ei vaikuta pääsyä muihin palveluihin eikä se poista tai muuta käyttäjiä jo olemassa SOGo profiilissa", "sogo_visible": "Alias näkyy SOGo-kohteessa", "sogo_visible_info": "Tämä asetus vaikuttaa vain objekteihin, jotka voidaan näyttää SOGo (jaetut tai ei-jaetut alias-osoitteet, jotka viittaavat vähintään yhteen paikalliseen posti laatikkoon).", "spam_alias": "Luo tai muuta aika rajoitettuja aliaksen osoitteita", diff --git a/data/web/lang/lang.fr.json b/data/web/lang/lang.fr.json index 07cd326c..9ba9e279 100644 --- a/data/web/lang/lang.fr.json +++ b/data/web/lang/lang.fr.json @@ -26,11 +26,7 @@ "syncjobs": "Tâches de synchronisation", "tls_policy": "Police TLS", "unlimited_quota": "Quota illimité pour les boites de courriel", - "domain_desc": "Modifier la description du domaine", - "xmpp_admin": "Promouvoir l'utilisateur XMPP en administrateur", - "xmpp_domain_access": "Configurer l'accès au domaine XMPP", - "xmpp_mailbox_access": "Configurer l'accès à l'utilisateur XMPP", - "xmpp_prefix": "Changer le sous-domaine XMPP (préfixe)" + "domain_desc": "Modifier la description du domaine" }, "add": { "activate_filter_warn": "Tous les autres filtres seront désactivés, quand activé est coché.", @@ -63,12 +59,6 @@ "full_name": "Nom complet", "gal": "Carnet d'Adresses Global (GAL)", "gal_info": "La liste d'adresse globale (GAL) contient tous les objets d'un domaine et ne peut être modifié par aucun utilisateur. Si elles sont désactivées,les informations libres/occupées dans SOGo sont cachées, ! Redémarrez SOGo pour appliquer les changements.", - "xmpp": "Activer XMPP pour ce domaine", - "xmpp_info": "Cette fonction activera la fonctionnalité de chat pour ce domaine.", - "xmpp_access": "Accès XMPP", - "xmpp_access_info": "XMPP doit être activé pour ce domaine.", - "xmpp_admin": "Administrateur XMPP", - "xmpp_admin_info": "Attention: promeut un utilisateur au rang d'administrateur XMPP pour ce domaine.", "generate": "Générer", "goto_ham": "Apprendre en tant que Courrier légitime (ham)", "goto_null": "Ignorer silencieusement le courriel", @@ -363,7 +353,6 @@ "global_filter_write_error": "Impossible d’écrire le fichier de filtre: %s", "global_map_invalid": "ID de carte globale %s non valide", "global_map_write_error": "Impossible d’écrire l’ID de la carte globale %s: %s", - "xmpp_map_write_error": "Impossible d'écrire la carte XMPP: %s", "goto_empty": "Une adresse alias doit contenir au moins une adresse 'goto'valide", "goto_invalid": "Adresse Goto %s non valide", "ham_learn_error": "Erreur d'apprentissage Ham: %s", @@ -449,9 +438,7 @@ "username_invalid": "Le nom d'utilisateur %s ne peut pas être utilisé", "validity_missing": "Veuillez attribuer une période de validité", "value_missing": "Veuillez fournir toutes les valeurs", - "yotp_verification_failed": "La vérification Yubico OTP a échoué: %s", - "xmpp_restart_failed": "XMPP n'a pas pu être redémarré", - "xmpp_reload_failed": "XMPP n'a pas pu être rechargé" + "yotp_verification_failed": "La vérification Yubico OTP a échoué: %s" }, "debug": { "chart_this_server": "Graphique (ce serveur)", @@ -465,7 +452,6 @@ "logs": "Logs", "restart_container": "Redémarrer", "solr_dead": "Solr est en cours de démarrage, désactivé ou mort.", - "xmpp_dead": "XMPP est en cours de démarrage, désactivé ou mort.", "docs": "Docs", "last_modified": "Dernière modification", "online_users": "Utilisateurs en ligne", @@ -475,8 +461,7 @@ "uptime": "Disponibilité", "started_on": "Démarré à", "static_logs": "Logs statiques", - "system_containers": "Système & Conteneurs", - "xmpp_status": "Status de XMPP" + "system_containers": "Système & Conteneurs" }, "diagnostics": { "cname_from_a": "Valeur dérivée de l’enregistrement A/AAAA. Ceci est supporté tant que l’enregistrement indique la bonne ressource.", @@ -525,15 +510,6 @@ "full_name": "Nom complet", "gal": "Liste d'adresses globale (GAL)", "gal_info": "La liste d'adresses globale (GAL) contient tous les objets d’un domaine et ne peut pas être édité par un utilisateur. Les informations libres/occupées dans SOGo sont manquantes si elles sont désactivées! Redémarrer SOGo pour appliquer les modifications.", - "xmpp": "Activer XMPP pour ce domaine", - "xmpp_prefix": "Préfixe XMPP pour le domaine (\"im\" pour utiliser im.exemple.org)", - "xmpp_prefix_info": "Pour demander des certificats XMPP, deux enregistrements DNS CNAME doivent pointer de im .exemple.org ainsi que de * .im .exemple.org vers % s . Veuillez également exécuter la vérification DNS pour ce domaine après avoir activé XMPP.", - "xmpp_info": "Cette fonction activera la fonctionnalité de chat pour ce domaine.", - "xmpp_access": "Accès XMPP", - "xmpp_access_info": "XMPP doit être activé pour ce domaine.", - "xmpp_admin": "Administrateur XMPP", - "xmpp_admin_info": "Attention: Promeut un utilisateur au rang d'administrateur XMPP de ce domaine.", - "xmpp_example_jid": "Exemple JID (se connecter avec le mot de passe de la boîte aux lettres)", "generate": "générer", "grant_types": "Types 'autorisation", "hostname": "Nom d'hôte", @@ -583,8 +559,6 @@ "sieve_desc": "Description courte", "sieve_type": "Type de filtre", "skipcrossduplicates": "Ignorer les messages en double dans les dossiers (premier arrivé, premier servi)", - "sogo_access": "Accorder l'accès à", - "sogo_access_info": "Accorder ou permettre l’accès à SOGo. Ce paramètre n’affecte pas l’accès à tous les autres services ni ne supprime ou ne modifie un profil SOGo existant.", "sogo_visible": "Alias visible dans SOGo", "sogo_visible_info": "Cette option affecte uniquement les objets qui peuvent être affichés dans SOGo (adresses alias partagées ou non partagées pointant vers au moins une boîte mail locale). Si caché, un alias n’apparaîtra pas comme expéditeur sélectionnable dans SOGo.", "spam_alias": "Créer ou modifier des adresses alias limitées dans le temps", @@ -923,10 +897,7 @@ "verified_totp_login": "Authentification TOTP vérifiée", "verified_u2f_login": "Authentification U2F vérifiée", "verified_fido2_login": "Authentification FIDO2 vérifiée", - "verified_yotp_login": "Authentification Yubico OTP vérifiée", - "xmpp_restarted": "Le service XMPP a été redémarré", - "xmpp_reloaded": "Le service XMPP a été rechargé", - "xmpp_maps_updated": "Les cartes XMPP ont été mises à jour" + "verified_yotp_login": "Authentification Yubico OTP vérifiée" }, "tfa": { "api_register": "%s utilise l'API Yubico Cloud. Veuillez obtenir une clé API pour votre clé here", @@ -982,7 +953,7 @@ "alias_valid_until": "Valide jusque", "aliases_also_send_as": "Aussi autorisé à envoyer en tant qu’utilisateur", "aliases_send_as_all": "Ne pas vérifier l’accès de l’expéditeur pour les domaines suivants et leurs alias", - "app_hint": "Les mots de passe d’application sont des mots de passe alternatifs pour votre connexion IMAP et SMTP. Le nom d’utilisateur reste inchangé.
    SOGo (incluant ActiveSync) n'est pas disponible au travers de mots de passe.", + "app_hint": "Les mots de passe d’application sont des mots de passe alternatifs pour votre connexion IMAP, SMTP, Caldav, Carddav et EAS. Le nom d’utilisateur reste inchangé.
    SOGo n'est pas disponible au travers de mots de passe.", "app_name": "Nom d'application", "app_passwds": "Mots de passe de l'application", "apple_connection_profile": "Profil de connexion Apple", diff --git a/data/web/lang/lang.it.json b/data/web/lang/lang.it.json index c02057ff..aa7a8dc2 100644 --- a/data/web/lang/lang.it.json +++ b/data/web/lang/lang.it.json @@ -28,11 +28,7 @@ "spam_score": "Punteggio SPAM", "syncjobs": "Processi di sync", "tls_policy": "TLS policy", - "unlimited_quota": "Spazio illimitato per le caselle di posta", - "xmpp_admin": "Promuovi l'utente XMPP ad amministratore", - "xmpp_domain_access": "Configura l'accesso al dominio XMPP", - "xmpp_mailbox_access": "Configura l'accesso utente XMPP", - "xmpp_prefix": "Cambia sottodominio XMPP (prefisso)" + "unlimited_quota": "Spazio illimitato per le caselle di posta" }, "add": { "activate_filter_warn": "Tutti gli altri filtri saranno disattivati, quando è attivo.", @@ -58,7 +54,7 @@ "destination": "Destinazione", "disable_login": "Disabilita l'accesso (la posta in arrivo viene correttamente recapitata)", "domain": "Dominio", - "domain_matches_hostname": "Il dominio %s corrisponde al'hostname", + "domain_matches_hostname": "Il dominio %s corrisponde al'hostname", "domain_quota_m": "Spazio totale dominio (MiB)", "enc_method": "Metodo di crittografia", "exclude": "Escludi oggetti (regex)", @@ -68,7 +64,7 @@ "generate": "crea", "goto_ham": "Etichetta come ham", "goto_null": "Elimina silenziosamente il messaggio", - "goto_spam": "Etichetta come spam", + "goto_spam": "Etichetta come spam", "hostname": "Hostname", "inactive": "Inattivo", "kind": "Genere", @@ -108,13 +104,7 @@ "timeout2": "Timeout per la connessione all'host locale", "username": "Username", "validate": "Convalida", - "validation_success": "Convalidato con successo", - "xmpp": "Attiva XMPP per questo dominio", - "xmpp_access": "Accesso XMPP", - "xmpp_access_info": "XMPP deve essere abilitato per questo dominio.", - "xmpp_admin": "Amministratore XMPP", - "xmpp_admin_info": "Attenzione: Promuove un utente ad amministratore XMPP di questo dominio.", - "xmpp_info": "Questa funzione abiliterà la funzionalità di chat per questo dominio." + "validation_success": "Convalidato con successo" }, "admin": { "access": "Accedi", @@ -158,7 +148,7 @@ "customer_id": "ID cliente", "customize": "Personalizzare", "delete_queue": "Elimina tutto", - "destination": "Destinazione", + "destination": "Destinazione", "dkim_add_key": "Aggiungi chiave ARC/DKIM", "dkim_domains_selector": "Selettore", "dkim_domains_wo_keys": "Seleziona i domini senza chiavi", @@ -228,7 +218,7 @@ "nexthop": "Next hop", "no": "✕", "no_active_bans": "Nessun ban attivo", - "no_new_rows": "Nessuna ulteriore riga disponibile", + "no_new_rows": "Nessuna ulteriore riga disponibile", "no_record": "Nessun risultato", "oauth2_client_id": "ID cliente", "oauth2_client_secret": "Client secret", @@ -342,7 +332,7 @@ "ui_texts": "UI labels and texts", "unban_pending": "unban pending", "unchanged_if_empty": "Se immutato lasciare vuoto", - "upload": "Upload", + "upload": "Upload", "username": "Username", "validate_license_now": "Validate GUID against license server", "verify": "Verifica", @@ -583,7 +573,7 @@ "quota_warning_bcc": "Quota warning BCC", "quota_warning_bcc_info": "Warnings will be sent as separate copies to the following recipients. The subject will be suffixed by the corresponding username in brackets, for example: Quota warning (user@example.com).", "ratelimit": "Rate limit", - "redirect_uri": "Redirect/Callback URL", + "redirect_uri": "Redirect/Callback URL", "relay_all": "Relay tutti i destinatari", "relay_all_info": "Se si sceglie di non inviare a tutti i destinatari, è necessario aggiungere una casella di posta (\"blind\") per ogni singolo destinatario a cui deve essere inoltrato.", "relay_domain": "Relay dominio", @@ -600,15 +590,13 @@ "sieve_desc": "Short description", "sieve_type": "Filter type", "skipcrossduplicates": "Skip duplicate messages across folders (first come, first serve)", - "sogo_access": "Grant access to SOGo", - "sogo_access_info": "Grant or permit access to SOGo. This setting does neither affect access to all other services nor does it delete or change a user's existing SOGo profile.", "sogo_visible": "Alias is visible in SOGo", "sogo_visible_info": "This option only affects objects, that can be displayed in SOGo (shared or non-shared alias addresses pointing to at least one local mailbox). If hidden, an alias will not appear as selectable sender in SOGo.", "spam_alias": "Create or change time limited alias addresses", "spam_filter": "Spam filter", "spam_policy": "Add or remove items to white-/blacklist", "spam_score": "Set a custom spam score", - "subfolder2": "Sincronizza in una sottocartella
    (vuoto = non sincronizzare in sottocartella)", + "subfolder2": "Sincronizza in una sottocartella
    (vuoto = non sincronizzare in sottocartella)", "syncjob": "Modifica sincronizzazione", "target_address": "Vai all'indirizzo/i (separato da virgola)", "target_domain": "Target dominio", @@ -1011,7 +999,7 @@ "alias_valid_until": "Valido fino a", "aliases_also_send_as": "Può inviare come utente", "aliases_send_as_all": "Do not check sender access for the following domain(s) and its alias domains", - "app_hint": "App passwords are alternative passwords for your IMAP and SMTP login. The username remains unchanged.
    SOGo (including ActiveSync) is not available through app passwords.", + "app_hint": "App passwords are alternative passwords for your IMAP, SMTP, CalDAV, CardDAV and EAS login. The username remains unchanged. SOGo webmail is not available through app passwords.", "app_name": "App name", "app_passwds": "App passwords", "apple_connection_profile": "Profilo di connessione Apple", diff --git a/data/web/lang/lang.ko.json b/data/web/lang/lang.ko.json index cdd34b1b..792b73a7 100644 --- a/data/web/lang/lang.ko.json +++ b/data/web/lang/lang.ko.json @@ -539,8 +539,6 @@ "sieve_desc": "Short description", "sieve_type": "Filter type", "skipcrossduplicates": "Skip duplicate messages across folders (first come, first serve)", - "sogo_access": "Grant access to SOGo", - "sogo_access_info": "Grant or permit access to SOGo. This setting does neither affect access to all other services nor does it delete or change a users existing SOGo profile.", "sogo_visible": "Alias is visible in SOGo", "sogo_visible_info": "This option only affects objects, that can be displayed in SOGo (shared or non-shared alias addresses pointing to at least one local mailbox). If hidden, an alias will not appear as selectable sender in SOGo.", "spam_alias": "Create or change time limited alias addresses", diff --git a/data/web/lang/lang.nl.json b/data/web/lang/lang.nl.json index 03c55e9a..4afd4b14 100644 --- a/data/web/lang/lang.nl.json +++ b/data/web/lang/lang.nl.json @@ -26,11 +26,7 @@ "syncjobs": "Sync jobs", "tls_policy": "Versleutelingsbeleid", "unlimited_quota": "Onbeperkte quota voor mailboxen", - "domain_desc": "Wijzig domeinbeschrijving", - "xmpp_admin": "Promoveer XMPP-gebruiker tot administrator", - "xmpp_domain_access": "Configureer XMPP-domeintoegang", - "xmpp_mailbox_access": "Configureer XMPP-gebruikerstoegang", - "xmpp_prefix": "Wijzig XMPP subdomein (prefix)" + "domain_desc": "Wijzig domeinbeschrijving" }, "add": { "activate_filter_warn": "Alle andere filters worden gedeactiveerd zolang deze geactiveerd is.", @@ -63,12 +59,6 @@ "full_name": "Volledige naam", "gal": "Globale adreslijst", "gal_info": "De globale adreslijst bevat alle objecten van een domein. Deze kunnen door geen enkele gebruiker worden bewerkt. Herstart SOGo om wijzigingen door te voeren.", - "xmpp": "Activeer XMPP voor dit domein", - "xmpp_info": "Deze optie activeert de chatfunctionaliteit voor dit domein.", - "xmpp_access": "XMPP-toegang", - "xmpp_access_info": "XMPP dient ingeschakeld te zijn voor dit domein.", - "xmpp_admin": "XMPP-administrator", - "xmpp_admin_info": "Waarschuwing: Promoveert een gebruiker tot XMPP-administrator van dit domein.", "generate": "genereer", "goto_ham": "Train als ham", "goto_null": "Verwijder mail onmiddelijk", @@ -583,8 +573,6 @@ "sieve_desc": "Korte beschrijving", "sieve_type": "Filtertype", "skipcrossduplicates": "Sla duplicaten verspreid over mappen over (wie het eerst komt, het eerst maalt)", - "sogo_access": "Geef toegang to SOGo", - "sogo_access_info": "Deze gebruiker kan, wanneer ingeschakeld, gebruikmaken van SOGo. Deze instelling heeft geen invloed op de overige services. Het SOGo-profiel van deze gebruiker zal bewaard blijven.", "sogo_visible": "Alias tonen in SOGo", "sogo_visible_info": "Wanneer verborgen zal een alias niet worden weergegeven als een selecteerbaar verzendadres. Deze optie beïnvloedt uitsluitend objecten die kunnen worden weergegeven in SOGo (gedeelde of niet-gedeelde aliasadressen die naar minstens één mailbox verwijzen).", "spam_alias": "Maak een nieuw tijdelijk alias aan, of pas deze aan", @@ -980,7 +968,7 @@ "alias_valid_until": "Geldig tot", "aliases_also_send_as": "Toegestaan om te verzenden als", "aliases_send_as_all": "Controleer verzendtoegang voor de volgende domeinen, inclusief aliassen, niet", - "app_hint": "Appwachtwoorden zijn alternatieve wachtwoorden voor IMAP en SMTP. De gebruikersnaam blijft ongewijzigd.
    SOGo (inclusief ActiveSync) is niet toegankelijk met een appwachtwoord.", + "app_hint": "Appwachtwoorden zijn alternatieve wachtwoorden voor IMAP, SMTP, CalDAV, CardDAV en EAS. De gebruikersnaam blijft ongewijzigd.
    SOGo is niet toegankelijk met een appwachtwoord.", "app_name": "Naam van app", "app_passwds": "Appwachtwoorden", "apple_connection_profile": "Apple-verbindingsprofiel", diff --git a/data/web/lang/lang.ro.json b/data/web/lang/lang.ro.json index 80a776c9..3e03351d 100644 --- a/data/web/lang/lang.ro.json +++ b/data/web/lang/lang.ro.json @@ -28,11 +28,7 @@ "spam_score": "Scor spam", "syncjobs": "Lucrări de sincronizare", "tls_policy": "Politică TLS", - "unlimited_quota": "Cota nelimitată pentru cutiile poștale", - "xmpp_admin": "Promovează utilizatorul XMPP ca administrator", - "xmpp_domain_access": "Configurează accesul domeniului la XMPP", - "xmpp_mailbox_access": "Configurează accesul utilizatorului la XMPP", - "xmpp_prefix": "Schimbă subdomeniul (prefixul) pentru XMPP" + "unlimited_quota": "Cota nelimitată pentru cutiile poștale" }, "add": { "activate_filter_warn": "Toate celelalte filtre vor fi dezactivate, când este bifată opțiunea activă.", @@ -65,12 +61,6 @@ "full_name": "Nume complet", "gal": "Lista adreselor globale", "gal_info": "GAL conține toate obiectele unui domeniu și nu poate fi editat de niciun utilizator. Informația liber/ocupat din SOGo lipsește dacă este dezactivat! Reporniți SOGo pentru a aplica modificările.", - "xmpp": "Activează XMPP pentru acest domeniu", - "xmpp_info": "Această funcție va activa mesageria pentru acest domeniu.", - "xmpp_access": "Acces XMPP", - "xmpp_access_info": "XMPP trebuie să fie activ pentru acest domeniu.", - "xmpp_admin": "Administrator XMPP", - "xmpp_admin_info": "Atenție: Promovează un utilizator ca administrator XMPP pentru acest domeniu.", "generate": "generează", "goto_ham": "Învață ca ham", "goto_null": "Aruncă emailul în mod silențios", @@ -610,8 +600,6 @@ "sieve_desc": "Descriere scurtă", "sieve_type": "Tip filtru", "skipcrossduplicates": "Sari peste mesajele duplicate din toate folderele (primul venit, primul servit)", - "sogo_access": "Acordă acces la SOGo", - "sogo_access_info": "Acordă sau permite accesul la SOGo. Această setare nu afectează accesul la toate celelalte servicii și nici nu șterge sau modifică profilul SOGo existent al utilizatorului.", "sogo_visible": "Aliasul este vizibil în SOGo", "sogo_visible_info": "Această opțiune afectează doar obiecte, care pot fi afișate în SOGo (adrese alias partajate sau ne-partajate cu cel puțin o căsuță poștală locală). Dacă este ascuns, un alias nu va apărea ca expeditor selectabil în SOGo.", "spam_alias": "Crează sau modifică adrese alias limitate în funcție de timp", @@ -1015,7 +1003,7 @@ "alias_valid_until": "Valabil până la", "aliases_also_send_as": "De asemenea, este permis să trimită ca utilizator", "aliases_send_as_all": "Nu se verifică accesul expeditorului pentru următorul(arele) domeniu(i) și domeniile sale alias", - "app_hint": "Parolele aplicației sunt parole alternative pentru autentificarea IMAP și SMTP. Numele de utilizator rămâne neschimbat.
    SOGo (inclusiv ActiveSync) nu este disponibil prin parolele aplicației.", + "app_hint": "Parolele aplicației sunt parole alternative pentru autentificarea IMAP, SMTP, CalDAV, CardDAV și EAS. Numele de utilizator rămâne neschimbat.
    SOGo nu este disponibil prin parolele aplicației.", "app_name": "Nume aplicație", "app_passwds": "Parole aplicație", "apple_connection_profile": "Profil de conexiune Apple", diff --git a/data/web/lang/lang.ru.json b/data/web/lang/lang.ru.json index f24ae355..8c8ab887 100644 --- a/data/web/lang/lang.ru.json +++ b/data/web/lang/lang.ru.json @@ -4,17 +4,20 @@ "app_passwds": "Пароли приложений", "bcc_maps": "Правила BBC", "delimiter_action": "Обработка тегированной почты", + "domain_desc": "Изменение описания домена", + "domain_relayhost": "Изменение промежуточных узлов для домена", "eas_reset": "Сброс кеша ActiveSync устройств", "extend_sender_acl": "Расширение ACL отправителя для внешних адресов", "filters": "Фильтры", "login_as": "Войти как пользователь почтового аккаунта", + "mailbox_relayhost": "Изменение промежуточных узлов для почтового аккаунта", "prohibited": "Запрещено правилами ACL", "protocol_access": "Настройка разрешенных протоколов", "pushover": "Pushover API", "quarantine": "Карантин - действия", "quarantine_attachments": "Карантин - вложения", - "quarantine_notification": "Уведомления о спаме", "quarantine_category": "Категория уведомлений о спаме", + "quarantine_notification": "Уведомления о спаме", "ratelimit": "Лимиты отправки", "recipient_maps": "Перезапись получателя", "smtp_ip_access": "Настройка разрешенных IP для SMTP", @@ -25,12 +28,7 @@ "spam_score": "Политика фильтрации спама", "syncjobs": "Задания синхронизации", "tls_policy": "Политика шифрования", - "unlimited_quota": "Неограниченная квота для почтовых ящиков", - "domain_desc": "Изменение описания домена", - "xmpp_admin": "Повышение пользователя XMPP до администратора", - "xmpp_domain_access": "Настройка доступа XMPP для домена", - "xmpp_mailbox_access": "Настройка доступа XMPP для пользователей", - "xmpp_prefix": "Измение субдомена (префикса) XMPP" + "unlimited_quota": "Неограниченная квота для почтовых ящиков" }, "add": { "activate_filter_warn": "Активация этого фильтра отключит все остальные фильтры этого типа.", @@ -46,6 +44,7 @@ "app_password": "Добавить пароль приложения", "automap": "Автоматическое слияние папок (\"Sent items\", \"Sent\" => \"Sent\" etc.)", "backup_mx_options": "Параметры резервного MX", + "bcc_dest_format": "Место назначения BCC должно быть единственным действительным адресом электронной почты.
    Если вам нужно отправить копию на несколько адресов - используйте псевдоним.", "comment_info": "Приватный комментарий не виден пользователям, а публичный - отображается рядом с псевдонимом в личном кабинете пользователя.", "custom_params": "Пользовательские параметры", "custom_params_hint": "Верно: --param=xy, не верно: --param xy", @@ -63,14 +62,8 @@ "full_name": "Полное имя", "gal": "GAL - Глобальная адресная книга", "gal_info": "GAL содержит все объекты домена и не подлежит редактированию. Информация о занятости в SOGo будет отсутствовать для домена, если эта функция не будет включена! Требуется перезапустить SOGo, чтобы изменения применились.", - "xmpp": "Активировать XMPP для этого домена", - "xmpp_info": "Эта опция добавит функциональность чата для этого домена.", - "xmpp_access": "Пользователь XMPP", - "xmpp_access_info": "XMPP должен быть включен для этого домена.", - "xmpp_admin": "Администратор XMPP", - "xmpp_admin_info": "Повысить пользователя XMPP до администратора домена.", "generate": "сгенерировать", - "goto_ham": "Запомнить как «ham»", + "goto_ham": "Запомнить как полезную почту", "goto_null": "Отключить входящую почту", "goto_spam": "Запомнить как спам", "hostname": "Имя хоста", @@ -104,7 +97,7 @@ "skipcrossduplicates": "Пропускать повторяющиеся сообщения в папках", "subscribeall": "Подписаться на все папки и подпапки", "syncjob": "Добавить задание синхронизации", - "syncjob_hint": "К сведению: пароли к вашему аккаунту будут сохранены на сервере в виде простого текста!", + "syncjob_hint": "Пароли к вашему аккаунту будут сохранены на сервере в виде простого текста!", "target_address": "Владельцы псевдонима", "target_address_info": "Адреса почтовых ящиков, разделенные запятыми.", "target_domain": "Целевой домен", @@ -133,14 +126,16 @@ "add_transports_hint": "Пожалуйста имейте в виду, что данные для аутентификации будут храниться в виде обычного текста.", "additional_rows": " добавлены дополнительные строки", "admin": "Администратор", - "admins": "Администраторы", - "admins_ldap": "LDAP Администраторы", "admin_details": "Изменить данные администратора", "admin_domains": "Домен назначения", + "admins": "Администраторы", + "admins_ldap": "Администраторы LDAP", "advanced_settings": "Расширенные настройки", "api_allow_from": "Список IP-адресов для доступа к API (разделенных запятой или новой строкой)", "api_info": "API находится в стадии разработки. Документация находится по адресу /api", "api_key": "Ключ API", + "api_read_only": "Доступ только для чтения", + "api_read_write": "Доступ на чтение и запись", "api_skip_ip_check": "Пропустить проверку IP для API", "app_links": "Ссылки на приложения", "app_name": "Название приложения", @@ -178,7 +173,7 @@ "duplicate": "Скопировать", "duplicate_dkim": "Копирование DKIM записи", "edit": "Изменить", - "empty": "Нет результатов", + "empty": "Пусто", "excludes": "Исключает этих получателей", "f2b_ban_time": "Время бана (в секундах)", "f2b_blacklist": "Черный список подсетей/хостов", @@ -211,15 +206,17 @@ "include_exclude": "Включить/Исключить", "include_exclude_info": "По умолчанию - без выбора - все почтовые ящики адресованы", "includes": "Включить этих получателей", + "is_mx_based": "На основе MX", "last_applied": "Посл. применение", "license_info": "Лицензия не обязательна, но её приобретение помогает дальнейшему развитию mailcow.
    Зарегистрируйте свой GUID здесь или приобретите поддержку для вашей установки mailcow.", "link": "Ссылка", "loading": "Пожалуйста, подождите...", + "login_time": "Время входа", "logo_info": "Ваше изображение будет масштабироваться до высоты 40px для верхней панели навигации и до 250px ширины для стартовой страницы.
    Рекомендуется использовать векторную графику, на пример: .svg.", - "lookup_mx": "Сопоставление назначения с записью MX (.outlook.com для маршрутизации всей почты, направленной на MX *.outlook.com через этот хост)", + "lookup_mx": "Назначение на основе резовинга MX записи по регулярному выражению (.*\\.example\\.com$ для маршрутизации всей почты через этот хост, если MX заканчивающийся на example.com)", "main_name": "Название для \"mailcow UI\"", "merged_vars_hint": "Серым цветом выделены строки полученные из vars.(local.)inc.php, они не могут быть изменены.", - "message": "Письма", + "message": "Сообщение", "message_size": "Размер сообщения", "nexthop": "Следующий хост", "no": "✕", @@ -227,8 +224,10 @@ "no_new_rows": "Нет доступных строк", "no_record": "Нет записей", "oauth2_client_id": "ID клиента", + "oauth2_apps": "Приложения OAuth2", + "oauth2_add_client": "Добавить клиента OAuth2", "oauth2_client_secret": "Секретный ключ пользователя", - "oauth2_info": "Реализация OAuth2 поддерживает предоставления кодов авторизации и выдает токены продления сессии.
    \r\nСервер также автоматически выдает новый токен продления сессии, после того, как предыдущий был использован.

    \r\n→ Scope по умолчанию: profile. Только пользователи почтовых аккаунтов могут проходить аутентификацию через OAuth2. Если параметр области не указан, он возвращается к profile.
    \r\n→ Параметр state должен быть отправлен клиентом как часть запроса для авторизации.

    \r\nПути для запросов OAuth2 API:
    \r\n
      \r\n
    • Authorization endpoint: /oauth/authorize
    • \r\n
    • Token endpoint: /oauth/token
    • \r\n
    • Resource page: /oauth/profile
    • \r\n
    \r\nГенерирование нового клиентского секрета не приводит к истечению существующих кодов авторизации, но они не смогут обновить свой токен.

    \r\nОтзыв клиентских токенов приведет к немедленному прекращению всех активных сеансов. Все клиенты должны будут пройти повторную аутентификацию.", + "oauth2_info": "Реализация OAuth2 поддерживает предоставления кодов авторизации и выдает токены продления сессии.
    \r\nСервер также автоматически выдает новый токен продления сессии, после того, как предыдущий был использован.

    \r\n• Scope по умолчанию: profile. Только пользователи почтовых аккаунтов могут проходить аутентификацию через OAuth2. Если параметр области не указан, он возвращается к profile.
    \r\n• Параметр state должен быть отправлен клиентом как часть запроса для авторизации.

    \r\nПути для запросов OAuth2 API:
    \r\n
      \r\n
    • Authorization endpoint: /oauth/authorize
    • \r\n
    • Token endpoint: /oauth/token
    • \r\n
    • Resource page: /oauth/profile
    • \r\n
    \r\nГенерирование нового клиентского секрета не приводит к истечению существующих кодов авторизации, но они не смогут обновить свой токен.

    \r\nОтзыв клиентских токенов приведет к немедленному прекращению всех активных сеансов. Все клиенты должны будут пройти повторную аутентификацию.", "oauth2_redirect_uri": "Переадресация URI", "oauth2_renew_secret": "Сгенерировать новый ключ клиента", "oauth2_revoke_tokens": "Отозвать все клиентские токены", @@ -238,8 +237,8 @@ "password_policy": "Политика паролей", "password_policy_chars": "Должен содержать алфавитный символ", "password_policy_length": "Минимальная длина пароля %d символов", - "password_policy_numbers": "Должен содержать цифру", "password_policy_lowerupper": "Должны содержать символы верхнего и нижнего регистров", + "password_policy_numbers": "Должен содержать цифру", "password_policy_special_chars": "Должны содержать специальный символ", "password_repeat": "Подтверждение пароля (повтор)", "priority": "Приоритет", @@ -248,8 +247,8 @@ "quarantine_bcc": "Отправка копии всех уведомлений (BCC) к получателю:
    Получатель должен быть внутренним, так как почта не подписана и не проверена.
    Отключено, если получатель не указан.
    ", "quarantine_exclude_domains": "Исключить домены и псевдонимы доменов", "quarantine_max_age": "Максимальный период хранения в днях
    Значение должно быть равно или больше 1 дня.", - "quarantine_max_size": "Максимальный размер в MiB (письма большего размера не будет сохранены):
    0 означает, что карантин отключён.", "quarantine_max_score": "Не уведомлять о спаме, если оценка письма выше, чем:
    По умолчанию 9999.0", + "quarantine_max_size": "Максимальный размер в MiB (письма большего размера не будет сохранены):
    0 означает, что карантин отключён.", "quarantine_notification_html": "Шаблон уведомления:
    Оставьте пустым, чтобы восстановить шаблон по умолчанию.", "quarantine_notification_sender": "Email-адрес для отправки уведомления", "quarantine_notification_subject": "Тема письма", @@ -269,7 +268,7 @@ "quota_notification_sender": "Email-адрес для отправки уведомления", "quota_notification_subject": "Тема письма", "quota_notifications": "Квота", - "quota_notifications_info": "Уведомления о достижении квоты отправляются пользователям дважды при достижении 80% и 95% от установленной квоты.", + "quota_notifications_info": "Уведомления о достижении квоты отправляются пользователям при достижении 80% и 95% от установленной квоты.", "quota_notifications_vars": "{{percent}} равно текущей квоте пользователя
    {{username}} - имя почтового аккаунта", "r_active": "Включенные ограничения", "r_inactive": "Отключенные ограничения", @@ -282,7 +281,7 @@ "relay_from": "\"От:\"", "relay_rcpt": "\"Кому:\"", "relay_run": "Запустить тест", - "relayhosts": "Транспортировка в зависимости от отправителя", + "relayhosts": "Маршрутизация на основе отправителя", "relayhosts_hint": "Определите промежуточные узлы здесь, чтобы иметь возможность выбрать их в диалоговом окне конфигурации доменов.", "remove": "Удалить", "remove_row": "Удалить строку", @@ -295,9 +294,10 @@ "rsetting_no_selection": "Пожалуйста, выберите правило", "rsetting_none": "Нет доступных правил", "rsettings_insert_preset": "Вставить пример \"%s\"", - "rsettings_preset_1": "Отключить все, кроме DKIM и ограничения скорости для аутентифицированных пользователей ", - "rsettings_preset_2": "Postmasters want spam", - "rsettings_preset_3": "Разрешить только определённых отправителей для почтового ящика (использование только в качестве внутреннего почтового ящика) ", + "rsettings_preset_1": "Отключить все, кроме DKIM и ограничения скорости для аутентифицированных пользователей", + "rsettings_preset_2": "Не проверять письма на спам Postmaster", + "rsettings_preset_3": "Разрешить только определённых отправителей для почтового ящика (использование только в качестве внутреннего почтового ящика)", + "rsettings_preset_4": "Отключить Rspamd для домена", "rspamd-com_settings": "Имена правил будут сгенерированы на основе их ID.
    Инструкция доступна на сайте документация Rspamd user settings, заготовленные шаблоны:", "rspamd_global_filters": "Глобальные правила фильтрации", "rspamd_global_filters_agree": "Я понимаю, что я делаю, и буду осторожен!", @@ -309,20 +309,22 @@ "search_domain_da": "Поиск доменов", "send": "Отправить", "sender": "Отправитель", + "service": "Сервис", "service_id": "ID сервиса", "source": "Источник", "spamfilter": "Спам фильтр", "subject": "Тема письма", + "success": "Успех", "sys_mails": "Системные сообщения", "text": "Обычный текст", "time": "Время", - "title": "Название \"mailcow UI\" для страницы входа:", - "title_name": "Заголовок title \"mailcow UI\":", + "title": "Название", + "title_name": "Заголовок сайта \"mailcow UI\"", "to_top": "Вернуться к началу", - "transport_dest_format": "example.org, .example.org, *, box@example.org (несколько значений могут быть разделены запятыми)", - "transport_maps": "Глобальные правила отправки", - "transports_hint": "→ Записи в transport map отменяют sender-dependent transport map
    .
    \r\n→ Пользовательские политики TLS для исходящей почты будут проигнорированы и будут использовать политику TLS для записей используемых здесь.
    \r\n→ Протокол для доставки всегда \"smtp:\".
    \r\n→ Адреса соответствующие \"/localhost$/\" всегда будут доставлены \"local:\", следовательно политика \"*\" не распространяется на них.
    \r\n→ Чтобы определить учётные данные для следующего узла \"[host]:25\", Postfix всегда ищет данные для \"host\" перед тем как искать \"[host]:25\". Такое поведение делает невозможным использование \"host\" and \"[host]:25\" одновременно.", - "transport_test_rcpt_info": "→ Используйте null@hosted.mailcow.de для тестирования пересылки на внешний пункт назначения.", + "transport_dest_format": "Регулярное выражение или: example.org, .example.org, *, box@example.org (несколько значений могут быть разделены запятыми)", + "transport_maps": "Глобальные правила маршрутизации", + "transport_test_rcpt_info": "• Используйте null@hosted.mailcow.de для тестирования пересылки на внешний пункт назначения.", + "transports_hint": "• Глобальные правила маршрутизации преобладают над маршрутами на основе отправителя.
    \r\n• Предпочтительно использовать транспорты на основе резолвинга MX.
    \r\n• Пользовательские политики TLS для исходящей почты будут проигнорированы и будут использовать политику TLS настроенную здесь.
    \r\n• Протокол для доставки всегда \"smtp:\" и поэтому будет пытаться использовать TLS, если следующий хост поддерживает его. SMTPS (TLS, чаще всего на порту 465) не поддерживается.
    \r\n• Адреса соответствующие \"/localhost$/\" всегда будут доставлены \"local:\", следовательно политика \"*\" не распространяется на них.
    \r\n• Чтобы определить учётные данные для следующего узла \"[host]:25\", Postfix всегда ищет данные для \"host\" перед тем как искать \"[host]:25\". Такое поведение делает невозможным использование \"host\" and \"[host]:25\" одновременно.", "ui_footer": "Добавить нижний колонтитул (использование HTML разрешено)", "ui_header_announcement": "Объявления", "ui_header_announcement_active": "Активировать объявление", @@ -333,7 +335,7 @@ "ui_header_announcement_type_danger": "Очень важное", "ui_header_announcement_type_info": "Инфо", "ui_header_announcement_type_warning": "Важное", - "ui_texts": "UI наименования и описания", + "ui_texts": "Наименования и описания в UI", "unban_pending": "ожидает разблокировки", "unchanged_if_empty": "Если без изменений, оставьте пустым", "upload": "Загрузить", @@ -355,7 +357,7 @@ "bcc_empty": "Назначение BCC не может быть пустым", "bcc_exists": "Для типов %s уже существует карта BCC %s", "bcc_must_be_email": "Назначение BCC %s не является правильным адресом электронной почты", - "comment_too_long": "Комментарий слишком длинный. Разрешено использовать максимум 160 символов.", + "comment_too_long": "Комментарий слишком длинный, придел 160 символов", "defquota_empty": "Квота по умолчанию не может быть 0.", "description_invalid": "Недопустимое описание ресурса %s", "dkim_domain_or_sel_exists": "Ключ DKIM для \"%s\" уже существует", @@ -367,17 +369,17 @@ "domain_not_found": "Домен %s не найден", "domain_quota_m_in_use": "Квота домена должна быть больше или равна %s MiB", "extra_acl_invalid": "Адрес внешнего отправителя \"%s\" не валидный.", - "extra_acl_invalid_domain": "Адрес внешнего отправителя \"%s\" не валидный домен.", + "extra_acl_invalid_domain": "Адрес внешнего отправителя \"%s\" не валидный домен", + "fido2_verification_failed": "Ошибка валидации FIDO2: %s", "file_open_error": "Файл не может быть открыт на запись", "filter_type": "Неверный тип фильтра", "from_invalid": "Отправитель не может быть пустым", "global_filter_write_error": "Ошибка записи фильтра в файл: %s", "global_map_invalid": "Идентификатор глобального правила %s не валидный", "global_map_write_error": "Не удалось создать глобальное правило ID %s: %s", - "xmpp_map_write_error": "Ошибка записи настроек XMPP: %s", "goto_empty": "Псевдоним должен содержать по крайней мере один валидный адрес владельца", "goto_invalid": "Недопустимый основной адрес %s", - "ham_learn_error": "Ошибка при обучении «ham» фильтра: %s", + "ham_learn_error": "Ошибка при обучении полезной почты: %s", "imagick_exception": "Ошибка в Imagick при чтении изображения", "img_invalid": "Невозможно проверить файл изображения", "img_tmp_missing": "Невозможно проверить файл изображения: временный файл не найден", @@ -409,10 +411,10 @@ "max_quota_in_use": "Квота почтового аккаунта должна быть больше или равна %d MiB", "maxquota_empty": "Максимальная квота почтового аккаунта не должна быть 0.", "mysql_error": "Ошибка в MySQL: %s", - "nginx_reload_failed": "Обновление конфигурации Nginx не удалось: %s", "network_host_invalid": "Сеть или хост: %s не валидный", "next_hop_interferes": "%s пересекается с %s", "next_hop_interferes_any": "Существующий хост пересекается с %s", + "nginx_reload_failed": "Обновление конфигурации Nginx не удалось: %s", "no_user_defined": "Пользователь не указан", "object_exists": "Объект %s уже существует", "object_is_not_numeric": "Значение %s не является числовым", @@ -453,54 +455,59 @@ "totp_verification_failed": "Ошибка валидации TOTP", "transport_dest_exists": "Назначение для отправки \"%s\" уже существует", "u2f_verification_failed": "Ошибка валидации U2F: %s", - "fido2_verification_failed": "Ошибка валидации FIDO2: %s", "unknown": "Произошла неизвестная ошибка", "unknown_tfa_method": "Неизвестный метод TFA", "unlimited_quota_acl": "Неограниченная квота запрещена политикой доступа", "username_invalid": "Имя пользователя %s нельзя использовать", "validity_missing": "Пожалуйста, назначьте срок действия", "value_missing": "Пожалуйста заполните все поля", - "yotp_verification_failed": "Ошибка валидации Yubico OTP: %s", + "xmpp_map_write_error": "Ошибка записи настроек XMPP: %s", + "xmpp_reload_failed": "Обновление конфигурации Dovecot не удалось", "xmpp_restart_failed": "Перезагрузка XMPP не удалась", - "xmpp_reload_failed": "Обновление конфигурации Dovecot не удалось" + "yotp_verification_failed": "Ошибка валидации Yubico OTP: %s" }, "debug": { "chart_this_server": "Диаграмма (текущий сервер)", "containers_info": "Статус контейнеров Docker", "disk_usage": "Использование дискового пространства", + "docs": "Проиндексировано объектов", "external_logs": "Внешние журналы", "history_all_servers": "История (все серверы)", "in_memory_logs": "Журналы контейнеров", "jvm_memory_solr": "Использовано оперативной памяти JVM", - "log_info": "

    Журналы контейнеров mailcow сохраняются в Redis, и раз в минуту строки журнала за пределами LOG_LINES (%d) удаляются, чтобы уменьшить нагрузку на сервер.\r\n
    Сами журналы контейнеров не сохраняются после перезагрузки контейнера. Все контейнеры дополнительно пишут логи в службу Docker, и, следовательно, используют драйвер логирования по умолчанию. Журналы контейнеров предусмотрены только для отладки мелких проблем. Для других задач, пожалуйста, настройте драйвер логирования Docker самостоятельно.

    \r\n

    Внешние журналы собираются через API приложений.

    \r\n

    Статические журналы – это, в основном, журналы активности, которые не записываются в Dockerd, но все равно должны быть постоянными (за исключением журналов API).

    ", - "logs": "Журналы", - "restart_container": "Перезапустить", - "solr_dead": "Solr не запущен. Если вы включили Solf в файле настроек mailcow.conf и это сообщение отображается более получаса, скорее всего Solr сломан.", - "xmpp_dead": "XMPP не запущен. Если вы включили XMPP в настройках домена и это сообщение отображается более получаса, скорее всего XMPP сломан.", - "docs": "Проиндексировано объектов", "last_modified": "Последние изменения", + "log_info": "

    Журналы контейнеров mailcow сохраняются в Redis, и раз в минуту строки журнала за пределами LOG_LINES (%d) удаляются, чтобы уменьшить нагрузку на сервер.\r\n
    Сами журналы контейнеров не сохраняются после перезагрузки контейнера. Все контейнеры дополнительно пишут логи в службу Docker, и, следовательно, используют драйвер логирования по умолчанию. Журналы контейнеров предусмотрены только для отладки мелких проблем. Для других задач, пожалуйста, настройте драйвер логирования Docker самостоятельно.

    \r\n

    Внешние журналы собираются через API приложений.

    \r\n

    Статические журналы – это, в основном, журналы активности, которые не записываются в Dockerd, но все равно должны быть постоянными (за исключением журналов API).

    ", + "login_time": "Время входа", + "logs": "Журналы", "online_users": "Подключено пользователей", + "restart_container": "Перезапустить", + "service": "Сервис", "size": "Индексы занимают", - "started_at": "Запущен", + "solr_dead": "Solr не запущен. Если вы включили Solf в файле настроек mailcow.conf и это сообщение отображается более получаса, скорее всего Solr сломан.", "solr_status": "Состояние Solr", - "uptime": "Время работы", + "started_at": "Запущен", "started_on": "Запущен в", "static_logs": "Статические журналы", + "success": "Успех", "system_containers": "Система и контейнеры", + "uptime": "Время работы", + "username": "Имя пользователя", + "xmpp_dead": "XMPP не запущен. Если вы включили XMPP в настройках домена и это сообщение отображается более получаса, скорее всего XMPP сломан.", "xmpp_status": "Статус XMPP" }, "diagnostics": { "cname_from_a": "Значение, полученное из записи A/AAAA. Это поддерживается до тех пор, пока запись указывает на правильный ресурс.", "dns_records": "Записи DNS", "dns_records_24hours": "Обратите внимание, что для внесения изменений в DNS может потребоваться до 24 часов, чтобы правильно отобразить их текущее состояние на этой странице. Эта страница предназначен для того, чтобы вы могли легко увидеть, как настроить записи DNS и проверить, все ли записи правильно занесены в DNS.", - "dns_records_docs": "Пожалуйста, ознакомьтесь с документацией.", "dns_records_data": "Значение", + "dns_records_docs": "Пожалуйста, ознакомьтесь с документацией.", "dns_records_name": "Название", "dns_records_status": "Статус", "dns_records_type": "Тип", "optional": "Эта запись не обязательна." }, "edit": { + "acl": "ACL (Список прав)", "active": "Активный", "admin": "Изменение администратора", "advanced_settings": "Расширенные настройки", @@ -537,22 +544,15 @@ "full_name": "Полное имя", "gal": "GAL - Глобальная адресная книга", "gal_info": "GAL содержит все объекты домена и не подлежит редактированию. Информация о занятости в SOGo будет отсутствовать для домена, если данная функция будет отключена! Требуется перезапустить SOGo, чтобы применить изменения.", - "xmpp": "Включить поддержку XMPP для этого домена", - "xmpp_prefix": "Префикс домена XMPP", - "xmpp_prefix_info": "Для получения SSL сертификатов для XMPP сервера необходимо настроить дополнительные CNAME DNS записи im.example.org и *.im.example.org, указывающие на %s. Пожалуйста, посетите страницу проверки DNS записей домена после включения XMPP сервера в mailcow UI.", - "xmpp_info": "Эта опция добавит функциональность чата для этого домена.", - "xmpp_access": "Пользователь XMPP", - "xmpp_access_info": "XMPP должен быть включен для этого домена.", - "xmpp_admin": "Администратор XMPP", - "xmpp_admin_info": "Повысить пользователя XMPP до администратора домена.", - "xmpp_example_jid": "Пример JID (используя пароль почтового аккаунта)", "generate": "сгенерировать", "grant_types": "Разрешено типы", "hostname": "Имя хоста", "inactive": "Неактивный", "kind": "Тип", + "lookup_mx": "Назначение на основе резовинга MX записи по регулярному выражению (.*\\.example\\.com$ для маршрутизации всей почты через этот хост, если MX заканчивающийся на example.com)", "mailbox": "Изменение почтового аккаунта", "mailbox_quota_def": "Квота по умолчанию", + "mailbox_relayhost_info": "Применяется только к почтовому ящику и личным псевдонимам, вне зависимости от настроек маршрутизации на уровне домена.", "max_aliases": "Максимум псевдонимов", "max_mailboxes": "Максимум почтовых ящиков", "max_quota": "Максимальная квота почтового аккаунта (MiB)", @@ -561,12 +561,14 @@ "mbox_rl_info": "Этот лимит применяется к SASL логину пользователя и соответствует любому адресу отправителя, используемому зарегистрированным пользователем. Лимит скорости почтового аккаунта перекрывает лимит скорости для всего домена.", "mins_interval": "Интервал (в минутах)", "multiple_bookings": "Несколько бронирований", + "none_inherit": "Отсутствует / Наследуется", "nexthop": "Следующий хост", "password": "Пароль", "password_repeat": "Подтверждение пароля (повтор)", "previous": "Предыдущая страница", "private_comment": "Приватный комментарий", "public_comment": "Публичный комментарий", + "pushover": "Pushover", "pushover_evaluate_x_prio": "Установить высокий приоритет уведомлений для писем с высоким приоритетом [X-Priority: 1]", "pushover_info": "Настройки Push-уведомления будут применяться ко всей почте %s (за исключением спама) включая псевдонимы (личные, общие и тегированные).", "pushover_only_x_prio": "Получать уведомления только об письмах с высоким приоритетом [X-Priority: 1]", @@ -577,6 +579,8 @@ "pushover_vars": "Когда фильтрация по отправителю не определена, уведомления будут доставлятся от всех отправителей.
    Можно использовать обычный фильтр по отправителю и расширенный regex-фильтр, а также оба сразу.
    Пожалуйста, ознакомьтесь с Pushover Privacy Policy перед использованием шаблонов для текста и заголовка", "pushover_verify": "Проверить доступ", "quota_mb": "Квота (MiB)", + "quota_warning_bcc": "Предупреждения о квоте BCC", + "quota_warning_bcc_info": "Предупреждения будут отправлены в виде отдельных копий следующим адресатам. В скобках к теме будет приписано соответствующее имя пользователя, например: Quota warning (user@example.com).", "ratelimit": "Лимит отправки", "redirect_uri": "URL-адрес переадресация/обратный вызов", "relay_all": "Ретрансляция всех получателей", @@ -584,7 +588,7 @@ "relay_domain": "Ретрансляция этого домена", "relay_transport_info": "
    Инфо
    Вы можете настроить собственный транспорт для домена. Если такой настройки нет, то доставка будет выполнена на основе MX записей.", "relay_unknown_only": "Ретрансляция только не существующих почтовых ящиков. Почта к существующим почтовым ящикам будут доставляться локально.", - "relayhost": "Транспортировка в зависимости от отправителя", + "relayhost": "Маршрутизация на основе отправителя", "remove": "Удалить", "resource": "Ресурс", "save": "Сохранить изменения", @@ -595,13 +599,11 @@ "sieve_desc": "Краткое описание", "sieve_type": "Тип фильтра", "skipcrossduplicates": "Пропускать повторяющиеся сообщения в папках", - "sogo_access": "Предоставить доступ к SOGo", - "sogo_access_info": "Этот параметр не влияет на доступ ко всем другим службам, в том числе на право удаления или изменение существующего профиля пользователя SOGo.", "sogo_visible": "Отображать псевдоним в SOGo", "sogo_visible_info": "Влияет только на объекты, которые могут отображаться в SOGo (персональные или общие псевдонимы, указывающие как минимум на один локальный почтовый аккаунт). Учтите, что если функция отключена, у пользователей не будет возможности выбрать адрес псевдонима в качестве отправителя в SOGo.", "spam_alias": "Создать или изменить временные (спам) псевдонимы", - "spam_policy": "Добавление или удаление элементов в белом/черном списке", "spam_filter": "Спам фильтр", + "spam_policy": "Добавление или удаление элементов в белом/черном списке", "spam_score": "Задать индивидуальное определение спама", "subfolder2": "Синхронизировать в подпапку
    (пусто = в корень)", "syncjob": "Изменить задание синхронизации", @@ -612,16 +614,42 @@ "title": "Изменение объекта", "unchanged_if_empty": "Если без изменений - оставьте пустым", "username": "Имя пользователя", - "validate_save": "Подтвердить и сохранить" + "validate_save": "Подтвердить и сохранить", + "xmpp": "Включить поддержку XMPP для этого домена", + "xmpp_access": "Пользователь XMPP", + "xmpp_access_info": "XMPP должен быть включен для этого домена.", + "xmpp_admin": "Администратор XMPP", + "xmpp_admin_info": "Повысить пользователя XMPP до администратора домена.", + "xmpp_example_jid": "Пример JID (используя пароль почтового аккаунта)", + "xmpp_info": "Эта опция добавит функциональность чата для этого домена.", + "xmpp_prefix": "Префикс домена XMPP", + "xmpp_prefix_info": "Для получения SSL сертификатов для XMPP сервера необходимо настроить дополнительные CNAME DNS записи im.example.org и *.im.example.org, указывающие на %s. Пожалуйста, посетите страницу проверки DNS записей домена после включения XMPP сервера в mailcow UI." + }, + "fido2": { + "confirm": "Подтвердить", + "fido2_auth": "Войти с помощью FIDO2", + "fido2_success": "Устройство успешно зарегистрировано", + "fido2_validation_failed": "Валидация не проведена", + "fn": "Название", + "known_ids": "Известные ID", + "none": "Отключено", + "register_status": "Статус регистрации", + "rename": "Переименовать", + "set_fido2": "Зарегистрировать устройство FIDO2", + "set_fido2_touchid": "Зарегистрировать Touch ID на Apple M1", + "set_fn": "Укажите понятное название", + "start_fido2_validation": "Запустить процесс валидации FIDO2" }, "footer": { "cancel": "Отмена", "confirm_delete": "Подтвердите удаление", "delete_now": "Удалить сейчас", "delete_these_items": "Пожалуйста, подтвердите свои изменения в следующих объектах:", - "hibp_nok": "Найдено совпадение! Это потенциально опасный пароль!", + "hibp_check": "Проверить на утечки в haveibeenpwned.com", + "hibp_nok": "Совпадение найдено! Это потенциально опасный пароль!", "hibp_ok": "Совпадений не найдено.", "loading": "Пожалуйста, подождите...", + "nothing_selected": "Ничего не выбрано", "restart_container": "Перезапустить контейнер", "restart_container_info": "Важно: полный перезапуск может занять некоторое время, пожалуйста, дождитесь его завершения – не обновляйте и не закрывайте страницу.", "restart_now": "Перезапустить сейчас", @@ -673,6 +701,7 @@ "alias_domain_alias_hint": "Псевдонимы не применяются к псевдонимам домена автоматически. Адрес псевдонима my-alias@domain не охватывает адрес my-alias@alias-domain (где \"alias-domain\" – воображаемый псевдоним домена для \"domain\").
    Используйте кнопку \"Скопировать псевдонимы на псевдонимы домена\" чтобы добавить выбранные псевдонимы на все псевдонимы доменов.
    Пожалуйста, используйте Sieve фильтры для перенаправления почты на внешние почтовые аккаунты (см. вкладку \"Фильтры\" или используйте SOGo -> Настройки -> Почта -> Пересылка).", "alias_domain_backupmx": "Псевдонимы домена не могут быть использованы для домена ретрансляции", "aliases": "Псевдонимы", + "all_domains": "Все домены", "allow_from_smtp": "Разрешить использование SMTP только для этих IP", "allow_from_smtp_info": "Укажите IPv4/IPv6 адреса и/или подсети.
    Оставьте поле пустым, чтобы разрешить отправку с любых адресов.", "allowed_protocols": "Разрешенные протоколы", @@ -680,7 +709,7 @@ "bcc": "Правила BBC", "bcc_destination": "Назначение BCC", "bcc_destinations": "Назначение BCC", - "bcc_info": "Правила BCC используются для пересылки копий всех сообщений на другой адрес. Правило типа \"получатель\" используется, когда локальный получатель выступает в качестве получателя почты. Правило типа \"отправитель\" соответствуют тому же принципу. Локальный домен не будут проинформированы о неудачной доставке.", + "bcc_info": "Правила BCC используются для скрытой пересылки копий всех сообщений на другой адрес. Правило типа \"получатель\" используется, когда локальный получатель выступает в качестве получателя почты. Правило типа \"отправитель\" соответствуют тому же принципу. Локальный домен не будут проинформированы о неудачной доставке.", "bcc_local_dest": "Локальный домен", "bcc_map": "Правила BBC", "bcc_map_type": "Тип BCC", @@ -696,6 +725,7 @@ "booking_custom_short": "Жесткий лимит", "booking_lt0": "Неограниченный, занят при бронировании", "booking_lt0_short": "Неограниченный лимит", + "catch_all": "Catch-all", "daily": "Раз в день", "deactivate": "Отключить", "description": "Описание", @@ -707,26 +737,29 @@ "domain_quota": "Квота", "domains": "Домены", "edit": "Изменить", - "empty": "Нет результатов", + "empty": "Пусто", "enable_x": "Включить", "excludes": "Исключает", "filter_table": "Поиск", "filters": "Фильтры", "fname": "Полное имя", + "goto_ham": "Запомнить как полезную почту", + "goto_spam": "Запомнить как спам", "hourly": "Раз в час", "in_use": "Использовано", "inactive": "Неактивный", "insert_preset": "Вставить пример \"%s\"", "kind": "Тип", "last_mail_login": "Последний вход", + "last_pw_change": "Последняя смена пароля", "last_run": "Последний запуск", "last_run_reset": "Следующей запуск", "mailbox": "Почтовый аккаунт", + "mailbox_defaults": "Настройки по умолчанию", + "mailbox_defaults_info": "Установите настройки по умолчанию для новых почтовых аккаунтов.", "mailbox_defquota": "Квота по умолчанию", "mailbox_quota": "Макс. квота почт. ящика", "mailboxes": "Почтовые ящики", - "mailbox_defaults": "Настройки по умолчанию", - "mailbox_defaults_info": "Установите настройки по умолчанию для новых почтовых аккаунтов.", "mins_interval": "Интервал (в минутах)", "msg_num": "Писем", "multiple_bookings": "Несколько бронирований", @@ -734,15 +767,17 @@ "no": "✕", "no_record": "Нет записей для объекта %s", "no_record_single": "Нет записей", + "open_logs": "Показать журнал", "owner": "Владелец", "private_comment": "Приватный комментарий", "public_comment": "Публичный комментарий", - "q_add_header": "Нежелательная почта", - "q_all": "Все категории", - "q_reject": "Отклонённая почта", - "quarantine_notification": "Уведомления о спаме", + "q_add_header": "при перемещении в папку \"Спам\"", + "q_all": " при перемещении в папку \"Спам\" и при отклонении", + "q_reject": "при отклонении", "quarantine_category": "Категория уведомлений о спаме", + "quarantine_notification": "Уведомления о спаме", "quick_actions": "Действия", + "recipient": "Получатель", "recipient_map": "Перезапись получателя", "recipient_map_info": "Перезапись получателя используются для замены получателя в сообщении до его доставки.", "recipient_map_new": "Перезапись на", @@ -752,10 +787,11 @@ "recipient_maps": "Перезапись получателя", "remove": "Удалить", "resources": "Ресурсы", - "running": "В процессе выполнения", + "running": "В процессе", + "sender": "Отправитель", "set_postfilter": "Использовать как постфильтр", "set_prefilter": "Использовать как предварительный фильтр", - "sieve_info": "Вы можете сохранить несколько фильтров для каждого пользователя, но только один предварительный фильтр и один постфильтр могут быть активными одновременно.
    \r\n Каждый фильтр будет обработан в описанном порядке. Не сломанный скрипт, не keep; не остановит обработку дальнейших скриптов.

    Global sieve prefilter → Prefilter → User scripts → Postfilter → Global sieve postfilter", + "sieve_info": "Вы можете сохранить несколько фильтров для каждого пользователя, но только один предварительный фильтр и один постфильтр могут быть активными одновременно.
    \r\n Каждый фильтр будет обработан в описанном порядке. Не сломанный скрипт, не keep; не остановит обработку дальнейших скриптов.

    Global sieve prefilter • Prefilter • User scripts • Postfilter • Global sieve postfilter", "sieve_preset_1": "Discard mail with probable dangerous file types", "sieve_preset_2": "Always mark the e-mail of a specific sender as seen", "sieve_preset_3": "Discard silently, stop all further sieve processing", @@ -772,6 +808,15 @@ "stats": "Статистика", "status": "Статус", "sync_jobs": "Задания синхронизации", + "syncjob_check_log": "Проверить журнал", + "syncjob_last_run_result": "Результат последнего запуска", + "syncjob_EX_OK": "Успешно", + "syncjob_EXIT_CONNECTION_FAILURE": "Ошибка связи с сервером", + "syncjob_EXIT_TLS_FAILURE": "Ошибка установки шифрованного соединения", + "syncjob_EXIT_AUTHENTICATION_FAILURE": "Ошибка авторизации", + "syncjob_EXIT_OVERQUOTA": "Целевой почтовый ящик превысил квоту", + "syncjob_EXIT_CONNECTION_FAILURE_HOST1": "Не удалось подключиться к удаленному серверу", + "syncjob_EXIT_AUTHENTICATION_FAILURE_USER1": "Неправильное имя пользователя или пароль", "table_size": "Размер таблицы", "table_size_show_n": "Отображать %s полей", "target_address": "Владельцы псевдонима", @@ -789,7 +834,7 @@ "tls_policy_maps_long": "Переопределение правил для политик исходящих соединений TLS", "toggle_all": "Выбрать все", "username": "Имя пользователя", - "waiting": "Ожидание", + "waiting": "В ожидании", "weekly": "Раз в неделю", "yes": "✓" }, @@ -811,7 +856,6 @@ "danger": "Опасность", "deliver_inbox": "Освободить из карантина", "disabled_by_config": "В текущей конфигурации системы функция карантина отключена.", - "settings_info": "Максимальное количество элементов, которые будут помещены в карантин: %s
    Максимальный размер электронного письма: %s MiB", "download_eml": "Скачать (.eml)", "empty": "Пусто", "high_danger": "Высокая", @@ -824,10 +868,13 @@ "notified": "Увед.", "qhandler_success": "Запрос успешно отправлен в систему. Теперь вы можете закрыть окно.", "qid": "Rspamd QID", - "qinfo": "Карантин сохраняет входящие сообщения, классифицированные как нежелательные, в базу данных.\r\n
    Отправители писем, которые помечены как отвергнутые, будут уверены что их письма не были доставлены вам.\r\n
    \"Освободить из карантина\" изучит сообщение как «ham» по теореме Байеса и доставит его вам в Inbox.\r\n
    \"Запомнить как спам и удалить\" изучит сообщение как спам по теореме Байеса, а также вычислит нечёткие хэши, чтобы лучше блокировать подобные сообщения в дальнейшем.\r\n
    Учтите, что в зависимости от технических характеристик вашей системы, изучение большого количества сообщений может занять много времени.", + "qinfo": "Карантин сохраняет входящие сообщения, классифицированные как нежелательные, в базу данных.\r\n
    Отправители писем, которые помечены как отвергнутые, будут уверены что их письма не были доставлены вам.\r\n
    \"Освободить из карантина\" изучит сообщение как полезную почту; по теореме Байеса и доставит его вам в Inbox.\r\n
    \"Запомнить как спам и удалить\" изучит сообщение как спам по теореме Байеса, а также вычислит нечёткие хэши, чтобы лучше блокировать подобные сообщения в дальнейшем.\r\n
    Учтите, что в зависимости от технических характеристик вашей системы, изучение большого количества сообщений может занять много времени.", "qitem": "Обьект карантина", "quarantine": "Карантин", "quick_actions": "Действия", + "quick_delete_link": "Ссылка для удаления", + "quick_info_link": "Ссылка на доп. информацию", + "quick_release_link": "Ссылка для восстановления", "rcpt": "Получатель", "received": "Получено", "recipients": "Получатель", @@ -841,10 +888,7 @@ "rspamd_result": "Результат Rspamd", "sender": "Отправитель (SMTP)", "sender_header": "Отправитель (заголовок \"From\")", - "type": "Тип", - "quick_release_link": "Ссылка для восстановления", - "quick_delete_link": "Ссылка для удаления", - "quick_info_link": "Ссылка на доп. информацию", + "settings_info": "Максимальное количество элементов, которые будут помещены в карантин: %s
    Максимальный размер электронного письма: %s MiB", "show_item": "Показать", "spam": "Спам", "spam_score": "Оценка", @@ -853,7 +897,15 @@ "table_size_show_n": "Отображать %s полей", "text_from_html_content": "Содержимое письма (сконвертированное из html)", "text_plain_content": "Содержимое письма (text/plain)", - "toggle_all": "Выбрать все" + "toggle_all": "Выбрать все", + "type": "Тип" + }, + "ratelimit": { + "disabled": "Отключен", + "second": "сообщений / секунду", + "minute": "сообщений / минуту", + "hour": "сообщений / час", + "day": "сообщений / день" }, "start": { "help": "Справка", @@ -904,7 +956,7 @@ "item_released": "Письмо %s восстановлено из карантина", "items_deleted": "Обьекты %s удалены", "items_released": "Выбраные письма восстановлены из карантина", - "learned_ham": "Письмо ID %s было изучено как «ham»", + "learned_ham": "Письмо ID %s было изучено как полезную почту;", "license_modified": "Изменения в лицензии сохранены", "logged_in_as": "Вы вошли как %s", "mailbox_added": "Почтовый аккаунт %s добавлен", @@ -912,10 +964,10 @@ "mailbox_removed": "Почтовый аккаунт %s удалён", "nginx_reloaded": "Обновление конфигурация Nginx закончено", "object_modified": "Изменения объекта %s сохранены", + "password_policy_saved": "Политика паролей сохранена", "pushover_settings_edited": "Настройки сохранены, пожалуйста, выполните проверку доступа", "qlearn_spam": "Письмо ID %s было изучено как спам и удалено", "queue_command_success": "Команда выполнена успешно", - "password_policy_saved": "Политика паролей сохранена", "recipient_map_entry_deleted": "Правило перезаписи получателя ID %s было удалено", "recipient_map_entry_saved": "Правило перезаписи получателя \"%s\" было сохранено", "relayhost_added": "Промежуточный узел %s добавлен", @@ -934,13 +986,13 @@ "tls_policy_map_entry_saved": "Политика TLS \"%s\" сохранена", "ui_texts": "Изменения текстов UI сохранены", "upload_success": "Файл загружен успешно", + "verified_fido2_login": "Авторизация FIDO2 пройдена", "verified_totp_login": "Авторизация TOTP пройдена", "verified_u2f_login": "Авторизация U2F пройдена", - "verified_fido2_login": "Авторизация FIDO2 пройдена", "verified_yotp_login": "Авторизация Yubico OTP пройдена", - "xmpp_restarted": "Сервис XMPP перезагружен", + "xmpp_maps_updated": "Настройки XMPP обновлены", "xmpp_reloaded": "Обновление конфигурация XMPP закончено", - "xmpp_maps_updated": "Настройки XMPP обновлены" + "xmpp_restarted": "Сервис XMPP перезагружен" }, "tfa": { "api_register": "%s использует Yubico Cloud API. Пожалуйста, получите ключ API для вашего ключа здесь", @@ -967,20 +1019,6 @@ "waiting_usb_register": "Ожидание устройства USB...

    Пожалуйста, введите пароль выше и подтвердите регистрацию, нажав кнопку на USB устройстве.", "yubi_otp": "Yubico OTP аутентификация" }, - "fido2": { - "set_fn": "Укажите понятное название", - "fn": "Название", - "rename": "Переименовать", - "confirm": "Подтвердить", - "register_status": "Статус регистрации", - "known_ids": "Известные ID", - "none": "Отключено", - "set_fido2": "Зарегистрировать устройство FIDO2", - "start_fido2_validation": "Запустить процесс валидации FIDO2", - "fido2_auth": "Войти с помощью FIDO2", - "fido2_success": "Устройство успешно зарегистрировано", - "fido2_validation_failed": "Валидация не проведена" - }, "user": { "action": "Действия", "active": "Активный", @@ -996,31 +1034,36 @@ "alias_valid_until": "Действителен до", "aliases_also_send_as": "Разрешено отправлять письма от имени", "aliases_send_as_all": "Разрешено отправлять письма от любого имени для домена и его псевдонимов", - "app_hint": "Пароли приложений - это альтернативные пароли для авторизации в IMAP и SMTP. При этом имя пользователя остается неизменным.
    SOGo (включая ActiveSync) недоступен через пароли приложений.", + "app_hint": "Пароли приложений - это альтернативные пароли для авторизации в IMAP, SMTP, CalDAV, CardDAV и EAS. При этом имя пользователя остается неизменным.
    SOGo недоступен через пароли приложений.", "app_name": "Название приложения", "app_passwds": "Пароли приложений", "apple_connection_profile": "Профиль подключения Apple", "apple_connection_profile_complete": "Этот профиль включает настройки IMAP и SMTP, а также CalDAV (календарей) и CardDAV (контактов) для устройства Apple.", "apple_connection_profile_mailonly": "Этот профиль включает только настройки IMAP и SMTP для устройства Apple.", "change_password": "Изменить пароль", + "clear_recent_successful_connections": "Очистить историю успешных подключений", "client_configuration": "Показать руководство по настройке почтовых клиентов и смартфонов", "create_app_passwd": "Создать новый пароль", "create_syncjob": "Создание нового задания синхронизации", + "created_on": "Дата создания", "daily": "Раз в день", "day": "день", "delete_ays": "Пожалуйста, подтвердите удаление", "direct_aliases": "Личные псевдонимы", - "direct_aliases_desc": "На адреса с прямым псевдонимом распространяются фильтры нежелательной почты и параметры политики TLS.", + "direct_aliases_desc": "На личные псевдонимы распространяются фильтры нежелательной почты и параметры политики TLS.", "eas_reset": "Сбросить кеш ActiveSync устройств", "eas_reset_help": "Во многих случаях сброс кеша устройств помогает восстановить повреждённый профиль ActiveSync.
    Внимание: все письма, календари и контакты будут загружены заново на все ваши устройства!", "eas_reset_now": "Сбросить кеш сейчас", "edit": "Изменить", "email": "Почта", "email_and_dav": "Почта, календари и контакты", + "empty": "Пусто", "encryption": "Шифрование", "excludes": "Исключает", "expire_in": "Истекает через", + "fido2_webauthn": "FIDO2/WebAuthn", "force_pw_update": "Вы должны установить новый пароль для доступа к сервисам, относящимся к данной учетной записи.", + "from": "с под", "generate": "сгенерировать", "hour": "час", "hourly": "Раз в час", @@ -1029,16 +1072,26 @@ "interval": "Интервал", "is_catch_all": "Catch-all для домена/ов", "last_mail_login": "Последний вход", + "last_pw_change": "Последняя смена пароля", "last_run": "Последний запуск", + "last_ui_login": "Последний вход в личный кабинет", "loading": "Загрука...", - "mailbox_details": "Сведения о почтовом ящике", - "messages": "письма", + "login_history": "История входа в систему", + "mailbox": "Почтовый ящик", + "mailbox_details": "Детали", + "mailbox_general": "Основные", + "mailbox_settings": "Настройки", + "messages": "писем", + "month": "месяц", + "months": "месяцев", "never": "Никогда", "new_password": "Новый пароль", "new_password_repeat": "Подтверждение пароля (повтор)", "no_active_filter": "Активированные фильтры отсутствуют", "no_last_login": "Информация о последнем входе в пользовательский интерфейс отсутствует", "no_record": "Записи отсутствуют", + "open_logs": "Показать журнал", + "open_webmail_sso": "Вход в веб-почту", "password": "Пароль", "password_now": "Текущий пароль (подтверждение изменения)", "password_repeat": "Подтверждение пароля (повтор)", @@ -1054,12 +1107,13 @@ "q_add_header": "Нежелательная почта", "q_all": "Все категории", "q_reject": "Отклонённая почта", - "quarantine_notification": "Уведомления о спаме", "quarantine_category": "Категория уведомлений о спаме", - "quarantine_notification_info": "После того, как уведомление будет отправлено, элементы будут помечены как \"уведомлённые\", и дальнейшие уведомления для этого сообщения отправляться не будут.", "quarantine_category_info": "Категория \"Отклонённая почта\" включает в себя почту, которая была отклонена, тогда как \"Нежелательная почта\" содержит письма, которые были помещены в папку Junk. Для того, чтобы получать уведомления обо всех категориях спама, выберите опцию \"Все категории\".", + "quarantine_notification": "Уведомления о спаме", + "quarantine_notification_info": "После того, как уведомление будет отправлено, элементы будут помечены как \"уведомлённые\", и дальнейшие уведомления для этого сообщения отправляться не будут.", + "recent_successful_connections": "История успешных подключений", "remove": "Удалить", - "running": "В процессе выполнения", + "running": "В процессе", "save": "Сохранить изменения", "save_changes": "Сохранить изменения", "sender_acl_disabled": "Проверка отправителя отключена", @@ -1078,18 +1132,27 @@ "spamfilter_default_score": "Значения по умолчанию", "spamfilter_green": "Зелёный: эти письма не являются спамом", "spamfilter_hint": "Первое значение отображает низкую оценку спама, второе – высокую.
    Заметка: пользователи POP3 должны использовать настройку 15:15 по умолчанию, чтобы отключить попадание потенциального спама в \"Спам\", так как POP3 скачивает только содержимое папки \"Входящие\"", - "spamfilter_red": "Красный: эти письма являются спамом и будут помещены в карантин, отправитель будет уведомлен об отказе доставки его письма, потому что оно не прошло спам-фильтр", + "spamfilter_red": "Красный: эти письма являются спамом и будут отклонены сервером", "spamfilter_table_action": "Действия", "spamfilter_table_add": "Добавить элемент", "spamfilter_table_domain_policy": "n/a (политика домена)", - "spamfilter_table_empty": "Нет данных для отображения", + "spamfilter_table_empty": "Пусто", "spamfilter_table_remove": "удалить", "spamfilter_table_rule": "Правило", "spamfilter_wl": "Белый список", "spamfilter_wl_desc": "Белый список адресов электронной почты позволяет никогда не классифицировать все полученные письма с указанных адресов как спам. Можно добавлять маски адресов. Фильтр применяется только к личным псевдонимам (с одним получателем), исключая catch-all псевдонимы и сам почтовый аккаунт.", - "spamfilter_yellow": "Жёлтый: это письма могут быть спамом, будут помечены как потенциальный спам и перемещены в папку \"Спам\"", + "spamfilter_yellow": "Жёлтый: эти письма могут быть спамом, будут доставлены в папку \"Спам\"", "status": "Статус", "sync_jobs": "Задания синхронизации", + "syncjob_check_log": "Проверить журнал", + "syncjob_last_run_result": "Результат", + "syncjob_EX_OK": "Успешно", + "syncjob_EXIT_CONNECTION_FAILURE": "Ошибка связи с сервером", + "syncjob_EXIT_TLS_FAILURE": "Ошибка установки шифрованного соединения", + "syncjob_EXIT_AUTHENTICATION_FAILURE": "Ошибка авторизации", + "syncjob_EXIT_OVERQUOTA": "Целевой почтовый ящик превысил квоту", + "syncjob_EXIT_CONNECTION_FAILURE_HOST1": "Не удалось подключиться к удаленному серверу", + "syncjob_EXIT_AUTHENTICATION_FAILURE_USER1": "Неправильное имя пользователя или пароль", "tag_handling": "Обработка тегированной почты", "tag_help_example": "Пример тегированного адреса электронной почты: ich+Facebook@example.org", "tag_help_explain": "Переместить в подпапку: будет создана новая подпапка в INBOX с именем тега, например: \"INBOX/Facebook\".
    \r\n Добавить к теме письма: имя тега будет добавлено к теме письма, например: \"[Facebook] My News\".", @@ -1105,10 +1168,12 @@ "user_settings": "Настройки пользователя", "username": "Имя пользователя", "verify": "Проверить", - "waiting": "Ожидание", + "waiting": "В ожидании", "week": "неделю", "weekly": "Раз в неделю", - "weeks": "недели" + "weeks": "недели", + "year": "год", + "years": "лет" }, "warning": { "cannot_delete_self": "Вы не можете удалить сами себя", diff --git a/data/web/lang/lang.sk.json b/data/web/lang/lang.sk.json index 40ed5c67..de2f47f8 100644 --- a/data/web/lang/lang.sk.json +++ b/data/web/lang/lang.sk.json @@ -9,7 +9,7 @@ "eas_reset": "Reset EAS zariadení", "extend_sender_acl": "Povoliť rozšírenie ACL odosielateľa externými adresami", "filters": "Filtre", - "login_as": "Prihlásiť sa ako poštový používateľ", + "login_as": "Prihlásiť sa ako mailový používateľ", "mailbox_relayhost": "Zmeniť predávajúci server schránky", "prohibited": "Zakázané cez ACL", "protocol_access": "Upraviť povolené protokoly", @@ -28,11 +28,7 @@ "spam_score": "Spam hodnota", "syncjobs": "Synchronizačné úlohy", "tls_policy": "TLS pravidlá", - "unlimited_quota": "Neobmedzená kvóta pre poštové schránky", - "xmpp_admin": "Povýšiť XMPP používateľa na správcu", - "xmpp_domain_access": "Nakonfigurovať prístup k XMPP doméne.", - "xmpp_mailbox_access": "Nakonfigurovať používateľovi XMPP prístup.", - "xmpp_prefix": "Zmeniť XMPP subdoménu (prefix)" + "unlimited_quota": "Neobmedzená kvóta pre mailové schránky" }, "add": { "activate_filter_warn": "Všetky ostatné filtre budú deaktivované, ak bude zaškrtnuté pole \"Aktívny\".", @@ -73,11 +69,11 @@ "hostname": "Hostiteľ", "inactive": "Neaktívny", "kind": "Druh", - "mailbox_quota_def": "Predvolená kvóta poštovej schránky", - "mailbox_quota_m": "Max. kvóta pre poštové schránky (MiB)", + "mailbox_quota_def": "Predvolená kvóta mailovej schránky", + "mailbox_quota_m": "Max. kvóta pre mailové schránky (MiB)", "mailbox_username": "Prihlasovacie meno (ľavá časť emailovej adresy)", "max_aliases": "Max. počet aliasov", - "max_mailboxes": "Max. počet poštových schránok", + "max_mailboxes": "Max. počet mailových schránok", "mins_interval": "Interval (min)", "multiple_bookings": "Viaceré rezervácie", "nexthop": "Ďalší skok", @@ -89,10 +85,10 @@ "public_comment": "Verejný komentár", "quota_mb": "Kvóta (MiB)", "relay_all": "Preposielať všetkým príjemcom", - "relay_all_info": "↪ Ak sa rozhodnete nepreposielať ďalej všetkých príjemcov, budete musieť pridať (\"tzv. slepú\") poštovú schránku pre každého príjemcu.", + "relay_all_info": "↪ Ak sa rozhodnete nepreposielať ďalej všetkých príjemcov, budete musieť pridať (\"tzv. slepú\") mailovú schránku pre každého príjemcu.", "relay_domain": "Preposielať túto doménu", "relay_transport_info": "
    Info
    Môžete definovať transportné mapy pre vlastné určenie cieľa pre túto doménu. Ak nie sú nastavené, použije sa MX záznam.", - "relay_unknown_only": "Preposielať len neexistujúce poštové schránky. Existujúce budú doručené lokálne.", + "relay_unknown_only": "Preposielať len neexistujúce mailové schránky. Existujúce budú doručené lokálne.", "relayhost_wrapped_tls_info": "Prosím nepoužívajte TLS-wrapped porty (najviac používane na prote 465).
    \r\nPoužite non-wrapped port a STARTTLS. Vynútené TLS pravidlá môžu byť vytvorené v \"TLS mapách\".", "select": "Prosím vyberte...", "select_domain": "Najskôr vyberte doménu prosím", @@ -109,13 +105,7 @@ "timeout2": "Časový limit pre spojenie s lokálnym serverom", "username": "Používateľské meno", "validate": "Overiť", - "validation_success": "Úspešne overené", - "xmpp": "Aktivovať XMPP pre túto doménu", - "xmpp_access": "XMPP prístup", - "xmpp_access_info": "XMPP musí byť aktivované pre túto doménu.", - "xmpp_admin": "XMPP administrátor", - "xmpp_admin_info": "Upozornenie: Povýši užívateľa na XMPP administrátora pre túto doménu.", - "xmpp_info": "Aktivovanie tejto funkcie umožní četovanie v tejto doméne." + "validation_success": "Úspešne overené" }, "admin": { "access": "Prístup", @@ -223,7 +213,7 @@ "loading": "Čakajte prosím ...", "login_time": "Čas prihlásenia", "logo_info": "Váš obrázok bude upravený na výšku 40px pre vrchný navigačný riadok a na maximálnu šírku 250px pre úvodnú stránku. Odporúča sa škálovateľná grafika.", - "lookup_mx": "Cieľ je regulárny výraz ktorý sa zhoduje s MX záznamom (.*google\\.com smeruje všetku poštu na MX ktoré sú cieľom pre google.com cez tento skok)", + "lookup_mx": "Cieľ je regulárny výraz ktorý sa porovnáva s MX záznamom (.*google\\.com smeruje všetku poštu určenú pre MX ktoré sú cieľom pre google.com cez tento skok)", "main_name": "\"mailcow UI\" názov", "merged_vars_hint": "Sivé riadky boli načítané z vars.(local.)inc.php a nemôžu byť modifikované cez UI.", "message": "Správa", @@ -237,7 +227,7 @@ "oauth2_add_client": "Pridať OAuth2 klienta", "oauth2_client_id": "ID klienta", "oauth2_client_secret": "Tajný kľuč", - "oauth2_info": "OAuth2 implementácia podporuje typ prideľovania \"Authorization Code\" a vydáva tokeny k obnoveniu.
    \r\nServer automaticky vydáva nové tokeny k obnoveniu, akonáhle bol predchádzajúci token použitý.

    \r\n• Predvolený rozsah je profile. Iba používatelia poštovej schránky môžu byť autentifikovaný cez OAuth2. Ak je rozsahový pramater vynechaný, spadá naspäť do profile.
    \r\n• Stavový parameter je potrebný poslať klientom ako súčasť autorizačnej požiadavky.

    \r\nCesty pre požiadavky ku OAuth2 API:
    \r\n
      \r\n
    • Koncový bod autorizácie: /oauth/authorize
    • \r\n
    • Koncový bod tokenu: /oauth/token
    • \r\n
    • Zdrojová stránka: /oauth/profile
    • \r\n
    \r\nAk príde k obnoveniu tajného kľúča, nezruší sa platnosť existujúcich autorizačných kódov, ale nebude možné obnoviť ich token.

    \r\nOdobratím tajného kľúča bude mať za následok zrušenie všetkých aktívnych relácií. Všetci klienti musia podstúpiť re-autentifikačný proces.", + "oauth2_info": "OAuth2 implementácia podporuje typ prideľovania \"Authorization Code\" a vydáva tokeny k obnoveniu.
    \r\nServer automaticky vydáva nové tokeny k obnoveniu, akonáhle bol predchádzajúci token použitý.

    \r\n• Predvolený rozsah je profile. Iba používatelia mailovej schránky môžu byť autentifikovaný cez OAuth2. Ak je rozsahový pramater vynechaný, spadá naspäť do profile.
    \r\n• Stavový parameter je potrebný poslať klientom ako súčasť autorizačnej požiadavky.

    \r\nCesty pre požiadavky ku OAuth2 API:
    \r\n
      \r\n
    • Koncový bod autorizácie: /oauth/authorize
    • \r\n
    • Koncový bod tokenu: /oauth/token
    • \r\n
    • Zdrojová stránka: /oauth/profile
    • \r\n
    \r\nAk príde k obnoveniu tajného kľúča, nezruší sa platnosť existujúcich autorizačných kódov, ale nebude možné obnoviť ich token.

    \r\nOdobratím tajného kľúča bude mať za následok zrušenie všetkých aktívnych relácií. Všetci klienti musia podstúpiť re-autentifikačný proces.", "oauth2_redirect_uri": "Presmerovať URI", "oauth2_renew_secret": "Vygenerovať nový tajný kľuč", "oauth2_revoke_tokens": "Odobrať všetky tokeny klienta", @@ -266,7 +256,7 @@ "quarantine_release_format": "Uvoľňovať položky z karantény ako", "quarantine_release_format_att": "Prílohu", "quarantine_release_format_raw": "Nemodifikovaný originál", - "quarantine_retention_size": "Počet zadržaných správ pre jednotlivé poštové schránky
    0 znamená neaktívne.", + "quarantine_retention_size": "Počet zadržaných správ pre jednotlivé mailové schránky
    0 znamená neaktívne.", "queue_ays": "Prosím potvrďte vymazanie všetkých položiek z aktuálnej fronty.", "queue_deliver_mail": "Doručiť", "queue_hold_mail": "Pozdržať", @@ -279,7 +269,7 @@ "quota_notification_subject": "Predmet notifikácií", "quota_notifications": "Notifikácie o kvótach", "quota_notifications_info": "Notifikácie o kvóte sú odosielané používateľom, keď prekročia 80% a 95% objemu schránky.", - "quota_notifications_vars": "{{percent}} sa rovná aktuálnej kvóte používateľa
    {{užívateľské meno}} je poštová schránka", + "quota_notifications_vars": "{{percent}} sa rovná aktuálnej kvóte používateľa
    {{užívateľské meno}} je mailová schránka", "r_active": "Aktívne obmedzenia", "r_inactive": "Neaktívne obmedzenia", "r_info": "Vyznačené/deaktivované položky na zozname aktívnych obmedzení nie sú považované ako platné obmedzenie pre mailcow a nemôžu byť presunuté. Neznáme položky budú napriek tomu zoradené za sebou.
    Môžete pridať nové položky v inc/vars.local.inc.php aby sa dali prepínať.", @@ -368,14 +358,14 @@ "bcc_exists": "Skrytá kópia %s už existuje pre typ %s", "bcc_must_be_email": "Cieľ kópie %s nie je platná emailová adresa", "comment_too_long": "Komentár je príliš dlhý, povolených je max. 160 znakov", - "defquota_empty": "Predvolená kvóta pre poštovú schránku nemôže byť 0.", + "defquota_empty": "Predvolená kvóta pre mailovú schránku nemôže byť 0.", "description_invalid": "Popis zdroja pre %s je neplatný", "dkim_domain_or_sel_exists": "DKIM kľúč pre \"%s\" existuje a nebude prepísaný", "dkim_domain_or_sel_invalid": "DKIM doména alebo selektor je neplatný: %s", "domain_cannot_match_hostname": "Doména sa nemôže zhodovať s menom hostiteľa", "domain_exists": "Doména %s už existuje", "domain_invalid": "Meno domény je prázdne alebo neplatné", - "domain_not_empty": "Nie je možné odstrániť doménu ktorá obsahuje poštové schránky", + "domain_not_empty": "Nie je možné odstrániť doménu ktorá obsahuje mailové schránky", "domain_not_found": "Doména %s sa nenašla", "domain_quota_m_in_use": "Doménová kvóta musí byť väčšia alebo rovnajúca sa %s MiB", "extra_acl_invalid": "Externá adresa odosielateľa \"%s\" je neplatná", @@ -404,21 +394,21 @@ "invalid_recipient_map_old": "Neplatná pôvodná mapa príjemcu: %s", "ip_list_empty": "Zoznam povolených IP nemôže byť prázdny", "is_alias": "%s je už používané ako alias adresa", - "is_alias_or_mailbox": "%s je už používaná ako adresa aliasu, poštovej schránky alebo aliasu odvodeného z aliasu domény", + "is_alias_or_mailbox": "%s je už používaná ako adresa aliasu, mailovej schránky alebo aliasu odvodeného z aliasu domény", "is_spam_alias": "%s je už používaná ako adresa dočasného aliasu (spam alias adresa)", "last_key": "Posledný kľúč nemôže byť vymazaný, deaktivujte najprv TFA", "login_failed": "Prihlásenie zlyhalo", - "mailbox_defquota_exceeds_mailbox_maxquota": "Predvolená kvóta presahuje max. kvótu poštovej schránky", - "mailbox_invalid": "Meno poštovej schránky je neplatné", + "mailbox_defquota_exceeds_mailbox_maxquota": "Predvolená kvóta presahuje max. kvótu mailovej schránky", + "mailbox_invalid": "Meno mailovej schránky je neplatné", "mailbox_quota_exceeded": "Kvóta presahuje doménový limit (max. %d MiB)", "mailbox_quota_exceeds_domain_quota": "Max. kvóta presahuje limit doménových kvót", "mailbox_quota_left_exceeded": "Nedostatok priestoru (space left: %d MiB)", - "mailboxes_in_use": "Max. počet poštových schránok musí byť väčší alebo rovnajúci sa %d", + "mailboxes_in_use": "Max. počet mailových schránok musí byť väčší alebo rovnajúci sa %d", "malformed_username": "Chybné používateľské meno", "map_content_empty": "Obsah mapy nemôže byť prázdny", "max_alias_exceeded": "Presiahnutý max. počet aliasov", - "max_mailbox_exceeded": "Presiahnutý max. počet poštových schránok (%d of %d)", - "max_quota_in_use": "Kvóta pre poštovú schránku musí byť väčšia alebo rovnajúca sa %d MiB", + "max_mailbox_exceeded": "Presiahnutý max. počet mailových schránok (%d of %d)", + "max_quota_in_use": "Kvóta pre mailovú schránku musí byť väčšia alebo rovnajúca sa %d MiB", "maxquota_empty": "Max. kvóta pre mailovú schránku nemôže byť 0.", "mysql_error": "MySQL chyba: %s", "network_host_invalid": "Neplatná sieť alebo hostiteľ: %s", @@ -517,6 +507,7 @@ "optional": "Tento záznam je voliteľný." }, "edit": { + "acl": "ACL (Oprávnenia)", "active": "Aktívny", "admin": "Upraviť administrátora", "advanced_settings": "Pokročilé nastavenia", @@ -559,15 +550,15 @@ "inactive": "Neaktívny", "kind": "Druh", "lookup_mx": "Cieľ je regulárny výraz ktorý sa zhoduje s MX záznamom (.*google\\.com smeruje všetku poštu na MX ktoré sú cieľom pre google.com cez tento skok)", - "mailbox": "Upraviť poštovú schránku", - "mailbox_quota_def": "Predvolená veľkosť poštovej schránky", + "mailbox": "Upraviť mailovú schránku", + "mailbox_quota_def": "Predvolená veľkosť mailovej schránky", "mailbox_relayhost_info": "Aplikované len na používateľské schránky a priame aliasy, prepisuje doménového preposielateľa.", "max_aliases": "Max. počet aliasov", "max_mailboxes": "Max. počet schránok", - "max_quota": "Max. kvóta pre poštovú schránku (MiB)", + "max_quota": "Max. kvóta pre mailovú schránku (MiB)", "maxage": "Maximálne obdobie správ v dňoch, ktoré sa budú vzdialene dotazovať
    (0 = ignorovať obdobie age)", "maxbytespersecond": "Max. bajtov za sekundu
    (0 = bez limitu)", - "mbox_rl_info": "Tento limit je aplikovaný na báze prihlasovacieho mena SASL, je zhodný s \"from\" adresou používanou prihláseným používateľom. Prenosový limit u poštovej adresy má prednosť pred domain-wide prenosovým limitom.", + "mbox_rl_info": "Tento limit je aplikovaný na báze prihlasovacieho mena SASL, je zhodný s \"from\" adresou používanou prihláseným používateľom. Prenosový limit u mailovej adresy má prednosť pred domain-wide prenosovým limitom.", "mins_interval": "Interval (min)", "multiple_bookings": "Viaceré rezervácie", "nexthop": "Ďalší skok", @@ -577,6 +568,7 @@ "previous": "Predchádzajúca strana", "private_comment": "Súkromný komentár", "public_comment": "Verejný komentár", + "pushover": "Pushover", "pushover_evaluate_x_prio": "Eskalovať správy s vysokou prioritou [X-Priority: 1]", "pushover_info": "Push notifikácie budú aplikované na všetky správy (s výnimkou spamu) doručené pre %s vrátane aliasov (zdieľané, nezdieľané, označené).", "pushover_only_x_prio": "Vyberať len správy s vysokou prioritou [X-Priority: 1]", @@ -592,10 +584,10 @@ "ratelimit": "Obmedzenie prenosu", "redirect_uri": "Presmerovať URL", "relay_all": "Preposielať všetkých prijemcov", - "relay_all_info": "↪ Ak sa rozhodnete nepreposielať všetkých príjemcov, budete musieť pridať (\"tzv. slepú\") poštovú schránku pre každého príjemcu.", + "relay_all_info": "↪ Ak sa rozhodnete nepreposielať všetkých príjemcov, budete musieť pridať (\"tzv. slepú\") mailovú schránku pre každého príjemcu.", "relay_domain": "Preposielať túto doménu", "relay_transport_info": "
    Info
    Môžete definovať transportné mapy pre vlastné určenie cieľa pre túto doménu. Ak nie sú nastavené, použije sa MX záznam.", - "relay_unknown_only": "Preposielať len neexistujúce poštové schránky. Existujúce budú doručené lokálne.", + "relay_unknown_only": "Preposielať len neexistujúce mailové schránky. Existujúce budú doručené lokálne.", "relayhost": "Transporty závislé na odosielateľovi", "remove": "Odstrániť", "resource": "Zdroj", @@ -603,14 +595,12 @@ "scope": "Rozsah", "sender_acl": "Povoliť odosielanie ako", "sender_acl_disabled": "Kontrola odosielateľa vypnutá", - "sender_acl_info": "Ak poštový používateľ A má povolenie poslať ako poštový používateľ B, adresa odosielateľa nieje automaticky viditeľná ako voliteľné \"from\" pole v SOGo.
    \r\n Poštový používateľ B potrebuje vytvoriť delegáciu v SOGo, aby bol schopný poštový používateľ A vybrať svoju adresu ako odosielateľ. Na delegovanie poštovej adresy v SOGo, použite menu (tri bodky) napravo vášho poštového mena v hornom ľavom rohu, v prehľade správ. Toto neplatí pre alias adresy.", + "sender_acl_info": "Ak mailový používateľ A má povolenie poslať ako mailový používateľ B, adresa odosielateľa nieje automaticky viditeľná ako voliteľné \"from\" pole v SOGo.
    \r\n Mailový používateľ B potrebuje vytvoriť delegáciu v SOGo, aby bol schopný mailový používateľ A vybrať jeho adresu ako odosielateľ. Na delegovanie mailovej adresy v SOGo, použite menu (tri bodky) napravo vášho mailového mena v hornom ľavom rohu, v prehľade správ. Toto neplatí pre alias adresy.", "sieve_desc": "Krátky popis", "sieve_type": "Typ filtru", "skipcrossduplicates": "Preskočiť duplikované správy naprieč priečinkami (akceptuje sa prvý nález)", - "sogo_access": "Povoliť prístup do SOGo", - "sogo_access_info": "Povoliť alebo umožniť prístup do SOGo. Toto nastavenie neovplyvňuje prístup všetkým službám alebo nemaže/nemení existujúci SOGo profil používateľa.", "sogo_visible": "Alias je viditeľný v SOGo", - "sogo_visible_info": "Táto voľba ovplyvňuje len objekty, ktoré dokážu byť zobrazené v SOGo (zdieľané alebo nezdieľané alias adresy ukazujúc na minimálne jednu lokálnu poštovú schránku). Ak je skrytý, alias nebude prezentovaný ako voliteľný odosielateľ v SOGo.", + "sogo_visible_info": "Táto voľba ovplyvňuje len objekty, ktoré dokážu byť zobrazené v SOGo (zdieľané alebo nezdieľané alias adresy ukazujúc na minimálne jednu lokálnu mailovú schránku). Ak je skrytý, alias nebude prezentovaný ako voliteľný odosielateľ v SOGo.", "spam_alias": "Vytvoriť alebo zmeniť časovo limitované alias adresy", "spam_filter": "Spam filter", "spam_policy": "Pridať alebo odstrániť položky do bielej/čiernej listiny", @@ -646,6 +636,7 @@ "register_status": "Stav registrácie", "rename": "Premenovať", "set_fido2": "Registrovať FIDO2 zariadenie", + "set_fido2_touchid": "Registrovať Touch ID na Apple M1", "set_fn": "Nastaviť zjednodušené meno", "start_fido2_validation": "Spustiť FIDO2 overenie" }, @@ -668,7 +659,7 @@ "administration": "Konfigurácia & Detaily", "apps": "Aplikácie", "debug": "Systémové informácie", - "mailboxes": "Nastavenie pošty", + "mailboxes": "Nastavenie mailov", "mailcow_settings": "Konfigurácia", "quarantine": "Karanténa", "restart_netfilter": "Reštartovať netfilter", @@ -684,7 +675,7 @@ "delayed": "Prihlásenie bolo oneskorené o %s sekúnd.", "fido2_webauthn": "FIDO2/WebAuthn", "login": "Prihlásenie", - "mobileconfig_info": "Prosím, prihláste sa ako poštový používateľ pre stiahnutie požadovaného Apple profilu.", + "mobileconfig_info": "Prosím, prihláste sa ako mailový používateľ pre stiahnutie požadovaného Apple profilu.", "other_logins": "Prihlásenie kľúčom", "password": "Heslo", "username": "Používateľské meno alebo email" @@ -701,13 +692,13 @@ "add_domain_alias": "Pridať alias doménu", "add_domain_record_first": "Prosím pridajte najprv doménu", "add_filter": "Pridať filter", - "add_mailbox": "Pridať poštovú schránku", + "add_mailbox": "Pridať mailovú schránku", "add_recipient_map_entry": "Pridať mapu príjemcu", "add_resource": "Pridať zdroj", "add_tls_policy_map": "Pridať TLS mapu pravidiel", "address_rewriting": "Prepisovanie adries", "alias": "Alias", - "alias_domain_alias_hint": "Aliasy nie sú aplikované na aliasy domén automaticky. Alias adresa my-alias@domain nezahŕňa adresu my-alias@alias-domain (kde \"alias-doména\" je imaginárna alias doména pre \"doména\").
    Prosím použite sieve filter na presmerovanie pošty na externú poštovú schránku (pozri sekciu \"Filtre\" alebo použite SOGo -> Forwarder). Použite \"Rozšíriť alias o aliasové domény\" na automatické doplnenie chýbajúcich aliasov.", + "alias_domain_alias_hint": "Aliasy nie sú aplikované na aliasy domén automaticky. Alias adresa my-alias@domain nezahŕňa adresu my-alias@alias-domain (kde \"alias-doména\" je imaginárna alias doména pre \"doména\").
    Prosím použite sieve filter na presmerovanie pošty na externú mailovú schránku (pozri sekciu \"Filtre\" alebo použite SOGo -> Forwarder). Použite \"Rozšíriť alias o aliasové domény\" na automatické doplnenie chýbajúcich aliasov.", "alias_domain_backupmx": "Doménový alias je neaktívny pre preposielaciu doménu", "aliases": "Aliasy", "all_domains": "Všetky Domény", @@ -763,12 +754,12 @@ "last_pw_change": "Naposledy zmenené heslo", "last_run": "Posledné spustenie", "last_run_reset": "Znovu naplánovať", - "mailbox": "Poštová schránka", + "mailbox": "Mailová schránka", "mailbox_defaults": "Predvolené nastavenia", "mailbox_defaults_info": "Definuje predvolené nastavenia pre nové schránky", "mailbox_defquota": "Predvolená veľkosť schránky", "mailbox_quota": "Max. veľkosť schránky", - "mailboxes": "Poštové schránky", + "mailboxes": "Mailové schránky", "mins_interval": "Interval (min)", "msg_num": "Počet správ", "multiple_bookings": "Viaceré rezervácie", @@ -817,6 +808,15 @@ "stats": "Štatistika", "status": "Status", "sync_jobs": "Synchronizačné úlohy", + "syncjob_check_log": "Skontrolujte záznam", + "syncjob_last_run_result": "Výsledok posledného spustenia", + "syncjob_EX_OK": "Úspech", + "syncjob_EXIT_CONNECTION_FAILURE": "Problém so spojením", + "syncjob_EXIT_TLS_FAILURE": "Problém so šifrovaným spojením", + "syncjob_EXIT_AUTHENTICATION_FAILURE": "Problém s autentifikáciou", + "syncjob_EXIT_OVERQUOTA": "Cieľová schránka je plná", + "syncjob_EXIT_CONNECTION_FAILURE_HOST1": "Nedá sa pripojiť k vzdialenému serveru", + "syncjob_EXIT_AUTHENTICATION_FAILURE_USER1": "Chybné uživateľské meno alebo heslo", "table_size": "Veľkosť tabuľky", "table_size_show_n": "Zobraziť %s položiek", "target_address": "Cieľová adresa", @@ -829,7 +829,7 @@ "tls_map_parameters_info": "Prázdny alebo parametre, napríklad: protocols=!SSLv2 ciphers=medium exclude=3DES", "tls_map_policy": "Podmienky", "tls_policy_maps": "Mapy TLS pravidiel", - "tls_policy_maps_enforced_tls": "Tieto politiky prepisujú používateľské nastavenia pre poštové schránky ktore majú vynútene odchodzie TLS pripojenie. Ak nižšie nie sú uvedené žiadne pravidlá, budú použité ako východzie pravidlá smtp_tls_mandatory_protocols a smtp_tls_mandatory_ciphers.", + "tls_policy_maps_enforced_tls": "Tieto politiky prepisujú používateľské nastavenia pre mailové schránky ktoré majú vynútene odchodzie TLS pripojenie. Ak nižšie nie sú uvedené žiadne pravidlá, budú použité ako východzie pravidlá smtp_tls_mandatory_protocols a smtp_tls_mandatory_ciphers.", "tls_policy_maps_info": "Táto mapa prevažuje nad TLS pravidlami nezávisle od TLS pravidiel jednotlivých používateľov.
    \r\n Viac informácií navštívte info k \"smtp_tls_policy_maps\" ", "tls_policy_maps_long": "Prepisovanie TLS pravidiel pre odosielanie", "toggle_all": "Označiť všetky", @@ -839,7 +839,7 @@ "yes": "✓" }, "oauth2": { - "access_denied": "Prosím prihláste sa ako používateľ poštovej schránky, aby ste mohli získať prístup cez OAuth2.", + "access_denied": "Prosím prihláste sa ako používateľ mailovej schránky, aby ste mohli získať prístup cez OAuth2.", "authorize_app": "Autorizovať aplikáciu", "deny": "Zamietnuť", "permit": "Autorizovať aplikáciu", @@ -910,7 +910,7 @@ "start": { "help": "Zobraziť/Skryť panel nápoveď", "imap_smtp_server_auth_info": "Prosím použite celú vašu emailovú adresu a metódu overenia PLAIN.
    \r\n Vaše prihlasovacie údaje budú zašifrované na strane servera.", - "mailcow_apps_detail": "Použite mailcow aplikácií pre prístup k vašej poštovej schránke, kalendáru, kontaktom a viac.", + "mailcow_apps_detail": "Použite mailcow aplikácie pre prístup k vašej mailovej schránke, kalendáru, kontaktom a viac.", "mailcow_panel_detail": "Administrátori domény môžu vytvárať, modifikovať alebo mazať schránky a aliasy, meniť domény a zobraziť informácie o priradených doménach.
    \r\nBežný používatelia majú možnosť vytvoriť časovo obmedzené aliasy (spam aliasy), meniť heslá a nastavenia spam filtra." }, "success": { @@ -959,8 +959,8 @@ "learned_ham": "ID %s úspešne naučené ako ham", "license_modified": "Zmeny v licencii uložené", "logged_in_as": "Prihlásený ako %s", - "mailbox_added": "Poštová schránka %s pridaná", - "mailbox_modified": "Zmeny v poštovej schránke %s uložené", + "mailbox_added": "Mailová schránka %s pridaná", + "mailbox_modified": "Zmeny v mailovej schránke %s uložené", "mailbox_removed": "Mailbox %s odstránený ", "nginx_reloaded": "Nginx sa reloadol", "object_modified": "Zmeny v objekte %s uložené", @@ -974,7 +974,7 @@ "relayhost_removed": "Preposielací hostiteľ %s odstránený", "reset_main_logo": "Reset na pôvodné logo", "resource_added": "Zdroj %s pridaný", - "resource_modified": "Zmeny v poštovej schránke %s uložené", + "resource_modified": "Zmeny v mailovej schránke %s uložené", "resource_removed": "Zdroj %s odstránený", "rl_saved": "Obmedzenie prenosu pre objekt %s uložený", "rspamd_ui_pw_set": "Heslo pre Rspamd rozhranie úspešne nastavené", @@ -1034,7 +1034,7 @@ "alias_valid_until": "Platné do", "aliases_also_send_as": "Môže odosielať ako používateľ", "aliases_send_as_all": "Nekontrolovať prístup odosielateľa pre nasledujúcu doménu/y a jej alias domény", - "app_hint": "Heslá aplikácií sú alternatívne heslá pre vaše IMAP a SMTP prihlásenie. Používateľské meno zostáva nezmenené.
    SOGo (zahŕňajúc ActiveSync) nie je momentálne podporovaný.", + "app_hint": "Heslá aplikácií sú alternatívne heslá pre vaše IMAP, SMTP, CalDAV, CardDAV a EAS prihlásenie. Používateľské meno zostáva nezmenené.
    SOGo nie je momentálne podporovaný.", "app_name": "Meno aplikácie", "app_passwds": "Heslá aplikácií", "apple_connection_profile": "Apple konfiguračný profil", @@ -1071,13 +1071,13 @@ "in_use": "Použité", "interval": "Interval", "is_catch_all": "Doménový kôš", - "last_mail_login": "Posledné poštové prihlásenie", + "last_mail_login": "Posledné prihlásenie", "last_pw_change": "Naposledy zmenené heslo", "last_run": "Posledné spustenie", "last_ui_login": "Posledné prihlásenie do web rozhrania", "loading": "Načítavanie...", "login_history": "História prihlásenia", - "mailbox": "Poštová schránka", + "mailbox": "Mailová schránka", "mailbox_details": "Detail", "mailbox_general": "Všeobecné", "mailbox_settings": "Nastavenia", @@ -1123,7 +1123,7 @@ "sogo_profile_reset": "Resetnúť SOGo profil", "sogo_profile_reset_help": "Táto činnosť odstraní SOGo profil používateľa a nenávratne vymaže všetky kontakty a kalendár.", "sogo_profile_reset_now": "Resetnúť profil", - "spam_aliases": "Dočasný poštový alias", + "spam_aliases": "Dočasný mailový alias", "spam_score_reset": "Obnoviť pôvodné spam nastavenia", "spamfilter": "Spam filter", "spamfilter_behavior": "Hodnotenie", @@ -1144,6 +1144,15 @@ "spamfilter_yellow": "Žltá: Táto správa môže byť spam, bude označená ako spam a presunutá do priečinku nevyžiadanej pošty", "status": "Status", "sync_jobs": "Synchronizačné úlohy", + "syncjob_check_log": "Skontrolujte záznam", + "syncjob_last_run_result": "Výsledok posledného spustenia", + "syncjob_EX_OK": "Úspech", + "syncjob_EXIT_CONNECTION_FAILURE": "Problém so spojením", + "syncjob_EXIT_TLS_FAILURE": "Problém so šifrovaným spojením", + "syncjob_EXIT_AUTHENTICATION_FAILURE": "Problém s autentifikáciou", + "syncjob_EXIT_OVERQUOTA": "Cieľová schránka je plná", + "syncjob_EXIT_CONNECTION_FAILURE_HOST1": "Nedá sa pripojiť k vzdialenému serveru", + "syncjob_EXIT_AUTHENTICATION_FAILURE_USER1": "Chybné uživateľské meno alebo heslo", "tag_handling": "Zaobchádzanie s označenou poštou", "tag_help_example": "Príklad tagu e-mailovej adresy: me+Facebook@example.org", "tag_help_explain": "V podadresári: nový podadresár s menom tag-u bude vytvorený nižšie INBOX (\"INBOX/Facebook\").
    \r\nIn subject: meno štítka bude pridané pred predmet pošty, napríklad: \"[Facebook] My News\".", @@ -1155,7 +1164,7 @@ "tls_enforce_in": "Vynútiť TLS pre prichádzajúcu poštu", "tls_enforce_out": "Vynútiť TLS pre odchádzajúcu poštu", "tls_policy": "TLS pravidlá", - "tls_policy_warning": "Upozornenie: Ak sa rozhodnete vynútiť šifrovaný prenos, môže prísť k strate e-mailov.
    Správy nespĺňajúce túto podmienku budú trvalo odmietané serverom.
    Táto možnosť platí pre vašu primárnu emailovú adresu (prihlasovacie meno), všetky odvodené adresy ako aj alias cieľovej poštovej schránky.", + "tls_policy_warning": "Upozornenie: Ak sa rozhodnete vynútiť šifrovaný prenos, môže prísť k strate e-mailov.
    Správy nespĺňajúce túto podmienku budú trvalo odmietané serverom.
    Táto možnosť platí pre vašu primárnu emailovú adresu (prihlasovacie meno), všetky odvodené adresy ako aj alias cieľovej mailovej schránky.", "user_settings": "Používateľské nastavenia", "username": "Prihlasovacie meno", "verify": "Overiť", @@ -1175,7 +1184,7 @@ "ip_invalid": "Preskočená neplatná IP adresa: %s", "is_not_primary_alias": "Preskočiť ne-primárny alias %s", "no_active_admin": "Nemožno deaktivovať posledného aktívneho admina", - "quota_exceeded_scope": "Prekročená kvóta domény, pre túto doménu je možné vytvárať iba neobmedzené poštové schránky.", + "quota_exceeded_scope": "Prekročená kvóta domény, pre túto doménu je možné vytvárať iba neobmedzené mailové schránky.", "session_token": "Formulárový token neplatný: Tokenová nezhoda", "session_ua": "Formulárový token neplatný: User-Agent validation error" } diff --git a/data/web/lang/lang.sv.json b/data/web/lang/lang.sv.json index d4e1daf9..063a8f4a 100644 --- a/data/web/lang/lang.sv.json +++ b/data/web/lang/lang.sv.json @@ -26,11 +26,7 @@ "syncjobs": "synkroniseringsjobb", "tls_policy": "Krypteringspolicy", "unlimited_quota": "Obegränsad kvot för postlådor", - "domain_desc": "Ändra domänbeskrivningen", - "xmpp_admin": "Ändra XMPP administratörs-status på en användare", - "xmpp_domain_access": "Ändra XMPP-åtkomsten på en domän", - "xmpp_mailbox_access": "Ändra XMPP-åtkomsten på en användare", - "xmpp_prefix": "Ändra XMPP-subdomän/prefix" + "domain_desc": "Ändra domänbeskrivningen" }, "add": { "activate_filter_warn": "Alla andra filter av den här typen kommer inaktiveras om det här skriptet markeras som aktivt.", @@ -63,14 +59,6 @@ "full_name": "Fullständiga namn", "gal": "Global adressbok", "gal_info": "Den global adressboken innehåller alla objekt i en domän och kan inte redigeras av någon användare. Informationen om tillgänglighet i SOGo är endast synlig när den globala adressboken är påslagen. Starta om SOGo för att tillämpa ändringar.", - "xmpp": "Aktivera XMPP funktion på denna domän", - "xmpp_prefix": "XMPP-prefix för domänen (Exempelvis \"im\" för im.example.org)", - "xmpp_prefix_info": "För att tillhandahålla ett säkerhetscertifikat måste vissa DNS-uppslag skapas, exempelvis två CNAME uppslag, ett för im.example.org och ett för *.im.example.org, som pekar mot %s. Efter att denna funktion har aktiverats, utför en DNS-kontroll för att testa att uppslagen är korrekt uppsatta.", - "xmpp_info": "Denna funktion aktiverar chatt-funktionalitet på denna domän.", - "xmpp_access": "XMPP-åtkomst", - "xmpp_access_info": "XMPP måste aktiveras på den här domänen.", - "xmpp_admin": "XMPP Administratör", - "xmpp_admin_info": "Varning: Befodrar en användare till XMPP-administratör på den här domänen.", "generate": "generera", "goto_ham": "Markera detta som en felaktig spam-registrering, detta kommer förhindra liknande fel i framtiden", "goto_null": "Kasta e-postmeddelanande omedelbart", @@ -599,8 +587,6 @@ "sieve_desc": "Kort beskrivning", "sieve_type": "Filtertyp", "skipcrossduplicates": "Hoppa över duplicerade meddelanden i katalogerna (först till kvarn)", - "sogo_access": "Ge åtkomst till SOGo", - "sogo_access_info": "Ge eller tillåt åtkomst till SOGo. Denna inställning påverkar varken åtkomsten till alla andra tjänster eller raderar eller ändrar inte en befintlig SOGo-profil.", "sogo_visible": "Alias visas i SOGo", "sogo_visible_info": "Det här alternativet påverkar endast objekt som kan visas i SOGo (delade eller icke-delade aliasadresser med destination för minst en lokal postlåda).", "spam_alias": "Skapa eller ändra tillfälliga e-postalias", @@ -1000,7 +986,7 @@ "alias_valid_until": "Giltig till", "aliases_also_send_as": "Som också har tillåtelse att skicka som användare", "aliases_send_as_all": "Kontrollera inte avsändaråtkomsten för följande domän/domäner och aliasdomäner", - "app_hint": "Applikationslösenord är ett alternativt lösenord för IMAP och SMTP inloggning på e-postservern. Användarnamnet förblir oförändrat.
    SOGo (och därmed ActiveSync) kan inte användas med det här lösenordet.", + "app_hint": "Applikationslösenord är ett alternativt lösenord för IMAP, SMTP, CalDAV, CardDAV och EAS inloggning på e-postservern. Användarnamnet förblir oförändrat.
    SOGo kan inte användas med det här lösenordet.", "app_name": "Applikationsnamn", "app_passwds": "Applikationslösenord", "apple_connection_profile": "Apple-anslutningsprofil", diff --git a/data/web/lang/lang.zh.json b/data/web/lang/lang.zh.json index 8993cb9c..e9589292 100644 --- a/data/web/lang/lang.zh.json +++ b/data/web/lang/lang.zh.json @@ -549,8 +549,6 @@ "sieve_desc": "简短描述", "sieve_type": "过滤器类型", "skipcrossduplicates": "跳过其他文件夹中已存在的邮件(保留先存在的邮件)", - "sogo_access": "授权访问SOGo", - "sogo_access_info": "授权访问SOGo,此设置既不会影响其他所有服务的访问也不会删除或更改用户在SOGo的上的个人资料。", "sogo_visible": "SOGo别名显示", "sogo_visible_info": "此设置只影响SOGo上的可显示对象(指向本地邮箱的共享或非共享别名地址)。如果设为隐藏,别名地址不会作为下拉可选发件人项显示。", "spam_alias": "添加或更改临时别名地址", diff --git a/data/web/mailbox.php b/data/web/mailbox.php index 6dfe3af5..489ac429 100644 --- a/data/web/mailbox.php +++ b/data/web/mailbox.php @@ -1,654 +1,45 @@ -
    - - - -
    -
    -
    -
    -
    -
    - - -
    - -
    -
    -
    -
    -
    - - - -
    - - - -
    -
    -
    -
    - -
    -
    -
    - -
    -
    - -
    -
    -
    - -
    -
    -
    - - -
    - -
    -
    -
    -
    - - -
    -
    -
    - -
    -
    -
    - - -
    -
    -

    -

    -

    -

    -

    -

    -
    - -
    -
    -
    -
    -
    - - - -
    - -
    -
    -
    -
    - -
    -
    -
    - - -
    - -
    -
    -
    -
    -
    - - - -
    - -
    -
    -
    -
    - -
    -
    -
    - - -
    -
    - -
    - -
    -
    -
    -
    -
    - - - -
    - - -
    -
    -
    -
    - -
    -
    -
    - - -
    - -
    -
    -
    -
    -
    - - - -
    - -
    -
    -
    -
    - -
    -
    -
    - - -
    -
    -


    -
    - -
    -
    -
    -
    -
    - - - -
    - -
    -
    -
    "> - -
    -
    -
    Global Prefilter
    -
    -
    -
    - -
    -
    -
    -
    -
    - - -
    -
    -
    -
    -
    -
    -
    -
    Global Postfilter
    -
    -
    -
    - -
    -
    -
    -
    -
    - - -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    - -
    -
    -
    - - -
    -

    - -
    -
    -
    -
    -
    - - - -
    - -
    -
    -
    -
    "> -
    - - -
    -

    - -
    -
    -
    -
    -
    - - - -
    - -
    -
    -
    -
    - -
    " id="tab-tls-policy"> -
    -
    - - -
    -

    - -
    -
    -
    -
    -
    - - - -
    - -
    -
    -
    -
    -
    -
    -
    -
    - - -add('/web/js/site/mailbox.js'); -$js_minifier->add('/web/js/presets/sieveMailbox.js'); -$js_minifier->add('/web/js/site/pwgen.js'); -require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/footer.inc.php'; -} -else { +if (!isset($_SESSION['mailcow_cc_role']) || $_SESSION['mailcow_cc_role'] != "admin" && $_SESSION['mailcow_cc_role'] != "domainadmin") { header('Location: /'); exit(); } -?> +require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/header.inc.php'; +$_SESSION['return_to'] = $_SERVER['REQUEST_URI']; + + + +$js_minifier->add('/web/js/site/mailbox.js'); +$js_minifier->add('/web/js/presets/sieveMailbox.js'); +$js_minifier->add('/web/js/site/pwgen.js'); + +$role = ($_SESSION['mailcow_cc_role'] == "admin") ? 'admin' : 'domainadmin'; +$is_dual = (!empty($_SESSION["dual-login"]["username"])) ? 'true' : 'false'; +$allow_admin_email_login = (preg_match("/^([yY][eE][sS]|[yY])+$/", $_ENV["ALLOW_ADMIN_EMAIL_LOGIN"])) ? 'true' : 'false'; + +// domains +$domains = mailbox('get', 'domains'); + +// mailboxes +$mailboxes = []; +foreach ($domains as $domain) { + foreach (mailbox('get', 'mailboxes', $domain) as $mailbox) { + $mailboxes[] = $mailbox; + } +} + +$template = 'mailbox.twig'; +$template_data = [ + 'acl' => $_SESSION['acl'], + 'acl_json' => json_encode($_SESSION['acl']), + 'role' => $role, + 'is_dual' => $is_dual, + 'allow_admin_email_login' => $allow_admin_email_login, + 'global_filters' => mailbox('get', 'global_filter_details'), + 'domains' => $domains, + 'mailboxes' => $mailboxes, + 'lang_mailbox' => json_encode($lang['mailbox']), +]; + +require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/footer.inc.php'; diff --git a/data/web/modals/admin.php b/data/web/modals/admin.php deleted file mode 100644 index 22bb412c..00000000 --- a/data/web/modals/admin.php +++ /dev/null @@ -1,271 +0,0 @@ - - - - - - - - - - - - - - - - - diff --git a/data/web/modals/debug.php b/data/web/modals/debug.php deleted file mode 100644 index e955a20b..00000000 --- a/data/web/modals/debug.php +++ /dev/null @@ -1,6 +0,0 @@ - diff --git a/data/web/modals/footer.php b/data/web/modals/footer.php deleted file mode 100644 index 7f732628..00000000 --- a/data/web/modals/footer.php +++ /dev/null @@ -1,256 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/data/web/modals/user.php b/data/web/modals/user.php deleted file mode 100644 index e5d5aa8b..00000000 --- a/data/web/modals/user.php +++ /dev/null @@ -1,342 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/data/web/oauth/authorize.php b/data/web/oauth/authorize.php index 48e99b0c..1fdcd033 100644 --- a/data/web/oauth/authorize.php +++ b/data/web/oauth/authorize.php @@ -1,69 +1,38 @@ -validateAuthorizeRequest($request, $response)) { - $response->send(); - exit(); -} - -if (!isset($_POST['authorized'])): -require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/header.inc.php'; - -?> -
    -
    -
    -
    - -

    - -

    :

    -
    -
    -
    -
    -
    -
    -
    - - - -
    -
    -
    - -
    -
    -
    -handleAuthorizeRequest($request, $response, $is_authorized, $_SESSION['mailcow_cc_username']); -if ($is_authorized) { - unset($_SESSION['oauth2_request']); - if ($GLOBALS['OAUTH2_FORGET_SESSION_AFTER_LOGIN'] === true) { - session_unset(); - session_destroy(); - } - header('Location: ' . $response->getHttpHeader('Location')); - exit; -} +validateAuthorizeRequest($request, $response)) { + $response->send(); + exit; +} + +if (!isset($_POST['authorized'])) { + require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/header.inc.php'; + + $template = 'oauth/authorize.twig'; + $template_data = []; + + require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/footer.inc.php'; + exit; +} + +// print the authorization code if the user has authorized your client +$is_authorized = ($_POST['authorized'] == '1'); +$oauth2_server->handleAuthorizeRequest($request, $response, $is_authorized, $_SESSION['mailcow_cc_username']); +if ($is_authorized) { + unset($_SESSION['oauth2_request']); + if ($GLOBALS['OAUTH2_FORGET_SESSION_AFTER_LOGIN'] === true) { + session_unset(); + session_destroy(); + } + header('Location: ' . $response->getHttpHeader('Location')); + exit; +} diff --git a/data/web/qhandler.php b/data/web/qhandler.php index 756c6955..6e4cce52 100644 --- a/data/web/qhandler.php +++ b/data/web/qhandler.php @@ -1,109 +1,24 @@ - -
    -
    -
    -
    -
    -
    - -

    -
    -
    -
    -
    -
    - -
    -
    -
    -
    -
    -
    - - - - - - -
    - -

    :

    -

    -
    -
    - -

    -
    -
    - -

    -
    -
    - -

    -
    -
    - -

    -
    -
    - -

    -
    -
    -
    -
    - - - - - -
    -
    -
    -
    -
    -
    -
    -
    - - -add('/web/js/site/qhandler.js'); -require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/footer.inc.php'; -?> +add('/web/js/site/qhandler.js'); + +$template = 'qhandler.twig'; +$template_data = [ + 'quick_release' => preg_match("/^([a-f0-9]{64})$/", $_POST['quick_release']), + 'quick_delete' => preg_match("/^([a-f0-9]{64})$/", $_POST['quick_delete']), + 'is_action_release_delete' => in_array($_GET['action'], array('release', 'delete')), + 'is_hash_present' => preg_match("/^([a-f0-9]{64})$/", $_GET['hash']), + 'action' => $_GET['action'], + 'hash' => $_GET['hash'], + 'lang_quarantine' => json_encode($lang['quarantine']), +]; + +require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/footer.inc.php'; + diff --git a/data/web/quarantine.php b/data/web/quarantine.php index 6343db40..4a537e50 100644 --- a/data/web/quarantine.php +++ b/data/web/quarantine.php @@ -1,87 +1,26 @@ -
    -
    -
    -
    -
    - -
    - - - -
    -
    -

    -

    - -

    - -

    - -

    -
    -
    -
    -
    -
    - - - -
    -
    -
    -
    -
    -
    -
    - - -add('/web/js/site/quarantine.js'); + +$role = ($_SESSION['mailcow_cc_role'] == "admin") ? 'admin' : 'domainadmin'; + +$template = 'quarantine.twig'; +$template_data = [ + 'acl' => $_SESSION['acl'], + 'acl_json' => json_encode($_SESSION['acl']), + 'role' => $role, + 'quarantine_settings' => $quarantine_settings, + 'lang_quarantine' => json_encode($lang['quarantine']), +]; + require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/footer.inc.php'; -} else { - header('Location: /'); - exit(); -} -?> diff --git a/data/web/sogo-auth.php b/data/web/sogo-auth.php index 3bd19c6e..bb2673a4 100644 --- a/data/web/sogo-auth.php +++ b/data/web/sogo-auth.php @@ -14,7 +14,16 @@ if (isset($_SERVER['PHP_AUTH_USER'])) { require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/prerequisites.inc.php'; $username = $_SERVER['PHP_AUTH_USER']; $password = $_SERVER['PHP_AUTH_PW']; - $login_check = check_login($username, $password); + $is_eas = false; + $is_dav = false; + $original_uri = isset($_SERVER['HTTP_X_ORIGINAL_URI']) ? $_SERVER['HTTP_X_ORIGINAL_URI'] : ''; + if (preg_match('/^(\/SOGo|)\/dav.*/', $original_uri) === 1) { + $is_dav = true; + } + elseif (preg_match('/^(\/SOGo|)\/Microsoft-Server-ActiveSync.*/', $original_uri) === 1) { + $is_eas = true; + } + $login_check = check_login($username, $password, array('dav' => $is_dav, 'eas' => $is_eas)); if ($login_check === 'user') { header("X-User: $username"); header("X-Auth: Basic ".base64_encode("$username:$password")); @@ -34,13 +43,8 @@ elseif (isset($_GET['login'])) { $is_dual = (!empty($_SESSION["dual-login"]["username"])) ? true : false; // check permissions (if dual_login is active, deny sso when acl is not given) $login = html_entity_decode(rawurldecode($_GET["login"])); - if ($ALLOW_ADMIN_EMAIL_LOGIN === 0 && $is_dual === true) { - header('HTTP/1.0 403 Forbidden'); - echo "Admin login is forbidden"; - exit; - } if (isset($_SESSION['mailcow_cc_role']) && - ($_SESSION['acl']['login_as'] == "1" || ($is_dual === false && $login == $_SESSION['mailcow_cc_username']))) { + (($_SESSION['acl']['login_as'] == "1" && $ALLOW_ADMIN_EMAIL_LOGIN !== 0) || ($is_dual === false && $login == $_SESSION['mailcow_cc_username']))) { if (filter_var($login, FILTER_VALIDATE_EMAIL)) { if (user_get_alias_details($login) !== false) { // load master password @@ -48,6 +52,13 @@ elseif (isset($_GET['login'])) { // register username and password in session $_SESSION[$session_var_user_allowed][] = $login; $_SESSION[$session_var_pass] = $sogo_sso_pass; + // update sasl logs + $service = ($app_passwd_data['eas'] === true) ? 'EAS' : 'DAV'; + $stmt = $pdo->prepare("REPLACE INTO sasl_log (`service`, `app_password`, `username`, `real_rip`) VALUES ('SSO', 0, :username, :remote_addr)"); + $stmt->execute(array( + ':username' => $login, + ':remote_addr' => ($_SERVER['HTTP_X_REAL_IP'] ?? $_SERVER['REMOTE_ADDR']) + )); // redirect to sogo (sogo will get the correct credentials via nginx auth_request header("Location: /SOGo/so/${login}"); exit; @@ -55,13 +66,11 @@ elseif (isset($_GET['login'])) { } } header('HTTP/1.0 403 Forbidden'); - echo "Access is forbidden"; + echo "Forbidden"; exit; } // only check for admin-login on sogo GUI requests -elseif ( - strcasecmp(substr($_SERVER['HTTP_X_ORIGINAL_URI'], 0, 9), "/SOGo/so/") === 0 -) { +elseif (isset($_SERVER['HTTP_X_ORIGINAL_URI']) && strcasecmp(substr($_SERVER['HTTP_X_ORIGINAL_URI'], 0, 9), "/SOGo/so/") === 0) { // this is an nginx auth_request call, we check for existing sogo-sso session variables session_start(); // extract email address from "/SOGo/so/user@domain/xy" diff --git a/data/web/templates/admin.twig b/data/web/templates/admin.twig new file mode 100644 index 00000000..ad96c585 --- /dev/null +++ b/data/web/templates/admin.twig @@ -0,0 +1,70 @@ +{% extends 'base.twig' %} + +{% block content %} + + +
    +
    + {% include 'admin/tab-config-admins.twig' %} + {% include 'admin/tab-ldap.twig' %} + {% include 'admin/tab-config-oauth2.twig' %} + {% include 'admin/tab-config-rspamd.twig' %} + {% include 'admin/tab-routing.twig' %} + {% include 'admin/tab-config-dkim.twig' %} + {% include 'admin/tab-config-fwdhosts.twig' %} + {% include 'admin/tab-config-f2b.twig' %} + {% include 'admin/tab-config-quarantine.twig' %} + {% include 'admin/tab-config-quota.twig' %} + {% include 'admin/tab-config-rsettings.twig' %} + {% include 'admin/tab-config-customize.twig' %} + {% include 'admin/tab-config-password-policy.twig' %} + {% include 'admin/tab-sys-mails.twig' %} + {% include 'admin/tab-mailq.twig' %} + {% include 'admin/tab-globalfilter-regex.twig' %} +
    +
    + +{% include 'modals/admin.twig' %} + + +{% endblock %} diff --git a/data/web/templates/admin/tab-config-admins.twig b/data/web/templates/admin/tab-config-admins.twig new file mode 100644 index 00000000..d7c17c8b --- /dev/null +++ b/data/web/templates/admin/tab-config-admins.twig @@ -0,0 +1,250 @@ +
    +
    +
    +
    {{ lang.admin.admin_details }}
    +
    +
    +
    +
    + + + {# TFA #} + + {{ lang.tfa.tfa }} + +
    +
    {{ lang.tfa.tfa }}:
    +
    +

    {{ tfa_data.pretty }}

    + {% include 'tfa_keys.twig' %} +
    +
    +
    +
    +
    {{ lang.tfa.set_tfa }}:
    +
    + +
    +
    + + {# FIDO2 #} + + + {{ lang.fido2.fido2_auth }} +
    +
    {{ lang.fido2.known_ids }}:
    +
    +
    + + + + + + {% include 'fido2.twig' %} +
    ID{{ lang.admin.action }}
    +
    +
    +
    +
    +
    +
    +
    + + + +
    +
    +
    +
    +
    +
    {{ lang.fido2.register_status }}:
    +
    +
    -
    +
    +
    +
    + + + {{ lang.admin.guid_and_license }} + +
    +
    +
    + +
    +
    + + + + +
    +

    + {{ lang.admin.customer_id }}: {{ gal.c|default('?')|raw }} - + {{ lang.admin.service_id }}: {{ gal.s|default('?')|raw }} - + {{ lang.admin.sal_level }}: {{ gal.m|default('?')|raw }} +

    +
    +
    +
    +
    +

    {{ lang.admin.license_info|raw }}

    +
    + +
    +
    +
    +
    +
    + + + API + +
    +
    +
    +

    {{ lang.admin.api_info|raw }}

    +
    +
    +
    +
    +

    {{ lang.admin.api_read_only }}

    +
    +
    +
    +
    + +
    + +
    +
    +
    +
    + +
    +
    +
    + +
    +
    {{ api.ro.api_key|default('-') }}
    +
    +
    +
    +
    + +
    +
    +
    +
    +
    + + +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +

    {{ lang.admin.api_read_write }}

    +
    +
    +
    +
    + +
    + +
    +
    +
    +
    + +
    +
    +
    + +
    +
    {{ api.rw.api_key|default('-') }}
    +
    +
    +
    +
    + +
    +
    +
    +
    +
    + + +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + + +
    diff --git a/data/web/templates/admin/tab-config-customize.twig b/data/web/templates/admin/tab-config-customize.twig new file mode 100644 index 00000000..49a84db4 --- /dev/null +++ b/data/web/templates/admin/tab-config-customize.twig @@ -0,0 +1,108 @@ +
    +
    +
    {{ lang.admin.customize }}
    +
    + {{ lang.admin.change_logo }} +

    {{ lang.admin.logo_info }}

    +
    +

    +
    + +

    +
    + {% if logo %} +
    +
    +
    + mailcow logo +
    + {{ logo_specs.geometry.width }}x{{ logo_specs.geometry.height }} px + {{ logo_specs.mimetype }} + {{ logo_specs.fileSize }} +
    +
    +
    +
    +

    +
    +
    +
    + {% endif %} + {{ lang.admin.app_links }} +

    {{ lang.admin.merged_vars_hint }}

    +
    + + + + + + + {% for row in app_links %} + {% for key, val in row %} + + + + + + {% endfor %} + {% endfor %} + {% for app in mailcow_apps %} + + + + + + {% endfor %} + +

    + + +
    +

    +
    + {{ lang.admin.ui_texts }} +
    +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    +
    +

    {{ lang.admin.ui_header_announcement_help }}

    + +

    +

    +
    + +
    +
    +
    +
    + + +
    + +
    +
    +
    +
    +
    diff --git a/data/web/templates/admin/tab-config-dkim.twig b/data/web/templates/admin/tab-config-dkim.twig new file mode 100644 index 00000000..859fe809 --- /dev/null +++ b/data/web/templates/admin/tab-config-dkim.twig @@ -0,0 +1,178 @@ +
    +
    +
    {{ lang.admin.dkim_keys }}
    +
    + + {% for domain, domain_data in dkim_domains %} + {% if domain_data.dkim %} +
    +
    +
    +

    {{ lang.admin.domain }}: {{ domain }} +

    {{ lang.admin.dkim_key_valid }}

    +

    {{ lang.admin.dkim_domains_selector }} '{{ domain_data.dkim.dkim_selector }}'

    +

    {{ domain_data.dkim.length }} bit

    +

    +
    +
    +
    {{ domain_data.dkim.dkim_txt }}
    +

    {{ lang.admin.dkim_private_key }}

    +
    +
    +
    + {% else %} +
    +
    +
    +

    {{ lang.admin.domain }}: {{ domain }}
    {{ lang.admin.dkim_key_missing }}

    +
    +
    -
    +
    +
    + {% endif %} + {% for alias_domain, alias_domain_data in domain_data.alias_domains %} + {% if alias_domain_data.dkim %} +
    +
    +
    +

    ↳ Alias-Domain: {{ alias_domain }} +

    {{ lang.admin.dkim_key_valid }}

    +

    Selector '{{ alias_domain_data.dkim.dkim_selector }}'

    +

    {{ alias_domain_data.dkim.length }} bit

    +

    +
    +
    +
    {{ alias_domain_data.dkim.dkim_txt }}
    +

    Private key

    +
    +
    +
    + {% else %} +
    +
    +
    +

    ↳ Alias-Domain: {{ alias_domain }}
    {{ lang.admin.dkim_key_missing }}

    +
    +
    -
    +
    +
    + {% endif %} + {% endfor %} + {% endfor %} + {% for blind, data in dkim_blind_domains|filter(data => data.dkim is not null) %} +
    +
    +
    +

    {{ lang.admin.domain }}: {{ blind }} +

    {{ lang.admin.dkim_key_unused }}

    +

    Selector '{{ data.dkim.dkim_selector }}'

    +

    {{ data.dkim.length }} bit

    +

    +
    +
    +
    {{ data.dkim.dkim_txt }}
    +

    Private key

    +
    +
    +
    + {% endfor %} + +
    +
    + + +
    +
    +
    + + {{ lang.admin.dkim_add_key }} +
    +
    + + + {{ lang.admin.dkim_domains_wo_keys }} +
    +
    + + +
    +
    + +
    + +
    + + + {{ lang.admin.import_private_key }} + +
    +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + +
    + +
    +
    + + + {{ lang.admin.duplicate_dkim }} + +
    +
    +
    + +
    + +
    +
    +
    + +
    + +
    +
    + +
    +
    +
    +
    +
    diff --git a/data/web/templates/admin/tab-config-f2b.twig b/data/web/templates/admin/tab-config-f2b.twig new file mode 100644 index 00000000..5c4c2a24 --- /dev/null +++ b/data/web/templates/admin/tab-config-f2b.twig @@ -0,0 +1,111 @@ +
    +
    +
    {{ lang.admin.f2b_parameters }}
    +
    +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + +
    + / + +
    +
    +
    + +
    + / + +
    +
    +
    +

    {{ lang.admin.f2b_list_info|raw }}

    +
    + + +
    +
    + + +
    +
    + + {{ lang.header.restart_netfilter }} +
    +
    +
    + + {{ lang.admin.f2b_filter }} + +
    +

    {{ lang.admin.f2b_regex_info }}

    +
    + + + + + + + {% for regex_id, regex_val in f2b_data.regex %} + + + + + + {% endfor %} +
    IDRegExp 
    {{ lang.admin.remove_row }}
    +

    + + + +

    +
    +
    + +

    {{ lang.admin.ban_list_info|raw }}

    + {% if not f2b_data.active_bans and not f2b_data.perm_bans %} + {{ lang.admin.no_active_bans }} + {% endif %} + {% for active_ban in f2b_data.active_bans %} +

    + + + + {{ active_ban.network }} + + ({{ active_ban.banned_until }}) - + {% if active_ban.queued_for_unban == 0 %} + [{{ lang.admin.queue_unban }}] + [whitelist] + [blacklist (needs restart)] + {% else %} + {{ lang.admin.unban_pending }} + {% endif %} + +

    + {% endfor %} +
    + {% for perm_ban in f2b_data.perm_bans %} +

    + + + + {{ perm_ban.network }} + + +

    + {% endfor %} +
    +
    +
    diff --git a/data/web/templates/admin/tab-config-fwdhosts.twig b/data/web/templates/admin/tab-config-fwdhosts.twig new file mode 100644 index 00000000..c691e27b --- /dev/null +++ b/data/web/templates/admin/tab-config-fwdhosts.twig @@ -0,0 +1,39 @@ +
    +
    +
    {{ lang.admin.forwarding_hosts }}
    +
    +

    {{ lang.admin.forwarding_hosts_hint }}

    +
    +
    +
    + + {{ lang.admin.add_forwarding_host }} +

    {{ lang.admin.forwarding_hosts_add_hint }}

    +
    +
    + + +
    +
    + +
    + +
    +
    +
    +
    diff --git a/data/web/templates/admin/tab-config-oauth2.twig b/data/web/templates/admin/tab-config-oauth2.twig new file mode 100644 index 00000000..146b88da --- /dev/null +++ b/data/web/templates/admin/tab-config-oauth2.twig @@ -0,0 +1,26 @@ + diff --git a/data/web/templates/admin/tab-config-password-policy.twig b/data/web/templates/admin/tab-config-password-policy.twig new file mode 100644 index 00000000..ca1c75db --- /dev/null +++ b/data/web/templates/admin/tab-config-password-policy.twig @@ -0,0 +1,35 @@ +
    +
    +
    {{ lang.admin.password_policy }}
    +
    +
    + {% for name, value in password_complexity %} + {% if name == 'length' %} +
    + +
    + +
    +
    + {% else %} + +
    +
    + +
    +
    + {% endif %} + {% endfor %} +
    +
    +
    + +
    +
    +
    +
    +
    +
    +
    diff --git a/data/web/templates/admin/tab-config-quarantine.twig b/data/web/templates/admin/tab-config-quarantine.twig new file mode 100644 index 00000000..047c3e39 --- /dev/null +++ b/data/web/templates/admin/tab-config-quarantine.twig @@ -0,0 +1,90 @@ +
    +
    +
    {{ lang.admin.quarantine }}
    +
    + {% if not q_data.retention_size or not q_data.max_size %} +
    {{ lang.quarantine.disabled_by_config }}
    + {% endif %} +
    +
    + +
    + +
    +
    +
    + +
    + +
    +
    +
    + +
    + +
    +
    +
    + +
    + +
    +
    +
    +
    + +
    + +
    +
    +
    + +
    + +
    +
    +
    +
    + +
    + +
    +
    +
    + +
    + +
    +
    +
    +
    + +
    + +
    +
    +
    + +
    + +
    +
    +
    + + {{ lang.admin.quarantine_notification_html|raw }} + +
    + +
    + +
    +
    +
    +
    diff --git a/data/web/templates/admin/tab-config-quota.twig b/data/web/templates/admin/tab-config-quota.twig new file mode 100644 index 00000000..eabf4742 --- /dev/null +++ b/data/web/templates/admin/tab-config-quota.twig @@ -0,0 +1,47 @@ +
    +
    +
    {{ lang.admin.quota_notifications }}
    +
    +

    {{ lang.admin.quota_notifications_info }}

    +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    +
    + + {{ lang.admin.quarantine_notification_html|raw }} + +
    + + +
    +
    +
    + +
    +
    +
    +
    diff --git a/data/web/templates/admin/tab-config-rsettings.twig b/data/web/templates/admin/tab-config-rsettings.twig new file mode 100644 index 00000000..3b776c4e --- /dev/null +++ b/data/web/templates/admin/tab-config-rsettings.twig @@ -0,0 +1,71 @@ +
    +
    +
    {{ lang.admin.rspamd_settings_map }}
    +
    + + {{ lang.admin.active_rspamd_settings_map }} + +
    + +
    +
    +
    +
    +
    +
    + {% if not rsettings %} + + {% endif %} + {% for rsetting in rsettings %} + {{ rsetting.details.desc }} (ID #{{ rsetting.id }}) + {% else %} + {{ lang.admin.rsetting_none }} + {% endfor %} + {{ lang.admin.rsetting_add_rule }} +
    +
    +
    +
    + {% if not rsettings %} +
    +

    {{ lang.admin.rsetting_none }}

    +
    + {% else %} +
    +

    {{ lang.admin.rsetting_no_selection }}

    +
    + {% for rsetting in rsettings %} +
    + + +
    + + +
    +
    + + +
    +
    + +
    + + + +
    + {% endfor %} + {% endif %} +
    +
    +
    + +
    +
    +
    diff --git a/data/web/templates/admin/tab-config-rspamd.twig b/data/web/templates/admin/tab-config-rspamd.twig new file mode 100644 index 00000000..f22cff78 --- /dev/null +++ b/data/web/templates/admin/tab-config-rspamd.twig @@ -0,0 +1,45 @@ +
    +
    +
    +

    Rspamd UI

    +
    +
    +
    +
    + Rspamd UI +
    +
    +
    +
    +
    + +
    +
    +
    + +
    + +
    +
    +
    + +
    + +
    +
    +
    +
    + +
    +
    +
    +
    + +
    +
    +
    +
    diff --git a/data/web/templates/admin/tab-globalfilter-regex.twig b/data/web/templates/admin/tab-globalfilter-regex.twig new file mode 100644 index 00000000..dfd52351 --- /dev/null +++ b/data/web/templates/admin/tab-globalfilter-regex.twig @@ -0,0 +1,48 @@ +
    +
    +
    + {{ lang.admin.rspamd_global_filters }} +
    +
    +

    {{ lang.admin.rspamd_global_filters_info }}

    + + +
    +
    +
    diff --git a/data/web/templates/admin/tab-ldap.twig b/data/web/templates/admin/tab-ldap.twig new file mode 100644 index 00000000..e5c4e67f --- /dev/null +++ b/data/web/templates/admin/tab-ldap.twig @@ -0,0 +1,7 @@ +
    +
    +
    {{ lang.admin.admins_ldap }}
    +
    +
    +
    +
    diff --git a/data/web/templates/admin/tab-mailq.twig b/data/web/templates/admin/tab-mailq.twig new file mode 100644 index 00000000..ab2f40f1 --- /dev/null +++ b/data/web/templates/admin/tab-mailq.twig @@ -0,0 +1,44 @@ + diff --git a/data/web/templates/admin/tab-routing.twig b/data/web/templates/admin/tab-routing.twig new file mode 100644 index 00000000..53f499d9 --- /dev/null +++ b/data/web/templates/admin/tab-routing.twig @@ -0,0 +1,104 @@ +
    +
    +
    {{ lang.admin.relayhosts }}
    +
    +

    {{ lang.admin.relayhosts_hint|raw }}

    +
    +
    +
    + + {{ lang.admin.add_relayhost }} +

    {{ lang.admin.add_relayhost_hint }}

    +
    +
    +
    +
    + + +
    +
    + + +
    +
    + + +
    + +
    +
    +
    +
    +
    + +
    +
    {{ lang.admin.transport_maps }}
    +
    +

    {{ lang.admin.transports_hint|raw }}

    +
    +
    +
    + + {{ lang.admin.add_transport }} +

    {{ lang.admin.add_transports_hint|raw }}

    +
    +
    +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + +
    +
    + +
    +

    {{ lang.admin.credentials_transport_warning|raw }}

    + +
    +
    +
    +
    +
    +
    diff --git a/data/web/templates/admin/tab-sys-mails.twig b/data/web/templates/admin/tab-sys-mails.twig new file mode 100644 index 00000000..44a8b438 --- /dev/null +++ b/data/web/templates/admin/tab-sys-mails.twig @@ -0,0 +1,70 @@ +
    +
    +
    {{ lang.admin.sys_mails }}
    +
    +
    +
    + +
    + +
    +
    +
    + +
    + +
    +
    + {% for domain in all_domains %} + + {% endfor %} +
    + +
    + + +
    +
    + + +
    +
    +
    + +
    + +
    +
    +
    + + +
    +
    +
    + +
    +
    +
    +
    + +
    +
    +
    +
    +
    +
    diff --git a/data/web/templates/base.twig b/data/web/templates/base.twig new file mode 100644 index 00000000..32b5f405 --- /dev/null +++ b/data/web/templates/base.twig @@ -0,0 +1,399 @@ + + + + + + + + + {{ ui_texts.title_name|raw }} + + + {% if theme != 'lumen' %} + + {% endif %} + + + + +
    +{% block navbar %} + +{% endblock navbar %} + +
    + +{% if ui_texts.ui_announcement_text and ui_texts.ui_announcement_active and not is_root_uri %} +
    +
    {{ ui_texts.ui_announcement_text }}
    +
    +{% endif %} + +
    +{% block content %}{% endblock %} +
    + +{% include 'modals/footer.twig' %} + + + + + + + diff --git a/data/web/templates/cache/.gitkeep b/data/web/templates/cache/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/data/web/templates/debug.twig b/data/web/templates/debug.twig new file mode 100644 index 00000000..97582b76 --- /dev/null +++ b/data/web/templates/debug.twig @@ -0,0 +1,328 @@ +{% extends 'base.twig' %} + +{% block content %} + + +
    +
    +
    +
    {{ lang.debug.log_info|format(log_lines+1)|raw }}
    +
    +
    +
    +

    {{ lang.debug.disk_usage }}

    +
    +
    +
    +
    +

    {{ vmail_df[0] }}

    +

    {{ vmail_df[2] }} / {{ vmail_df[1] }} ({{ vmail_df[4] }})

    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +

    {{ lang.debug.solr_status }}

    +
    +
    +
    +
    +

    Solr Logo

    +
    +
    + {% if solr_status != false %} +
    +
    +
    +

    {{ lang.debug.jvm_memory_solr }}: {{ (solr_status.jvm.memory.total - solr_status.jvm.memory.free) }} / {{ solr_status.jvm.memory.total }} + ({{ solr_status.jvm.memory.raw['used%']|round }}%)

    +
    +

    {{ lang.debug.uptime }}: {{ solr_uptime }}h

    +

    {{ lang.debug.started_at }}: {{ solr_status.status['dovecot-fts'].startTime }}

    +

    {{ lang.debug.last_modified }}: {{ solr_status.status['dovecot-fts'].index.lastModified }}

    +

    {{ lang.debug.size }}: {{ solr_status.status['dovecot-fts'].index.size }}

    +

    {{ lang.debug.docs }}: {{ solr_status.status['dovecot-fts'].index.numDocs }}

    + {% else %} +

    {{ lang.debug.solr_dead }}

    + {% endif %} +
    +
    +
    +
    +
    +
    +

    {{ lang.debug.containers_info }}

    +
    +
    +
      + {% for container, container_info in containers %} +
    • + {{ container }} ({{ container_info.Config.Image }}) +
      + ({{ lang.debug.started_on }} {{ container_info.State.StartedAtHR }}) + {{ lang.debug.restart_container }} + +
    • + {% endfor %} +
    +
    +
    +
    + +
    +
    +
    Postfix +
    + + + +
    +
    +
    +
    +
    +
    +
    +
    +
    + +
    +
    +
    Mailcow UI +
    + + + +
    +
    +
    +
    +
    +
    +
    +
    +
    + +
    +
    +
    SASL +
    + + + +
    +
    +
    +
    +
    +
    +
    +
    +
    + +
    +
    +
    Dovecot +
    + + + +
    +
    +
    +
    +
    +
    +
    +
    +
    + +
    +
    +
    SOGo +
    + + + +
    +
    +
    +
    +
    +
    +
    +
    +
    + +
    +
    +
    Netfilter +
    + + + +
    +
    +
    +
    +
    +
    +
    +
    +
    + +
    +
    +
    Rspamd history +
    + + + +
    +
    +
    + {{ lang.debug.chart_this_server }} +
    + +
    + {{ lang.debug.history_all_servers }} +
    +
    +
    +
    +
    +
    + +
    +
    +
    Autodiscover +
    + + + +
    +
    +
    +
    +
    +
    +
    +
    +
    + +
    +
    +
    Watchdog +
    + + + +
    +
    +
    +
    +
    +
    +
    +
    +
    + +
    +
    +
    ACME +
    + + + +
    +
    +
    +
    +
    +
    +
    +
    +
    + +
    +
    +
    API +
    + + + +
    +
    +
    +
    +
    +
    +
    +
    +
    + +
    +
    +
    Ratelimits +
    + + + +
    +
    +
    +

    {{ lang.admin.hash_remove_info }}

    +
    +
    +
    +
    +
    +
    + +
    +
    +
    + + +{% endblock %} diff --git a/data/web/templates/domainadmin.twig b/data/web/templates/domainadmin.twig new file mode 100644 index 00000000..6aae54ba --- /dev/null +++ b/data/web/templates/domainadmin.twig @@ -0,0 +1,84 @@ +{% extends 'base.twig' %} + +{% block content %} +

    {{ lang.user.user_settings }}

    +
    +
    {{ lang.user.user_settings }}
    +
    +
    +
    +

    [{{ lang.user.change_password }}]

    + + {{ lang.user.clear_recent_successful_connections }} +
    +
    +
    + + {# TFA #} +
    +
    {{ lang.tfa.tfa }}
    +
    +

    {{ tfa_data.pretty }}

    + {% include 'tfa_keys.twig' %} +
    +
    +
    +
    +
    {{ lang.tfa.set_tfa }}
    +
    + +
    +
    + +
    + {# FIDO2 #} +
    +
    +

    {{ lang.fido2.fido2_auth }}

    +
    +
    +
    +
    {{ lang.fido2.known_ids }}:
    +
    +
    + + + + + + {% include 'fido2.twig' %} +
    ID{{ lang.admin.action }}
    +
    +
    +
    +
    +
    +
    +
    + + + +
    +
    +
    +
    +
    +
    {{ lang.fido2.register_status }}:
    +
    +
    -
    +
    +
    +
    +
    +
    +{% include 'user_domainadmin_common.twig' %} +{% endblock %} diff --git a/data/web/templates/edit.twig b/data/web/templates/edit.twig new file mode 100644 index 00000000..2bce91a2 --- /dev/null +++ b/data/web/templates/edit.twig @@ -0,0 +1,30 @@ +{% extends 'base.twig' %} + +{% block content %} +
    +
    +
    +
    +

    {{ lang.edit.title }}

    +
    +
    + {% block inner_content %} + {% if access_denied %} + + {% else %} + + {% endif %} + {% endblock %} +
    +
    +
    +
    +← {{ lang.edit.previous }} + + +{% endblock %} diff --git a/data/web/templates/edit/admin.twig b/data/web/templates/edit/admin.twig new file mode 100644 index 00000000..7d63c4f2 --- /dev/null +++ b/data/web/templates/edit/admin.twig @@ -0,0 +1,51 @@ +{% extends 'edit.twig' %} + +{% block inner_content %} +{% if result %} +

    {{ lang.edit.admin }}

    +
    +
    + +
    + +
    + + ↳ a-z - _ . +
    +
    +
    + +
    + +
    +
    +
    + +
    + +
    +
    +
    +
    +
    + +
    +
    +
    +
    +
    +
    + +
    +
    +
    +
    +
    + +
    +
    +
    +{% else %} + {{ parent() }} +{% endif %} +{% endblock %} diff --git a/data/web/templates/edit/alias.twig b/data/web/templates/edit/alias.twig new file mode 100644 index 00000000..7ed5d7c0 --- /dev/null +++ b/data/web/templates/edit/alias.twig @@ -0,0 +1,70 @@ +{% extends 'edit.twig' %} + +{% block inner_content %} +{% if result %} +

    {{ lang.edit.alias }}

    +
    +
    + + {% if not skip_sogo %} + + {% endif %} +
    + +
    + +
    +
    +
    + +
    + +
    + +
    +
    + +
    +
    + +
    + {% if not skip_sogo %} +
    +
    + +
    +

    {{ lang.edit.sogo_visible_info }}

    + {% endif %} +
    +
    +
    +
    + +
    + +
    +
    +
    + +
    + +
    +
    +
    +
    +
    +
    + +
    +
    +
    +
    +
    + +
    +
    +
    +{% else %} + {{ parent() }} +{% endif %} +{% endblock %} diff --git a/data/web/templates/edit/aliasdomain.twig b/data/web/templates/edit/aliasdomain.twig new file mode 100644 index 00000000..2580b5f3 --- /dev/null +++ b/data/web/templates/edit/aliasdomain.twig @@ -0,0 +1,60 @@ +{% extends 'edit.twig' %} + +{% block inner_content %} +{% if result %} +

    {{ lang.edit.edit_alias_domain }}

    +
    + +
    + +
    + +
    +
    +
    +
    +
    + +
    +
    +
    +
    +
    + +
    +
    +
    +
    +
    +
    + + +
    +
    + +
    +
    + +
    +
    +{% if dkim %} +
    +
    +
    +

    Domain: {{ result.alias_domain }} ({{ dkim.dkim_selector }}._domainkey)

    +
    +
    +
    {{ dkim.dkim_txt }}
    +
    +
    +{% endif %} +{% else %} + {{ parent() }} +{% endif %} +{% endblock %} diff --git a/data/web/templates/edit/app-passwd.twig b/data/web/templates/edit/app-passwd.twig new file mode 100644 index 00000000..046a34f5 --- /dev/null +++ b/data/web/templates/edit/app-passwd.twig @@ -0,0 +1,56 @@ +{% extends 'edit.twig' %} + +{% block inner_content %} +{% if result %} +

    {{ lang.edit.app_passwd }}

    +
    + + +
    + +
    + +
    +
    +
    + +
    + +
    +
    +
    + +
    + +
    +
    +
    +
    +
    + +
    +
    +
    +
    + +
    + +
    +
    +
    +
    + +
    +
    +
    +{% else %} + {{ parent() }} +{% endif %} +{% endblock %} diff --git a/data/web/templates/edit/bcc.twig b/data/web/templates/edit/bcc.twig new file mode 100644 index 00000000..e50239d4 --- /dev/null +++ b/data/web/templates/edit/bcc.twig @@ -0,0 +1,41 @@ +{% extends 'edit.twig' %} + +{% block inner_content %} +{% if result %} +

    {{ lang.mailbox.bcc_map }}

    +
    +
    + +
    + +
    + + {{ lang.edit.bcc_dest_format|raw }} +
    +
    +
    + +
    + +
    +
    +
    +
    +
    + +
    +
    +
    +
    +
    + +
    +
    +
    +{% else %} + {{ parent() }} +{% endif %} +{% endblock %} diff --git a/data/web/templates/edit/domain.twig b/data/web/templates/edit/domain.twig new file mode 100644 index 00000000..2ece7ff3 --- /dev/null +++ b/data/web/templates/edit/domain.twig @@ -0,0 +1,221 @@ +{% extends 'edit.twig' %} + +{% block inner_content %} +{% if result %} + +
    +
    +
    +
    + + + + + +
    + +
    + +
    +
    +
    + +
    + +
    +
    + {% if mailcow_cc_role == 'admin' %} +
    + +
    + +
    +
    +
    + +
    + +
    +
    +
    + +
    + +
    +
    +
    + +
    + +
    +
    +
    + +
    + +
    +
    +
    + +
    +
    + +
    + +

    {{ lang.edit.relay_all_info|raw }}

    + +
    +

    {{ lang.edit.relay_transport_info|raw }}

    +
    +
    +
    +
    + {% endif %} +
    +
    +
    + + {{ lang.edit.gal_info|raw }} +
    +
    +
    +
    +
    +
    +
    + +
    +
    +
    +
    +
    + +
    +
    +
    + {% if dkim %} +
    +
    +
    +

    Domain: {{ result.domain_name }} ({{ dkim.dkim_selector }}._domainkey)

    +
    +
    +
    {{ dkim.dkim_txt }}
    +
    +
    + {% endif %} +
    +
    +
    +
    + + +
    +
    + +
    +
    + +
    +
    +
    +
    +
    +
    +

    {{ lang.user.spamfilter_wl }}

    +

    {{ lang.user.spamfilter_wl_desc|raw }}

    +
    +
    + + + + +
    +
    +
    +
    +
    + +
    +
    +

    {{ lang.user.spamfilter_bl }}

    +

    {{ lang.user.spamfilter_bl_desc|raw }}

    +
    +
    + + + + +
    +
    +
    +
    +
    + +
    +
    +
    +
    +
    +
    +

    {{ lang.edit.quota_warning_bcc }}

    +

    {{ lang.edit.quota_warning_bcc_info|raw }}

    +
    + +
    + +
    + +
    +
    +
    +
    +
    + +
    +
    +
    +
    +
    + +
    +
    +
    +
    +
    +
    +
    +{% else %} + {{ parent() }} +{% endif %} +{% endblock %} diff --git a/data/web/templates/edit/domainadmin.twig b/data/web/templates/edit/domainadmin.twig new file mode 100644 index 00000000..4381843d --- /dev/null +++ b/data/web/templates/edit/domainadmin.twig @@ -0,0 +1,83 @@ +{% extends 'edit.twig' %} + +{% block inner_content %} +{% if result %} +

    {{ lang.edit.domain_admin }}

    +
    +
    + +
    + +
    + + ↳ a-z - _ . +
    +
    +
    + +
    + +
    +
    +
    + +
    + +
    +
    +
    + +
    + +
    +
    +
    +
    +
    + +
    +
    +
    +
    +
    +
    + +
    +
    +
    +
    +
    + +
    +
    +
    +
    +
    +
    +

    ACL

    +
    +
    +
    + +
    +
    + +
    +
    +
    +
    +{% else %} + {{ parent() }} +{% endif %} +{% endblock %} diff --git a/data/web/templates/edit/filter.twig b/data/web/templates/edit/filter.twig new file mode 100644 index 00000000..5aa69230 --- /dev/null +++ b/data/web/templates/edit/filter.twig @@ -0,0 +1,45 @@ +{% extends 'edit.twig' %} + +{% block inner_content %} +{% if result %} +

    Filter

    +
    + +
    + +
    + +
    +
    +
    + +
    + +
    +
    +
    + +
    + +
    +
    +
    +
    +
    + +
    +
    +
    +
    +
    + +
    +
    +
    +{% else %} + {{ parent() }} +{% endif %} +{% endblock %} diff --git a/data/web/templates/edit/mailbox.twig b/data/web/templates/edit/mailbox.twig new file mode 100644 index 00000000..ecfc75cc --- /dev/null +++ b/data/web/templates/edit/mailbox.twig @@ -0,0 +1,375 @@ +{% extends 'edit.twig' %} + +{% block inner_content %} +{% if result %} + +
    +
    +
    +
    + + + + +
    + +
    + +
    +
    +
    + +
    + + 0 = ∞ +
    +
    +
    + +
    + +
    {{ lang.edit.sender_acl_disabled }}
    + {{ lang.edit.sender_acl_info|raw }} +
    +
    +
    + +
    + +

     

    + {{ lang.edit.mailbox_relayhost_info }} +
    +
    +
    + +
    +
    + + + + +
    +
    +

    {{ lang.user.quarantine_notification_info }}

    +
    +
    +
    + +
    +
    + + + +
    +
    +

    {{ lang.user.quarantine_category_info }}

    +
    +
    +
    + +
    +
    + + +
    +
    +
    +
    +
    + +
    + +
    +
    +
    + +
    + +
    +
    +
    + +
    + {% if sender_acl_handles.external_sender_aliases %} + {% set ext_sender_acl = sender_acl_handles.external_sender_aliases|join(', ') %} + {% endif %} + + {{ lang.edit.extended_sender_acl_info|raw }} +
    +
    +
    + +
    + +
    +
    + +
    +
    +
    + +
    +
    +
    +
    +
    + + {{ lang.edit.force_pw_update_info|format(ui_texts.main_name) }} +
    +
    +
    + {% if not skip_sogo %} +
    +
    +
    + + {{ lang.edit.sogo_access_info }} +
    +
    +
    + {% endif %} +
    +
    + +
    +
    +
    +
    +
    +
    + + + +
    +
    +

    +
    +
    +

    {{ lang.user.pushover_info|format(mailbox)|raw }}

    +

    {{ lang.edit.pushover_vars|raw }}: {SUBJECT}, {SENDER}

    +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    + +
    +
    +
    + + {{ lang.edit.advanced_settings }} + +
    +
    +
    +
    + + +
    + +
    +
    + +
    +
    +
    +
    +
    +
    + +
    +
    +
    +
    +
    +
    +
    +
    +

    ACL

    +
    +
    +
    + +
    +
    + +
    +
    +
    +
    +
    +
    +
    +
    +
    +

    {{ lang.acl.ratelimit }}

    +
    +
    +
    + +
    +
    + +
    +
    + +
    +

    {{ lang.edit.mbox_rl_info }}

    +
    +
    +
    +
    +
    +{% else %} + {{ parent() }} +{% endif %} +{% endblock %} diff --git a/data/web/templates/edit/oauth2client.twig b/data/web/templates/edit/oauth2client.twig new file mode 100644 index 00000000..0a123fc5 --- /dev/null +++ b/data/web/templates/edit/oauth2client.twig @@ -0,0 +1,40 @@ +{% extends 'edit.twig' %} + +{% block inner_content %} +{% if result %} +

    OAuth2

    +
    +
    + +
    + +
    +
    +
    + +
    + +
    +
    +
    + +
    + +
    +
    +
    + +
    + +
    +
    +
    +
    + +
    +
    +
    +{% else %} + {{ parent() }} +{% endif %} +{% endblock %} diff --git a/data/web/templates/edit/recipient_map.twig b/data/web/templates/edit/recipient_map.twig new file mode 100644 index 00000000..73837130 --- /dev/null +++ b/data/web/templates/edit/recipient_map.twig @@ -0,0 +1,39 @@ +{% extends 'edit.twig' %} + +{% block inner_content %} +{% if result %} +

    {{ lang.mailbox.recipient_map }}: {{ result.recipient_map_old }}

    +
    +
    + +
    + +
    + + {{ lang.mailbox.recipient_map_old_info }} +
    +
    +
    + +
    + + {{ lang.mailbox.recipient_map_new_info }} +
    +
    +
    +
    +
    + +
    +
    +
    +
    +
    + +
    +
    +
    +{% else %} + {{ parent() }} +{% endif %} +{% endblock %} diff --git a/data/web/templates/edit/relayhost.twig b/data/web/templates/edit/relayhost.twig new file mode 100644 index 00000000..9e3d67c1 --- /dev/null +++ b/data/web/templates/edit/relayhost.twig @@ -0,0 +1,43 @@ +{% extends 'edit.twig' %} + +{% block inner_content %} +{% if result %} +

    {{ lang.edit.resource }}

    +
    + +
    + +
    + +

    {{ lang.add.relayhost_wrapped_tls_info|raw }}

    +
    +
    +
    + +
    + +
    +
    +
    + +
    + +
    +
    +
    +
    +
    + +
    +
    +
    +
    +
    + +
    +
    +
    +{% else %} + {{ parent() }} +{% endif %} +{% endblock %} diff --git a/data/web/templates/edit/resource.twig b/data/web/templates/edit/resource.twig new file mode 100644 index 00000000..db273287 --- /dev/null +++ b/data/web/templates/edit/resource.twig @@ -0,0 +1,55 @@ +{% extends 'edit.twig' %} + +{% block inner_content %} +{% if result %} +

    {{ lang.edit.resource }}

    +
    + +
    + +
    + +
    +
    +
    + +
    + +
    +
    +
    + +
    + + + +
    +
    +
    +
    +
    + +
    +
    +
    +
    +
    + +
    +
    +
    +{% else %} + {{ parent() }} +{% endif %} +{% endblock %} diff --git a/data/web/templates/edit/syncjob.twig b/data/web/templates/edit/syncjob.twig new file mode 100644 index 00000000..6af7e0a0 --- /dev/null +++ b/data/web/templates/edit/syncjob.twig @@ -0,0 +1,160 @@ +{% extends 'edit.twig' %} + +{% block inner_content %} +{% if result %} +

    {{ lang.edit.syncjob }}

    +
    + + + + + + + +
    + +
    + +
    +
    +
    + +
    + +
    +
    +
    + +
    + +
    +
    +
    + +
    + +
    +
    +
    + +
    + +
    +
    +
    + +
    + + 1-43800 +
    +
    +
    + +
    + +
    +
    +
    + +
    + + 0-32000 +
    +
    +
    + +
    + + 0-125000000 +
    +
    +
    + +
    + + 1-32000 +
    +
    +
    + +
    + + 1-32000 +
    +
    +
    + +
    + +
    +
    +
    + +
    + + {{ lang.add.custom_params_hint }} +
    +
    +
    +
    +
    + +
    +
    +
    +
    +
    +
    + +
    +
    +
    +
    +
    +
    + +
    +
    +
    +
    +
    +
    + +
    +
    +
    +
    +
    +
    + +
    +
    +
    +
    +
    +
    + +
    +
    +
    +
    +
    +
    + +
    +
    +
    +
    +
    + +
    +
    +
    +{% else %} + {{ parent() }} +{% endif %} +{% endblock %} diff --git a/data/web/templates/edit/tls_policy_map.twig b/data/web/templates/edit/tls_policy_map.twig new file mode 100644 index 00000000..a40621c5 --- /dev/null +++ b/data/web/templates/edit/tls_policy_map.twig @@ -0,0 +1,49 @@ +{% extends 'edit.twig' %} + +{% block inner_content %} +{% if result %} +

    {{ lang.mailbox.tls_policy_maps }}: {{ result.dest }}

    +
    +
    + +
    + +
    + + {{ lang.mailbox.tls_map_dest_info }} +
    +
    +
    + +
    + +
    +
    +
    + +
    + + {{ lang.mailbox.tls_map_parameters_info }} +
    +
    +
    +
    +
    + +
    +
    +
    +
    +
    + +
    +
    +
    +{% else %} + {{ parent() }} +{% endif %} +{% endblock %} diff --git a/data/web/templates/edit/transport.twig b/data/web/templates/edit/transport.twig new file mode 100644 index 00000000..bf804ccd --- /dev/null +++ b/data/web/templates/edit/transport.twig @@ -0,0 +1,56 @@ +{% extends 'edit.twig' %} + +{% block inner_content %} +{% if result %} +

    {{ lang.edit.resource }}

    +
    + + +
    + +
    + +
    +
    +
    + +
    + +
    +
    +
    + +
    + +
    +
    +
    + +
    + +
    +
    +
    +
    +
    + +
    +
    +
    +
    +
    +
    + +
    +
    +
    +
    +
    + +
    +
    +
    +{% else %} + {{ parent() }} +{% endif %} +{% endblock %} diff --git a/data/web/templates/fido2.twig b/data/web/templates/fido2.twig new file mode 100644 index 00000000..8d10ffe1 --- /dev/null +++ b/data/web/templates/fido2.twig @@ -0,0 +1,29 @@ +{% if fido2_data %} + {% for key_info in fido2_data %} + + + {% if fido2_cid == key_info.cid %} + + {% endif %} + {% if key_info.fn %} + {{ key_info.fn }} + {% else %} + {{ key_info.subject }} + {% endif %} + + +
    + + +
    + + + {% endfor %} +{% endif %} diff --git a/data/web/templates/index.twig b/data/web/templates/index.twig new file mode 100644 index 00000000..056421fe --- /dev/null +++ b/data/web/templates/index.twig @@ -0,0 +1,111 @@ +{% extends 'base.twig' %} + +{% block navbar %}{% endblock %} + +{% block content %} +
    +
    + +
    + {% if not oauth2_request %} +
    +
    + +
    +
    + {% if ui_texts.help_text %} +

    {{ ui_texts.help_text|raw }}

    + {% else %} +

    {{ ui_texts.main_name|raw }}

    +

    {{ lang.start.mailcow_panel_detail|raw }}

    +

    {{ ui_texts.apps_name|raw }}

    +

    {{ lang.start.mailcow_apps_detail|raw }}

    + {% endif %} +
    +
    +
    +
    + {% endif %} +
    +{% endblock %} diff --git a/data/web/templates/mailbox.twig b/data/web/templates/mailbox.twig new file mode 100644 index 00000000..80177b85 --- /dev/null +++ b/data/web/templates/mailbox.twig @@ -0,0 +1,58 @@ +{% extends 'base.twig' %} + +{% block content %} + + +
    +
    +
    + {% include 'mailbox/tab-domains.twig' %} + {% include 'mailbox/tab-mailbox-defaults.twig' %} + {% include 'mailbox/tab-mailboxes.twig' %} + {% include 'mailbox/tab-resources.twig' %} + {% include 'mailbox/tab-domain-aliases.twig' %} + {% include 'mailbox/tab-mbox-aliases.twig' %} + {% include 'mailbox/tab-syncjobs.twig' %} + {% include 'mailbox/tab-filters.twig' %} + {% include 'mailbox/tab-bcc.twig' %} + {% include 'mailbox/tab-tls-policy.twig' %} +
    +
    +
    + +{% include 'modals/mailbox.twig' %} + + +{% endblock %} diff --git a/data/web/templates/mailbox/page-size.twig b/data/web/templates/mailbox/page-size.twig new file mode 100644 index 00000000..7f5aaff7 --- /dev/null +++ b/data/web/templates/mailbox/page-size.twig @@ -0,0 +1,6 @@ +
  • {{ lang.mailbox.table_size_show_n|format(3) }}
  • +
  • {{ lang.mailbox.table_size_show_n|format(10) }}
  • +
  • {{ lang.mailbox.table_size_show_n|format(20) }}
  • +
  • {{ lang.mailbox.table_size_show_n|format(50) }}
  • +
  • {{ lang.mailbox.table_size_show_n|format(100) }}
  • +
  • {{ lang.mailbox.table_size_show_n|format(200) }}
  • diff --git a/data/web/templates/mailbox/rl-frame.twig b/data/web/templates/mailbox/rl-frame.twig new file mode 100644 index 00000000..26af5fa0 --- /dev/null +++ b/data/web/templates/mailbox/rl-frame.twig @@ -0,0 +1,4 @@ + + + + diff --git a/data/web/templates/mailbox/tab-bcc.twig b/data/web/templates/mailbox/tab-bcc.twig new file mode 100644 index 00000000..2cb199d2 --- /dev/null +++ b/data/web/templates/mailbox/tab-bcc.twig @@ -0,0 +1,73 @@ +
    +
    +
    + {{ lang.mailbox.bcc_maps }} + +
    +

    {{ lang.mailbox.bcc_info|raw }}

    +{#
    #} +
    +
    +
    + +
    +
    +
    + {{ lang.mailbox.recipient_maps }} + +
    +

    {{ lang.mailbox.recipient_map_info }}

    + {#
    #} +
    +
    +
    + +
    +
    diff --git a/data/web/templates/mailbox/tab-domain-aliases.twig b/data/web/templates/mailbox/tab-domain-aliases.twig new file mode 100644 index 00000000..357981bb --- /dev/null +++ b/data/web/templates/mailbox/tab-domain-aliases.twig @@ -0,0 +1,35 @@ +
    +
    +
    + {{ lang.mailbox.domain_aliases }} + +
    +{#
    #} +
    +
    +
    + +
    +
    diff --git a/data/web/templates/mailbox/tab-domains.twig b/data/web/templates/mailbox/tab-domains.twig new file mode 100644 index 00000000..e29d8544 --- /dev/null +++ b/data/web/templates/mailbox/tab-domains.twig @@ -0,0 +1,41 @@ +
    +
    +
    + {{ lang.mailbox.domains }} + +
    +{#
    #} +
    +
    +
    +
    +
    + {{ lang.mailbox.toggle_all }} + {{ lang.mailbox.quick_actions }} + +
    + {% if mailcow_cc_role == 'admin' %} + {{ lang.mailbox.add_domain }} + {% endif %} +
    +
    +
    +
    diff --git a/data/web/templates/mailbox/tab-filters.twig b/data/web/templates/mailbox/tab-filters.twig new file mode 100644 index 00000000..f7b23ecd --- /dev/null +++ b/data/web/templates/mailbox/tab-filters.twig @@ -0,0 +1,83 @@ +
    +
    +
    + {{ lang.mailbox.filters }} + +
    +
    +

    {{ lang.mailbox.sieve_info|raw }}


    +
    +{#
    #} +
    +
    +
    + +
    +
    +
    +
    Global Prefilter
    +
    +
    +
    + +
    +
    +
    +
    +
    + + +
    +
    +
    +
    +
    +
    +
    +
    Global Postfilter
    +
    +
    +
    + +
    +
    +
    +
    +
    + + +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    diff --git a/data/web/templates/mailbox/tab-mailbox-defaults.twig b/data/web/templates/mailbox/tab-mailbox-defaults.twig new file mode 100644 index 00000000..6a364690 --- /dev/null +++ b/data/web/templates/mailbox/tab-mailbox-defaults.twig @@ -0,0 +1,10 @@ +
    +
    +
    + {{ lang.mailbox.mailbox_defaults }} +
    +
    + {{ lang.mailbox.mailbox_defaults_info }} +
    +
    +
    diff --git a/data/web/templates/mailbox/tab-mailboxes.twig b/data/web/templates/mailbox/tab-mailboxes.twig new file mode 100644 index 00000000..a0ee9bd2 --- /dev/null +++ b/data/web/templates/mailbox/tab-mailboxes.twig @@ -0,0 +1,121 @@ +
    +
    +
    + {{ lang.mailbox.mailboxes }} + +
    + +
    +
    +
    +
    + + +
    +
    +
    diff --git a/data/web/templates/mailbox/tab-mbox-aliases.twig b/data/web/templates/mailbox/tab-mbox-aliases.twig new file mode 100644 index 00000000..2d7e7fc3 --- /dev/null +++ b/data/web/templates/mailbox/tab-mbox-aliases.twig @@ -0,0 +1,44 @@ +
    +
    +
    + {{ lang.mailbox.aliases }} + +
    +
    + {{ lang.mailbox.alias_domain_alias_hint|raw }} +
    + +
    +
    +
    + +
    +
    diff --git a/data/web/templates/mailbox/tab-resources.twig b/data/web/templates/mailbox/tab-resources.twig new file mode 100644 index 00000000..ff5bde26 --- /dev/null +++ b/data/web/templates/mailbox/tab-resources.twig @@ -0,0 +1,40 @@ +
    +
    +
    + {{ lang.mailbox.resources }} + +
    +
    +

    {{ lang.mailbox.booking_0_short }} - {{ lang.mailbox.booking_0 }}

    +

    {{ lang.mailbox.booking_lt0_short }} - {{ lang.mailbox.booking_lt0 }}

    +

    {{ lang.mailbox.booking_custom_short }} - {{ lang.mailbox.booking_custom }}

    +
    +{#
    #} +
    +
    +
    + +
    +
    diff --git a/data/web/templates/mailbox/tab-syncjobs.twig b/data/web/templates/mailbox/tab-syncjobs.twig new file mode 100644 index 00000000..e8c4c361 --- /dev/null +++ b/data/web/templates/mailbox/tab-syncjobs.twig @@ -0,0 +1,37 @@ +
    +
    +
    + {{ lang.mailbox.sync_jobs }} + +
    + +
    +
    +
    + +
    +
    diff --git a/data/web/templates/mailbox/tab-tls-policy.twig b/data/web/templates/mailbox/tab-tls-policy.twig new file mode 100644 index 00000000..dd4ba229 --- /dev/null +++ b/data/web/templates/mailbox/tab-tls-policy.twig @@ -0,0 +1,36 @@ +
    +
    +
    + {{ lang.mailbox.tls_policy_maps_long }} + +
    +

    {{ lang.mailbox.tls_policy_maps_info|raw }}

    +{#
    #} +
    +
    +
    + +
    +
    diff --git a/data/web/templates/modals/admin.twig b/data/web/templates/modals/admin.twig new file mode 100644 index 00000000..a5454042 --- /dev/null +++ b/data/web/templates/modals/admin.twig @@ -0,0 +1,263 @@ + + + + + + + + + + + + + + + + diff --git a/data/web/templates/modals/footer.twig b/data/web/templates/modals/footer.twig new file mode 100644 index 00000000..f5e51d2e --- /dev/null +++ b/data/web/templates/modals/footer.twig @@ -0,0 +1,231 @@ +{% if mailcow_cc_role %} + + + + + + + +{% endif %} +{% if pending_tfa_method %} + +{% endif %} +{% if mailcow_cc_role == 'admin' %} + +{% endif %} + diff --git a/data/web/modals/mailbox.php b/data/web/templates/modals/mailbox.twig similarity index 59% rename from data/web/modals/mailbox.php rename to data/web/templates/modals/mailbox.twig index 8751050c..932779e2 100644 --- a/data/web/modals/mailbox.php +++ b/data/web/templates/modals/mailbox.twig @@ -1,819 +1,817 @@ - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/data/web/modals/quarantine.php b/data/web/templates/modals/quarantine.twig similarity index 55% rename from data/web/modals/quarantine.php rename to data/web/templates/modals/quarantine.twig index 3cb53303..aed4b849 100644 --- a/data/web/modals/quarantine.php +++ b/data/web/templates/modals/quarantine.twig @@ -1,79 +1,68 @@ - - - + diff --git a/data/web/templates/modals/user.twig b/data/web/templates/modals/user.twig new file mode 100644 index 00000000..6de779b9 --- /dev/null +++ b/data/web/templates/modals/user.twig @@ -0,0 +1,349 @@ + + + + + + + + + + + + + + diff --git a/data/web/templates/oauth/authorize.twig b/data/web/templates/oauth/authorize.twig new file mode 100644 index 00000000..289eab34 --- /dev/null +++ b/data/web/templates/oauth/authorize.twig @@ -0,0 +1,27 @@ +{% extends 'base.twig' %} + +{% block content %} +
    +
    {{ lang.oauth2.authorize_app }}
    +
    + {% if mailcow_cc_role == 'user' %} +

    {{ lang.oauth2.scope_ask_permission }}:

    +
    +
    {{ lang.oauth2.profile }}
    +
    {{ lang.oauth2.profile_desc }}
    +
    +
    +
    +
    + + {{ lang.oauth2.deny }} + +
    +
    +
    + {% else %} +

    {{ lang.oauth2.access_denied }}

    + {% endif %} +
    +
    +{% endblock %} diff --git a/data/web/templates/qhandler.twig b/data/web/templates/qhandler.twig new file mode 100644 index 00000000..b2ef4375 --- /dev/null +++ b/data/web/templates/qhandler.twig @@ -0,0 +1,82 @@ +{% extends 'base.twig' %} + +{% block content %} +
    +{% if quick_release or quick_delete %} +
    +
    +
    {{ lang.header.quarantine }}
    +
    + + {% if quick_release %} + {{ lang.quarantine.release }} + {% else %} + {{ lang.quarantine.remove }} + {% endif %} + +

    {{ lang.quarantine.qhandler_success }}

    +
    +
    +
    +{% else %} +{% if is_action_release_delete and is_hash_present %} +
    +
    +
    {{ lang.header.quarantine }}
    +
    + {% if action == 'release' %} + {{ lang.quarantine.release }} + {% endif %} + {% if action == 'delete' %} + {{ lang.quarantine.remove }} + {% endif %} + +
    + +

    {{ lang.quarantine.spam_score }}:

    +

    +
    +
    + +

    +
    +
    + +

    +
    +
    + +

    +
    +
    + +

    +
    +
    + +

    +
    +
    +
    +
    + {% if action == 'release' %} + + {% endif %} + {% if action == 'delete' %} + + {% endif %} +
    +
    +
    +
    +
    +
    +{% endif %} +{% endif %} +
    + + + +{% endblock %} diff --git a/data/web/templates/quarantine.twig b/data/web/templates/quarantine.twig new file mode 100644 index 00000000..3b51f946 --- /dev/null +++ b/data/web/templates/quarantine.twig @@ -0,0 +1,64 @@ +{% extends 'base.twig' %} + +{% block content %} +
    +
    +
    + +

    {{ lang.quarantine.qinfo|raw }}

    +

    + {% if not quarantine_settings.retention_size or not quarantine_settings.max_size %} +

    {{ lang.quarantine.disabled_by_config }}
    + {% else %} +

    + {{ lang.quarantine.settings_info|format(quarantine_settings.retention_size, quarantine_settings.max_size)|raw }} +

    + {% endif %} +

    +
    +
    +
    + +
    +
    +
    + +{% include 'modals/quarantine.twig' %} + + +{% endblock %} diff --git a/data/web/templates/tfa_keys.twig b/data/web/templates/tfa_keys.twig new file mode 100644 index 00000000..ad631725 --- /dev/null +++ b/data/web/templates/tfa_keys.twig @@ -0,0 +1,15 @@ +
    + {% if tfa_data.additional %} + {% for key_info in tfa_data.additional %} +
    + +

    + + {{ key_info.key_id }} + [{{ lang.admin.remove }}] + +

    +
    + {% endfor %} + {% endif %} +
    diff --git a/data/web/templates/user.twig b/data/web/templates/user.twig new file mode 100644 index 00000000..573acfb1 --- /dev/null +++ b/data/web/templates/user.twig @@ -0,0 +1,34 @@ +{% extends 'base.twig' %} + +{% block content %} + + +
    + +
    + {% include 'user/tab-user-auth.twig' %} + {% include 'user/tab-user-details.twig' %} + {% include 'user/tab-user-settings.twig' %} + {% include 'user/SpamAliases.twig' %} + {% include 'user/Spamfilter.twig' %} + {% include 'user/Syncjobs.twig' %} + {% include 'user/AppPasswds.twig' %} + {% include 'user/Pushover.twig' %} +
    +
    +{% include 'user_domainadmin_common.twig' %} +{% endblock %} diff --git a/data/web/templates/user/AppPasswds.twig b/data/web/templates/user/AppPasswds.twig new file mode 100644 index 00000000..d8d125e8 --- /dev/null +++ b/data/web/templates/user/AppPasswds.twig @@ -0,0 +1,24 @@ + diff --git a/data/web/templates/user/Pushover.twig b/data/web/templates/user/Pushover.twig new file mode 100644 index 00000000..c7abe164 --- /dev/null +++ b/data/web/templates/user/Pushover.twig @@ -0,0 +1,80 @@ +
    +
    + + + +
    +
    +

    +
    +
    +

    {{ lang.user.pushover_info|format(mailcow_cc_username)|raw }}

    +

    {{ lang.user.pushover_vars|raw }}: {SUBJECT}, {SENDER}

    +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    + + +
    +
    +
    +
    + +
    +
    +
    + + {{ lang.user.advanced_settings }} + +
    +
    +
    +
    + + +
    + +
    +
    + +
    +
    +
    +
    +
    +
    + +
    +
    +
    +
    diff --git a/data/web/templates/user/SpamAliases.twig b/data/web/templates/user/SpamAliases.twig new file mode 100644 index 00000000..49153c06 --- /dev/null +++ b/data/web/templates/user/SpamAliases.twig @@ -0,0 +1,40 @@ + diff --git a/data/web/templates/user/Spamfilter.twig b/data/web/templates/user/Spamfilter.twig new file mode 100644 index 00000000..ccd7e7d2 --- /dev/null +++ b/data/web/templates/user/Spamfilter.twig @@ -0,0 +1,79 @@ +
    +

    {{ lang.user.spamfilter_behavior }}

    +
    +
    +
    +
    +
    +
    + +
      +
    • {{ lang.user.spamfilter_green }}
    • +
    • {{ lang.user.spamfilter_yellow }}
    • +
    • {{ lang.user.spamfilter_red }}
    • +
    +
    +
    + +
    +
    +
    +
    +
    +
    +

    {{ lang.user.spamfilter_wl }}

    +

    {{ lang.user.spamfilter_wl_desc|raw }}

    +
    +
    + + + + +
    +
    +
    +
    +
    + +
    +
    +

    {{ lang.user.spamfilter_bl }}

    +

    {{ lang.user.spamfilter_bl_desc|raw }}

    +
    +
    + + + + +
    +
    +
    +
    +
    + +
    +
    +
    diff --git a/data/web/templates/user/Syncjobs.twig b/data/web/templates/user/Syncjobs.twig new file mode 100644 index 00000000..1b6cda2b --- /dev/null +++ b/data/web/templates/user/Syncjobs.twig @@ -0,0 +1,23 @@ + diff --git a/data/web/templates/user/tab-user-auth.twig b/data/web/templates/user/tab-user-auth.twig new file mode 100644 index 00000000..dfc397f8 --- /dev/null +++ b/data/web/templates/user/tab-user-auth.twig @@ -0,0 +1,132 @@ +
    +
    +
    {{ lang.user.mailbox_general }}
    +
    + {% if not skip_sogo %} +
    + +
    + {% if dual_login and allow_admin_email_login == 'n' %} + + {% else %} + + {{ lang.user.open_webmail_sso }} + + {% endif %} +
    +
    +
    +
    + +
    +

    {{ lang.user.direct_protocol_access|raw }}

    + {% if mailboxdata.attributes.imap_access == 1 %}
    IMAP
    {% else %}
    IMAP
    {% endif %} + {% if mailboxdata.attributes.smtp_access == 1 %}
    SMTP
    {% else %}
    SMTP
    {% endif %} + {% if mailboxdata.attributes.sieve_access == 1 %}
    Sieve
    {% else %}
    Sieve
    {% endif %} + {% if mailboxdata.attributes.pop3_access == 1 %}
    POP3
    {% else %}
    POP3
    {% endif %} + {% if mailboxdata.attributes.sogo_access == 1 %}
    SOGo
    {% else %}
    SOGo
    {% endif %} +
    +
    +
    + {% endif %} +
    +
    {{ lang.user.in_use }}:
    +
    +
    +
    + {{ mailboxdata.percent_in_use }}% +
    +
    +

    {{ mailboxdata.quota_used|formatBytes(2) }} / {% if mailboxdata.quota == 0 %}∞{% else %}{{ mailboxdata.quota|formatBytes(2) }}{% endif %}
    {{ mailboxdata.messages }} {{ lang.user.messages }}

    +
    +

    {{ lang.user.change_password }}

    +
    +
    +
    + {# FIDO2 #} +
    +
    +

    {{ lang.fido2.fido2_auth }}

    +
    +
    +
    +
    + {{ lang.fido2.known_ids }}: +
    +
    +
    + + + + + + {% include 'fido2.twig' %} +
    ID{{ lang.admin.action }}
    +
    +
    +
    +
    +
    +
    +
    + + + +
    +
    +
    +
    +
    +
    {{ lang.fido2.register_status }}:
    +
    +
    -
    +
    +
    +
    +
    +
    +
    {{ lang.user.apple_connection_profile }}:
    +
    +

    {{ lang.user.email }} IMAP, SMTP

    +

    {{ lang.user.apple_connection_profile_mailonly }}

    + {% if not skip_sogo %} +

    {{ lang.user.email_and_dav }} IMAP, SMTP, Cal/CardDAV

    +

    {{ lang.user.apple_connection_profile_complete }}

    + {% endif %} +
    +
    +
    +
    +
    + {% if mailboxdata.attributes.force_pw_update == '1' %} +
    {{ lang.user.force_pw_update|raw }}
    + {% endif %} +

    [{{ lang.user.client_configuration }}]

    +

    [{{ lang.user.show_sieve_filters }}]

    +
    + + +
    + + + {{ lang.user.clear_recent_successful_connections }} + +
    +
    +
    +
    +
    diff --git a/data/web/templates/user/tab-user-details.twig b/data/web/templates/user/tab-user-details.twig new file mode 100644 index 00000000..c024af16 --- /dev/null +++ b/data/web/templates/user/tab-user-details.twig @@ -0,0 +1,67 @@ +
    +
    +
    {{ lang.user.mailbox_details }}
    +
    +
    +
    {{ lang.user.direct_aliases }}: +

    {{ lang.user.direct_aliases_desc }}

    +
    +
    + {% for direct_alias, direct_alias_meta in user_get_alias_details.direct_aliases %} + {% if direct_alias_meta.public_comment %} + {{ direct_alias }} — {{ direct_alias_meta.public_comment }}
    + {% else %} + {{ direct_alias }}
    + {% endif %} + {% else %} + + {% endfor %} +
    +
    +
    +
    +
    {{ lang.user.shared_aliases }}: +

    {{ lang.user.shared_aliases_desc }}

    +
    +
    + {% for shared_alias, shared_alias_meta in user_get_alias_details.shared_aliases %} + {% if shared_alias_meta.public_comment %} + {{ shared_alias }} — {{ shared_alias_meta.public_comment }}
    + {% else %} + {{ shared_alias }}
    + {% endif %} + {% else %} + + {% endfor %} +
    +
    +
    +
    +
    {{ lang.user.aliases_also_send_as }}:
    +
    +

    + {% if user_get_alias_details.aliases_also_send_as == '*' %} + {{ lang.user.sender_acl_disabled }} + {% elseif user_get_alias_details.aliases_also_send_as %} + {{ user_get_alias_details.aliases_also_send_as }} + {% else %} + + {% endif %} +

    +
    +
    +
    +
    {{ lang.user.aliases_send_as_all }}:
    +
    +

    {% if not user_get_alias_details.aliases_send_as_all %}{% endif %}

    +
    +
    +
    +
    {{ lang.user.is_catch_all }}:
    +
    +

    {% if not user_get_alias_details.is_catch_all %}{% endif %}

    +
    +
    +
    +
    +
    diff --git a/data/web/templates/user/tab-user-settings.twig b/data/web/templates/user/tab-user-settings.twig new file mode 100644 index 00000000..f59ba397 --- /dev/null +++ b/data/web/templates/user/tab-user-settings.twig @@ -0,0 +1,136 @@ +
    +
    +
    {{ lang.user.mailbox_settings }}
    +
    + {# Show tagging options #} +
    +
    {{ lang.user.tag_handling }}:
    +
    +
    + + + +
    +
    +

    {{ lang.user.tag_help_explain|raw }}

    +

    {{ lang.user.tag_help_example|raw }}

    +
    +
    + {# Show TLS policy options #} +
    +
    {{ lang.user.tls_policy }}:
    +
    +
    + + +
    +
    +

    {{ lang.user.tls_policy_warning|raw }}

    +
    +
    + {# Show quarantine_notification options #} +
    +
    {{ lang.user.quarantine_notification }}:
    +
    +
    + + + + +
    +
    +

    {{ lang.user.quarantine_notification_info }}

    +
    +
    +
    +
    {{ lang.user.quarantine_category }}:
    +
    +
    + + + +
    +
    +

    {{ lang.user.quarantine_category_info }}

    +
    +
    + {% if not skip_sogo %} +
    +
    +
    {{ lang.user.eas_reset }}:
    +
    + +

    {{ lang.user.eas_reset_help|raw }}

    +
    +
    +
    +
    {{ lang.user.sogo_profile_reset }}:
    +
    + +

    {{ lang.user.sogo_profile_reset_help|raw }}

    +
    +
    + {% endif %} +
    +
    +
    diff --git a/data/web/templates/user_domainadmin_common.twig b/data/web/templates/user_domainadmin_common.twig new file mode 100644 index 00000000..be8bff23 --- /dev/null +++ b/data/web/templates/user_domainadmin_common.twig @@ -0,0 +1,10 @@ +{% include 'modals/user.twig' %} + + diff --git a/data/web/user.php b/data/web/user.php index de0598e2..c4e8b8f4 100644 --- a/data/web/user.php +++ b/data/web/user.php @@ -11,118 +11,16 @@ if (isset($_SESSION['mailcow_cc_role']) && $_SESSION['mailcow_cc_role'] == 'doma $tfa_data = get_tfa(); $fido2_data = fido2(array("action" => "get_friendly_names")); $username = $_SESSION['mailcow_cc_username']; - print_r(mailbox('get', 'mailbox_count')); -?> -
    - -

    -
    -
    -
    -
    -
    -

    []

    - - -
    -
    -
    - - -
    -
    - -
    -
    -
    -
    - -
    -
    - -
    - -
    -
    -

    -
    -
    -
    -
    :
    -
    -
    - - - - - - - - - - - -
    ID
    - - -
    - -
    -
    -
    -
    -
    -
    -
    -
    - -
    -
    -
    -
    -
    :
    -
    -
    -
    -
    -
    -
    - -
    -
    -
    - $_SESSION['acl'], + 'acl_json' => json_encode($_SESSION['acl']), + 'user_spam_score' => mailbox('get', 'spam_score', $username), + 'tfa_data' => $tfa_data, + 'fido2_data' => $fido2_data, + 'lang_user' => json_encode($lang['user']), + ]; } elseif (isset($_SESSION['mailcow_cc_role']) && $_SESSION['mailcow_cc_role'] == 'user') { @@ -152,659 +50,43 @@ elseif (isset($_SESSION['mailcow_cc_role']) && $_SESSION['mailcow_cc_role'] == ' fclose($fh); } } -?> -
    - - -
    + // Get user information about aliases + $user_get_alias_details = user_get_alias_details($username); + $user_get_alias_details['direct_aliases'] = array_filter($user_get_alias_details['direct_aliases']); + $user_get_alias_details['shared_aliases'] = array_filter($user_get_alias_details['shared_aliases']); + $user_domains[] = mailbox('get', 'mailbox_details', $username)['domain']; + $user_alias_domains = $user_get_alias_details['alias_domains']; + if (!empty($user_alias_domains)) { + $user_domains = array_merge($user_domains, $user_alias_domains); + } -
    - -
    -
    -
    -
    - -
    - -
    - - - -
    -
    -
    - -
    -
    :
    -
    -
    -
    - % -
    -
    -

    /

    -
    -

    -
    -
    -
    - -
    -
    -

    -
    -
    -
    -
    - : -
    -
    -
    - - - - - - - - - - - -
    ID
    - ' : NULL; ?> - -
    - - -
    -
    -
    -
    -
    -
    -
    -
    - -
    -
    -
    -
    -
    :
    -
    -
    -
    -
    -
    -
    -
    -
    -
    :
    -
    -

    IMAP, SMTP

    -

    - -

    IMAP, SMTP, Cal/CardDAV

    -

    - -
    -
    -
    -
    -
    - -
    - -

    []

    -

    []

    -
    - - -
    - - - - -
    -
    -
    -
    -
    - -
    -
    -
    -
    - -
    -
    : -

    -
    -
    - '; - } - else { - foreach (array_filter($user_get_alias_details['direct_aliases']) as $direct_alias => $direct_alias_meta) { - (!empty($direct_alias_meta['public_comment'])) ? - printf('%s — %s
    ', $direct_alias, $direct_alias_meta['public_comment']) : - printf('%s
    ', $direct_alias); - } - } - ?> -
    -
    -
    -
    -
    : -

    -
    -
    - '; - } - else { - foreach (array_filter($user_get_alias_details['shared_aliases']) as $shared_alias => $shared_alias_meta) { - (!empty($shared_alias_meta['public_comment'])) ? - printf('%s — %s
    ', $shared_alias, $shared_alias_meta['public_comment']) : - printf('%s
    ', $shared_alias); - } - } - ?> -
    -
    -
    -
    -
    :
    -
    -

    ' : $user_get_alias_details['aliases_also_send_as']);?>

    -
    -
    -
    -
    :
    -
    -

    ' : '' ;?>

    -
    -
    -
    -
    :
    -
    -

    ' : '' ;?>

    -
    -
    -
    -
    -
    - -
    -
    -
    -
    - -
    -
    :
    -
    -
    - - - -
    -
    -

    -

    -
    -
    - -
    -
    :
    -
    -
    - - -
    -
    -

    -
    -
    - -
    -
    :
    -
    -
    - - - - -
    -
    -

    -
    -
    -
    -
    :
    -
    -
    - - - -
    -
    -

    -
    -
    - -
    -
    -
    :
    -
    - -

    -
    -
    -
    -
    :
    -
    - -

    -
    -
    - -
    -
    -
    - -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    - - - -
    -
    -
    - , 1 - -
    -
    -
    -
    - -
    -

    -
    -
    -
    -
    -
    -
    - -
      -
    • -
    • -
    • -
    -
    -
    -
    - - -
    -
    -
    -
    -
    -
    -
    -

    -

    -
    -
    - - - - -
    -
    -
    -
    -
    -
    -
    - - -
    -
    -
    -
    -
    -

    -

    -
    -
    - - - - -
    -
    -
    -
    -
    -
    -
    - - -
    -
    -
    -
    -
    -
    - -
    -
    -
    -
    -
    -
    -
    - - - -
    -
    -
    - -
    -
    -
    -
    - -
    -

    -
    -
    -
    -
    -
    -
    - - - -
    -
    -
    - -
    -
    -
    -
    - -
    -
    - - - -
    -
    -

    -
    -
    -

    -

    : {SUBJECT}, {SENDER}

    -
    -
    -
    -
    - - -
    -
    -
    -
    - - -
    -
    -
    -
    - - -
    -
    -
    -
    - - -
    -
    -
    -
    - - -
    -
    -
    -
    - -
    -
    -
    - - - -
    -
    -
    -
    - - -
    - -
    -
    - -
    -
    -
    -
    -
    -
    -
    - - -
    - -
    -
    -
    -
    - -
    -
    -
    -
    - $_SESSION['acl'], + 'acl_json' => json_encode($_SESSION['acl']), + 'user_spam_score' => mailbox('get', 'spam_score', $username), + 'tfa_data' => $tfa_data, + 'fido2_data' => $fido2_data, + 'mailboxdata' => $mailboxdata, + 'clientconfigstr' => $clientconfigstr, + 'user_get_alias_details' => $user_get_alias_details, + 'get_tagging_options' => mailbox('get', 'delimiter_action', $username), + 'get_tls_policy' => mailbox('get', 'tls_policy', $username), + 'quarantine_notification' => mailbox('get', 'quarantine_notification', $username), + 'quarantine_category' => mailbox('get', 'quarantine_category', $username), + 'user_domains' => $user_domains, + 'pushover_data' => $pushover_data, + 'lang_user' => json_encode($lang['user']), + ]; } -if (isset($_SESSION['mailcow_cc_role']) && $_SESSION['mailcow_cc_role'] != 'admin') { -require_once $_SERVER['DOCUMENT_ROOT'] . '/modals/user.php'; -?> - -add('/web/js/site/user.js'); -$js_minifier->add('/web/js/site/pwgen.js'); -require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/footer.inc.php'; -} -else { + +if (!isset($_SESSION['mailcow_cc_role']) && $_SESSION['mailcow_cc_role'] == 'admin') { header('Location: /'); exit(); } -?> + +$js_minifier->add('/web/js/site/user.js'); +$js_minifier->add('/web/js/site/pwgen.js'); + +require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/footer.inc.php'; diff --git a/docker-compose.yml b/docker-compose.yml index 1d76f303..60847bef 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -2,7 +2,7 @@ version: '2.1' services: unbound-mailcow: - image: mailcow/unbound:1.13 + image: mailcow/unbound:1.14 environment: - TZ=${TZ} volumes: @@ -58,7 +58,7 @@ services: - redis clamd-mailcow: - image: mailcow/clamd:1.40 + image: mailcow/clamd:1.41 restart: always dns: - ${IPV4_NETWORK:-172.22.1}.254 @@ -73,7 +73,7 @@ services: - clamd rspamd-mailcow: - image: mailcow/rspamd:1.77 + image: mailcow/rspamd:1.79 stop_grace_period: 30s depends_on: - dovecot-mailcow @@ -103,7 +103,7 @@ services: - rspamd php-fpm-mailcow: - image: mailcow/phpfpm:1.76 + image: mailcow/phpfpm:1.78 command: "php-fpm -d date.timezone=${TZ} -d expose_php=0" depends_on: - redis-mailcow @@ -156,6 +156,7 @@ services: - SKIP_SOGO=${SKIP_SOGO:-n} - ALLOW_ADMIN_EMAIL_LOGIN=${ALLOW_ADMIN_EMAIL_LOGIN:-n} - MASTER=${MASTER:-y} + - DEV_MODE=${DEV_MODE:-n} restart: always networks: mailcow-network: @@ -163,7 +164,7 @@ services: - phpfpm sogo-mailcow: - image: mailcow/sogo:1.101 + image: mailcow/sogo:1.102 environment: - DBNAME=${DBNAME} - DBUSER=${DBUSER} @@ -210,7 +211,7 @@ services: - sogo dovecot-mailcow: - image: mailcow/dovecot:1.155 + image: mailcow/dovecot:1.158 depends_on: - mysql-mailcow dns: @@ -412,7 +413,7 @@ services: acme-mailcow: depends_on: - nginx-mailcow - image: mailcow/acme:1.79 + image: mailcow/acme:1.80 dns: - ${IPV4_NETWORK:-172.22.1}.254 environment: @@ -448,7 +449,7 @@ services: - acme netfilter-mailcow: - image: mailcow/netfilter:1.43 + image: mailcow/netfilter:1.45 stop_grace_period: 30s depends_on: - dovecot-mailcow @@ -471,9 +472,7 @@ services: - /lib/modules:/lib/modules:ro watchdog-mailcow: - image: mailcow/watchdog:1.92 - # Debug - #command: /watchdog.sh + image: mailcow/watchdog:1.95 dns: - ${IPV4_NETWORK:-172.22.1}.254 tmpfs: @@ -498,6 +497,7 @@ services: - WATCHDOG_SUBJECT=${WATCHDOG_SUBJECT:-Watchdog ALERT} - WATCHDOG_EXTERNAL_CHECKS=${WATCHDOG_EXTERNAL_CHECKS:-n} - WATCHDOG_MYSQL_REPLICATION_CHECKS=${WATCHDOG_MYSQL_REPLICATION_CHECKS:-n} + - WATCHDOG_VERBOSE=${WATCHDOG_VERBOSE:-n} - MAILCOW_HOSTNAME=${MAILCOW_HOSTNAME} - COMPOSE_PROJECT_NAME=${COMPOSE_PROJECT_NAME:-mailcow-dockerized} - IPV4_NETWORK=${IPV4_NETWORK:-172.22.1} @@ -534,7 +534,7 @@ services: - watchdog dockerapi-mailcow: - image: mailcow/dockerapi:1.38 + image: mailcow/dockerapi:1.40 security_opt: - label=disable restart: always @@ -568,7 +568,7 @@ services: - solr olefy-mailcow: - image: mailcow/olefy:1.7 + image: mailcow/olefy:1.8 restart: always environment: - TZ=${TZ} @@ -595,6 +595,8 @@ services: - dovecot-mailcow labels: ofelia.enabled: "true" + security_opt: + - label=disable volumes: - /var/run/docker.sock:/var/run/docker.sock:ro networks: diff --git a/generate_config.sh b/generate_config.sh index 33823a7f..93343818 100755 --- a/generate_config.sh +++ b/generate_config.sh @@ -12,8 +12,8 @@ if [[ "$(uname -r)" =~ ^4\.4\. ]]; then if grep -q Ubuntu <<< $(uname -a); then echo "DO NOT RUN mailcow ON THIS UBUNTU KERNEL!"; echo "Please update to linux-generic-hwe-16.04 by running \"apt-get install --install-recommends linux-generic-hwe-16.04\"" + exit 1 fi - exit 1 fi if grep --help 2>&1 | grep -q -i "busybox"; then @@ -287,6 +287,9 @@ WATCHDOG_NOTIFY_BAN=n # Will only work with unmodified mailcow setups. WATCHDOG_EXTERNAL_CHECKS=n +# Enable watchdog verbose logging +WATCHDOG_VERBOSE=n + # Max log lines per service to keep in Redis logs LOG_LINES=9999 diff --git a/helper-scripts/_cold-standby.sh b/helper-scripts/_cold-standby.sh new file mode 100755 index 00000000..c4439ea8 --- /dev/null +++ b/helper-scripts/_cold-standby.sh @@ -0,0 +1,273 @@ +#!/usr/bin/env bash + +PATH=${PATH}:/opt/bin +DATE=$(date +%Y-%m-%d_%H_%M_%S) +export LC_ALL=C + +echo +echo "If this script is run automatically by cron or a timer AND you are using block-level snapshots on your backup destination, make sure both do not run at the same time." +echo "The snapshots of your backup destination should run AFTER the cold standby script finished to ensure consistent snapshots." +echo + +function docker_garbage() { + IMGS_TO_DELETE=() + + for container in $(grep -oP "image: \Kmailcow.+" docker-compose.yml); do + + REPOSITORY=${container/:*} + TAG=${container/*:} + V_MAIN=${container/*.} + V_SUB=${container/*.} + EXISTING_TAGS=$(docker images | grep ${REPOSITORY} | awk '{ print $2 }') + + for existing_tag in ${EXISTING_TAGS[@]}; do + + V_MAIN_EXISTING=${existing_tag/*.} + V_SUB_EXISTING=${existing_tag/*.} + + # Not an integer + [[ ! ${V_MAIN_EXISTING} =~ ^[0-9]+$ ]] && continue + [[ ! ${V_SUB_EXISTING} =~ ^[0-9]+$ ]] && continue + + if [[ ${V_MAIN_EXISTING} == "latest" ]]; then + echo "Found deprecated label \"latest\" for repository ${REPOSITORY}, it should be deleted." + IMGS_TO_DELETE+=(${REPOSITORY}:${existing_tag}) + elif [[ ${V_MAIN_EXISTING} -lt ${V_MAIN} ]]; then + echo "Found tag ${existing_tag} for ${REPOSITORY}, which is older than the current tag ${TAG} and should be deleted." + IMGS_TO_DELETE+=(${REPOSITORY}:${existing_tag}) + elif [[ ${V_SUB_EXISTING} -lt ${V_SUB} ]]; then + echo "Found tag ${existing_tag} for ${REPOSITORY}, which is older than the current tag ${TAG} and should be deleted." + IMGS_TO_DELETE+=(${REPOSITORY}:${existing_tag}) + fi + + done + + done + + if [[ ! -z ${IMGS_TO_DELETE[*]} ]]; then + docker rmi ${IMGS_TO_DELETE[*]} + fi +} + +function preflight_local_checks() { + if [[ -z "${REMOTE_SSH_KEY}" ]]; then + >&2 echo -e "\e[31mREMOTE_SSH_KEY is not set\e[0m" + exit 1 + fi + + if [[ ! -s "${REMOTE_SSH_KEY}" ]]; then + >&2 echo -e "\e[31mKeyfile ${REMOTE_SSH_KEY} is empty\e[0m" + exit 1 + fi + + if [[ $(stat -c "%a" "${REMOTE_SSH_KEY}") -ne 600 ]]; then + >&2 echo -e "\e[31mKeyfile ${REMOTE_SSH_KEY} has insecure permissions\e[0m" + exit 1 + fi + + if [[ ! -z "${REMOTE_SSH_PORT}" ]]; then + if [[ ${REMOTE_SSH_PORT} != ?(-)+([0-9]) ]] || [[ ${REMOTE_SSH_PORT} -gt 65535 ]]; then + >&2 echo -e "\e[31mREMOTE_SSH_PORT is set but not an integer < 65535\e[0m" + exit 1 + fi + fi + + if [[ -z "${REMOTE_SSH_HOST}" ]]; then + >&2 echo -e "\e[31mREMOTE_SSH_HOST cannot be empty\e[0m" + exit 1 + fi + + for bin in rsync docker-compose docker grep cut; do + if [[ -z $(which ${bin}) ]]; then + >&2 echo -e "\e[31mCannot find ${bin} in local PATH, exiting...\e[0m" + exit 1 + fi + done + + if grep --help 2>&1 | head -n 1 | grep -q -i "busybox"; then + >&2 echo -e "\e[31mBusyBox grep detected on local system, please install GNU grep\e[0m" + exit 1 + fi +} + +function preflight_remote_checks() { + + if ! ssh -o StrictHostKeyChecking=no \ + -i "${REMOTE_SSH_KEY}" \ + ${REMOTE_SSH_HOST} \ + -p ${REMOTE_SSH_PORT} \ + rsync --version > /dev/null ; then + >&2 echo -e "\e[31mCould not verify connection to ${REMOTE_SSH_HOST}\e[0m" + >&2 echo -e "\e[31mPlease check the output above (is rsync >= 3.1.0 installed on the remote system?)\e[0m" + exit 1 + fi + + if ssh -o StrictHostKeyChecking=no \ + -i "${REMOTE_SSH_KEY}" \ + ${REMOTE_SSH_HOST} \ + -p ${REMOTE_SSH_PORT} \ + grep --help 2>&1 | head -n 1 | grep -q -i "busybox" ; then + >&2 echo -e "\e[31mBusyBox grep detected on remote system ${REMOTE_SSH_HOST}, please install GNU grep\e[0m" + exit 1 + fi + + for bin in rsync docker-compose docker; do + if ! ssh -o StrictHostKeyChecking=no \ + -i "${REMOTE_SSH_KEY}" \ + ${REMOTE_SSH_HOST} \ + -p ${REMOTE_SSH_PORT} \ + which ${bin} > /dev/null ; then + >&2 echo -e "\e[31mCannot find ${bin} in remote PATH, exiting...\e[0m" + exit 1 + fi + done + +} + +preflight_local_checks +preflight_remote_checks + +SCRIPT_DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd ) +COMPOSE_FILE="${SCRIPT_DIR}/../docker-compose.yml" +source "${SCRIPT_DIR}/../mailcow.conf" +CMPS_PRJ=$(echo ${COMPOSE_PROJECT_NAME} | tr -cd 'A-Za-z-_') +SQLIMAGE=$(grep -iEo '(mysql|mariadb)\:.+' "${COMPOSE_FILE}") + +echo +echo -e "\033[1mFound compose project name ${CMPS_PRJ} for ${MAILCOW_HOSTNAME}\033[0m" +echo -e "\033[1mFound SQL ${SQLIMAGE}\033[0m" +echo + +# Make sure destination exists, rsync can fail under some circumstances +echo -e "\033[1mPreparing remote...\033[0m" +if ! ssh -o StrictHostKeyChecking=no \ + -i "${REMOTE_SSH_KEY}" \ + ${REMOTE_SSH_HOST} \ + -p ${REMOTE_SSH_PORT} \ + mkdir -p "${SCRIPT_DIR}/../" ; then + >&2 echo -e "\e[31m[ERR]\e[0m - Could not prepare remote for mailcow base directory transfer" + exit 1 +fi + +# Syncing the mailcow base directory +echo -e "\033[1mSynchronizing mailcow base directory...\033[0m" +rsync --delete -aH -e "ssh -o StrictHostKeyChecking=no \ + -i \"${REMOTE_SSH_KEY}\" \ + -p ${REMOTE_SSH_PORT}" \ + "${SCRIPT_DIR}/../" root@${REMOTE_SSH_HOST}:"${SCRIPT_DIR}/../" +ec=$? +if [ ${ec} -ne 0 ] && [ ${ec} -ne 24 ]; then + >&2 echo -e "\e[31m[ERR]\e[0m - Could not transfer mailcow base directory to remote" + exit 1 +fi + +# Trigger a Redis save for a consistent Redis copy +echo -ne "\033[1mRunning redis-cli save... \033[0m" +docker exec $(docker ps -qf name=redis-mailcow) redis-cli save + +# Syncing volumes related to compose project +# Same here: make sure destination exists +for vol in $(docker volume ls -qf name="${CMPS_PRJ}"); do + + mountpoint="$(docker inspect ${vol} | grep Mountpoint | cut -d '"' -f4)" + + echo -e "\033[1mCreating remote mountpoint ${mountpoint} for ${vol}...\033[0m" + + ssh -o StrictHostKeyChecking=no \ + -i "${REMOTE_SSH_KEY}" \ + ${REMOTE_SSH_HOST} \ + -p ${REMOTE_SSH_PORT} \ + mkdir -p "${mountpoint}" + + if [[ "${vol}" =~ "mysql-vol-1" ]]; then + + # Make sure a previous backup does not exist + rm -rf "${SCRIPT_DIR}/../_tmp_mariabackup/" + + echo -e "\033[1mCreating consistent backup of MariaDB volume...\033[0m" + if ! docker run --rm \ + --network $(docker network ls -qf name=${CMPS_PRJ}_) \ + -v $(docker volume ls -qf name=${CMPS_PRJ}_mysql-vol-1):/var/lib/mysql/:ro \ + --entrypoint= \ + -v "${SCRIPT_DIR}/../_tmp_mariabackup":/backup \ + ${SQLIMAGE} mariabackup --host mysql --user root --password ${DBROOT} --backup --target-dir=/backup 2>/dev/null ; then + >&2 echo -e "\e[31m[ERR]\e[0m - Could not create MariaDB backup on source" + rm -rf "${SCRIPT_DIR}/../_tmp_mariabackup/" + exit 1 + fi + + if ! docker run --rm \ + --network $(docker network ls -qf name=${CMPS_PRJ}_) \ + --entrypoint= \ + -v "${SCRIPT_DIR}/../_tmp_mariabackup":/backup \ + ${SQLIMAGE} mariabackup --prepare --target-dir=/backup 2> /dev/null ; then + >&2 echo -e "\e[31m[ERR]\e[0m - Could not transfer MariaDB backup to remote" + rm -rf "${SCRIPT_DIR}/../_tmp_mariabackup/" + exit 1 + fi + + chown -R 999:999 "${SCRIPT_DIR}/../_tmp_mariabackup" + + echo -e "\033[1mSynchronizing MariaDB backup...\033[0m" + rsync --delete --info=progress2 -aH -e "ssh -o StrictHostKeyChecking=no \ + -i \"${REMOTE_SSH_KEY}\" \ + -p ${REMOTE_SSH_PORT}" \ + "${SCRIPT_DIR}/../_tmp_mariabackup/" root@${REMOTE_SSH_HOST}:"${mountpoint}" + ec=$? + if [ ${ec} -ne 0 ] && [ ${ec} -ne 24 ]; then + >&2 echo -e "\e[31m[ERR]\e[0m - Could not transfer MariaDB backup to remote" + exit 1 + fi + + # Cleanup + rm -rf "${SCRIPT_DIR}/../_tmp_mariabackup/" + + else + + echo -e "\033[1mSynchronizing ${vol} from local ${mountpoint}...\033[0m" + rsync --delete --info=progress2 -aH -e "ssh -o StrictHostKeyChecking=no \ + -i \"${REMOTE_SSH_KEY}\" \ + -p ${REMOTE_SSH_PORT}" \ + "${mountpoint}/" root@${REMOTE_SSH_HOST}:"${mountpoint}" + ec=$? + if [ ${ec} -ne 0 ] && [ ${ec} -ne 24 ]; then + >&2 echo -e "\e[31m[ERR]\e[0m - Could not transfer ${vol} from local ${mountpoint} to remote" + exit 1 + fi + fi + + echo -e "\e[32mCompleted\e[0m" + +done + +# Restart Dockerd on destination +echo -ne "\033[1mRestarting Docker daemon on remote to detect new volumes... \033[0m" +if ! ssh -o StrictHostKeyChecking=no \ + -i "${REMOTE_SSH_KEY}" \ + ${REMOTE_SSH_HOST} \ + -p ${REMOTE_SSH_PORT} \ + systemctl restart docker ; then + >&2 echo -e "\e[31m[ERR]\e[0m - Could not restart Docker daemon on remote" + exit 1 +fi +echo "OK" + +echo -e "\033[1mPulling images on remote...\033[0m" +if ! ssh -o StrictHostKeyChecking=no \ + -i "${REMOTE_SSH_KEY}" \ + ${REMOTE_SSH_HOST} \ + -p ${REMOTE_SSH_PORT} \ + docker-compose -f "${SCRIPT_DIR}/../docker-compose.yml" pull --no-parallel 2>&1 ; then + >&2 echo -e "\e[31m[ERR]\e[0m - Could not pull images on remote" +fi + +echo -e "\033[1mForcing garbage cleanup on remote...\033[0m" +if ! ssh -o StrictHostKeyChecking=no \ + -i "${REMOTE_SSH_KEY}" \ + ${REMOTE_SSH_HOST} \ + -p ${REMOTE_SSH_PORT} \ + ${SCRIPT_DIR}/../update.sh -f --gc ; then + >&2 echo -e "\e[31m[ERR]\e[0m - Could not cleanup old images on remote" +fi + +echo -e "\e[32mDone\e[0m" diff --git a/helper-scripts/add-new-lang-keys.php b/helper-scripts/add-new-lang-keys.php new file mode 100644 index 00000000..19010f86 --- /dev/null +++ b/helper-scripts/add-new-lang-keys.php @@ -0,0 +1,63 @@ + $v) { + if (is_array($arr1[$k]) && is_array($arr2[$k])) { + $d = array_diff_key_recursive($arr1[$k], $arr2[$k]); + + if ($d) { + $diff[$k] = $d; + } + } + } + + return $diff; +} + +// target lang +$targetLang = $argv[1]; + +if(empty($targetLang)) { + die('Please specify target lang as the first argument, to which you want to add missing keys from master lang (EN). Use the lowercase name, + for example `sk` for the Slovak language'."\n"); +} + +// load master lang +$masterLang = file_get_contents(__DIR__.'/../data/web/lang/lang.en.json'); +$masterLang = json_decode($masterLang, true); + +// load target lang +$lang = file_get_contents(__DIR__.'/../data/web/lang/lang.'.$targetLang.'.json'); +$lang = json_decode($lang, true); + +// compare lang keys +$result = array_diff_key_recursive($masterLang, $lang); + +if(empty($result)) { + die('No new keys were added. Looks like target lang is up to date.'."\n"); +} + +foreach($result as $key => $val) { + // check if section key exists in target lang + if(array_key_exists($key, $lang)) { + // add only missing section keys + foreach ($val as $k => $v) { + $lang[$key][$k] = $v; + } + // sort keys + ksort($lang[$key]); + } else { + // add whole section + $lang[$key] = $val; + ksort($lang); + } +} + +$lang = json_encode($lang, JSON_PRETTY_PRINT|JSON_UNESCAPED_UNICODE|JSON_UNESCAPED_SLASHES); +file_put_contents(__DIR__.'/../data/web/lang/lang.'.$targetLang.'.json', $lang); + +echo 'Following new lang keys were added and need translation:'."\n"; +print_r($result); diff --git a/helper-scripts/docker-compose.override.yml.d/EXTERNAL_DNS/docker-compose.override.yml b/helper-scripts/docker-compose.override.yml.d/EXTERNAL_DNS/docker-compose.override.yml index 8b68783e..74763bf2 100644 --- a/helper-scripts/docker-compose.override.yml.d/EXTERNAL_DNS/docker-compose.override.yml +++ b/helper-scripts/docker-compose.override.yml.d/EXTERNAL_DNS/docker-compose.override.yml @@ -42,7 +42,3 @@ services: dockerapi-mailcow: dns: - my.resolvers.ip.addr - - ejabberd-mailcow: - dns: - - my.resolvers.ip.addr diff --git a/update.sh b/update.sh index cc8357e6..cf093eab 100755 --- a/update.sh +++ b/update.sh @@ -46,7 +46,7 @@ done export LC_ALL=C DATE=$(date +%Y-%m-%d_%H_%M_%S) -BRANCH=$(git rev-parse --abbrev-ref HEAD) +BRANCH=$(cd ${SCRIPT_DIR}; git rev-parse --abbrev-ref HEAD) check_online_status() { CHECK_ONLINE_IPS=(1.1.1.1 9.9.9.9 8.8.8.8) @@ -79,7 +79,7 @@ prefetch_images() { docker_garbage() { IMGS_TO_DELETE=() - for container in $(grep -oP "image: \Kmailcow.+" docker-compose.yml); do + for container in $(grep -oP "image: \Kmailcow.+" "${SCRIPT_DIR}/docker-compose.yml"); do REPOSITORY=${container/:*} TAG=${container/*:} V_MAIN=${container/*.} @@ -121,9 +121,9 @@ docker_garbage() { echo "Running image removal without extra confirmation due to force mode." docker rmi ${IMGS_TO_DELETE[*]} fi + echo -e "\e[32mFurther cleanup...\e[0m" + echo "If you want to cleanup further garbage collected by Docker, please make sure all containers are up and running before cleaning your system by executing \"docker system prune\"" fi - echo -e "\e[32mFurther cleanup...\e[0m" - echo "If you want to cleanup further garbage collected by Docker, please make sure all containers are up and running before cleaning your system by executing \"docker system prune\"" } in_array() { @@ -232,7 +232,7 @@ while (($#)); do exit 0 ;; -f|--force) - echo -e "\e[32mForcing Update...\e[0m" + echo -e "\e[32mRunning in forced mode...\e[0m" FORCE=y ;; --no-update-compose) @@ -513,6 +513,11 @@ for option in ${CONFIG_ARRAY[@]}; do echo '# https://mailcow.github.io/mailcow-dockerized-docs/debug-reset-tls/' >> mailcow.conf echo 'ACME_CONTACT=' >> mailcow.conf fi +elif [[ ${option} == "WATCHDOG_VERBOSE" ]]; then + if ! grep -q ${option} mailcow.conf; then + echo '# Enable watchdog verbose logging' >> mailcow.conf + echo 'WATCHDOG_VERBOSE=n' >> mailcow.conf + fi elif ! grep -q ${option} mailcow.conf; then echo "Adding new option \"${option}\" to mailcow.conf" echo "${option}=n" >> mailcow.conf