[
  {
    "path": ".dockerignore",
    "content": ".cpan\n.cpanm\n.git\ndocker-compose.yml\nlocal\nlog/*\nlstu.conf\nlstu.db"
  },
  {
    "path": ".gitattributes",
    "content": "zanata.xml merge=ours\n"
  },
  {
    "path": ".gitignore",
    "content": ".cpan\n.cpanm\n.*_history\nlocal/*\ncover_db/*\nsafebrowsing_db/*\n.tx/*\n*.db\n*.db-shm\n*.db-wal\n*.db-journal\nlstu.conf\n*.swp\nscript/hypnotoad.pid\n.zanata-cache/*\nthemes/*\nthemes/default/public/robots.txt\nthemes/milligram/public/robots.txt\n!themes/default\n!themes/default/*\n!themes/milligram\n!themes/milligram/*\n"
  },
  {
    "path": ".gitlab-ci.yml",
    "content": "image: hatsoftwares/lstu-test-ci:latest\nstages:\n  - tags\n  - carton\n  - carton_bdd\n  - tests\n\nvariables:\n  POSTGRES_DB: lstu_db\n  POSTGRES_USER: lstu\n  POSTGRES_PASSWORD: lstu_pwd\n  MYSQL_DATABASE: lstu_db\n  MYSQL_USER: lstu\n  MYSQL_PASSWORD: lstu_pwd\n  MYSQL_ROOT_PASSWORD: root\n\nbefore_script:\n  - if [[ $CI_JOB_NAME == \"postgresql 3/3\" ]]; then export PGPASSWORD=lstu_pwd; echo 'CREATE DATABASE lstu_minion WITH OWNER lstu;' | psql -h postgres -U lstu lstu_db; fi\n  - if [[ $CI_JOB_NAME == \"mysql 3/3\" ]]; then echo \"CREATE DATABASE lstu_minion; GRANT ALL ON lstu_minion.* TO lstu@'%'; FLUSH PRIVILEGES;\" | mysql -h mariadb -u root -proot; fi\n\n### Jobs templates\n##\n#\n.retry: &retry\n  retry: 2\n  except:\n    - tags\n.carton_bdd_template: &carton_bdd_definition\n  <<: *retry\n  stage: carton_bdd\n  needs:\n    - carton\n  cache:\n    key: \"$CI_COMMIT_REF_NAME\"\n    paths:\n      - local/\n    policy: pull\n  artifacts:\n    paths:\n      - local.tar\n    expire_in: 3 hours\n  after_script:\n    - tar cf local.tar local/\n\n.tests_template: &tests_definition\n  <<: *retry\n  stage: tests\n  parallel: 3\n  script:\n    - tar xf local.tar && rm local.tar\n    - export CI_JOB_NAME=$(echo $CI_JOB_NAME | sed -e 's@ .*@@')\n    - echo \"Database $CI_JOB_NAME test $CI_NODE_INDEX on $CI_NODE_TOTAL\"\n    - MOJO_CONFIG=\"t/${CI_JOB_NAME}${CI_NODE_INDEX}.conf\" make test\n    - MOJO_CONFIG=\"t/${CI_JOB_NAME}${CI_NODE_INDEX}.conf\" make cover\n    - MOJO_CONFIG=\"t/${CI_JOB_NAME}${CI_NODE_INDEX}.conf\" make test-junit-output\n  coverage: '/Total.* (\\d+\\.\\d+)$/'\n  artifacts:\n    reports:\n      junit: tap.xml\n\n.sqlite_template: &sqlite_definition\n  <<: *tests_definition\n  needs:\n    - carton_sqlite\n  services:\n    - name: rroemhild/test-openldap\n      alias: rroemhild-test-openldap\n\n.pg_template: &pg_definition\n  <<: *tests_definition\n  needs:\n    - carton_postgresql\n  services:\n    - name: rroemhild/test-openldap\n      alias: rroemhild-test-openldap\n    - name: postgres:9.6\n      alias: postgres\n\n.mysql_template: &mysql_definition\n  <<: *tests_definition\n  needs:\n    - carton_mysql\n  services:\n    - name: rroemhild/test-openldap\n      alias: rroemhild-test-openldap\n    - name: mariadb:10.1\n      alias: mariadb\n\n### Publish tag changelog\n##\n#\npublish_changelog:\n  image: hatsoftwares/curl-jq:latest\n  stage: tags\n  script:\n    - export PROJECT_API_URL=\"https://framagit.org/api/v4/projects/${CI_PROJECT_ID}\"\n    - export DESCRIPTION_URL=\"${PROJECT_API_URL}/repository/tags/${CI_COMMIT_TAG}/release\"\n    - 'export HEADER=\"Private-Token: ${GITLAB_API_TOKEN}\"'\n    - sed -n '/^'$CI_COMMIT_TAG'[[:space:]]/,/^[^\\t]/p' CHANGELOG | sed -e 's/^[^\\t].*//' -e 's/\\t//g' | sed '/^[[:space:]]*$/d' > /tmp/text\n    - if [[ ! -z $GITLAB_API_TOKEN ]]; then curl -s --request POST --data-urlencode \"description@/tmp/text\" --header \"${HEADER}\" \"${DESCRIPTION_URL}\"; fi\n  only:\n    - tags\n\n### Toot tag\n##\n#\npouet-it:\n  image: hatsoftwares/pouet-it-from-ci:latest\n  stage: tags\n  script:\n    - cd /opt/pouet-it-from-ci\n    - export project=\"$(echo $CI_PROJECT_NAME | perl -p -e 's/(?:^(.)|-(.))/\\U$1\\U$2/g')\"\n    - export MESSAGE=$(echo -e \"Je viens de sortir \"'#'\"${project} en version ${CI_COMMIT_TAG} !\"\"\\n${CI_PROJECT_URL}/tags/${CI_COMMIT_TAG}\")\n    - carton exec ./pouet-it-from-ci.pl\n  only:\n    - tags\n\n### Podcheck\n##\n#\npodcheck:\n  <<: *retry\n  stage: carton\n  script:\n    - make podcheck\n\n### Install common dependencies\n##\n#\ncarton:\n  <<: *retry\n  stage: carton\n  cache:\n    key: \"$CI_COMMIT_REF_NAME\"\n    paths:\n      - local/\n  script:\n    - carton install --deployment --without=sqlite --without=postgresql --without=mysql\n\n### Install DB related dependencies\n##\n#\ncarton_sqlite:\n  <<: *carton_bdd_definition\n  script:\n    - carton install --deployment --without=postgresql --without=mysql\ncarton_postgresql:\n  <<: *carton_bdd_definition\n  script:\n    - carton install --deployment --without=sqlite --without=mysql\ncarton_mysql:\n  <<: *carton_bdd_definition\n  script:\n    - carton install --deployment --without=sqlite --without=postgresql\n\n### Tests\n##\n#\nsqlite:\n  <<: *sqlite_definition\npostgresql:\n  <<: *pg_definition\nmysql:\n  <<: *mysql_definition\n"
  },
  {
    "path": ".provision/README.md",
    "content": "## ansible-role-lstu\n\nAn ansible role deploy the application on host machine(Ubuntu 20.04)\n\n## terraform-aws-lstu\n\nA terraform plan creates necessary AWS infrastructure and deploy the lstu. This terraform plan uses the `lstu_startup.sh` script to deploy application on AWS and also uses above ansible roles `ansible-role-lstu` to configure the application on AWS."
  },
  {
    "path": ".provision/ansible-role-lstu/README.md",
    "content": "Ansible-Role-Lstu\n=========\nThis role installs the and configures lstu on Debian/Ubuntu servers with nginx web server configuration.\n\nRole Variables\n-------------- \n| Variable name | Value | Description |\n| ------------- | ----- | ----------- |\n| `app_dir` | /var/www/lstu | Set the application directory for the best practice |\n| `lstu_owner` | www-data | Set the application user for the best practice |\n| `lstu_group` | www-data | Set the application group for the best practice |\n| `_contact` | contact.example.com | contact option (mandatory), where you have to put some way for the users to contact you. |\n| `_secret` | IWIWojnokd | secret  option (mandatory) array of random strings used to encrypt cookies |\n| `_project_version` | master | We can chose the project version either Master branch, Dev branch or tag based |\n| `_server_name` | IP address (or) CNAME/FQDN | Mention the Server Name for the Nginx configurations |\n\nSample example of use in a playbook\n--------------\n\nThe following code has been tested with Ubuntu 20.04\n\n```yaml\n \n- name: \"install lstu\"\n  hosts: enter your hosts file\n  become: yes\n  role:\n    - ansible-role-lstu\n  vars:\n    lstu_owner: \"www-data\"\n    lstu_group: \"www-data\"\n    app_dir: \"/var/www/lstu\"\n    _contact: \"contact.example.com\"\n    _report: \"report@example.com\"\n    _project_version: \"master\"\n    _server_name: \"IP address (or) CNAME/FQDN\"\n```   \n\nContributing\n------------\nDon’t hesitate to create a pull request\n\n\n\n\n\n\n\n\n\n"
  },
  {
    "path": ".provision/ansible-role-lstu/handlers/main.yml",
    "content": "---\n# handlers file for ansible-role-lstu\n- name: restart nginx\n  service: name=nginx state=restarted\n"
  },
  {
    "path": ".provision/ansible-role-lstu/tasks/apprun.yaml",
    "content": "#apprun.yml\n---\n- name: This command will install the postgress module\n  ansible.builtin.shell:\n    cmd: carton install --deployment --without=test --without=sqlite --without=mysql\n    chdir: \"{{ app_dir }}\"   \n\n- name: Upload application file\n  template:\n    src: ../templates/lstu.conf.j2\n    dest: \"{{ app_dir }}/lstu.conf\"\n\n- name: Run the command for app_executes\n  ansible.builtin.shell:\n    cmd: carton exec hypnotoad script/lstu\n    chdir: \"{{ app_dir }}\" \n\n- name: Nginx configuration file add\n  template:\n    src: ../templates/app.conf\n    dest: /etc/nginx/conf.d/\n    mode: '0644'\n  notify: restart nginx"
  },
  {
    "path": ".provision/ansible-role-lstu/tasks/dependencies.yaml",
    "content": "#dependencies.yaml\n---\n- name: Lstu | Update apt cache\n  ansible.builtin.apt: update_cache=yes \n  changed_when: no\n\n- name: Install Dependencies\n  ansible.builtin.apt:\n   name:\n     - nginx\n     - carton\n     - build-essential\n     - libpng-dev\n     - libssl-dev \n     - libpq-dev \n     - zlib1g-dev\n     - libmojo-sqlite-perl  \n   state: present\n   "
  },
  {
    "path": ".provision/ansible-role-lstu/tasks/gitclone.yaml",
    "content": "#gitclone\n---\n- name: Clone the repository\n  ansible.builtin.git:\n    repo: 'https://framagit.org/luc/lstu.git'\n    dest: \"{{ app_dir }}\"\n    clone: yes\n    update: yes\n    version: \"{{ _project_version }}\"\n    \n- name: Change the owner \n  ansible.builtin.file:\n    path: \"{{ app_dir }}\"\n    owner: \"{{ lstu_owner }}\"\n    group: \"{{ lstu_group }}\"\n    state: directory\n    recurse: yes\n\n\n\n\n\n      \n\n\n"
  },
  {
    "path": ".provision/ansible-role-lstu/tasks/main.yml",
    "content": "---\n# tasks file for ansible-role-lstu\n- include: dependencies.yaml\n- include: gitclone.yaml\n- include: apprun.yaml"
  },
  {
    "path": ".provision/ansible-role-lstu/templates/app.conf",
    "content": "upstream lstu {\n    server 127.0.0.1:8080;\n}\n\nserver {\n    listen 80; \n    listen [::]:80;\n\n    server_name {{ _server_name }};\n\n    access_log  /var/log/nginx/lstu.access.log;\n    error_log   /var/log/nginx/lstu.error.log;\n\n    location / {\n        proxy_http_version 1.1;\n        proxy_set_header Host $host;\n        proxy_set_header X-Real-IP $remote_addr;\n        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n        proxy_set_header X-Remote-Port $remote_port;\n        proxy_set_header X-Forwarded-Proto $scheme;\n\n        proxy_pass http://lstu;\n        proxy_redirect http://lstu https://lstu.example.org;\n    }\n}\n"
  },
  {
    "path": ".provision/ansible-role-lstu/templates/lstu.conf.j2",
    "content": "# vim:set sw=4 ts=4 sts=4 ft=perl expandtab:\n{\n    ####################\n    # Hypnotoad settings\n    ####################\n    # see http://mojolicio.us/perldoc/Mojo/Server/Hypnotoad for a full list of settings\n    hypnotoad => {\n        # array of IP addresses and ports you want to listen to\n        listen => ['http://0.0.0.0:8080'],\n        # if you use Lstu behind a reverse proxy like Nginx, you want to set proxy to 1\n        # if you use Lstu directly, let it commented\n        #proxy  => 1,\n    },\n\n    # put a way to contact you here and uncomment it\n    # MANDATORY\n    contact       => '{{ _contact }}',\n\n    # array of random strings used to encrypt cookies\n    # optional, default is ['fdjsofjoihrei'], PLEASE, CHANGE IT\n    secret        => ['{{ _secret }}'],\n\n    # secret passphrase to access some admin features\n    # If you don't want to have a plain text password in configuration,\n    # use hashed_adminpwd instead\n    # optional, but you won't have access to admin /stats if not set and if hashed_adminpwd is not set either\n    #adminpwd      => 's3cr3T',\n\n    # secret hashed passphrase to access some admin features\n    # Hash your password by issuing `echo -n s3cr3T | sha256sum` on your terminal\n    # optional, but you won't have access to admin /stats if not set and if adminpwd is not set either\n    #hashed_adminpwd => '94b2feede6ea5e2eec62f457ecb7d3f719b24d19c29d4e5466246a31908fc23b',\n\n    # choose a theme. See the available themes in `themes` directory\n    # optional, default is 'default'\n    #theme         => 'default',\n\n    # number of URLs to be displayed per page in /stats\n    # optional, default is 10\n    #page_offset   => 10,\n\n    # length of the random URL\n    # optional, default is 8\n    #length            => 8,\n\n    # how many URLs will be provisioned in a batch ?\n    # optional, default is 5\n    #provis_step       => 5,\n\n    # max number of URLs to be provisioned\n    # optional, default is 100\n    #provisioning      => 100,\n\n    # URL sub-directory in which you want Lstu to be accessible\n    # example: you want to have Lstu under https://example.org/lstu/\n    # => set prefix to '/lstu' or to '/lstu/', it doesn't matter\n    # optional, defaut is /\n    #prefix        => '/',\n\n    # array of authorized domains for API calls.\n    # if you want to authorize everyone to use the API: ['*']\n    # optional, no domains allowed by default\n    #allowed_domains   => ['http://1.example.com', 'http://2.example.com'],\n\n    # if set, the shortened URLs will use this domain\n    # optional\n    #fixed_domain => 'example.org',\n\n    # choose what database you want to use\n    # valid choices are sqlite, postgresql and mysql (all lowercase)\n    # optional, default is sqlite\n    #dbtype => 'sqlite',\n\n    # SQLite ONLY - only used if dbtype is set to sqlite\n    # define a path to the SQLite database\n    # you can define it relative to lstu directory or set an absolute path\n    # remember that it has to be in a directory writable by Lstu user\n    # optional, default is lstu.db\n    #db_path           => 'lstu.db',\n\n    # PostgreSQL ONLY - only used if dbtype is set to postgresql\n    # these are the credentials to access the PostgreSQL database\n    # mandatory if you choosed postgresql as dbtype\n    pgdb => {\n        database => 'lstu',\n        host     => 'localhost',\n        # optional, default is 5432\n        port     => 5432,\n        user     => 'DBUSER',\n        pwd      => 'DBPASSWORD',\n        # optional, default is 1\n        #max_connections => 1,\n    },\n\n    # MySQL ONLY - only used if dbtype is set to mysql\n    # these are the credentials to access the MySQL database\n    # mandatory if you choosed mysql as dbtype\n    #mysqldb => {\n    #    database => 'lstu',\n    #    host     => 'localhost',\n    #    # optional, default is 3306\n    #    #port     => 3306,\n    #    user     => 'DBUSER',\n    #    pwd      => 'DBPASSWORD',\n    #    # optional, default is 5 (set to 0 to disable persistent connections)\n    #    #max_connections => 5,\n    #},\n\n    # Rate-limiting for the API\n    # After ban_min_strike requests in a second, the IP address will be\n    # banned for one hour.\n    # If it continues to query the API during this ban time at least\n    # ban_min_strike times, it will be banned for a month.\n    # optional, default is 3\n    #ban_min_strike    => 3,\n\n    # Ban whitelist\n    # You can whitelist IP addresses to prevent you from being banned\n    # Be careful, the IP addresses are compared as string, not as IP addresses\n    # a network range will not work\n    # Example of valid input: ban_whitelist => ['198.51.100.42', '2001:0DB8::42'],¬\n    # optional, default is an empty array\n    #ban_whitelist => [],\n\n    # Ban blacklist\n    # You can blacklist IP addresses to always ban those IP addresses\n    # Be careful, the IP addresses are compared as string, not as IP addresses\n    # a network range will not work\n    # Example of valid input: ban_blacklist => ['198.51.100.42', '2001:0DB8::42'],¬\n    # optional, default is an empty array\n    #ban_blacklist => [],\n\n    # define an URL to the Piwik instance and the ID of a website to track\n    # set if you want to track views in Piwik\n    # optional, Piwik tracking is disabled by default\n    #piwik => {\n    #    url    => 'http://piwik.example.com',\n    #    idsite => '1',\n    #},\n\n    # use Minion instead of directly increase counters\n    # need to launch a minion worker service if enabled\n    # optional, Minion is disabled by default\n    # It will use the same DB type as Lstu: sqlite if you choose sqlite for `dbtype`,\n    # postgresql for postgresql, etc.\n    #minion => {\n    #    enabled => 0,\n    #    # SQLite ONLY - only used if if you choose sqlite as DB type,\n    #    # define the path to the minion database\n    #    # you can define it relative to lstu directory or set an absolute path\n    #    # remember that it has to be in a directory writable by Lutim user\n    #    # optional, default is minion.db\n    #    db_path => 'minion.db',\n    #    # PostgreSQL ONLY - only used if you choose postgresql as DB type\n    #    # these are the credentials to access the Minion's PostgreSQL database\n    #    # mandatory if you choosed postgresql as DB type, no default\n    #    pgdb => {\n    #        database => 'lstu_minion',\n    #        host     => 'localhost',\n    #        # optional, default is 5432\n    #        port     => 5432,\n    #        user     => 'DBUSER',\n    #        pwd      => 'DBPASSWORD'\n    #    },\n    #    # MySQL ONLY - only used if you choose mysql as DB type\n    #    # these are the credentials to access the Minion's MySQL database\n    #    # mandatory if you choosed mysql as DB type, no default\n    #    mysqldb => {\n    #        database => 'lstu_minion',\n    #        host     => 'localhost',\n    #        # optional, default is 3306\n    #        #port     => 3306,\n    #        user     => 'DBUSER',\n    #        pwd      => 'DBPASSWORD',\n    #    },\n    #},\n\n    # set `ldap` if you want that only authenticated users can shorten URLs\n    # please note that everybody can still use shortend URLs\n    # optional, no default\n    #ldap => {\n    #    uri         => 'ldaps://ldap.example.org',                 # server URI\n    #    user_tree   => 'ou=users,dc=example,dc=org',               # search base DN\n    #    bind_dn     => 'uid=ldap_user,ou=users,dc=example,dc=org', # search bind DN\n    #    bind_pwd    => 'secr3t',                                   # search bind password\n    #    user_attr   => 'uid',                                      # user attribute (uid, mail, sAMAccountName, etc.)\n    #    user_filter => '(!(uid=ldap_user))',                       # user filter (to exclude some users, etc.)\n    #},\n\n    # set `htpasswd` if you want to use an htpasswd file instead of ldap\n    # create the file with `htpasswd -c lstu.passwd user`, update it with `htpasswd lstu.passwd user2`\n    # make sure that lstu can read the file!\n    # optional, no default\n    #htpasswd => 'lstu.passwd',\n\n    # if you've set ldap or htpasswd above, the session will last `session_duration` seconds before\n    # the user needs to reauthenticate\n    # optional, default is 3600\n    #session_duration => 3600,\n\n    # how many redirections are allowed for the shortened URL before considering it as a spam?\n    # optional, default is 2. Set to -1 to allow infinite redirections (not recommended)\n    #max_redir => 2,\n\n    # spam blacklist regex. All URLs (or redirection) whose host part matches this regex are considered as spam\n    # optional, no default\n    #spam_blacklist_regex => 'foo|bar',\n\n    # spam path blacklist regex. All URLs (or redirection) whose path part matches this regex are considered as spam\n    # optional, no default\n    #spam_path_blacklist_regex => 'foo|bar',\n\n    # spam whitelist regex. All URLs (or redirection) whose host part matches this regex will never be considered as spam\n    # optional, no default\n    #spam_whitelist_regex => 'foo|bar',\n\n    # set to 1 to skip SpamHaus check (not recommended)\n    # optional, default is 0\n    #skip_spamhaus => 0,\n\n    # put your Google API key to enable Google safebrowsing check\n    # This will allow Lstu to download the Google safebrowsing database and use a local copy to check the URLs.\n    # Google does not get the URLs that are checked.\n    # Instructions to get a key: https://developers.google.com/safe-browsing/v4/get-started\n    # TL;DR: https://console.developers.google.com/projectselector/apis/library\n    # optional, no default\n    #safebrowsing_api_key => '',\n\n    # array of memcached servers to cache URL in order to accelerate responses to often-viewed URL.\n    # If set to [], the cache is disabled\n    # optional, default is []\n    #memcached_servers => [],\n\n    # Content-Security-Policy header that will be sent by Lstu\n    # Set to '' to disable CSP header\n    # https://content-security-policy.com/ provides a good documentation about CSP.\n    # https://report-uri.com/home/generate provides a tool to generate a CSP header.\n    # optional, default is \"default-src 'none'; script-src 'self'; style-src 'self'; img-src 'self' data:; font-src 'self'; form-action 'self'; base-uri 'self'\"\n    # the default value is good for `default` and `milligram` themes\n    #csp => \"default-src 'none'; script-src 'self'; style-src 'self'; img-src 'self' data:; font-src 'self'; form-action 'self'; base-uri 'self'\",\n\n    # X-Frame-Options header that will be sent by Lstu\n    # Valid values are: 'DENY', 'SAMEORIGIN', 'ALLOW-FROM https://example.com/'\n    # Set to '' to disable X-Frame-Options header\n    # See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options\n    # Please note that this will add a \"frame-ancestors\" directive to the CSP header (see above) accordingly\n    # to the chosen setting (See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/frame-ancestors)\n    # optional, default is 'DENY'\n    #x_frame_options => 'DENY',\n\n    # X-Content-Type-Options that will be sent by Lstu\n    # See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Content-Type-Options\n    # Set to '' to disable X-Content-Type-Options header\n    # optional, default is 'nosniff'\n    #x_content_type_options => 'nosniff',\n\n    # X-XSS-Protection that will be sent by Lstu\n    # See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-XSS-Protection\n    # Set to '' to disable X-XSS-Protection header\n    # optional, default is '1; mode=block'\n    #x_xss_protection => '1; mode=block',\n\n    # Log creator's IP address\n    # Set to 1 if you want to register the IP addresses of URL creators\n    # optional, default is 0\n    #log_creator_ip => 0,\n};\n"
  },
  {
    "path": ".provision/ansible-role-lstu/vars/main.yml",
    "content": "---\n# vars file for ansible-role-lstu\n\nlstu_owner: \"www-data\"\n\nlstu_group: \"www-data\"\n\napp_dir: \"/var/www/lstu\"\n\n_contact: \"\"\n\n_secret: \"\"\n\n_project_version: \"\"\n\n_server_name: \"\"\n"
  },
  {
    "path": ".provision/terraform-aws-lstu/README.md",
    "content": "# Terraform-AWS-Deploy\n\n This terraform plan create the resourcess of EC2 instance\n\n## Terraform Variables\n Edit the `vars.tf` file to add the variables as per your need.\n\n| Variable name | Value | Description |\n| ------------- | ----- | ----------- |\n| `aws_region` | us-east-1 | Set the region  |\n| `vpc_cidr` | 10.0.0.0/16 | Set the cidr value for the vpc |\n| `public_subnet_cidr` | 10.0.2.0/24 | Set the cidr value for the public subnet |\n| `user` | ubuntu | Set the EC2 instance user name |\n| `public_key` | /home/user_name/.ssh/id_rsa_pub | Set the publickey value for the ec2 instance from the host machine |\n| `private_key` | /home/user_name/.ssh/id_rsa | Set the private key value for the ec2 instance from the hostmachine |\n| `aws_access_key` | AWSACCESSKEY | Enter your aws access key |\n| `aws_secrete_key` | AWSSECRETEKEY | Enter your aws secrete key |\n| `instance_name` | lstu_app_instance | Set the name for instance |\n| `app_dir` | /var/www/lstu | Set the application directory for the best practice |\n| `lstu_owner` | www-data | Set the application user for the best practice |\n| `lstu_group` | www-data | Set the application group for the best practice |\n| `contact` | contact.example.com | contact option (mandatory), where you have to put some way for the users to contact you. |\n| `secret` | IWIWojnokd | secret  option (mandatory) array of random strings used to encrypt cookies |\n| `project_version` | master | We can chose the project version either Master branch, Dev branch or tag based |\n\n## Usage of terraform plan with lstu deploy script\n\n```sh \ngit clone https://github.com/ldidry/lstu\n\ncd lstu/.provision/terraform-aws-lstu\n\nterraform init\nterraform plan\nterraform apply\n```\n## Usage of terraform plan with ansible role\n\n- Comment out the below `data template` and `user_data` source in __main.tf__ file\n\n```sh\ndata \"template_file\" \"init\" {\n  template = file(\"./lstu_startup.sh\")\n  vars = {\n    user = var.lstu_owner\n    group = var.lstu_group\n    directory = var.app_dir\n    git_branch = var.project_version\n    contact_lstu = var.contact\n    secret_lstu = var.secret\n\n  }\n}\n```\n```sh\n  user_data          = data.template_file.init.rendered\n```\n\n- Add the below provisioner data in __main.tf__ file at the `aws_instance` resource\n\n```sh\n  connection          {\n    agent            = false\n    type             = \"ssh\"\n    host             = aws_instance.ec2_instance.public_dns \n    private_key      = \"${file(var.private_key)}\"\n    user             = \"${var.user}\"\n  }\n\n  provisioner \"remote-exec\" {\n    inline = [\n      \"sudo apt update -y\",\n      \"sudo apt install python3.9 -y\",\n      ]\n  }\n\n  provisioner \"local-exec\" {\n    command = <<EOT\n      sleep 120 && \\\n      > hosts && \\\n      echo \"[lstu]\" | tee -a hosts && \\\n      echo \"${aws_instance.ec2_instance.public_ip} ansible_user=${var.user} ansible_ssh_private_key_file=${var.private_key}\" | tee -a hosts && \\\n      export ANSIBLE_HOST_KEY_CHECKING=False && \\\n      ansible-playbook -u ${var.user} --private-key ${var.private_key} -i hosts site.yaml\n    EOT\n  } \n ``` "
  },
  {
    "path": ".provision/terraform-aws-lstu/lstu_startup.sh",
    "content": "#!/bin/bash\n\necho \"**********************************************************************\"\necho \"                                                                     *\"\necho \"Install dependencies                                                 *\"\necho \"                                                                     *\"\necho \"**********************************************************************\"\n\nSUDO=sudo\n$SUDO apt update\n$SUDO apt install jq -y\n$SUDO apt install wget -y\n$SUDO apt install unzip -y\n$SUDO apt install carton -y\n$SUDO apt install build-essential -y\n$SUDO apt install nginx -y\n$SUDO apt install libssl-dev -y\n$SUDO apt install libpng-dev -y\n$SUDO apt install libio-socket-ssl-perl -y\n$SUDO apt install liblwp-protocol-https-perl -y\n$SUDO apt install zlib1g-dev -y\n$SUDO apt install libmojo-sqlite-perl -y\n$SUDO apt install libpq-dev -y\n\necho \"**********************************************************************\"\necho \"                                                                     *\"\necho \"Configuring the Application                                          *\"\necho \"                                                                     *\"\necho \"**********************************************************************\"\n\nsleep 10;\nversion=$(curl -s https://framagit.org/api/v4/projects/5/releases | jq '.[]' | jq -r '.name' | head -1)\necho $version\npushd ${directory} \n$SUDO wget https://framagit.org/fiat-tux/hat-softwares/lstu/-/archive/$version/lstu-$version.zip\n$SUDO unzip lstu-$version.zip\n$SUDO chown ${user} lstu-$version\n$SUDO chgrp ${group} lstu-$version\npushd lstu-$version\n\n\necho \"**********************************************************************\"\necho \"                                                                     *\"\necho \"Install Carton Packages                                              *\"\necho \"                                                                     *\"\necho \"**********************************************************************\"\n\n$SUDO carton install --deployment --without=test --without=sqlite --without=mysql\n\nsleep 10;\n\n$SUDO cp lstu.conf.template lstu.conf\n$SUDO sed -i 's/127.0.0.1/0.0.0.0/'  lstu.conf\n$SUDO sed -i 's/#contact/contact/g' lstu.conf\n$SUDO sed -i \"s/admin\\[at]\\example.com/${contact_lstu}/g\" lstu.conf\n$SUDO sed -i 's/#secret/secret/' -i lstu.conf\n$SUDO sed -i \"s/fdjsofjoihrei/${secret_lstu}/g\" lstu.conf\n$SUDO sed -i '89 , 91 s/#/ /g' lstu.conf\n$SUDO sed -i '94 , 95 s/#/ /g' lstu.conf\n$SUDO sed -i '98 s/#/ /g' lstu.conf\n\n\n\n\necho \"**********************************************************************\"\necho \"                                                                     *\"\necho \"Run the Application                                                  *\"\necho \"                                                                     *\"\necho \"**********************************************************************\"\n\n$SUDO carton exec hypnotoad script/lstu\n\n"
  },
  {
    "path": ".provision/terraform-aws-lstu/main.tf",
    "content": "locals {\n  user_data_vars = {\n    user = var.lstu_owner\n    group = var.lstu_group\n    directory = var.app_dir\n    contact_lstu = var.contact\n    secret_lstu = var.secret \n  }\n}\n\n#Create the VPC \nresource \"aws_vpc\" \"vpc\" {\n  cidr_block           = \"${var.vpc_cidr}\"\n  enable_dns_hostnames = true \n  enable_dns_support   = true\n  instance_tenancy     = \"default\"\n  tags                 = {\n      Name             = \"lstu-master-vpc\"\n  }\n}\n\n# Create InternetGateWay and attach to VPC\n\nresource \"aws_internet_gateway\" \"IGW\" {\n  vpc_id           = \"${aws_vpc.vpc.id}\"\n  tags = {\n    \"Name\"         = \"lstu-master-igw\"\n  } \n}\n\n# Create a public subnet\n\nresource \"aws_subnet\" \"publicsubnet\" {\n  vpc_id                  = \"${aws_vpc.vpc.id}\" \n  cidr_block              = \"${var.public_subnet_cidr}\"\n  map_public_ip_on_launch = true\n  tags                    = {\n      Name                = \"lstu-master-us-east-1-public\"\n  }  \n}\n\n# Create routeTable\nresource \"aws_route_table\" \"publicroute\" {\n    vpc_id         = \"${aws_vpc.vpc.id}\"\n    route {\n        cidr_block = \"0.0.0.0/0\"\n        gateway_id = \"${aws_internet_gateway.IGW.id}\"\n    }\n             \n    tags           = {\n      Name         = \"lstu-master-us-east-1-public-rt\"\n }\n}\n\nresource \"aws_main_route_table_association\" \"mainRTB\" {\n  vpc_id         = \"${aws_vpc.vpc.id}\"\n  route_table_id = \"${aws_route_table.publicroute.id}\"\n}\n\n## Create security group\nresource \"aws_security_group\" \"security\" {\n  name             = \"lstu-master-sg\"  \n  description      = \"allow all traffic\"\n  vpc_id           = \"${aws_vpc.vpc.id}\"\n\n  ingress  {\n    description    =  \"allow all traffic\"\n    from_port      = \"0\"\n    to_port        = \"65535\"  \n    protocol       = \"tcp\"\n    cidr_blocks    = [\"0.0.0.0/0\"]\n  }\n  ingress  {\n    description    = \"allow port SSH\"\n    from_port      = \"22\"\n    to_port        = \"22\"\n    protocol       = \"tcp\"\n    cidr_blocks    = [\"0.0.0.0/0\"]\n  }\n  egress  {\n    from_port      = 0\n    to_port        = 0\n    protocol       = \"-1\"\n    cidr_blocks    = [\"0.0.0.0/0\"]\n  }\n  \n}\n\n# Add ubuntu AMI\ndata \"aws_ami\" \"ubuntu\" {\n  most_recent = true\n  owners = [\"099720109477\"]\n\n    filter {\n        name   = \"name\"\n        values = [\"ubuntu/images/hvm-ssd/ubuntu-focal-20.04-amd64-server-*\"]\n    }\n}\n\n#Create key_pair for the instance\n\nresource \"aws_key_pair\" \"genkey\" {\n  key_name           = \"lstu.webapp\"\n  public_key         = \"${file(var.public_key)}\"\n}\n\n# Craete ec2 instance\nresource \"aws_instance\" \"ec2_instance\" {\n  ami                = \"${data.aws_ami.ubuntu.id}\"   \n  instance_type      = \"t2.medium\"\n  associate_public_ip_address = \"true\"\n  subnet_id          = \"${aws_subnet.publicsubnet.id}\"\n  vpc_security_group_ids = [\"${aws_security_group.security.id}\"]\n  user_data          = templatefile(\"${path.module}/lstu_startup.sh\", local.user_data_vars)\n  key_name           = \"lstu.webapp\"\n  \n  tags               = {\n    Name             = \"${var.instance_name}\"\n  }\n}\n\n \n\n\n"
  },
  {
    "path": ".provision/terraform-aws-lstu/output.tf",
    "content": "output \"public_ip\" {\n  value = \"${aws_instance.ec2_instance.public_ip}\"\n}\n\noutput \"App_running_at\" {\n  value = \"http://${aws_instance.ec2_instance.public_ip}:8080\"\n}\n"
  },
  {
    "path": ".provision/terraform-aws-lstu/provider.tf",
    "content": "terraform {\n  required_providers {\n    aws = {\n      source  = \"hashicorp/aws\"\n      version = \"~> 3.0\"\n    }\n  }\n}\n\nprovider \"aws\" {\naccess_key = \"${var.aws_access_key}\"\nsecret_key = \"${var.aws_secret_key}\"\nregion     = \"${var.aws_region}\" \n}"
  },
  {
    "path": ".provision/terraform-aws-lstu/vars.tf",
    "content": "variable \"aws_region\" {\n    default = \"aws_region\"\n}\nvariable \"vpc_cidr\" {\n    default = \"cidr_value\"\n}\nvariable \"public_subnet_cidr\" {\n    default = \"cidr_value\"\n}\nvariable \"public_subnet1_cidr\" {\n    default = \"cidr_value\"\n}\n\nvariable \"user\" {\n    default = \"user_of_instance\" \n}\n\nvariable \"public_key\" {\n    default = \"$PWD_publickey\"\n}\nvariable \"private_key\" {\n    default = \"$PWD_privatekey\"\n}\nvariable \"aws_access_key\" {\n    default = \"aws_access_key\"\n}\n\nvariable \"aws_secret_key\" {\n    default = \"aws_secret_key\"\n}\n\nvariable \"instance_name\" {\n    default = \"lstu\"  \n}\n\nvariable \"lstu_owner\" {\n    default = \"\"  \n}\n\nvariable \"lstu_group\" {\n    default = \"\"  \n}\n\nvariable \"app_dir\" {\n    default = \"\"  \n}\n\nvariable \"project_version\" {\n    default = \"\"  \n}\n\nvariable \"contact\" {\n    default = \"\"  \n}\n\nvariable \"secret\" {\n    default = \"\"  \n}\n\n\n"
  },
  {
    "path": ".weblate",
    "content": "[weblate]\nurl = https://weblate.framasoft.org/api/\ntranslation = lstu\n"
  },
  {
    "path": "AUTHORS.md",
    "content": "# Lstu's authors\n\n## Main developer\n\n* Luc Didry, aka Sky (<https://fiat-tux.fr>), core developer, framasky@framasphere.org on [Diaspora*](https://framasphere.org/public/framasky)\n\n## Contributors\n\n* Benjamin Bouvier\n* Armando Lüscher\n* Quentin Pagès (occitan translation)\n* Phyks (Lucas Verney)\n* Pierre Rudloff\n* Belvar (Gwenn M) (breton translation)\n* Ira W. Snyder\n* Arnaud de Mouhy (docker port)\n* Mathieu Aubin\n* frju365 (Julien Gomes Dias)\n* Arunodhayam Sam (IaC and ConfigManagement)"
  },
  {
    "path": "CHANGELOG",
    "content": "Revision history for Perl application Lstu\n\n0.29-0 ????-??-??\n\n0.28-0 2023-12-17\n\t- ⬆️ Update dependencies\n\t- 💥 BREAKING CHANGE: Use `?_format=json` instead of `?format=json`\n\t- 💥 BREAKING CHANGE: Use `?_format=json` instead of terminating the URL with `.json`\n\n0.27-0 2023-01-11\n\t- 🐛 Fix length of ip column for MySQL (#64)\n\t- 🔥 Remove everything about browser extensions (#98)\n\t- 🌐 Update translations\n\n0.26-0 2022-05-23\n\t- ✨ Add a config setting to change QR code size\n\n0.25-0 2022-05-09\n\t- ✨ Add a config flag to disable API\n\t- ⚡ Use a HEAD request instead of a GET when checking for redirections\n\t- 🐛 Handle disabled URLs in `url` CLI command\n\n0.24-0 2022-04-26\n\t- ✨ Allow to sort results in admin stats page (#91)\n\t- Fix disabled URLs still showing in admin interface (#79)\n\t- Make a distinction between inexistant and disabled URLs\n\n0.23-0 2021-04-26\n\t- Update translations\n\t- Improve tests\n\t- Improve CI\n\t- Upgrade some dependencies\n\n0.22-0 2019-11-08\n\t- Disable URLs instead of removing them (prevents spammers to reuse a\n\t  deleted shortened URL)\n\t- Slugify custom URLs and add a suffix (-2, -3…) if the custom URL is\n\t  already taken\n\t- Allow to search several IP addresses at once\n\t- New logo and update theme!\n\t- Now use https://weblate.framasoft.org/projects/lstu for translations\n\n0.21-4 2018-12-17\n\t- Add a lockfile to GSB database update to prevent concurrent updates\n\n0.21-3 2018-11-19\n\t- Fix Pg sessions and urls delete fonctions\n\n0.21-2 2018-11-19\n\t- Fix URL removal in memcached from safebrowsingcheck and url commands\n\n0.21-1 2018-10-17\n\t- Fix URL removal in memcached from safebrowsingcheck command\n\n0.21-0 2018-10-17\n\t- Allow to delete URLs and ban IPs from safebrowsingcheck\n\t- Add ban CLI tool for banning and unbanning IP addresses\n\n0.20-2 2018-10-07\n\t- Handle very long URLs\n\n0.20-1 2018-09-20\n\t- Fix safebrowsingcheck CLI help message\n\n0.20-0 2018-09-20\n\t- Docker port, thanks to Arnaud de Mouhy\n\t- Improve safebrowsingcheck CLI:\n\t  - displays creators' IP addresses + other URLs from thoses IPs\n\t  - allow to specify URLs to check\n\t  - allow to check URLs created <argument> seconds ago\n\n0.19-3 2018-09-08\n\t- Update translations\n\n0.19-2 2018-09-08\n\t- Improve GSB object creation and GSB DB update\n\n0.19-1 2018-09-08\n\t- Update translations\n\n0.19-0 2018-09-08\n\t- Allow to use Google Safe Browsing database to check if the URLs are harmless\n\t  It uses a local copy of the GSB DB, so Google won't see the URLs to shorten\n\t- safebrowsingcheck CLI to check all the URLs in the database against GSB DB.\n\t  usage: carton exec script/lstu safebrowsingcheck\n\t- Fix bugs (#45)\n\n0.18-1 2018-08-21\n\t- Update url CLI help message\n\n0.18-0 2018-08-20\n\t- Add option to store IP address of URL creator\n\t- Add command to search URL with the IP address of its creator\n\t- Add option to blacklist IP address\n\t- Allow to remove multiple URLs at once with the CLI\n\n0.17-3 2018-08-20\n\t- Fix missing default db_path\n\n0.17-2 2018-05-15\n\t- Add ability to respond to /robots.txt either by sending the file if it exists or by answering 404\n\n0.17-1 2018-04-28\n\t- Fix bug in making LDAP and Htpasswd dependencies optional\n\n0.17 2018-04-28\n\t- Import URL into cookie by JSON upload\n\t- Add X-Content-Type-Options, X-XSS-Protection and X-Frame-Options headers\n\t- More dependencies become optional to install\n\t- Some refactoring\n\t- Add LDAP tests to test suite\n\n0.16-1 2018-04-27\n\t- Fix bug in LDAP authentication\n\n0.16 2018-04-24\n\t- Add Content-Security-Policy header\n\t- Use Memcached for cache system (previous cache was unstable)\n\n0.15-2 2018-04-23\n\t- Update Mojolicious::Plugin::GzipStatic\n\n0.15-1 2018-04-23\n\t- Fix url command help function\n\n0.15 2018-04-23\n\t- Add CLI command to search and delete url\n\t- Fix CI\n\n0.14-1 2018-04-23\n\t- Fix for PostgreSQL and MySQL connections\n\n0.14 2018-04-22\n\t- Use same DB backend for Minion than db_type\n\n0.13-1 2018-04-22\n\t- Better CSS minification\n\n0.13 2018-04-22\n\t- Gzip static assets with Mojolicious::Plugin::GzipStatic (increase page load speed)\n\t- Other page load speed improvements\n\n0.12-1 2018-04-22\n\t- Force Mojo::SQLite version\n\n0.12 2018-04-22\n\t- Improve LDAP User Authentication Support (beware of configuration changes!) <Ira W.  Snyder>\n\t- Allow users to configure maximum number of database connections <Ira W.  Snyder>\n\t- Use CHI for cache system\n\t- Move some tasks to recurring instead of being in after_dispatch hook\n\t- Allow to install only deps related to one DB instead of all supported DBs\n\t- Use Mojo::SQLite instead of ORLite\n\t- Better CI\n\t- Put documentation on the wiki (https://framagit.org/luc/lstu/wikis/home)\n\t- Update dependencies\n\t- Fix bugs\n\n0.11-2 2018-03-22\n\t- Update packages dependencies in README\n\t- Fix CI\n\n0.11-1 2018-03-22\n\t- Update dependencies\n\n0.11 2018-03-22\n\t- Add home link to stats page\n\t- Fix copy-to-clipboard button\n\t- Option to blacklist URLs whose path part matches the configured regex\n\n0.10 2018-02-22\n\t- Performance improvments (cache + assets minification)\n\t- Add /stats/:short API endpoint\n\t- Update API page\n\t- Zanata integration (https://trad.framasoft.org)\n\n0.09-2 2017-09-05\n\t- Handle redirections without host\n\n0.09-1 2017-09-05\n\t- Handle redirections without host\n\n0.09 2017-09-05\n\t- Add QRcode generation\n\t- Option to disable the spamhaus check (#29)\n\t- Option to blacklist and/or whitelist domains (#30)\n\t- Option to set the maximum number of redirections (#31)\n\t- Instance statistics available at /fullstats URL\n\t- Now return 404 status for non-existent URLs\n\n0.08 2017-02-08\n\t- Add Piwik tracking option\n\t- Add Minion option for async counters increasing\n\t- Add LDAP and Htpasswd authentication (#8)\n\t- Add Database abstraction layer\n\t- Add PostgreSQL (#21)\n\t- Allow to run several Lstu's instances from the same code but with\n\t  different configuration files (#23)\n\t- Cache dependencies for the different stages of the CI\n\t- Allow whitelisted IPs to bypass anti-spam/anti-bruteforce systems (#24)\n\t- Add breton translation\n\n0.07 2016-12-20\n\t- Add logo\n\t- Add theme system\n\t- Better Spamhaus checking\n\t- Add ban system\n\t- Add occitan translation\n\t- Add Milligram theme\n\t- Add cache system\n\t- Add hashed_adminpwd option\n\n0.06 2015-09-04\n\t- Add Spamhaus checking before accepting the URL\n\t- Fix small bug\n\n0.05 2015-07-31\n\t- Add copy-to-clipboard button (#1)\n\t- Add test suite\n\t- Add Net::Domain::TLD >= 1.73 as dependancy\n\n0.04 2015-06-10\n\t- Change internationalization system (.po files now)\n\t- Fixed domain for shortened URLs system (#12)\n\t- Fix XSS vulnerability (#15)\n\t- Subdirectory mounting system (#16)\n\t- Show your URLs (\"stats\") page\n\t- Show all URLs page for admin (#11)\n\t- API description page\n\t- API change\n\t- Self-documented configuration template\n\t- add doc and templates for systemd and sysVinit\n\t- add template for nginx\n\n0.03 2013-09-25\n\t- FIX #5 again by using transactions\n\n0.02 2013-09-24\n\t- use of morbo or hypnotoad servers availables\n\t- use of config file\n\t- FIX #1 : GET parameters deleted when using /a/*url route\n\t- FIX #2 : Can't use morbo or hypnotoad\n\t- FIX #3 : Internationalization\n\t- FIX #5 : Scalability issues\n\n0.01 2013-09-21\n\t- original version;\n"
  },
  {
    "path": "CONTRIBUTING.md",
    "content": "# How to contribute?\n\nThe official git repository is <https://framagit.org/fiat-tux/hat-softwares/lstu>.\n\nYou can create an account on Framagit with your Github/Gitlab/Bitbucket account.\n\n## Issues\n\nPlease, post any issue on <https://framagit.org/fiat-tux/hat-softwares/lstu/issues>.\n\n## Merge requests\n\nPlease, post any merge request on <https://framagit.org/fiat-tux/hat-softwares/lstu/merge_requests>.\n\nFor your merge request to be accepted, please:\n- use 4 spaces for indentation\n- add yourself to [AUTHORS.md](AUTHORS.md)\n- be sure that it passed the automated tests before submitting the MR\n- [squash your commits](http://gitready.com/advanced/2009/02/10/squashing-commits-with-rebase.html)\n"
  },
  {
    "path": "Dockerfile",
    "content": "FROM alpine:3.19\n\nARG BUILD_DATE\nARG VCS_REF\nARG VERSION\nLABEL org.label-schema.build-date=$BUILD_DATE \\\n      org.label-schema.name=\"Let's Shorten That URL\" \\\n      org.label-schema.url=\"https://lstu.fr/\" \\\n      org.label-schema.vcs-ref=$VCS_REF \\\n      org.label-schema.vcs-url=\"https://framagit.org/fiat-tux/hat-softwares/lstu\" \\\n      org.label-schema.vendor=\"Luc Didry\" \\\n      org.label-schema.version=$VERSION \\\n      org.label-schema.schema-version=\"1.0\"\n\nRUN adduser -D lstu\nCOPY --chown=lstu:lstu . /home/lstu\nWORKDIR /home/lstu\nRUN apk --update add ca-certificates perl perl-netaddr-ip perl-io-socket-ssl perl-dbd-pg mariadb-connector-c-dev libpng zlib openssl perl-dbd-mysql\nRUN apk add --virtual .build-deps build-base perl-utils perl-dev make sudo zlib-dev libpng-dev postgresql-dev mariadb-dev openssl-dev\nRUN cpan -T Carton\nRUN sudo -u lstu carton install --deployment --without=test --without=cache\nRUN perl -MCPAN -e 'install inc::latest'\nRUN perl -MCPAN -e 'install Config::FromHash'\nRUN apk del .build-deps\nRUN rm -rf /var/cache/apk/*\nUSER lstu\n\nENTRYPOINT [\"/bin/sh\", \"/home/lstu/docker/entrypoint.sh\"]\n"
  },
  {
    "path": "LICENSE",
    "content": "        DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE \n                    Version 2, December 2004 \n\n Copyright (C) 2004 Sam Hocevar <sam@hocevar.net> \n\n Everyone is permitted to copy and distribute verbatim or modified \n copies of this license document, and changing it is allowed as long \n as the name is changed. \n\n            DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE \n   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION \n\n  0. You just DO WHAT THE FUCK YOU WANT TO.\n"
  },
  {
    "path": "Makefile",
    "content": "EXTRACTDIR=-D lib -D themes/default/templates\nPOT=themes/default/lib/Lstu/I18N/lstu.pot\nXGETTEXT=carton exec local/bin/xgettext.pl\nCARTON=carton exec\nREAL_LSTU=script/application\nLSTU=script/lstu\nHARNESS_PERL_SWITCHES=-MDevel::Cover=+ignore,local\n\nminify:\n\t@echo \"CSS concatenation\"\n\t@cd ./themes/default/public/css/   && cat bootstrap.min.css lstu.css fontelico.css | csso > bootstrap-lstu.min.css\n\t@cd ./themes/milligram/public/css/ && cat milligram.min.css lstu.css ../../../default/public/css/fontelico.css | csso > milli-lstu.min.css\n\nlocales:\n\t$(XGETTEXT) $(EXTRACTDIR) -o $(POT) 2>/dev/null\n\tcd ./themes/milligram && make locales\n\npodcheck:\n\tpodchecker lib/Lstu/DB/*pm lib/Lstu/Command/*pm\n\ncheck-syntax:\n\tfind lib/ themes/ -name \\*.pm -exec carton exec perl -Ilib -c {} \\;\n\tfind t/ -name \\*.t -exec carton exec perl -Ilib -c {} \\;\n\ncover:\n\tPERL5OPT='-Ilib/' $(CARTON) cover --ignore_re '^local'\n\ntest:\n\t@PERL5OPT='-Ilib/' HARNESS_PERL_SWITCHES='$(HARNESS_PERL_SWITCHES)' $(CARTON) prove --comments --failures\n\ntest-junit-output:\n\t@PERL5OPT='-Ilib/' HARNESS_PERL_SWITCHES='$(HARNESS_PERL_SWITCHES)' $(CARTON) prove --comments --failures --formatter TAP::Formatter::JUnit > tap.xml\n\ntest-sqlite:\n\t@rm -rf test1.db test1.db-journal cover_db/\n\t@echo 'MOJO_CONFIG=t/sqlite1.conf'\n\t@PERL5OPT='-Ilib/' HARNESS_PERL_SWITCHES='$(HARNESS_PERL_SWITCHES)' MOJO_CONFIG=t/sqlite1.conf $(CARTON) prove --comments --failures\n\t@PERL5OPT='-Ilib/' HARNESS_PERL_SWITCHES='$(HARNESS_PERL_SWITCHES)' $(CARTON) cover --ignore_re '^local'\n\nrun-ldap-container:\n\tpodman run -d --name rroemhild-test-openldap -p 127.0.0.1:10389:10389 docker.io/rroemhild/test-openldap\n\ndev: minify\n\t$(CARTON) morbo $(LSTU) --listen http://0.0.0.0:3000 --watch lib/ --watch script/ --watch themes/ --watch lstu.conf\n\ndevlog:\n\tmultitail log/development.log\n\nminion:\n\t$(CARTON) $(REAL_LSTU) minion worker\n\ninstalldeps:\n\tcarton install\n\nupdatedeps:\n\tcarton update\n"
  },
  {
    "path": "README.md",
    "content": "# Lstu\n\n## What does Lstu mean?\n\nIt means Let's Shorten That Url.\n\n## License\n\nLstu is licensed under the terms of the WTFPL. See the LICENSE file.\n\n## Installation\n\nPlease, see the [wiki](https://framagit.org/fiat-tux/hat-softwares/lstu/wikis/home).\n\nOr you can see [usage with Docker](https://framagit.org/fiat-tux/hat-softwares/lstu/wikis/usage-with-docker).\n\n## How many URLs can it handle ?\n\nBy default, there are 8 361 453 672 available combinations.\n\nI think the sqlite db will explode before you reach this limit, but you can use PostgreSQL or MySQL as database instead of SQLite.\n\nIf you want more shortened URLs than that, open `lstu.conf` and change the `length` setting.\n\nEvery time somebody uses Lstu, it will create 'waiting' shortened URLs codes in order to be quick to shorten the URLs.\n\nAccordingly to the `lstu.conf` configuration file, it will create `provisioning` waiting URLs, adding them `provis_step` by `provis_step`.\n\n## Official instance\n\nYou can see it working and use it at <https://lstu.fr>.\n\n## API\n\nSee <https://lstu.fr/api>.\nYour instance will provide the same page with your URL.\n\n## Contributing\n\nSee the [contributing guidelines](CONTRIBUTING.md).\n\n## Other projects dependencies\n\nLstu is written in Perl with the Mojolicious framework and uses [Milligram](https://milligram.io/) CSS framework to look not too ugly.\n\n## Authors\n\nSee the [AUTHORS.md](AUTHORS.md) file.\n\n## Deploy Lstu\n\nAn ansible role and a terraform plan reside under the `.provision` directory. An user could utilize the terraform plan if they chose to deploy lstu on AWS, if that's not the goal, they could simply execute the ansible role in part. Usage docs for both are present in their respective directories.\n"
  },
  {
    "path": "cpanfile",
    "content": "requires 'inc::Module::Install::DSL';\nrequires 'Mojolicious', '>= 8.09';\nrequires 'Data::Validate::URI';\nrequires 'Net::Domain::TLD', '>= 1.74';\nrequires 'Mojolicious::Plugin::I18N';\nrequires 'Mojolicious::Plugin::DebugDumperHelper';\nrequires 'Mojolicious::Plugin::Piwik';\nrequires 'Mojolicious::Plugin::StaticCache';\nrequires 'Mojolicious::Plugin::GzipStatic';\nrequires 'Mojolicious::Plugin::CSPHeader', '>= 0.03';\nrequires 'Minion';\nrequires 'Locale::Maketext';\nrequires 'Locale::Maketext::Extract';\nrequires 'Net::Abuse::Utils::Spamhaus';\nrequires 'Net::DNS', '>= 1.12';\nrequires 'Net::SSLeay', '>= 1.81';\nrequires 'IO::Socket::SSL';\nrequires 'Image::PNG::QRCode';\nrequires 'Cpanel::JSON::XS';\n\nfeature 'ldap', 'LDAP authentication support' => sub {\n    requires 'Net::LDAP';\n    requires 'Mojolicious::Plugin::Authentication';\n};\nfeature 'htpasswd', 'Htpasswd authentication support' => sub {\n    requires 'Apache::Htpasswd';\n    requires 'Mojolicious::Plugin::Authentication';\n};\nfeature 'cache', 'URL cache system' => sub {\n    requires 'Mojolicious::Plugin::CHI';\n    requires 'CHI::Driver::Memcached';\n    requires 'Cache::Memcached';\n};\nfeature 'test' => sub {\n    requires 'Devel::Cover', '>= 1.36';\n};\nfeature 'sqlite', 'SQLite support' => sub {\n    requires 'Mojo::SQLite', '>= 3.000';\n    requires 'Minion::Backend::SQLite', '>= 4.001';\n};\nfeature 'postgresql', 'PostgreSQL support' => sub {\n    requires 'Mojo::Pg';\n    requires 'Mojolicious::Plugin::PgURLHelper';\n};\nfeature 'mysql', 'MySQL support' => sub {\n    requires 'Mojo::mysql', '>= 1.22';\n    requires 'Minion::Backend::mysql';\n    requires 'Mojolicious::Plugin::PgURLHelper';\n};\n\nfeature 'safebrowsing', 'Check URLs against Google safebrowsing database' => sub {\n    requires 'Net::Google::SafeBrowsing4', '>= 0.8';\n    requires 'Term::ProgressBar::Quiet';\n};\n"
  },
  {
    "path": "cpanfile.snapshot",
    "content": "# carton snapshot format: version 1.0\nDISTRIBUTIONS\n  Apache-Htpasswd-1.9\n    pathname: K/KM/KMELTZ/Apache-Htpasswd-1.9.tar.gz\n    provides:\n      Apache::Htpasswd 1.9\n    requirements:\n      Crypt::PasswdMD5 0\n      Digest::SHA 2\n      ExtUtils::MakeMaker 0\n      MIME::Base64 0\n  Authen-SASL-2.1700\n    pathname: E/EH/EHUELS/Authen-SASL-2.1700.tar.gz\n    provides:\n      Authen::SASL 2.1700\n      Authen::SASL::CRAM_MD5 2.1700\n      Authen::SASL::EXTERNAL 2.1700\n      Authen::SASL::Perl 2.1700\n      Authen::SASL::Perl::ANONYMOUS 2.1700\n      Authen::SASL::Perl::CRAM_MD5 2.1700\n      Authen::SASL::Perl::DIGEST_MD5 2.1700\n      Authen::SASL::Perl::EXTERNAL 2.1700\n      Authen::SASL::Perl::GSSAPI 2.1700\n      Authen::SASL::Perl::LOGIN 2.1700\n      Authen::SASL::Perl::PLAIN 2.1700\n    requirements:\n      Digest::HMAC_MD5 0\n      Digest::MD5 0\n      ExtUtils::MakeMaker 0\n      perl 5.006000\n  B-Hooks-EndOfScope-0.26\n    pathname: E/ET/ETHER/B-Hooks-EndOfScope-0.26.tar.gz\n    provides:\n      B::Hooks::EndOfScope 0.26\n      B::Hooks::EndOfScope::PP 0.26\n      B::Hooks::EndOfScope::XS 0.26\n    requirements:\n      ExtUtils::MakeMaker 0\n      Hash::Util::FieldHash 0\n      Module::Implementation 0.05\n      Scalar::Util 0\n      Sub::Exporter::Progressive 0.001006\n      Text::ParseWords 0\n      Tie::Hash 0\n      Variable::Magic 0.48\n      perl 5.006001\n      strict 0\n      warnings 0\n  CHI-0.61\n    pathname: A/AS/ASB/CHI-0.61.tar.gz\n    provides:\n      CHI 0.61\n      CHI::CacheObject 0.61\n      CHI::Driver 0.61\n      CHI::Driver::Base::CacheContainer 0.61\n      CHI::Driver::CacheCache 0.61\n      CHI::Driver::FastMmap 0.61\n      CHI::Driver::File 0.61\n      CHI::Driver::Memory 0.61\n      CHI::Driver::Metacache 0.61\n      CHI::Driver::Null 0.61\n      CHI::Driver::RawMemory 0.61\n      CHI::Driver::Role::HasSubcaches 0.61\n      CHI::Driver::Role::IsSizeAware 0.61\n      CHI::Driver::Role::IsSubcache 0.61\n      CHI::Stats 0.61\n    requirements:\n      Carp::Assert 0.20\n      Class::Load 0\n      Data::UUID 0\n      Digest::JHash 0\n      Digest::MD5 0\n      ExtUtils::MakeMaker 0\n      File::Spec 0.80\n      Hash::MoreUtils 0\n      JSON::MaybeXS 1.003003\n      List::MoreUtils 0.13\n      Log::Any 0.08\n      Moo 1.003\n      MooX::Types::MooseLike 0.23\n      MooX::Types::MooseLike::Base 0\n      MooX::Types::MooseLike::Numeric 0\n      Storable 0\n      String::RewritePrefix 0\n      Task::Weaken 0\n      Time::Duration 1.06\n      Time::Duration::Parse 0.03\n      Time::HiRes 1.30\n      Try::Tiny 0.05\n  CHI-Driver-Memcached-0.16\n    pathname: J/JS/JSWARTZ/CHI-Driver-Memcached-0.16.tar.gz\n    provides:\n      CHI::Driver::Memcached 0.16\n      CHI::Driver::Memcached::Base 0.16\n      CHI::Driver::Memcached::Fast 0.16\n      CHI::Driver::Memcached::libmemcached 0.16\n    requirements:\n      CHI 0.33\n      ExtUtils::MakeMaker 0\n      Moose 0.66\n  Cache-Memcached-1.30\n    pathname: D/DO/DORMANDO/Cache-Memcached-1.30.tar.gz\n    provides:\n      Cache::Memcached 1.30\n      Cache::Memcached::GetParser undef\n    requirements:\n      Encode 0\n      ExtUtils::MakeMaker 0\n      Storable 0\n      String::CRC32 0\n      Time::HiRes 0\n  Canary-Stability-2013\n    pathname: M/ML/MLEHMANN/Canary-Stability-2013.tar.gz\n    provides:\n      Canary::Stability 2013\n    requirements:\n      ExtUtils::MakeMaker 0\n  Capture-Tiny-0.48\n    pathname: D/DA/DAGOLDEN/Capture-Tiny-0.48.tar.gz\n    provides:\n      Capture::Tiny 0.48\n    requirements:\n      Carp 0\n      Exporter 0\n      ExtUtils::MakeMaker 6.17\n      File::Spec 0\n      File::Temp 0\n      IO::Handle 0\n      Scalar::Util 0\n      perl 5.006\n      strict 0\n      warnings 0\n  Carp-Assert-0.22\n    pathname: Y/YV/YVES/Carp-Assert-0.22.tar.gz\n    provides:\n      Carp::Assert 0.22\n    requirements:\n      Carp 0\n      Exporter 0\n      ExtUtils::MakeMaker 0\n      perl 5.006\n      strict 0\n      vars 0\n      warnings 0\n  Class-Load-0.25\n    pathname: E/ET/ETHER/Class-Load-0.25.tar.gz\n    provides:\n      Class::Load 0.25\n      Class::Load::PP 0.25\n    requirements:\n      Carp 0\n      Data::OptList 0.110\n      Exporter 0\n      ExtUtils::MakeMaker 0\n      Module::Implementation 0.04\n      Module::Runtime 0.012\n      Package::Stash 0.14\n      Scalar::Util 0\n      Try::Tiny 0\n      base 0\n      perl 5.006\n      strict 0\n      warnings 0\n  Class-Load-XS-0.10\n    pathname: E/ET/ETHER/Class-Load-XS-0.10.tar.gz\n    provides:\n      Class::Load::XS 0.10\n    requirements:\n      Class::Load 0.20\n      ExtUtils::MakeMaker 0\n      XSLoader 0\n      perl 5.006\n      strict 0\n      warnings 0\n  Class-Method-Modifiers-2.15\n    pathname: E/ET/ETHER/Class-Method-Modifiers-2.15.tar.gz\n    provides:\n      Class::Method::Modifiers 2.15\n    requirements:\n      B 0\n      Carp 0\n      Exporter 0\n      ExtUtils::MakeMaker 0\n      base 0\n      perl 5.006\n      strict 0\n      warnings 0\n  Class-MethodMaker-2.24\n    pathname: S/SC/SCHWIGON/class-methodmaker/Class-MethodMaker-2.24.tar.gz\n    provides:\n      Class::MethodMaker 2.24\n      Class::MethodMaker::Constants undef\n      Class::MethodMaker::Engine 2.24\n      Class::MethodMaker::OptExt undef\n      Class::MethodMaker::V1Compat undef\n      Generate undef\n    requirements:\n      ExtUtils::MakeMaker 0\n      perl 5.006\n  Clone-0.46\n    pathname: G/GA/GARU/Clone-0.46.tar.gz\n    provides:\n      Clone 0.46\n    requirements:\n      ExtUtils::MakeMaker 0\n  Clone-Choose-0.010\n    pathname: H/HE/HERMES/Clone-Choose-0.010.tar.gz\n    provides:\n      Clone::Choose 0.010\n    requirements:\n      ExtUtils::MakeMaker 0\n      Storable 0\n      perl 5.008001\n  Convert-ASN1-0.34\n    pathname: T/TI/TIMLEGGE/Convert-ASN1-0.34.tar.gz\n    provides:\n      Convert::ASN1 0.34\n    requirements:\n      ExtUtils::MakeMaker 0\n  Cpanel-JSON-XS-4.37\n    pathname: R/RU/RURBAN/Cpanel-JSON-XS-4.37.tar.gz\n    provides:\n      Cpanel::JSON::XS 4.37\n      Cpanel::JSON::XS::Type undef\n    requirements:\n      Carp 0\n      Config 0\n      Encode 1.9801\n      Exporter 0\n      ExtUtils::MakeMaker 0\n      Pod::Text 2.08\n      XSLoader 0\n      overload 0\n      strict 0\n      warnings 0\n  Crypt-PasswdMD5-1.42\n    pathname: R/RS/RSAVAGE/Crypt-PasswdMD5-1.42.tgz\n    provides:\n      Crypt::PasswdMD5 1.42\n    requirements:\n      Digest::MD5 2.53\n      ExtUtils::MakeMaker 0\n      strict 0\n      warnings 0\n  DBD-MariaDB-1.23\n    pathname: P/PA/PALI/DBD-MariaDB-1.23.tar.gz\n    provides:\n      DBD::MariaDB 1.23\n    requirements:\n      Config 0\n      DBI 1.608\n      Data::Dumper 0\n      Devel::CheckLib 1.12\n      DynaLoader 0\n      ExtUtils::MakeMaker 0\n      File::Spec 0\n      Getopt::Long 0\n      perl 5.008001\n      strict 0\n      utf8 0\n      warnings 0\n  DBD-Pg-3.18.0\n    pathname: T/TU/TURNSTEP/DBD-Pg-3.18.0.tar.gz\n    provides:\n      Bundle::DBD::Pg v3.18.0\n      DBD::Pg v3.18.0\n    requirements:\n      DBI 1.614\n      ExtUtils::MakeMaker 6.58\n      File::Temp 0\n      Test::More 0.88\n      Time::HiRes 0\n      version 0\n  DBD-SQLite-1.74\n    pathname: I/IS/ISHIGAKI/DBD-SQLite-1.74.tar.gz\n    provides:\n      DBD::SQLite 1.74\n      DBD::SQLite::Constants undef\n      DBD::SQLite::GetInfo undef\n      DBD::SQLite::VirtualTable 1.74\n      DBD::SQLite::VirtualTable::Cursor 1.74\n      DBD::SQLite::VirtualTable::FileContent undef\n      DBD::SQLite::VirtualTable::FileContent::Cursor undef\n      DBD::SQLite::VirtualTable::PerlData undef\n      DBD::SQLite::VirtualTable::PerlData::Cursor undef\n    requirements:\n      DBI 1.57\n      ExtUtils::MakeMaker 0\n      File::Spec 0.82\n      Test::More 0.88\n      Tie::Hash 0\n      perl 5.006\n  DBI-1.643\n    pathname: T/TI/TIMB/DBI-1.643.tar.gz\n    provides:\n      Bundle::DBI 12.008696\n      DBD::DBM 0.08\n      DBD::DBM::Statement 0.08\n      DBD::DBM::Table 0.08\n      DBD::DBM::db 0.08\n      DBD::DBM::dr 0.08\n      DBD::DBM::st 0.08\n      DBD::ExampleP 12.014311\n      DBD::ExampleP::db 12.014311\n      DBD::ExampleP::dr 12.014311\n      DBD::ExampleP::st 12.014311\n      DBD::File 0.44\n      DBD::File::DataSource::File 0.44\n      DBD::File::DataSource::Stream 0.44\n      DBD::File::Statement 0.44\n      DBD::File::Table 0.44\n      DBD::File::TableSource::FileSystem 0.44\n      DBD::File::db 0.44\n      DBD::File::dr 0.44\n      DBD::File::st 0.44\n      DBD::Gofer 0.015327\n      DBD::Gofer::Policy::Base 0.010088\n      DBD::Gofer::Policy::classic 0.010088\n      DBD::Gofer::Policy::pedantic 0.010088\n      DBD::Gofer::Policy::rush 0.010088\n      DBD::Gofer::Transport::Base 0.014121\n      DBD::Gofer::Transport::corostream undef\n      DBD::Gofer::Transport::null 0.010088\n      DBD::Gofer::Transport::pipeone 0.010088\n      DBD::Gofer::Transport::stream 0.014599\n      DBD::Gofer::db 0.015327\n      DBD::Gofer::dr 0.015327\n      DBD::Gofer::st 0.015327\n      DBD::Mem 0.001\n      DBD::Mem::DataSource 0.001\n      DBD::Mem::Statement 0.001\n      DBD::Mem::Table 0.001\n      DBD::Mem::db 0.001\n      DBD::Mem::dr 0.001\n      DBD::Mem::st 0.001\n      DBD::NullP 12.014715\n      DBD::NullP::db 12.014715\n      DBD::NullP::dr 12.014715\n      DBD::NullP::st 12.014715\n      DBD::Proxy 0.2004\n      DBD::Proxy::RPC::PlClient 0.2004\n      DBD::Proxy::db 0.2004\n      DBD::Proxy::dr 0.2004\n      DBD::Proxy::st 0.2004\n      DBD::Sponge 12.010003\n      DBD::Sponge::db 12.010003\n      DBD::Sponge::dr 12.010003\n      DBD::Sponge::st 12.010003\n      DBDI 12.015129\n      DBI 1.643\n      DBI::Const::GetInfo::ANSI 2.008697\n      DBI::Const::GetInfo::ODBC 2.011374\n      DBI::Const::GetInfoReturn 2.008697\n      DBI::Const::GetInfoType 2.008697\n      DBI::DBD 12.015129\n      DBI::DBD::Metadata 2.014214\n      DBI::DBD::SqlEngine 0.06\n      DBI::DBD::SqlEngine::DataSource 0.06\n      DBI::DBD::SqlEngine::Statement 0.06\n      DBI::DBD::SqlEngine::Table 0.06\n      DBI::DBD::SqlEngine::TableSource 0.06\n      DBI::DBD::SqlEngine::TieMeta 0.06\n      DBI::DBD::SqlEngine::TieTables 0.06\n      DBI::DBD::SqlEngine::db 0.06\n      DBI::DBD::SqlEngine::dr 0.06\n      DBI::DBD::SqlEngine::st 0.06\n      DBI::Gofer::Execute 0.014283\n      DBI::Gofer::Request 0.012537\n      DBI::Gofer::Response 0.011566\n      DBI::Gofer::Serializer::Base 0.009950\n      DBI::Gofer::Serializer::DataDumper 0.009950\n      DBI::Gofer::Serializer::Storable 0.015586\n      DBI::Gofer::Transport::Base 0.012537\n      DBI::Gofer::Transport::pipeone 0.012537\n      DBI::Gofer::Transport::stream 0.012537\n      DBI::Profile 2.015065\n      DBI::ProfileData 2.010008\n      DBI::ProfileDumper 2.015325\n      DBI::ProfileDumper::Apache 2.014121\n      DBI::ProfileSubs 0.009396\n      DBI::ProxyServer 0.3005\n      DBI::ProxyServer::db 0.3005\n      DBI::ProxyServer::dr 0.3005\n      DBI::ProxyServer::st 0.3005\n      DBI::SQL::Nano 1.015544\n      DBI::SQL::Nano::Statement_ 1.015544\n      DBI::SQL::Nano::Table_ 1.015544\n      DBI::Util::CacheMemory 0.010315\n      DBI::Util::_accessor 0.009479\n      DBI::common 1.643\n    requirements:\n      ExtUtils::MakeMaker 6.48\n      Test::Simple 0.90\n      perl 5.008001\n  Data-OptList-0.114\n    pathname: R/RJ/RJBS/Data-OptList-0.114.tar.gz\n    provides:\n      Data::OptList 0.114\n    requirements:\n      ExtUtils::MakeMaker 6.78\n      List::Util 0\n      Params::Util 0\n      Sub::Install 0.921\n      perl 5.012\n      strict 0\n      warnings 0\n  Data-UUID-1.226\n    pathname: R/RJ/RJBS/Data-UUID-1.226.tar.gz\n    provides:\n      Data::UUID 1.226\n    requirements:\n      Digest::MD5 0\n      ExtUtils::MakeMaker 0\n  Data-Validate-Domain-0.15\n    pathname: D/DR/DROLSKY/Data-Validate-Domain-0.15.tar.gz\n    provides:\n      Data::Validate::Domain 0.15\n    requirements:\n      Exporter 0\n      ExtUtils::MakeMaker 0\n      Net::Domain::TLD 1.74\n      strict 0\n      warnings 0\n  Data-Validate-IP-0.31\n    pathname: D/DR/DROLSKY/Data-Validate-IP-0.31.tar.gz\n    provides:\n      Data::Validate::IP 0.31\n    requirements:\n      Exporter 0\n      ExtUtils::MakeMaker 0\n      NetAddr::IP 4\n      Scalar::Util 0\n      base 0\n      perl 5.008\n      strict 0\n      warnings 0\n  Data-Validate-URI-0.07\n    pathname: S/SO/SONNEN/Data-Validate-URI-0.07.tar.gz\n    provides:\n      Data::Validate::URI 0.07\n    requirements:\n      Data::Validate::Domain 0\n      Data::Validate::IP 0\n      ExtUtils::MakeMaker 0\n  Devel-CheckLib-1.16\n    pathname: M/MA/MATTN/Devel-CheckLib-1.16.tar.gz\n    provides:\n      Devel::CheckLib 1.16\n    requirements:\n      Exporter 0\n      ExtUtils::MakeMaker 0\n      File::Spec 0\n      File::Temp 0.16\n      perl 5.004050\n  Devel-Cover-1.40\n    pathname: P/PJ/PJCJ/Devel-Cover-1.40.tar.gz\n    provides:\n      Devel::Cover 1.40\n      Devel::Cover::Annotation::Git 1.40\n      Devel::Cover::Annotation::Random 1.40\n      Devel::Cover::Annotation::Svk 1.40\n      Devel::Cover::Branch 1.40\n      Devel::Cover::Collection 1.40\n      Devel::Cover::Collection::Template::Provider 1.40\n      Devel::Cover::Condition 1.40\n      Devel::Cover::Condition_and_2 1.40\n      Devel::Cover::Condition_and_3 1.40\n      Devel::Cover::Condition_or_2 1.40\n      Devel::Cover::Condition_or_3 1.40\n      Devel::Cover::Condition_xor_4 1.40\n      Devel::Cover::Criterion 1.40\n      Devel::Cover::DB 1.40\n      Devel::Cover::DB::Criterion 1.40\n      Devel::Cover::DB::Digests 1.40\n      Devel::Cover::DB::File 1.40\n      Devel::Cover::DB::IO 1.40\n      Devel::Cover::DB::IO::Base 1.40\n      Devel::Cover::DB::IO::JSON 1.40\n      Devel::Cover::DB::IO::Sereal 1.40\n      Devel::Cover::DB::IO::Storable 1.40\n      Devel::Cover::DB::Run 1.40\n      Devel::Cover::DB::Structure 1.40\n      Devel::Cover::Html_Common 1.40\n      Devel::Cover::Op 1.40\n      Devel::Cover::Pod 1.40\n      Devel::Cover::Report::Compilation 1.40\n      Devel::Cover::Report::Html 1.40\n      Devel::Cover::Report::Html_basic 1.40\n      Devel::Cover::Report::Html_basic::Template::Provider 1.40\n      Devel::Cover::Report::Html_minimal 1.40\n      Devel::Cover::Report::Html_subtle 1.40\n      Devel::Cover::Report::Html_subtle::Template::Provider 1.40\n      Devel::Cover::Report::Json 1.40\n      Devel::Cover::Report::Sort 1.40\n      Devel::Cover::Report::Text 1.40\n      Devel::Cover::Report::Text2 1.40\n      Devel::Cover::Report::Vim 1.40\n      Devel::Cover::Report::Vim::Template::Provider 1.40\n      Devel::Cover::Statement 1.40\n      Devel::Cover::Subroutine 1.40\n      Devel::Cover::Test 1.40\n      Devel::Cover::Time 1.40\n      Devel::Cover::Truth_Table 1.40\n      Devel::Cover::Truth_Table::Row 1.40\n      Devel::Cover::Util 1.40\n      Devel::Cover::Web 1.40\n    requirements:\n      Digest::MD5 0\n      ExtUtils::MakeMaker 0\n      HTML::Entities 3.69\n      Storable 0\n      Test::More 0\n  Devel-Cycle-1.12\n    pathname: L/LD/LDS/Devel-Cycle-1.12.tar.gz\n    provides:\n      Devel::Cycle 1.12\n    requirements:\n      ExtUtils::MakeMaker 0\n      Scalar::Util 0\n      Test::More 0\n  Devel-GlobalDestruction-0.14\n    pathname: H/HA/HAARG/Devel-GlobalDestruction-0.14.tar.gz\n    provides:\n      Devel::GlobalDestruction 0.14\n    requirements:\n      ExtUtils::MakeMaker 0\n      Sub::Exporter::Progressive 0.001011\n      perl 5.006\n  Devel-OverloadInfo-0.007\n    pathname: I/IL/ILMARI/Devel-OverloadInfo-0.007.tar.gz\n    provides:\n      Devel::OverloadInfo 0.007\n    requirements:\n      B 0\n      Exporter 5.57\n      ExtUtils::MakeMaker 0\n      MRO::Compat 0\n      Package::Stash 0.14\n      Scalar::Util 0\n      Sub::Util 1.40\n      Text::ParseWords 0\n      overload 0\n      perl 5.006\n      strict 0\n      warnings 0\n  Devel-StackTrace-2.04\n    pathname: D/DR/DROLSKY/Devel-StackTrace-2.04.tar.gz\n    provides:\n      Devel::StackTrace 2.04\n      Devel::StackTrace::Frame 2.04\n    requirements:\n      ExtUtils::MakeMaker 0\n      File::Spec 0\n      Scalar::Util 0\n      overload 0\n      perl 5.006\n      strict 0\n      warnings 0\n  Devel-Symdump-2.18\n    pathname: A/AN/ANDK/Devel-Symdump-2.18.tar.gz\n    provides:\n      Devel::Symdump 2.18\n      Devel::Symdump::Export undef\n    requirements:\n      Compress::Zlib 0\n      ExtUtils::MakeMaker 0\n      Test::More 0\n      perl 5.004\n  Digest-HMAC-1.04\n    pathname: A/AR/ARODLAND/Digest-HMAC-1.04.tar.gz\n    provides:\n      Digest::HMAC 1.04\n      Digest::HMAC_MD5 1.04\n      Digest::HMAC_SHA1 1.04\n    requirements:\n      Digest::MD5 2\n      Digest::SHA 1\n      ExtUtils::MakeMaker 0\n      perl 5.004\n  Digest-JHash-0.10\n    pathname: S/SH/SHLOMIF/Digest-JHash-0.10.tar.gz\n    provides:\n      Digest::JHash 0.10\n    requirements:\n      DynaLoader 0\n      Exporter 0\n      ExtUtils::MakeMaker 0\n      perl 5.008\n      strict 0\n      vars 0\n      warnings 0\n  Dist-CheckConflicts-0.11\n    pathname: D/DO/DOY/Dist-CheckConflicts-0.11.tar.gz\n    provides:\n      Dist::CheckConflicts 0.11\n    requirements:\n      Carp 0\n      Exporter 0\n      ExtUtils::MakeMaker 6.30\n      Module::Runtime 0.009\n      base 0\n      strict 0\n      warnings 0\n  Encode-Locale-1.05\n    pathname: G/GA/GAAS/Encode-Locale-1.05.tar.gz\n    provides:\n      Encode::Locale 1.05\n    requirements:\n      Encode 2\n      Encode::Alias 0\n      ExtUtils::MakeMaker 0\n      perl 5.008\n  Eval-Closure-0.14\n    pathname: D/DO/DOY/Eval-Closure-0.14.tar.gz\n    provides:\n      Eval::Closure 0.14\n    requirements:\n      Carp 0\n      Exporter 0\n      ExtUtils::MakeMaker 0\n      Scalar::Util 0\n      constant 0\n      overload 0\n      strict 0\n      warnings 0\n  Exporter-Tiny-1.006002\n    pathname: T/TO/TOBYINK/Exporter-Tiny-1.006002.tar.gz\n    provides:\n      Exporter::Shiny 1.006002\n      Exporter::Tiny 1.006002\n    requirements:\n      ExtUtils::MakeMaker 6.17\n      perl 5.006001\n  ExtUtils-Config-0.008\n    pathname: L/LE/LEONT/ExtUtils-Config-0.008.tar.gz\n    provides:\n      ExtUtils::Config 0.008\n    requirements:\n      Data::Dumper 0\n      ExtUtils::MakeMaker 6.30\n      strict 0\n      warnings 0\n  ExtUtils-Helpers-0.026\n    pathname: L/LE/LEONT/ExtUtils-Helpers-0.026.tar.gz\n    provides:\n      ExtUtils::Helpers 0.026\n      ExtUtils::Helpers::Unix 0.026\n      ExtUtils::Helpers::VMS 0.026\n      ExtUtils::Helpers::Windows 0.026\n    requirements:\n      Carp 0\n      Exporter 5.57\n      ExtUtils::MakeMaker 0\n      File::Basename 0\n      File::Copy 0\n      File::Spec::Functions 0\n      Text::ParseWords 3.24\n      perl 5.006\n      strict 0\n      warnings 0\n  ExtUtils-InstallPaths-0.012\n    pathname: L/LE/LEONT/ExtUtils-InstallPaths-0.012.tar.gz\n    provides:\n      ExtUtils::InstallPaths 0.012\n    requirements:\n      Carp 0\n      ExtUtils::Config 0.002\n      ExtUtils::MakeMaker 0\n      File::Spec 0\n      perl 5.006\n      strict 0\n      warnings 0\n  File-Listing-6.16\n    pathname: P/PL/PLICEASE/File-Listing-6.16.tar.gz\n    provides:\n      File::Listing 6.16\n      File::Listing::apache 6.16\n      File::Listing::dosftp 6.16\n      File::Listing::netware 6.16\n      File::Listing::unix 6.16\n      File::Listing::vms 6.16\n    requirements:\n      Exporter 5.57\n      ExtUtils::MakeMaker 0\n      HTTP::Date 0\n      perl 5.006\n  File-Remove-1.61\n    pathname: S/SH/SHLOMIF/File-Remove-1.61.tar.gz\n    provides:\n      File::Remove 1.61\n    requirements:\n      Cwd 3.29\n      ExtUtils::MakeMaker 0\n      File::Glob 0\n      File::Path 0\n      File::Spec 3.29\n      Module::Build 0.28\n      constant 0\n      perl 5.008\n      strict 0\n      vars 0\n      warnings 0\n  HTML-Parser-3.81\n    pathname: O/OA/OALDERS/HTML-Parser-3.81.tar.gz\n    provides:\n      HTML::Entities 3.81\n      HTML::Filter 3.81\n      HTML::HeadParser 3.81\n      HTML::LinkExtor 3.81\n      HTML::Parser 3.81\n      HTML::PullParser 3.81\n      HTML::TokeParser 3.81\n    requirements:\n      Carp 0\n      Exporter 0\n      ExtUtils::MakeMaker 6.52\n      HTML::Tagset 0\n      HTTP::Headers 0\n      IO::File 0\n      URI 0\n      URI::URL 0\n      XSLoader 0\n      strict 0\n  HTML-Tagset-3.20\n    pathname: P/PE/PETDANCE/HTML-Tagset-3.20.tar.gz\n    provides:\n      HTML::Tagset 3.20\n    requirements:\n      ExtUtils::MakeMaker 0\n  HTTP-CookieJar-0.014\n    pathname: D/DA/DAGOLDEN/HTTP-CookieJar-0.014.tar.gz\n    provides:\n      HTTP::CookieJar 0.014\n      HTTP::CookieJar::LWP 0.014\n    requirements:\n      Carp 0\n      ExtUtils::MakeMaker 6.17\n      HTTP::Date 0\n      Time::Local 1.1901\n      parent 0\n      perl 5.008001\n      strict 0\n      warnings 0\n  HTTP-Cookies-6.11\n    pathname: O/OA/OALDERS/HTTP-Cookies-6.11.tar.gz\n    provides:\n      HTTP::Cookies 6.11\n      HTTP::Cookies::Microsoft 6.11\n      HTTP::Cookies::Netscape 6.11\n    requirements:\n      Carp 0\n      ExtUtils::MakeMaker 0\n      HTTP::Date 6\n      HTTP::Headers::Util 6\n      HTTP::Request 0\n      locale 0\n      perl 5.008001\n      strict 0\n  HTTP-Date-6.06\n    pathname: O/OA/OALDERS/HTTP-Date-6.06.tar.gz\n    provides:\n      HTTP::Date 6.06\n    requirements:\n      Exporter 0\n      ExtUtils::MakeMaker 0\n      Time::Local 1.28\n      Time::Zone 0\n      perl 5.006002\n      strict 0\n  HTTP-Message-6.45\n    pathname: O/OA/OALDERS/HTTP-Message-6.45.tar.gz\n    provides:\n      HTTP::Config 6.45\n      HTTP::Headers 6.45\n      HTTP::Headers::Auth 6.45\n      HTTP::Headers::ETag 6.45\n      HTTP::Headers::Util 6.45\n      HTTP::Message 6.45\n      HTTP::Request 6.45\n      HTTP::Request::Common 6.45\n      HTTP::Response 6.45\n      HTTP::Status 6.45\n    requirements:\n      Carp 0\n      Clone 0.46\n      Compress::Raw::Bzip2 0\n      Compress::Raw::Zlib 2.062\n      Encode 3.01\n      Encode::Locale 1\n      Exporter 5.57\n      ExtUtils::MakeMaker 0\n      File::Spec 0\n      HTTP::Date 6\n      IO::Compress::Bzip2 2.021\n      IO::Compress::Deflate 0\n      IO::Compress::Gzip 0\n      IO::HTML 0\n      IO::Uncompress::Inflate 0\n      IO::Uncompress::RawInflate 0\n      LWP::MediaTypes 6\n      MIME::Base64 2.1\n      MIME::QuotedPrint 0\n      URI 1.10\n      parent 0\n      perl 5.008001\n      strict 0\n      warnings 0\n  HTTP-Negotiate-6.01\n    pathname: G/GA/GAAS/HTTP-Negotiate-6.01.tar.gz\n    provides:\n      HTTP::Negotiate 6.01\n    requirements:\n      ExtUtils::MakeMaker 0\n      HTTP::Headers 6\n      perl 5.008001\n  Hash-Merge-0.302\n    pathname: H/HE/HERMES/Hash-Merge-0.302.tar.gz\n    provides:\n      Hash::Merge 0.302\n    requirements:\n      Clone::Choose 0.008\n      ExtUtils::MakeMaker 6.64\n      Scalar::Util 0\n      perl 5.008001\n  Hash-MoreUtils-0.06\n    pathname: R/RE/REHSACK/Hash-MoreUtils-0.06.tar.gz\n    provides:\n      Hash::MoreUtils 0.06\n    requirements:\n      ExtUtils::MakeMaker 0\n      perl 5.008001\n  IO-HTML-1.004\n    pathname: C/CJ/CJM/IO-HTML-1.004.tar.gz\n    provides:\n      IO::HTML 1.004\n    requirements:\n      Carp 0\n      Encode 2.10\n      Exporter 5.57\n      ExtUtils::MakeMaker 0\n      perl 5.008\n  IO-Interactive-1.025\n    pathname: B/BD/BDFOY/IO-Interactive-1.025.tar.gz\n    provides:\n      IO::Interactive 1.025\n    requirements:\n      ExtUtils::MakeMaker 6.64\n      File::Spec::Functions 0\n      perl 5.008\n  IO-Socket-SSL-2.084\n    pathname: S/SU/SULLR/IO-Socket-SSL-2.084.tar.gz\n    provides:\n      IO::Socket::SSL 2.084\n      IO::Socket::SSL::Intercept 2.056\n      IO::Socket::SSL::OCSP_Cache 2.084\n      IO::Socket::SSL::OCSP_Resolver 2.084\n      IO::Socket::SSL::PublicSuffix undef\n      IO::Socket::SSL::SSL_Context 2.084\n      IO::Socket::SSL::SSL_HANDLE 2.084\n      IO::Socket::SSL::Session_Cache 2.084\n      IO::Socket::SSL::Trace 2.084\n      IO::Socket::SSL::Utils 2.015\n    requirements:\n      ExtUtils::MakeMaker 0\n      Mozilla::CA 0\n      Net::SSLeay 1.46\n      Scalar::Util 0\n  Image-PNG-QRCode-0.10\n    pathname: B/BK/BKB/Image-PNG-QRCode-0.10.tar.gz\n    provides:\n      Image::PNG::QRCode 0.10\n    requirements:\n      ExtUtils::MakeMaker 0\n      perl 5.006001\n  JSON-4.10\n    pathname: I/IS/ISHIGAKI/JSON-4.10.tar.gz\n    provides:\n      JSON 4.10\n      JSON::Backend::PP 4.10\n    requirements:\n      ExtUtils::MakeMaker 0\n      Test::More 0\n  JSON-MaybeXS-1.004005\n    pathname: E/ET/ETHER/JSON-MaybeXS-1.004005.tar.gz\n    provides:\n      JSON::MaybeXS 1.004005\n    requirements:\n      Carp 0\n      Cpanel::JSON::XS 2.3310\n      ExtUtils::MakeMaker 0\n      JSON::PP 2.27300\n      Scalar::Util 0\n      perl 5.006\n  JSON-XS-4.03\n    pathname: M/ML/MLEHMANN/JSON-XS-4.03.tar.gz\n    provides:\n      JSON::XS 4.03\n    requirements:\n      Canary::Stability 0\n      ExtUtils::MakeMaker 6.52\n      Types::Serialiser 0\n      common::sense 0\n  LWP-MediaTypes-6.04\n    pathname: O/OA/OALDERS/LWP-MediaTypes-6.04.tar.gz\n    provides:\n      LWP::MediaTypes 6.04\n    requirements:\n      Carp 0\n      Exporter 0\n      ExtUtils::MakeMaker 0\n      File::Basename 0\n      Scalar::Util 0\n      perl 5.006002\n      strict 0\n  List-BinarySearch-0.25\n    pathname: D/DA/DAVIDO/List-BinarySearch-0.25.tar.gz\n    provides:\n      List::BinarySearch 0.25\n      List::BinarySearch::PP 0.25\n    requirements:\n      English 0\n      ExtUtils::MakeMaker 6.62\n      List::BinarySearch::XS 0\n      Scalar::Util 0\n      Test::More 0.98\n      perl 5.008000\n  List-BinarySearch-XS-0.09\n    pathname: D/DA/DAVIDO/List-BinarySearch-XS-0.09.tar.gz\n    provides:\n      List::BinarySearch::XS 0.09\n    requirements:\n      ExtUtils::MakeMaker 6.62\n      Test::More 0.98\n      perl 5.008000\n  List-MoreUtils-0.430\n    pathname: R/RE/REHSACK/List-MoreUtils-0.430.tar.gz\n    provides:\n      List::MoreUtils 0.430\n      List::MoreUtils::PP 0.430\n    requirements:\n      Exporter::Tiny 0.038\n      ExtUtils::MakeMaker 0\n      List::MoreUtils::XS 0.430\n  List-MoreUtils-XS-0.430\n    pathname: R/RE/REHSACK/List-MoreUtils-XS-0.430.tar.gz\n    provides:\n      List::MoreUtils::XS 0.430\n    requirements:\n      Carp 0\n      ExtUtils::MakeMaker 0\n      File::Basename 0\n      File::Copy 0\n      File::Path 0\n      File::Spec 0\n      IPC::Cmd 0\n      XSLoader 0.22\n      base 0\n  Locale-Maketext-Lexicon-1.00\n    pathname: D/DR/DRTECH/Locale-Maketext-Lexicon-1.00.tar.gz\n    provides:\n      Locale::Maketext::Extract 1.00\n      Locale::Maketext::Extract::Plugin::Base 1.00\n      Locale::Maketext::Extract::Plugin::FormFu 1.00\n      Locale::Maketext::Extract::Plugin::FormFu::Extractor 1.00\n      Locale::Maketext::Extract::Plugin::Generic 1.00\n      Locale::Maketext::Extract::Plugin::Haml 1.00\n      Locale::Maketext::Extract::Plugin::Mason 1.00\n      Locale::Maketext::Extract::Plugin::PPI 1.00\n      Locale::Maketext::Extract::Plugin::Perl 1.00\n      Locale::Maketext::Extract::Plugin::TT2 1.00\n      Locale::Maketext::Extract::Plugin::TT2::Directive 1.00\n      Locale::Maketext::Extract::Plugin::TT2::Parser 1.00\n      Locale::Maketext::Extract::Plugin::TextTemplate 1.00\n      Locale::Maketext::Extract::Plugin::TextTemplate::Parser 1.00\n      Locale::Maketext::Extract::Plugin::YAML 1.00\n      Locale::Maketext::Extract::Plugin::YAML::Extractor 1.00\n      Locale::Maketext::Extract::Run 1.00\n      Locale::Maketext::Lexicon 1.00\n      Locale::Maketext::Lexicon::Auto 1.00\n      Locale::Maketext::Lexicon::Gettext 1.00\n      Locale::Maketext::Lexicon::Msgcat 1.00\n      Locale::Maketext::Lexicon::Tie 1.00\n    requirements:\n      ExtUtils::MakeMaker 6.30\n      Locale::Maketext 1.17\n  Log-Any-1.717\n    pathname: P/PR/PREACTION/Log-Any-1.717.tar.gz\n    provides:\n      Log::Any 1.717\n      Log::Any::Adapter 1.717\n      Log::Any::Adapter::Base 1.717\n      Log::Any::Adapter::Capture 1.717\n      Log::Any::Adapter::File 1.717\n      Log::Any::Adapter::Multiplex 1.717\n      Log::Any::Adapter::Null 1.717\n      Log::Any::Adapter::Stderr 1.717\n      Log::Any::Adapter::Stdout 1.717\n      Log::Any::Adapter::Syslog 1.717\n      Log::Any::Adapter::Test 1.717\n      Log::Any::Adapter::Util 1.717\n      Log::Any::Manager 1.717\n      Log::Any::Proxy 1.717\n      Log::Any::Proxy::Null 1.717\n      Log::Any::Proxy::Test 1.717\n      Log::Any::Proxy::WithStackTrace 1.717\n      Log::Any::Test 1.717\n    requirements:\n      ExtUtils::MakeMaker 0\n  MRO-Compat-0.15\n    pathname: H/HA/HAARG/MRO-Compat-0.15.tar.gz\n    provides:\n      MRO::Compat 0.15\n    requirements:\n      ExtUtils::MakeMaker 0\n      perl 5.006\n  Minion-10.28\n    pathname: S/SR/SRI/Minion-10.28.tar.gz\n    provides:\n      LinkCheck undef\n      LinkCheck::Controller::Links undef\n      LinkCheck::Task::CheckLinks undef\n      Minion 10.28\n      Minion::Backend undef\n      Minion::Backend::Pg undef\n      Minion::Command::minion undef\n      Minion::Command::minion::job undef\n      Minion::Command::minion::worker undef\n      Minion::Iterator undef\n      Minion::Job undef\n      Minion::Worker undef\n      Mojolicious::Plugin::Minion undef\n      Mojolicious::Plugin::Minion::Admin undef\n    requirements:\n      ExtUtils::MakeMaker 0\n      Mojolicious 9.0\n      YAML::XS 0.67\n      perl 5.016\n  Minion-Backend-SQLite-v5.0.7\n    pathname: D/DB/DBOOK/Minion-Backend-SQLite-v5.0.7.tar.gz\n    provides:\n      Minion::Backend::SQLite v5.0.7\n    requirements:\n      List::Util 0\n      Minion 10.13\n      Module::Build::Tiny 0.034\n      Mojo::SQLite 3.000\n      Mojolicious 7.49\n      Sys::Hostname 0\n      Time::HiRes 0\n      perl 5.010001\n  Minion-Backend-mysql-1.004\n    pathname: P/PR/PREACTION/Minion-Backend-mysql-1.004.tar.gz\n    provides:\n      Minion::Backend::mysql 1.004\n    requirements:\n      ExtUtils::MakeMaker 0\n      Minion 10.13\n      Mojo::mysql 1.04\n      Mojolicious 9.0\n      perl 5.016\n  Module-Build-0.4234\n    pathname: L/LE/LEONT/Module-Build-0.4234.tar.gz\n    provides:\n      Module::Build 0.4234\n      Module::Build::Base 0.4234\n      Module::Build::Compat 0.4234\n      Module::Build::Config 0.4234\n      Module::Build::Cookbook 0.4234\n      Module::Build::Dumper 0.4234\n      Module::Build::Notes 0.4234\n      Module::Build::PPMMaker 0.4234\n      Module::Build::Platform::Default 0.4234\n      Module::Build::Platform::MacOS 0.4234\n      Module::Build::Platform::Unix 0.4234\n      Module::Build::Platform::VMS 0.4234\n      Module::Build::Platform::VOS 0.4234\n      Module::Build::Platform::Windows 0.4234\n      Module::Build::Platform::aix 0.4234\n      Module::Build::Platform::cygwin 0.4234\n      Module::Build::Platform::darwin 0.4234\n      Module::Build::Platform::os2 0.4234\n      Module::Build::PodParser 0.4234\n    requirements:\n      CPAN::Meta 2.142060\n      Cwd 0\n      Data::Dumper 0\n      ExtUtils::CBuilder 0.27\n      ExtUtils::Install 0\n      ExtUtils::Manifest 0\n      ExtUtils::Mkbootstrap 0\n      ExtUtils::ParseXS 2.21\n      File::Basename 0\n      File::Compare 0\n      File::Copy 0\n      File::Find 0\n      File::Path 0\n      File::Spec 0.82\n      Getopt::Long 0\n      Module::Metadata 1.000002\n      Perl::OSType 1\n      TAP::Harness 3.29\n      Text::Abbrev 0\n      Text::ParseWords 0\n      perl 5.006001\n      version 0.87\n  Module-Build-Tiny-0.047\n    pathname: L/LE/LEONT/Module-Build-Tiny-0.047.tar.gz\n    provides:\n      Module::Build::Tiny 0.047\n    requirements:\n      CPAN::Meta 0\n      DynaLoader 0\n      Exporter 5.57\n      ExtUtils::CBuilder 0\n      ExtUtils::Config 0.003\n      ExtUtils::Helpers 0.020\n      ExtUtils::Install 0\n      ExtUtils::InstallPaths 0.002\n      ExtUtils::ParseXS 0\n      File::Basename 0\n      File::Find 0\n      File::Path 0\n      File::Spec::Functions 0\n      Getopt::Long 2.36\n      JSON::PP 2\n      Pod::Man 0\n      TAP::Harness::Env 0\n      perl 5.006\n      strict 0\n      warnings 0\n  Module-Implementation-0.09\n    pathname: D/DR/DROLSKY/Module-Implementation-0.09.tar.gz\n    provides:\n      Module::Implementation 0.09\n    requirements:\n      Carp 0\n      ExtUtils::MakeMaker 0\n      Module::Runtime 0.012\n      Try::Tiny 0\n      strict 0\n      warnings 0\n  Module-Install-1.20-withdate\n    pathname: E/ET/ETHER/Module-Install-1.20-withdate.tar.gz\n    provides:\n      Module::AutoInstall 1.20\n      Module::Install 1.20\n      Module::Install::Admin 1.20\n      Module::Install::Admin::Bundle 1.20\n      Module::Install::Admin::Compiler 1.20\n      Module::Install::Admin::Find 1.20\n      Module::Install::Admin::Include 1.20\n      Module::Install::Admin::Makefile 1.20\n      Module::Install::Admin::Manifest 1.20\n      Module::Install::Admin::Metadata 1.20\n      Module::Install::Admin::ScanDeps 1.20\n      Module::Install::Admin::WriteAll 1.20\n      Module::Install::AutoInstall 1.20\n      Module::Install::Base 1.20\n      Module::Install::Base::FakeAdmin 1.20\n      Module::Install::Bundle 1.20\n      Module::Install::Can 1.20\n      Module::Install::Compiler 1.20\n      Module::Install::Deprecated 1.20\n      Module::Install::External 1.20\n      Module::Install::Fetch 1.20\n      Module::Install::Include 1.20\n      Module::Install::Inline 1.20\n      Module::Install::MakeMaker 1.20\n      Module::Install::Makefile 1.20\n      Module::Install::Metadata 1.20\n      Module::Install::PAR 1.20\n      Module::Install::Run 1.20\n      Module::Install::Scripts 1.20\n      Module::Install::Share 1.20\n      Module::Install::Win32 1.20\n      Module::Install::With 1.20\n      Module::Install::WriteAll 1.20\n      inc::Module::Install 1.20\n      inc::Module::Install::DSL 1.20\n    requirements:\n      Devel::PPPort 3.16\n      ExtUtils::Install 1.52\n      ExtUtils::MakeMaker 6.59\n      ExtUtils::ParseXS 2.19\n      File::Path 0\n      File::Remove 1.42\n      File::Spec 3.28\n      Module::Build 0.29\n      Module::CoreList 2.17\n      Module::ScanDeps 1.09\n      Parse::CPAN::Meta 1.4413\n      Test::Harness 3.13\n      Test::More 0.86\n      YAML::Tiny 1.38\n      autodie 0\n      perl 5.006\n  Module-Runtime-0.016\n    pathname: Z/ZE/ZEFRAM/Module-Runtime-0.016.tar.gz\n    provides:\n      Module::Runtime 0.016\n    requirements:\n      Module::Build 0\n      Test::More 0.41\n      perl 5.006\n      strict 0\n      warnings 0\n  Module-Runtime-Conflicts-0.003\n    pathname: E/ET/ETHER/Module-Runtime-Conflicts-0.003.tar.gz\n    provides:\n      Module::Runtime::Conflicts 0.003\n    requirements:\n      Dist::CheckConflicts 0\n      ExtUtils::MakeMaker 0\n      Module::Runtime 0\n      perl 5.006\n      strict 0\n      warnings 0\n  Module-ScanDeps-1.35\n    pathname: R/RS/RSCHUPP/Module-ScanDeps-1.35.tar.gz\n    provides:\n      Module::ScanDeps 1.35\n    requirements:\n      ExtUtils::MakeMaker 0\n      File::Spec 0\n      File::Temp 0\n      Getopt::Long 0\n      List::Util 1.33\n      Module::Metadata 0\n      Text::ParseWords 0\n      perl 5.008009\n      version 0\n  Mojo-Pg-4.27\n    pathname: S/SR/SRI/Mojo-Pg-4.27.tar.gz\n    provides:\n      Mojo::Pg 4.27\n      Mojo::Pg::Database undef\n      Mojo::Pg::Migrations undef\n      Mojo::Pg::PubSub undef\n      Mojo::Pg::Results undef\n      Mojo::Pg::Transaction undef\n    requirements:\n      DBD::Pg 3.007004\n      ExtUtils::MakeMaker 0\n      Mojolicious 8.50\n      SQL::Abstract::Pg 1.0\n      perl 5.016\n  Mojo-SQLite-3.009\n    pathname: D/DB/DBOOK/Mojo-SQLite-3.009.tar.gz\n    provides:\n      Mojo::SQLite 3.009\n      Mojo::SQLite::Database 3.009\n      Mojo::SQLite::Migrations 3.009\n      Mojo::SQLite::PubSub 3.009\n      Mojo::SQLite::Results 3.009\n      Mojo::SQLite::Transaction 3.009\n    requirements:\n      Carp 0\n      DBD::SQLite 1.68\n      DBI 1.627\n      File::Spec::Functions 0\n      File::Temp 0\n      Module::Build::Tiny 0.034\n      Mojolicious 8.03\n      SQL::Abstract::Pg 1.0\n      Scalar::Util 0\n      URI 1.69\n      URI::db 0.15\n      URI::file 4.21\n      perl 5.010001\n  Mojo-mysql-1.27\n    pathname: J/JH/JHTHORSEN/Mojo-mysql-1.27.tar.gz\n    provides:\n      Mojo::mysql 1.27\n      Mojo::mysql::Database undef\n      Mojo::mysql::Migrations undef\n      Mojo::mysql::PubSub undef\n      Mojo::mysql::Results undef\n      Mojo::mysql::Transaction undef\n      SQL::Abstract::mysql undef\n    requirements:\n      DBD::MariaDB 1.21\n      DBI 1.643\n      ExtUtils::MakeMaker 0\n      Mojolicious 8.03\n      SQL::Abstract 1.86\n      perl 5.016\n  Mojolicious-9.35\n    pathname: S/SR/SRI/Mojolicious-9.35.tar.gz\n    provides:\n      Mojo undef\n      Mojo::Asset undef\n      Mojo::Asset::File undef\n      Mojo::Asset::Memory undef\n      Mojo::Base undef\n      Mojo::ByteStream undef\n      Mojo::Cache undef\n      Mojo::Collection undef\n      Mojo::Content undef\n      Mojo::Content::MultiPart undef\n      Mojo::Content::Single undef\n      Mojo::Cookie undef\n      Mojo::Cookie::Request undef\n      Mojo::Cookie::Response undef\n      Mojo::DOM undef\n      Mojo::DOM::CSS undef\n      Mojo::DOM::HTML undef\n      Mojo::Date undef\n      Mojo::DynamicMethods undef\n      Mojo::EventEmitter undef\n      Mojo::Exception undef\n      Mojo::File undef\n      Mojo::Headers undef\n      Mojo::HelloWorld undef\n      Mojo::Home undef\n      Mojo::IOLoop undef\n      Mojo::IOLoop::Client undef\n      Mojo::IOLoop::Server undef\n      Mojo::IOLoop::Stream undef\n      Mojo::IOLoop::Subprocess undef\n      Mojo::IOLoop::TLS undef\n      Mojo::JSON undef\n      Mojo::JSON::Pointer undef\n      Mojo::Loader undef\n      Mojo::Log undef\n      Mojo::Message undef\n      Mojo::Message::Request undef\n      Mojo::Message::Response undef\n      Mojo::Parameters undef\n      Mojo::Path undef\n      Mojo::Promise undef\n      Mojo::Reactor undef\n      Mojo::Reactor::EV undef\n      Mojo::Reactor::Poll undef\n      Mojo::Server undef\n      Mojo::Server::CGI undef\n      Mojo::Server::Daemon undef\n      Mojo::Server::Hypnotoad undef\n      Mojo::Server::Morbo undef\n      Mojo::Server::Morbo::Backend undef\n      Mojo::Server::Morbo::Backend::Poll undef\n      Mojo::Server::PSGI undef\n      Mojo::Server::Prefork undef\n      Mojo::Template undef\n      Mojo::Transaction undef\n      Mojo::Transaction::HTTP undef\n      Mojo::Transaction::WebSocket undef\n      Mojo::URL undef\n      Mojo::Upload undef\n      Mojo::UserAgent undef\n      Mojo::UserAgent::CookieJar undef\n      Mojo::UserAgent::Proxy undef\n      Mojo::UserAgent::Server undef\n      Mojo::UserAgent::Transactor undef\n      Mojo::Util undef\n      Mojo::WebSocket undef\n      Mojolicious 9.35\n      Mojolicious::Command undef\n      Mojolicious::Command::Author::cpanify undef\n      Mojolicious::Command::Author::generate undef\n      Mojolicious::Command::Author::generate::app undef\n      Mojolicious::Command::Author::generate::dockerfile undef\n      Mojolicious::Command::Author::generate::lite_app undef\n      Mojolicious::Command::Author::generate::makefile undef\n      Mojolicious::Command::Author::generate::plugin undef\n      Mojolicious::Command::Author::inflate undef\n      Mojolicious::Command::cgi undef\n      Mojolicious::Command::daemon undef\n      Mojolicious::Command::eval undef\n      Mojolicious::Command::get undef\n      Mojolicious::Command::prefork undef\n      Mojolicious::Command::psgi undef\n      Mojolicious::Command::routes undef\n      Mojolicious::Command::version undef\n      Mojolicious::Commands undef\n      Mojolicious::Controller undef\n      Mojolicious::Lite undef\n      Mojolicious::Plugin undef\n      Mojolicious::Plugin::Config undef\n      Mojolicious::Plugin::DefaultHelpers undef\n      Mojolicious::Plugin::EPLRenderer undef\n      Mojolicious::Plugin::EPRenderer undef\n      Mojolicious::Plugin::HeaderCondition undef\n      Mojolicious::Plugin::JSONConfig undef\n      Mojolicious::Plugin::Mount undef\n      Mojolicious::Plugin::NotYAMLConfig undef\n      Mojolicious::Plugin::TagHelpers undef\n      Mojolicious::Plugins undef\n      Mojolicious::Renderer undef\n      Mojolicious::Routes undef\n      Mojolicious::Routes::Match undef\n      Mojolicious::Routes::Pattern undef\n      Mojolicious::Routes::Route undef\n      Mojolicious::Sessions undef\n      Mojolicious::Static undef\n      Mojolicious::Types undef\n      Mojolicious::Validator undef\n      Mojolicious::Validator::Validation undef\n      Test::Mojo undef\n      ojo undef\n    requirements:\n      ExtUtils::MakeMaker 0\n      IO::Socket::IP 0.37\n      Sub::Util 1.41\n      perl 5.016\n  Mojolicious-Plugin-Authentication-1.39\n    pathname: J/JJ/JJATRIA/Mojolicious-Plugin-Authentication-1.39.tar.gz\n    provides:\n      Mojolicious::Plugin::Authentication 1.39\n    requirements:\n      Exporter 0\n      ExtUtils::MakeMaker 0\n      Mojolicious 8.0\n      perl 5.016\n  Mojolicious-Plugin-CHI-0.20\n    pathname: A/AK/AKRON/Mojolicious-Plugin-CHI-0.20.tar.gz\n    provides:\n      Mojolicious::Plugin::CHI 0.20\n      Mojolicious::Plugin::CHI::chi undef\n    requirements:\n      CHI 0.58\n      Digest::JHash 0.05\n      ExtUtils::MakeMaker 0\n      Mojolicious 4.77\n      Test::Memory::Cycle 1.06\n      Test::More 0\n      Test::Output 1\n      perl 5.010001\n  Mojolicious-Plugin-CSPHeader-0.06\n    pathname: L/LD/LDIDRY/Mojolicious-Plugin-CSPHeader-0.06.tar.gz\n    provides:\n      Mojolicious::Plugin::CSPHeader 0.06\n    requirements:\n      ExtUtils::MakeMaker 0\n      Mojolicious 7.75\n  Mojolicious-Plugin-DebugDumperHelper-0.03\n    pathname: L/LD/LDIDRY/Mojolicious-Plugin-DebugDumperHelper-0.03.tar.gz\n    provides:\n      Mojolicious::Plugin::DebugDumperHelper 0.03\n    requirements:\n      ExtUtils::MakeMaker 0\n      Mojolicious 6.11\n  Mojolicious-Plugin-GzipStatic-0.04\n    pathname: L/LD/LDIDRY/Mojolicious-Plugin-GzipStatic-0.04.tar.gz\n    provides:\n      Mojolicious::Plugin::GzipStatic 0.04\n    requirements:\n      ExtUtils::MakeMaker 0\n      IO::Compress::Gzip 0\n      Mojolicious 7.75\n  Mojolicious-Plugin-I18N-1.6\n    pathname: S/SH/SHARIFULN/Mojolicious-Plugin-I18N-1.6.tar.gz\n    provides:\n      Mojolicious::Plugin::I18N 1.6\n    requirements:\n      I18N::LangTags 0.35\n      Module::Build 0.42\n      Mojolicious 5\n      Test::More 0\n      perl 5.010001\n  Mojolicious-Plugin-PgURLHelper-0.03\n    pathname: L/LD/LDIDRY/Mojolicious-Plugin-PgURLHelper-0.03.tar.gz\n    provides:\n      Mojolicious::Plugin::PgURLHelper 0.03\n    requirements:\n      ExtUtils::MakeMaker 0\n      Mojolicious 7.23\n  Mojolicious-Plugin-Piwik-2.00\n    pathname: A/AK/AKRON/Mojolicious-Plugin-Piwik-2.00.tar.gz\n    provides:\n      Mojolicious::Plugin::Piwik 2.00\n    requirements:\n      ExtUtils::MakeMaker 0\n      Mojolicious 8.02\n      Test::More 0\n      perl 5.010001\n  Mojolicious-Plugin-StaticCache-0.02\n    pathname: L/LD/LDIDRY/Mojolicious-Plugin-StaticCache-0.02.tar.gz\n    provides:\n      Mojolicious::Plugin::StaticCache 0.02\n    requirements:\n      ExtUtils::MakeMaker 0\n      Mojolicious 7.33\n  Moo-2.005005\n    pathname: H/HA/HAARG/Moo-2.005005.tar.gz\n    provides:\n      Method::Generate::Accessor undef\n      Method::Generate::BuildAll undef\n      Method::Generate::Constructor undef\n      Method::Generate::DemolishAll undef\n      Moo 2.005005\n      Moo::HandleMoose undef\n      Moo::HandleMoose::FakeConstructor undef\n      Moo::HandleMoose::FakeMetaClass undef\n      Moo::HandleMoose::_TypeMap undef\n      Moo::Object undef\n      Moo::Role 2.005005\n      Moo::_Utils undef\n      Moo::sification undef\n      oo undef\n    requirements:\n      Carp 0\n      Class::Method::Modifiers 1.10\n      Exporter 0\n      ExtUtils::MakeMaker 0\n      Role::Tiny 2.002003\n      Scalar::Util 1.00\n      Sub::Defer 2.006006\n      Sub::Quote 2.006006\n      perl 5.006\n  MooX-Types-MooseLike-0.29\n    pathname: M/MA/MATEU/MooX-Types-MooseLike-0.29.tar.gz\n    provides:\n      MooX::Types::MooseLike 0.29\n      MooX::Types::MooseLike::Base 0.29\n    requirements:\n      ExtUtils::MakeMaker 0\n      Module::Runtime 0.014\n  MooX-Types-MooseLike-Numeric-1.03\n    pathname: M/MA/MATEU/MooX-Types-MooseLike-Numeric-1.03.tar.gz\n    provides:\n      MooX::Types::MooseLike::Numeric 1.03\n    requirements:\n      ExtUtils::MakeMaker 0\n      Moo 1.004002\n      MooX::Types::MooseLike 0.23\n      Test::Fatal 0.003\n      Test::More 0.96\n  Moose-2.2206\n    pathname: E/ET/ETHER/Moose-2.2206.tar.gz\n    provides:\n      Class::MOP 2.2206\n      Class::MOP::Attribute 2.2206\n      Class::MOP::Class 2.2206\n      Class::MOP::Class::Immutable::Trait 2.2206\n      Class::MOP::Deprecated 2.2206\n      Class::MOP::Instance 2.2206\n      Class::MOP::Method 2.2206\n      Class::MOP::Method::Accessor 2.2206\n      Class::MOP::Method::Constructor 2.2206\n      Class::MOP::Method::Generated 2.2206\n      Class::MOP::Method::Inlined 2.2206\n      Class::MOP::Method::Meta 2.2206\n      Class::MOP::Method::Wrapped 2.2206\n      Class::MOP::MiniTrait 2.2206\n      Class::MOP::Mixin 2.2206\n      Class::MOP::Mixin::AttributeCore 2.2206\n      Class::MOP::Mixin::HasAttributes 2.2206\n      Class::MOP::Mixin::HasMethods 2.2206\n      Class::MOP::Mixin::HasOverloads 2.2206\n      Class::MOP::Module 2.2206\n      Class::MOP::Object 2.2206\n      Class::MOP::Overload 2.2206\n      Class::MOP::Package 2.2206\n      Moose 2.2206\n      Moose::Cookbook 2.2206\n      Moose::Cookbook::Basics::BankAccount_MethodModifiersAndSubclassing 2.2206\n      Moose::Cookbook::Basics::BinaryTree_AttributeFeatures 2.2206\n      Moose::Cookbook::Basics::BinaryTree_BuilderAndLazyBuild 2.2206\n      Moose::Cookbook::Basics::Company_Subtypes 2.2206\n      Moose::Cookbook::Basics::DateTime_ExtendingNonMooseParent 2.2206\n      Moose::Cookbook::Basics::Document_AugmentAndInner 2.2206\n      Moose::Cookbook::Basics::Genome_OverloadingSubtypesAndCoercion 2.2206\n      Moose::Cookbook::Basics::HTTP_SubtypesAndCoercion 2.2206\n      Moose::Cookbook::Basics::Immutable 2.2206\n      Moose::Cookbook::Basics::Person_BUILDARGSAndBUILD 2.2206\n      Moose::Cookbook::Basics::Point_AttributesAndSubclassing 2.2206\n      Moose::Cookbook::Extending::Debugging_BaseClassRole 2.2206\n      Moose::Cookbook::Extending::ExtensionOverview 2.2206\n      Moose::Cookbook::Extending::Mooseish_MooseSugar 2.2206\n      Moose::Cookbook::Legacy::Debugging_BaseClassReplacement 2.2206\n      Moose::Cookbook::Legacy::Labeled_AttributeMetaclass 2.2206\n      Moose::Cookbook::Legacy::Table_ClassMetaclass 2.2206\n      Moose::Cookbook::Meta::GlobRef_InstanceMetaclass 2.2206\n      Moose::Cookbook::Meta::Labeled_AttributeTrait 2.2206\n      Moose::Cookbook::Meta::PrivateOrPublic_MethodMetaclass 2.2206\n      Moose::Cookbook::Meta::Table_MetaclassTrait 2.2206\n      Moose::Cookbook::Meta::WhyMeta 2.2206\n      Moose::Cookbook::Roles::ApplicationToInstance 2.2206\n      Moose::Cookbook::Roles::Comparable_CodeReuse 2.2206\n      Moose::Cookbook::Roles::Restartable_AdvancedComposition 2.2206\n      Moose::Cookbook::Snack::Keywords 2.2206\n      Moose::Cookbook::Snack::Types 2.2206\n      Moose::Cookbook::Style 2.2206\n      Moose::Deprecated 2.2206\n      Moose::Exception 2.2206\n      Moose::Exception::AccessorMustReadWrite 2.2206\n      Moose::Exception::AddParameterizableTypeTakesParameterizableType 2.2206\n      Moose::Exception::AddRoleTakesAMooseMetaRoleInstance 2.2206\n      Moose::Exception::AddRoleToARoleTakesAMooseMetaRole 2.2206\n      Moose::Exception::ApplyTakesABlessedInstance 2.2206\n      Moose::Exception::AttachToClassNeedsAClassMOPClassInstanceOrASubclass 2.2206\n      Moose::Exception::AttributeConflictInRoles 2.2206\n      Moose::Exception::AttributeConflictInSummation 2.2206\n      Moose::Exception::AttributeExtensionIsNotSupportedInRoles 2.2206\n      Moose::Exception::AttributeIsRequired 2.2206\n      Moose::Exception::AttributeMustBeAnClassMOPMixinAttributeCoreOrSubclass 2.2206\n      Moose::Exception::AttributeNamesDoNotMatch 2.2206\n      Moose::Exception::AttributeValueIsNotAnObject 2.2206\n      Moose::Exception::AttributeValueIsNotDefined 2.2206\n      Moose::Exception::AutoDeRefNeedsArrayRefOrHashRef 2.2206\n      Moose::Exception::BadOptionFormat 2.2206\n      Moose::Exception::BothBuilderAndDefaultAreNotAllowed 2.2206\n      Moose::Exception::BuilderDoesNotExist 2.2206\n      Moose::Exception::BuilderMethodNotSupportedForAttribute 2.2206\n      Moose::Exception::BuilderMethodNotSupportedForInlineAttribute 2.2206\n      Moose::Exception::BuilderMustBeAMethodName 2.2206\n      Moose::Exception::CallingMethodOnAnImmutableInstance 2.2206\n      Moose::Exception::CallingReadOnlyMethodOnAnImmutableInstance 2.2206\n      Moose::Exception::CanExtendOnlyClasses 2.2206\n      Moose::Exception::CanOnlyConsumeRole 2.2206\n      Moose::Exception::CanOnlyWrapBlessedCode 2.2206\n      Moose::Exception::CanReblessOnlyIntoASubclass 2.2206\n      Moose::Exception::CanReblessOnlyIntoASuperclass 2.2206\n      Moose::Exception::CannotAddAdditionalTypeCoercionsToUnion 2.2206\n      Moose::Exception::CannotAddAsAnAttributeToARole 2.2206\n      Moose::Exception::CannotApplyBaseClassRolesToRole 2.2206\n      Moose::Exception::CannotAssignValueToReadOnlyAccessor 2.2206\n      Moose::Exception::CannotAugmentIfLocalMethodPresent 2.2206\n      Moose::Exception::CannotAugmentNoSuperMethod 2.2206\n      Moose::Exception::CannotAutoDerefWithoutIsa 2.2206\n      Moose::Exception::CannotAutoDereferenceTypeConstraint 2.2206\n      Moose::Exception::CannotCalculateNativeType 2.2206\n      Moose::Exception::CannotCallAnAbstractBaseMethod 2.2206\n      Moose::Exception::CannotCallAnAbstractMethod 2.2206\n      Moose::Exception::CannotCoerceAWeakRef 2.2206\n      Moose::Exception::CannotCoerceAttributeWhichHasNoCoercion 2.2206\n      Moose::Exception::CannotCreateHigherOrderTypeWithoutATypeParameter 2.2206\n      Moose::Exception::CannotCreateMethodAliasLocalMethodIsPresent 2.2206\n      Moose::Exception::CannotCreateMethodAliasLocalMethodIsPresentInClass 2.2206\n      Moose::Exception::CannotDelegateLocalMethodIsPresent 2.2206\n      Moose::Exception::CannotDelegateWithoutIsa 2.2206\n      Moose::Exception::CannotFindDelegateMetaclass 2.2206\n      Moose::Exception::CannotFindType 2.2206\n      Moose::Exception::CannotFindTypeGivenToMatchOnType 2.2206\n      Moose::Exception::CannotFixMetaclassCompatibility 2.2206\n      Moose::Exception::CannotGenerateInlineConstraint 2.2206\n      Moose::Exception::CannotInitializeMooseMetaRoleComposite 2.2206\n      Moose::Exception::CannotInlineTypeConstraintCheck 2.2206\n      Moose::Exception::CannotLocatePackageInINC 2.2206\n      Moose::Exception::CannotMakeMetaclassCompatible 2.2206\n      Moose::Exception::CannotOverrideALocalMethod 2.2206\n      Moose::Exception::CannotOverrideBodyOfMetaMethods 2.2206\n      Moose::Exception::CannotOverrideLocalMethodIsPresent 2.2206\n      Moose::Exception::CannotOverrideNoSuperMethod 2.2206\n      Moose::Exception::CannotRegisterUnnamedTypeConstraint 2.2206\n      Moose::Exception::CannotUseLazyBuildAndDefaultSimultaneously 2.2206\n      Moose::Exception::CircularReferenceInAlso 2.2206\n      Moose::Exception::ClassDoesNotHaveInitMeta 2.2206\n      Moose::Exception::ClassDoesTheExcludedRole 2.2206\n      Moose::Exception::ClassNamesDoNotMatch 2.2206\n      Moose::Exception::CloneObjectExpectsAnInstanceOfMetaclass 2.2206\n      Moose::Exception::CodeBlockMustBeACodeRef 2.2206\n      Moose::Exception::CoercingWithoutCoercions 2.2206\n      Moose::Exception::CoercionAlreadyExists 2.2206\n      Moose::Exception::CoercionNeedsTypeConstraint 2.2206\n      Moose::Exception::ConflictDetectedInCheckRoleExclusions 2.2206\n      Moose::Exception::ConflictDetectedInCheckRoleExclusionsInToClass 2.2206\n      Moose::Exception::ConstructClassInstanceTakesPackageName 2.2206\n      Moose::Exception::CouldNotCreateMethod 2.2206\n      Moose::Exception::CouldNotCreateWriter 2.2206\n      Moose::Exception::CouldNotEvalConstructor 2.2206\n      Moose::Exception::CouldNotEvalDestructor 2.2206\n      Moose::Exception::CouldNotFindTypeConstraintToCoerceFrom 2.2206\n      Moose::Exception::CouldNotGenerateInlineAttributeMethod 2.2206\n      Moose::Exception::CouldNotLocateTypeConstraintForUnion 2.2206\n      Moose::Exception::CouldNotParseType 2.2206\n      Moose::Exception::CreateMOPClassTakesArrayRefOfAttributes 2.2206\n      Moose::Exception::CreateMOPClassTakesArrayRefOfSuperclasses 2.2206\n      Moose::Exception::CreateMOPClassTakesHashRefOfMethods 2.2206\n      Moose::Exception::CreateTakesArrayRefOfRoles 2.2206\n      Moose::Exception::CreateTakesHashRefOfAttributes 2.2206\n      Moose::Exception::CreateTakesHashRefOfMethods 2.2206\n      Moose::Exception::DefaultToMatchOnTypeMustBeCodeRef 2.2206\n      Moose::Exception::DelegationToAClassWhichIsNotLoaded 2.2206\n      Moose::Exception::DelegationToARoleWhichIsNotLoaded 2.2206\n      Moose::Exception::DelegationToATypeWhichIsNotAClass 2.2206\n      Moose::Exception::DoesRequiresRoleName 2.2206\n      Moose::Exception::EnumCalledWithAnArrayRefAndAdditionalArgs 2.2206\n      Moose::Exception::EnumValuesMustBeString 2.2206\n      Moose::Exception::ExtendsMissingArgs 2.2206\n      Moose::Exception::HandlesMustBeAHashRef 2.2206\n      Moose::Exception::IllegalInheritedOptions 2.2206\n      Moose::Exception::IllegalMethodTypeToAddMethodModifier 2.2206\n      Moose::Exception::IncompatibleMetaclassOfSuperclass 2.2206\n      Moose::Exception::InitMetaRequiresClass 2.2206\n      Moose::Exception::InitializeTakesUnBlessedPackageName 2.2206\n      Moose::Exception::InstanceBlessedIntoWrongClass 2.2206\n      Moose::Exception::InstanceMustBeABlessedReference 2.2206\n      Moose::Exception::InvalidArgPassedToMooseUtilMetaRole 2.2206\n      Moose::Exception::InvalidArgumentToMethod 2.2206\n      Moose::Exception::InvalidArgumentsToTraitAliases 2.2206\n      Moose::Exception::InvalidBaseTypeGivenToCreateParameterizedTypeConstraint 2.2206\n      Moose::Exception::InvalidHandleValue 2.2206\n      Moose::Exception::InvalidHasProvidedInARole 2.2206\n      Moose::Exception::InvalidNameForType 2.2206\n      Moose::Exception::InvalidOverloadOperator 2.2206\n      Moose::Exception::InvalidRoleApplication 2.2206\n      Moose::Exception::InvalidTypeConstraint 2.2206\n      Moose::Exception::InvalidTypeGivenToCreateParameterizedTypeConstraint 2.2206\n      Moose::Exception::InvalidValueForIs 2.2206\n      Moose::Exception::IsaDoesNotDoTheRole 2.2206\n      Moose::Exception::IsaLacksDoesMethod 2.2206\n      Moose::Exception::LazyAttributeNeedsADefault 2.2206\n      Moose::Exception::Legacy 2.2206\n      Moose::Exception::MOPAttributeNewNeedsAttributeName 2.2206\n      Moose::Exception::MatchActionMustBeACodeRef 2.2206\n      Moose::Exception::MessageParameterMustBeCodeRef 2.2206\n      Moose::Exception::MetaclassIsAClassNotASubclassOfGivenMetaclass 2.2206\n      Moose::Exception::MetaclassIsARoleNotASubclassOfGivenMetaclass 2.2206\n      Moose::Exception::MetaclassIsNotASubclassOfGivenMetaclass 2.2206\n      Moose::Exception::MetaclassMustBeASubclassOfMooseMetaClass 2.2206\n      Moose::Exception::MetaclassMustBeASubclassOfMooseMetaRole 2.2206\n      Moose::Exception::MetaclassMustBeDerivedFromClassMOPClass 2.2206\n      Moose::Exception::MetaclassNotLoaded 2.2206\n      Moose::Exception::MetaclassTypeIncompatible 2.2206\n      Moose::Exception::MethodExpectedAMetaclassObject 2.2206\n      Moose::Exception::MethodExpectsFewerArgs 2.2206\n      Moose::Exception::MethodExpectsMoreArgs 2.2206\n      Moose::Exception::MethodModifierNeedsMethodName 2.2206\n      Moose::Exception::MethodNameConflictInRoles 2.2206\n      Moose::Exception::MethodNameNotFoundInInheritanceHierarchy 2.2206\n      Moose::Exception::MethodNameNotGiven 2.2206\n      Moose::Exception::MustDefineAMethodName 2.2206\n      Moose::Exception::MustDefineAnAttributeName 2.2206\n      Moose::Exception::MustDefineAnOverloadOperator 2.2206\n      Moose::Exception::MustHaveAtLeastOneValueToEnumerate 2.2206\n      Moose::Exception::MustPassAHashOfOptions 2.2206\n      Moose::Exception::MustPassAMooseMetaRoleInstanceOrSubclass 2.2206\n      Moose::Exception::MustPassAPackageNameOrAnExistingClassMOPPackageInstance 2.2206\n      Moose::Exception::MustPassEvenNumberOfArguments 2.2206\n      Moose::Exception::MustPassEvenNumberOfAttributeOptions 2.2206\n      Moose::Exception::MustProvideANameForTheAttribute 2.2206\n      Moose::Exception::MustSpecifyAtleastOneMethod 2.2206\n      Moose::Exception::MustSpecifyAtleastOneRole 2.2206\n      Moose::Exception::MustSpecifyAtleastOneRoleToApplicant 2.2206\n      Moose::Exception::MustSupplyAClassMOPAttributeInstance 2.2206\n      Moose::Exception::MustSupplyADelegateToMethod 2.2206\n      Moose::Exception::MustSupplyAMetaclass 2.2206\n      Moose::Exception::MustSupplyAMooseMetaAttributeInstance 2.2206\n      Moose::Exception::MustSupplyAnAccessorTypeToConstructWith 2.2206\n      Moose::Exception::MustSupplyAnAttributeToConstructWith 2.2206\n      Moose::Exception::MustSupplyArrayRefAsCurriedArguments 2.2206\n      Moose::Exception::MustSupplyPackageNameAndName 2.2206\n      Moose::Exception::NeedsTypeConstraintUnionForTypeCoercionUnion 2.2206\n      Moose::Exception::NeitherAttributeNorAttributeNameIsGiven 2.2206\n      Moose::Exception::NeitherClassNorClassNameIsGiven 2.2206\n      Moose::Exception::NeitherRoleNorRoleNameIsGiven 2.2206\n      Moose::Exception::NeitherTypeNorTypeNameIsGiven 2.2206\n      Moose::Exception::NoAttributeFoundInSuperClass 2.2206\n      Moose::Exception::NoBodyToInitializeInAnAbstractBaseClass 2.2206\n      Moose::Exception::NoCasesMatched 2.2206\n      Moose::Exception::NoConstraintCheckForTypeConstraint 2.2206\n      Moose::Exception::NoDestructorClassSpecified 2.2206\n      Moose::Exception::NoImmutableTraitSpecifiedForClass 2.2206\n      Moose::Exception::NoParentGivenToSubtype 2.2206\n      Moose::Exception::OnlyInstancesCanBeCloned 2.2206\n      Moose::Exception::OperatorIsRequired 2.2206\n      Moose::Exception::OverloadConflictInSummation 2.2206\n      Moose::Exception::OverloadRequiresAMetaClass 2.2206\n      Moose::Exception::OverloadRequiresAMetaMethod 2.2206\n      Moose::Exception::OverloadRequiresAMetaOverload 2.2206\n      Moose::Exception::OverloadRequiresAMethodNameOrCoderef 2.2206\n      Moose::Exception::OverloadRequiresAnOperator 2.2206\n      Moose::Exception::OverloadRequiresNamesForCoderef 2.2206\n      Moose::Exception::OverrideConflictInComposition 2.2206\n      Moose::Exception::OverrideConflictInSummation 2.2206\n      Moose::Exception::PackageDoesNotUseMooseExporter 2.2206\n      Moose::Exception::PackageNameAndNameParamsNotGivenToWrap 2.2206\n      Moose::Exception::PackagesAndModulesAreNotCachable 2.2206\n      Moose::Exception::ParameterIsNotSubtypeOfParent 2.2206\n      Moose::Exception::ReferencesAreNotAllowedAsDefault 2.2206\n      Moose::Exception::RequiredAttributeLacksInitialization 2.2206\n      Moose::Exception::RequiredAttributeNeedsADefault 2.2206\n      Moose::Exception::RequiredMethodsImportedByClass 2.2206\n      Moose::Exception::RequiredMethodsNotImplementedByClass 2.2206\n      Moose::Exception::Role::Attribute 2.2206\n      Moose::Exception::Role::AttributeName 2.2206\n      Moose::Exception::Role::Class 2.2206\n      Moose::Exception::Role::EitherAttributeOrAttributeName 2.2206\n      Moose::Exception::Role::Instance 2.2206\n      Moose::Exception::Role::InstanceClass 2.2206\n      Moose::Exception::Role::InvalidAttributeOptions 2.2206\n      Moose::Exception::Role::Method 2.2206\n      Moose::Exception::Role::ParamsHash 2.2206\n      Moose::Exception::Role::Role 2.2206\n      Moose::Exception::Role::RoleForCreate 2.2206\n      Moose::Exception::Role::RoleForCreateMOPClass 2.2206\n      Moose::Exception::Role::TypeConstraint 2.2206\n      Moose::Exception::RoleDoesTheExcludedRole 2.2206\n      Moose::Exception::RoleExclusionConflict 2.2206\n      Moose::Exception::RoleNameRequired 2.2206\n      Moose::Exception::RoleNameRequiredForMooseMetaRole 2.2206\n      Moose::Exception::RolesDoNotSupportAugment 2.2206\n      Moose::Exception::RolesDoNotSupportExtends 2.2206\n      Moose::Exception::RolesDoNotSupportInner 2.2206\n      Moose::Exception::RolesDoNotSupportRegexReferencesForMethodModifiers 2.2206\n      Moose::Exception::RolesInCreateTakesAnArrayRef 2.2206\n      Moose::Exception::RolesListMustBeInstancesOfMooseMetaRole 2.2206\n      Moose::Exception::SingleParamsToNewMustBeHashRef 2.2206\n      Moose::Exception::TriggerMustBeACodeRef 2.2206\n      Moose::Exception::TypeConstraintCannotBeUsedForAParameterizableType 2.2206\n      Moose::Exception::TypeConstraintIsAlreadyCreated 2.2206\n      Moose::Exception::TypeParameterMustBeMooseMetaType 2.2206\n      Moose::Exception::UnableToCanonicalizeHandles 2.2206\n      Moose::Exception::UnableToCanonicalizeNonRolePackage 2.2206\n      Moose::Exception::UnableToRecognizeDelegateMetaclass 2.2206\n      Moose::Exception::UndefinedHashKeysPassedToMethod 2.2206\n      Moose::Exception::UnionCalledWithAnArrayRefAndAdditionalArgs 2.2206\n      Moose::Exception::UnionTakesAtleastTwoTypeNames 2.2206\n      Moose::Exception::ValidationFailedForInlineTypeConstraint 2.2206\n      Moose::Exception::ValidationFailedForTypeConstraint 2.2206\n      Moose::Exception::WrapTakesACodeRefToBless 2.2206\n      Moose::Exception::WrongTypeConstraintGiven 2.2206\n      Moose::Exporter 2.2206\n      Moose::Intro 2.2206\n      Moose::Manual 2.2206\n      Moose::Manual::Attributes 2.2206\n      Moose::Manual::BestPractices 2.2206\n      Moose::Manual::Classes 2.2206\n      Moose::Manual::Concepts 2.2206\n      Moose::Manual::Construction 2.2206\n      Moose::Manual::Contributing 2.2206\n      Moose::Manual::Delegation 2.2206\n      Moose::Manual::Delta 2.2206\n      Moose::Manual::Exceptions 2.2206\n      Moose::Manual::Exceptions::Manifest 2.2206\n      Moose::Manual::FAQ 2.2206\n      Moose::Manual::MOP 2.2206\n      Moose::Manual::MethodModifiers 2.2206\n      Moose::Manual::MooseX 2.2206\n      Moose::Manual::Resources 2.2206\n      Moose::Manual::Roles 2.2206\n      Moose::Manual::Support 2.2206\n      Moose::Manual::Types 2.2206\n      Moose::Manual::Unsweetened 2.2206\n      Moose::Meta::Attribute 2.2206\n      Moose::Meta::Attribute::Native 2.2206\n      Moose::Meta::Attribute::Native::Trait 2.2206\n      Moose::Meta::Attribute::Native::Trait::Array 2.2206\n      Moose::Meta::Attribute::Native::Trait::Bool 2.2206\n      Moose::Meta::Attribute::Native::Trait::Code 2.2206\n      Moose::Meta::Attribute::Native::Trait::Counter 2.2206\n      Moose::Meta::Attribute::Native::Trait::Hash 2.2206\n      Moose::Meta::Attribute::Native::Trait::Number 2.2206\n      Moose::Meta::Attribute::Native::Trait::String 2.2206\n      Moose::Meta::Class 2.2206\n      Moose::Meta::Class::Immutable::Trait 2.2206\n      Moose::Meta::Instance 2.2206\n      Moose::Meta::Method 2.2206\n      Moose::Meta::Method::Accessor 2.2206\n      Moose::Meta::Method::Accessor::Native 2.2206\n      Moose::Meta::Method::Accessor::Native::Array 2.2206\n      Moose::Meta::Method::Accessor::Native::Array::Writer 2.2206\n      Moose::Meta::Method::Accessor::Native::Array::accessor 2.2206\n      Moose::Meta::Method::Accessor::Native::Array::clear 2.2206\n      Moose::Meta::Method::Accessor::Native::Array::count 2.2206\n      Moose::Meta::Method::Accessor::Native::Array::delete 2.2206\n      Moose::Meta::Method::Accessor::Native::Array::elements 2.2206\n      Moose::Meta::Method::Accessor::Native::Array::first 2.2206\n      Moose::Meta::Method::Accessor::Native::Array::first_index 2.2206\n      Moose::Meta::Method::Accessor::Native::Array::get 2.2206\n      Moose::Meta::Method::Accessor::Native::Array::grep 2.2206\n      Moose::Meta::Method::Accessor::Native::Array::insert 2.2206\n      Moose::Meta::Method::Accessor::Native::Array::is_empty 2.2206\n      Moose::Meta::Method::Accessor::Native::Array::join 2.2206\n      Moose::Meta::Method::Accessor::Native::Array::map 2.2206\n      Moose::Meta::Method::Accessor::Native::Array::natatime 2.2206\n      Moose::Meta::Method::Accessor::Native::Array::pop 2.2206\n      Moose::Meta::Method::Accessor::Native::Array::push 2.2206\n      Moose::Meta::Method::Accessor::Native::Array::reduce 2.2206\n      Moose::Meta::Method::Accessor::Native::Array::set 2.2206\n      Moose::Meta::Method::Accessor::Native::Array::shallow_clone 2.2206\n      Moose::Meta::Method::Accessor::Native::Array::shift 2.2206\n      Moose::Meta::Method::Accessor::Native::Array::shuffle 2.2206\n      Moose::Meta::Method::Accessor::Native::Array::sort 2.2206\n      Moose::Meta::Method::Accessor::Native::Array::sort_in_place 2.2206\n      Moose::Meta::Method::Accessor::Native::Array::splice 2.2206\n      Moose::Meta::Method::Accessor::Native::Array::uniq 2.2206\n      Moose::Meta::Method::Accessor::Native::Array::unshift 2.2206\n      Moose::Meta::Method::Accessor::Native::Bool::not 2.2206\n      Moose::Meta::Method::Accessor::Native::Bool::set 2.2206\n      Moose::Meta::Method::Accessor::Native::Bool::toggle 2.2206\n      Moose::Meta::Method::Accessor::Native::Bool::unset 2.2206\n      Moose::Meta::Method::Accessor::Native::Code::execute 2.2206\n      Moose::Meta::Method::Accessor::Native::Code::execute_method 2.2206\n      Moose::Meta::Method::Accessor::Native::Collection 2.2206\n      Moose::Meta::Method::Accessor::Native::Counter::Writer 2.2206\n      Moose::Meta::Method::Accessor::Native::Counter::dec 2.2206\n      Moose::Meta::Method::Accessor::Native::Counter::inc 2.2206\n      Moose::Meta::Method::Accessor::Native::Counter::reset 2.2206\n      Moose::Meta::Method::Accessor::Native::Counter::set 2.2206\n      Moose::Meta::Method::Accessor::Native::Hash 2.2206\n      Moose::Meta::Method::Accessor::Native::Hash::Writer 2.2206\n      Moose::Meta::Method::Accessor::Native::Hash::accessor 2.2206\n      Moose::Meta::Method::Accessor::Native::Hash::clear 2.2206\n      Moose::Meta::Method::Accessor::Native::Hash::count 2.2206\n      Moose::Meta::Method::Accessor::Native::Hash::defined 2.2206\n      Moose::Meta::Method::Accessor::Native::Hash::delete 2.2206\n      Moose::Meta::Method::Accessor::Native::Hash::elements 2.2206\n      Moose::Meta::Method::Accessor::Native::Hash::exists 2.2206\n      Moose::Meta::Method::Accessor::Native::Hash::get 2.2206\n      Moose::Meta::Method::Accessor::Native::Hash::is_empty 2.2206\n      Moose::Meta::Method::Accessor::Native::Hash::keys 2.2206\n      Moose::Meta::Method::Accessor::Native::Hash::kv 2.2206\n      Moose::Meta::Method::Accessor::Native::Hash::set 2.2206\n      Moose::Meta::Method::Accessor::Native::Hash::shallow_clone 2.2206\n      Moose::Meta::Method::Accessor::Native::Hash::values 2.2206\n      Moose::Meta::Method::Accessor::Native::Number::abs 2.2206\n      Moose::Meta::Method::Accessor::Native::Number::add 2.2206\n      Moose::Meta::Method::Accessor::Native::Number::div 2.2206\n      Moose::Meta::Method::Accessor::Native::Number::mod 2.2206\n      Moose::Meta::Method::Accessor::Native::Number::mul 2.2206\n      Moose::Meta::Method::Accessor::Native::Number::set 2.2206\n      Moose::Meta::Method::Accessor::Native::Number::sub 2.2206\n      Moose::Meta::Method::Accessor::Native::Reader 2.2206\n      Moose::Meta::Method::Accessor::Native::String::append 2.2206\n      Moose::Meta::Method::Accessor::Native::String::chomp 2.2206\n      Moose::Meta::Method::Accessor::Native::String::chop 2.2206\n      Moose::Meta::Method::Accessor::Native::String::clear 2.2206\n      Moose::Meta::Method::Accessor::Native::String::inc 2.2206\n      Moose::Meta::Method::Accessor::Native::String::length 2.2206\n      Moose::Meta::Method::Accessor::Native::String::match 2.2206\n      Moose::Meta::Method::Accessor::Native::String::prepend 2.2206\n      Moose::Meta::Method::Accessor::Native::String::replace 2.2206\n      Moose::Meta::Method::Accessor::Native::String::substr 2.2206\n      Moose::Meta::Method::Accessor::Native::Writer 2.2206\n      Moose::Meta::Method::Augmented 2.2206\n      Moose::Meta::Method::Constructor 2.2206\n      Moose::Meta::Method::Delegation 2.2206\n      Moose::Meta::Method::Destructor 2.2206\n      Moose::Meta::Method::Meta 2.2206\n      Moose::Meta::Method::Overridden 2.2206\n      Moose::Meta::Mixin::AttributeCore 2.2206\n      Moose::Meta::Object::Trait 2.2206\n      Moose::Meta::Role 2.2206\n      Moose::Meta::Role::Application 2.2206\n      Moose::Meta::Role::Application::RoleSummation 2.2206\n      Moose::Meta::Role::Application::ToClass 2.2206\n      Moose::Meta::Role::Application::ToInstance 2.2206\n      Moose::Meta::Role::Application::ToRole 2.2206\n      Moose::Meta::Role::Attribute 2.2206\n      Moose::Meta::Role::Composite 2.2206\n      Moose::Meta::Role::Method 2.2206\n      Moose::Meta::Role::Method::Conflicting 2.2206\n      Moose::Meta::Role::Method::Required 2.2206\n      Moose::Meta::TypeCoercion 2.2206\n      Moose::Meta::TypeCoercion::Union 2.2206\n      Moose::Meta::TypeConstraint 2.2206\n      Moose::Meta::TypeConstraint::Class 2.2206\n      Moose::Meta::TypeConstraint::DuckType 2.2206\n      Moose::Meta::TypeConstraint::Enum 2.2206\n      Moose::Meta::TypeConstraint::Parameterizable 2.2206\n      Moose::Meta::TypeConstraint::Parameterized 2.2206\n      Moose::Meta::TypeConstraint::Registry 2.2206\n      Moose::Meta::TypeConstraint::Role 2.2206\n      Moose::Meta::TypeConstraint::Union 2.2206\n      Moose::Object 2.2206\n      Moose::Role 2.2206\n      Moose::Spec::Role 2.2206\n      Moose::Unsweetened 2.2206\n      Moose::Util 2.2206\n      Moose::Util::MetaRole 2.2206\n      Moose::Util::TypeConstraints 2.2206\n      Moose::Util::TypeConstraints::Builtins 2.2206\n      Test::Moose 2.2206\n      metaclass 2.2206\n      oose 2.2206\n    requirements:\n      Carp 1.22\n      Class::Load 0.09\n      Class::Load::XS 0.01\n      Data::OptList 0.107\n      Devel::GlobalDestruction 0\n      Devel::OverloadInfo 0.005\n      Devel::StackTrace 2.03\n      Dist::CheckConflicts 0.02\n      Eval::Closure 0.04\n      ExtUtils::MakeMaker 0\n      List::Util 1.56\n      MRO::Compat 0.05\n      Module::Runtime 0.014\n      Module::Runtime::Conflicts 0.002\n      Package::DeprecationManager 0.11\n      Package::Stash 0.32\n      Package::Stash::XS 0.24\n      Params::Util 1.00\n      Scalar::Util 1.19\n      Sub::Exporter 0.980\n      Sub::Util 1.40\n      Try::Tiny 0.17\n      parent 0.223\n      strict 1.03\n      warnings 1.03\n  Mozilla-CA-20231213\n    pathname: L/LW/LWP/Mozilla-CA-20231213.tar.gz\n    provides:\n      Mozilla::CA 20231213\n    requirements:\n      ExtUtils::MakeMaker 0\n  Net-Abuse-Utils-Spamhaus-0.09\n    pathname: S/SA/SAXJAZMAN/net/Net-Abuse-Utils-Spamhaus-0.09.tar.gz\n    provides:\n      Net::Abuse::Utils::Spamhaus 0.09\n    requirements:\n      ExtUtils::MakeMaker 6.59\n      Net::DNS 0.74\n      perl 5.008008\n  Net-DNS-1.41\n    pathname: N/NL/NLNETLABS/Net-DNS-1.41.tar.gz\n    provides:\n      Net::DNS 1.41\n      Net::DNS::Domain 1913\n      Net::DNS::DomainName 1898\n      Net::DNS::DomainName1035 1898\n      Net::DNS::DomainName2535 1898\n      Net::DNS::Header 1910\n      Net::DNS::Mailbox 1910\n      Net::DNS::Mailbox1035 1910\n      Net::DNS::Mailbox2535 1910\n      Net::DNS::Nameserver 1949\n      Net::DNS::Packet 1947\n      Net::DNS::Parameters 1945\n      Net::DNS::Question 1895\n      Net::DNS::RR 1910\n      Net::DNS::RR::A 1896\n      Net::DNS::RR::AAAA 1896\n      Net::DNS::RR::AFSDB 1945\n      Net::DNS::RR::AMTRELAY 1896\n      Net::DNS::RR::APL 1896\n      Net::DNS::RR::APL::Item 1896\n      Net::DNS::RR::CAA 1910\n      Net::DNS::RR::CDNSKEY 1909\n      Net::DNS::RR::CDS 1909\n      Net::DNS::RR::CERT 1896\n      Net::DNS::RR::CNAME 1896\n      Net::DNS::RR::CSYNC 1910\n      Net::DNS::RR::DHCID 1896\n      Net::DNS::RR::DNAME 1896\n      Net::DNS::RR::DNSKEY 1910\n      Net::DNS::RR::DS 1909\n      Net::DNS::RR::EUI48 1896\n      Net::DNS::RR::EUI64 1896\n      Net::DNS::RR::GPOS 1910\n      Net::DNS::RR::HINFO 1896\n      Net::DNS::RR::HIP 1896\n      Net::DNS::RR::HTTPS 1945\n      Net::DNS::RR::IPSECKEY 1909\n      Net::DNS::RR::ISDN 1896\n      Net::DNS::RR::KEY 1896\n      Net::DNS::RR::KX 1945\n      Net::DNS::RR::L32 1896\n      Net::DNS::RR::L64 1896\n      Net::DNS::RR::LOC 1896\n      Net::DNS::RR::LP 1896\n      Net::DNS::RR::MB 1910\n      Net::DNS::RR::MG 1910\n      Net::DNS::RR::MINFO 1896\n      Net::DNS::RR::MR 1910\n      Net::DNS::RR::MX 1945\n      Net::DNS::RR::NAPTR 1898\n      Net::DNS::RR::NID 1896\n      Net::DNS::RR::NS 1896\n      Net::DNS::RR::NSEC 1945\n      Net::DNS::RR::NSEC3 1910\n      Net::DNS::RR::NSEC3PARAM 1896\n      Net::DNS::RR::NULL 1896\n      Net::DNS::RR::OPENPGPKEY 1896\n      Net::DNS::RR::OPT 1934\n      Net::DNS::RR::OPT::CHAIN 1934\n      Net::DNS::RR::OPT::CLIENT_SUBNET 1934\n      Net::DNS::RR::OPT::COOKIE 1934\n      Net::DNS::RR::OPT::DAU 1934\n      Net::DNS::RR::OPT::DHU 1934\n      Net::DNS::RR::OPT::EXPIRE 1934\n      Net::DNS::RR::OPT::EXTENDED_ERROR 1934\n      Net::DNS::RR::OPT::KEY_TAG 1934\n      Net::DNS::RR::OPT::N3U 1934\n      Net::DNS::RR::OPT::NSID 1934\n      Net::DNS::RR::OPT::PADDING 1934\n      Net::DNS::RR::OPT::REPORT_CHANNEL 1934\n      Net::DNS::RR::OPT::TCP_KEEPALIVE 1934\n      Net::DNS::RR::PTR 1896\n      Net::DNS::RR::PX 1945\n      Net::DNS::RR::RP 1945\n      Net::DNS::RR::RRSIG 1896\n      Net::DNS::RR::RT 1945\n      Net::DNS::RR::SIG 1908\n      Net::DNS::RR::SMIMEA 1896\n      Net::DNS::RR::SOA 1945\n      Net::DNS::RR::SPF 1896\n      Net::DNS::RR::SRV 1945\n      Net::DNS::RR::SSHFP 1896\n      Net::DNS::RR::SVCB 1945\n      Net::DNS::RR::TKEY 1908\n      Net::DNS::RR::TLSA 1896\n      Net::DNS::RR::TSIG 1909\n      Net::DNS::RR::TXT 1911\n      Net::DNS::RR::URI 1896\n      Net::DNS::RR::X25 1896\n      Net::DNS::RR::ZONEMD 1896\n      Net::DNS::Resolver 1895\n      Net::DNS::Resolver::Base 1947\n      Net::DNS::Resolver::MSWin32 1856\n      Net::DNS::Resolver::Recurse 1930\n      Net::DNS::Resolver::UNIX 1856\n      Net::DNS::Resolver::android 1856\n      Net::DNS::Resolver::cygwin 1856\n      Net::DNS::Resolver::os2 1856\n      Net::DNS::Resolver::os390 1856\n      Net::DNS::Text 1894\n      Net::DNS::Update 1895\n      Net::DNS::ZoneFile 1910\n      Net::DNS::ZoneFile::Generator 1910\n      Net::DNS::ZoneFile::Text 1910\n    requirements:\n      Carp 1.1\n      Digest::HMAC 1.03\n      Digest::MD5 2.13\n      Digest::SHA 5.23\n      Encode 2.26\n      Exporter 5.63\n      ExtUtils::MakeMaker 6.48\n      File::Spec 3.29\n      Getopt::Long 2.43\n      IO::File 1.14\n      IO::Select 1.17\n      IO::Socket 1.3\n      IO::Socket::IP 0.38\n      MIME::Base64 2.13\n      PerlIO 1.05\n      Scalar::Util 1.19\n      Time::Local 1.19\n      perl 5.008009\n  Net-Domain-TLD-1.75\n    pathname: A/AL/ALEXP/Net-Domain-TLD-1.75.tar.gz\n    provides:\n      Net::Domain::TLD 1.75\n    requirements:\n      Carp 0\n      ExtUtils::MakeMaker 0\n      Storable 0\n  Net-Google-SafeBrowsing4-0.8\n    pathname: J/JS/JSOBRIER/Net-Google-SafeBrowsing4-0.8.tar.gz\n    provides:\n      Net::Google::SafeBrowsing4 0.8\n      Net::Google::SafeBrowsing4::Storage 0.3\n      Net::Google::SafeBrowsing4::Storage::File 0.4\n      Net::Google::SafeBrowsing4::URI undef\n    requirements:\n      Carp 0\n      Digest::SHA 0\n      Exporter 0\n      ExtUtils::MakeMaker 0\n      HTTP::Message 0\n      JSON::XS 0\n      LWP::UserAgent 0\n      List::BinarySearch 0\n      List::Util 0\n      MIME::Base64 0\n      Net::IP::Lite 0\n      Path::Tiny 0\n      Storable 0\n      Test::LWP::UserAgent 0\n      Test::More 0.92\n      Test::Pod::Coverage 0\n      Text::Trim 0\n      Time::HiRes 0\n      URI 1.61\n      constant 0\n  Net-HTTP-6.23\n    pathname: O/OA/OALDERS/Net-HTTP-6.23.tar.gz\n    provides:\n      Net::HTTP 6.23\n      Net::HTTP::Methods 6.23\n      Net::HTTP::NB 6.23\n      Net::HTTPS 6.23\n    requirements:\n      Carp 0\n      Compress::Raw::Zlib 0\n      ExtUtils::MakeMaker 0\n      IO::Socket::INET 0\n      IO::Uncompress::Gunzip 0\n      URI 0\n      base 0\n      perl 5.006002\n      strict 0\n      warnings 0\n  Net-IP-Lite-0.03\n    pathname: A/AL/ALEXKOM/Net-IP-Lite-0.03.tar.gz\n    provides:\n      Net::IP::Lite 0.03\n      Net::IP::Lite::Net 0.03\n    requirements:\n      ExtUtils::MakeMaker 0\n      Test::Exception 0\n      Test::More 0\n  Net-SSLeay-1.92\n    pathname: C/CH/CHRISN/Net-SSLeay-1.92.tar.gz\n    provides:\n      Net::SSLeay 1.92\n      Net::SSLeay::Handle 1.92\n    requirements:\n      English 0\n      ExtUtils::MakeMaker 0\n      File::Spec::Functions 0\n      MIME::Base64 0\n      Text::Wrap 0\n      constant 0\n      perl 5.008001\n  NetAddr-IP-4.079\n    pathname: M/MI/MIKER/NetAddr-IP-4.079.tar.gz\n    provides:\n      NetAddr::IP 4.079\n      NetAddr::IP::InetBase 0.08\n      NetAddr::IP::Lite 1.57\n      NetAddr::IP::Util 1.53\n      NetAddr::IP::UtilPP 1.09\n      NetAddr::IP::UtilPolluted 1.53\n      NetAddr::IP::Util_IS 1\n    requirements:\n      ExtUtils::MakeMaker 0\n      Test::More 0\n  Package-DeprecationManager-0.18\n    pathname: D/DR/DROLSKY/Package-DeprecationManager-0.18.tar.gz\n    provides:\n      Package::DeprecationManager 0.18\n    requirements:\n      Carp 0\n      ExtUtils::MakeMaker 0\n      List::Util 1.33\n      Package::Stash 0\n      Params::Util 0\n      Sub::Install 0\n      Sub::Util 0\n      strict 0\n      warnings 0\n  Package-Stash-0.40\n    pathname: E/ET/ETHER/Package-Stash-0.40.tar.gz\n    provides:\n      Package::Stash 0.40\n      Package::Stash::PP 0.40\n    requirements:\n      B 0\n      Carp 0\n      Dist::CheckConflicts 0.02\n      ExtUtils::MakeMaker 0\n      Getopt::Long 0\n      Module::Implementation 0.06\n      Package::Stash::XS 0.26\n      Scalar::Util 0\n      Symbol 0\n      Text::ParseWords 0\n      constant 0\n      perl 5.008001\n      strict 0\n      warnings 0\n  Package-Stash-XS-0.30\n    pathname: E/ET/ETHER/Package-Stash-XS-0.30.tar.gz\n    provides:\n      Package::Stash::XS 0.30\n    requirements:\n      ExtUtils::MakeMaker 0\n      XSLoader 0\n      perl 5.008001\n      strict 0\n      warnings 0\n  PadWalker-2.5\n    pathname: R/RO/ROBIN/PadWalker-2.5.tar.gz\n    provides:\n      PadWalker 2.5\n    requirements:\n      ExtUtils::MakeMaker 0\n      perl 5.008001\n  Params-Util-1.102\n    pathname: R/RE/REHSACK/Params-Util-1.102.tar.gz\n    provides:\n      Params::Util 1.102\n      Params::Util::PP 1.102\n    requirements:\n      Carp 0\n      ExtUtils::MakeMaker 0\n      File::Basename 0\n      File::Copy 0\n      File::Path 0\n      File::Spec 0\n      IPC::Cmd 0\n      Scalar::Util 1.18\n      XSLoader 0.22\n      parent 0\n  Path-Tiny-0.144\n    pathname: D/DA/DAGOLDEN/Path-Tiny-0.144.tar.gz\n    provides:\n      Path::Tiny 0.144\n      Path::Tiny::Error 0.144\n    requirements:\n      Carp 0\n      Cwd 0\n      Digest 1.03\n      Digest::SHA 5.45\n      Encode 0\n      Exporter 5.57\n      ExtUtils::MakeMaker 6.17\n      Fcntl 0\n      File::Compare 0\n      File::Copy 0\n      File::Glob 0\n      File::Path 2.07\n      File::Spec 0.86\n      File::Temp 0.19\n      File::stat 0\n      constant 0\n      overload 0\n      perl 5.008001\n      strict 0\n      warnings 0\n      warnings::register 0\n  Pod-Coverage-0.23\n    pathname: R/RC/RCLAMP/Pod-Coverage-0.23.tar.gz\n    provides:\n      Pod::Coverage 0.23\n      Pod::Coverage::CountParents undef\n      Pod::Coverage::ExportOnly undef\n      Pod::Coverage::Extractor 0.23\n      Pod::Coverage::Overloader undef\n    requirements:\n      Devel::Symdump 2.01\n      ExtUtils::MakeMaker 0\n      Pod::Find 0.21\n      Pod::Parser 1.13\n      Test::More 0\n  Pod-Parser-1.66\n    pathname: M/MA/MAREKR/Pod-Parser-1.66.tar.gz\n    provides:\n      Pod::Cache 1.66\n      Pod::Cache::Item 1.66\n      Pod::Find 1.66\n      Pod::Hyperlink 1.66\n      Pod::InputObjects 1.66\n      Pod::InputSource 1.66\n      Pod::InteriorSequence 1.66\n      Pod::List 1.66\n      Pod::Paragraph 1.66\n      Pod::ParseTree 1.66\n      Pod::ParseUtils 1.66\n      Pod::Parser 1.66\n      Pod::PlainText 2.07\n      Pod::Select 1.66\n    requirements:\n      Cwd 0\n      ExtUtils::MakeMaker 0\n      File::Basename 0\n      Test::More 0.6\n  Role-Tiny-2.002004\n    pathname: H/HA/HAARG/Role-Tiny-2.002004.tar.gz\n    provides:\n      Role::Tiny 2.002004\n      Role::Tiny::With 2.002004\n    requirements:\n      Exporter 5.57\n      perl 5.006\n  SQL-Abstract-2.000001\n    pathname: M/MS/MSTROUT/SQL-Abstract-2.000001.tar.gz\n    provides:\n      Chunkstrumenter undef\n      DBIx::Class::SQLMaker::Role::SQLA2Passthrough undef\n      SQL::Abstract 2.000001\n      SQL::Abstract::Formatter undef\n      SQL::Abstract::Parts undef\n      SQL::Abstract::Plugin::BangOverrides undef\n      SQL::Abstract::Plugin::ExtraClauses undef\n      SQL::Abstract::Reference undef\n      SQL::Abstract::Role::Plugin undef\n      SQL::Abstract::Test undef\n      SQL::Abstract::Tree undef\n    requirements:\n      Exporter 5.57\n      ExtUtils::MakeMaker 0\n      Hash::Merge 0.12\n      List::Util 0\n      MRO::Compat 0.12\n      Moo 2.000001\n      Scalar::Util 0\n      Sub::Quote 2.000001\n      Test::Builder::Module 0.84\n      Test::Deep 0.101\n      Text::Balanced 2.00\n      perl 5.006\n  SQL-Abstract-Pg-1.0\n    pathname: S/SR/SRI/SQL-Abstract-Pg-1.0.tar.gz\n    provides:\n      SQL::Abstract::Pg 1.0\n    requirements:\n      ExtUtils::MakeMaker 0\n      SQL::Abstract 2.0\n      perl 5.016\n  Safe-Isa-1.000010\n    pathname: E/ET/ETHER/Safe-Isa-1.000010.tar.gz\n    provides:\n      Safe::Isa 1.000010\n    requirements:\n      Exporter 5.57\n      ExtUtils::MakeMaker 0\n      Scalar::Util 0\n      perl 5.006\n  String-CRC32-2.100\n    pathname: L/LE/LEEJO/String-CRC32-2.100.tar.gz\n    provides:\n      String::CRC32 2.100\n    requirements:\n      ExtUtils::MakeMaker 0\n  String-RewritePrefix-0.009\n    pathname: R/RJ/RJBS/String-RewritePrefix-0.009.tar.gz\n    provides:\n      String::RewritePrefix 0.009\n    requirements:\n      Carp 0\n      ExtUtils::MakeMaker 6.78\n      Sub::Exporter 0.972\n      perl 5.012\n      strict 0\n      warnings 0\n  Sub-Exporter-0.991\n    pathname: R/RJ/RJBS/Sub-Exporter-0.991.tar.gz\n    provides:\n      Sub::Exporter 0.991\n      Sub::Exporter::Util 0.991\n    requirements:\n      Carp 0\n      Data::OptList 0.100\n      ExtUtils::MakeMaker 6.78\n      Params::Util 0.14\n      Sub::Install 0.92\n      perl 5.012\n      strict 0\n      warnings 0\n  Sub-Exporter-Progressive-0.001013\n    pathname: F/FR/FREW/Sub-Exporter-Progressive-0.001013.tar.gz\n    provides:\n      Sub::Exporter::Progressive 0.001013\n    requirements:\n      ExtUtils::MakeMaker 0\n  Sub-Install-0.929\n    pathname: R/RJ/RJBS/Sub-Install-0.929.tar.gz\n    provides:\n      Sub::Install 0.929\n    requirements:\n      B 0\n      Carp 0\n      ExtUtils::MakeMaker 6.78\n      Scalar::Util 0\n      perl 5.008000\n      strict 0\n      warnings 0\n  Sub-Quote-2.006008\n    pathname: H/HA/HAARG/Sub-Quote-2.006008.tar.gz\n    provides:\n      Sub::Defer 2.006008\n      Sub::Quote 2.006008\n    requirements:\n      ExtUtils::MakeMaker 0\n      Scalar::Util 0\n      perl 5.006\n  Sub-Uplevel-0.2800\n    pathname: D/DA/DAGOLDEN/Sub-Uplevel-0.2800.tar.gz\n    provides:\n      Sub::Uplevel 0.2800\n    requirements:\n      Carp 0\n      ExtUtils::MakeMaker 6.17\n      constant 0\n      perl 5.006\n      strict 0\n      warnings 0\n  Task-Weaken-1.06\n    pathname: E/ET/ETHER/Task-Weaken-1.06.tar.gz\n    provides:\n      Task::Weaken 1.06\n    requirements:\n      Config 0\n      ExtUtils::MakeMaker 0\n      File::Spec 0\n      Scalar::Util 1.14\n      perl 5.006\n      strict 0\n  Term-ProgressBar-2.23\n    pathname: M/MA/MANWAR/Term-ProgressBar-2.23.tar.gz\n    provides:\n      Term::ProgressBar 2.23\n      Term::ProgressBar::IO 2.23\n    requirements:\n      Capture::Tiny 0.13\n      Carp 0\n      Class::MethodMaker 1.02\n      ExtUtils::MakeMaker 0\n      Fatal 0\n      File::Temp 0\n      POSIX 0\n      Term::ReadKey 2.14\n      Test::Exception 0.31\n      Test::More 0.80\n      Test::Warnings 0\n      perl 5.006\n  Term-ProgressBar-Quiet-0.31\n    pathname: L/LB/LBROCARD/Term-ProgressBar-Quiet-0.31.tar.gz\n    provides:\n      Term::ProgressBar::Quiet 0.31\n    requirements:\n      ExtUtils::MakeMaker 0\n      IO::Interactive 0\n      Term::ProgressBar 0\n      Test::MockObject 0\n      Test::More 0\n  TermReadKey-2.38\n    pathname: J/JS/JSTOWE/TermReadKey-2.38.tar.gz\n    provides:\n      Term::ReadKey 2.38\n    requirements:\n      ExtUtils::MakeMaker 6.58\n  Test-Deep-1.204\n    pathname: R/RJ/RJBS/Test-Deep-1.204.tar.gz\n    provides:\n      Test::Deep 1.204\n      Test::Deep::All 1.204\n      Test::Deep::Any 1.204\n      Test::Deep::Array 1.204\n      Test::Deep::ArrayEach 1.204\n      Test::Deep::ArrayElementsOnly 1.204\n      Test::Deep::ArrayLength 1.204\n      Test::Deep::ArrayLengthOnly 1.204\n      Test::Deep::Blessed 1.204\n      Test::Deep::Boolean 1.204\n      Test::Deep::Cache 1.204\n      Test::Deep::Cache::Simple 1.204\n      Test::Deep::Class 1.204\n      Test::Deep::Cmp 1.204\n      Test::Deep::Code 1.204\n      Test::Deep::Hash 1.204\n      Test::Deep::HashEach 1.204\n      Test::Deep::HashElements 1.204\n      Test::Deep::HashKeys 1.204\n      Test::Deep::HashKeysOnly 1.204\n      Test::Deep::Ignore 1.204\n      Test::Deep::Isa 1.204\n      Test::Deep::ListMethods 1.204\n      Test::Deep::MM 1.204\n      Test::Deep::Methods 1.204\n      Test::Deep::NoTest 1.204\n      Test::Deep::None 1.204\n      Test::Deep::Number 1.204\n      Test::Deep::Obj 1.204\n      Test::Deep::Ref 1.204\n      Test::Deep::RefType 1.204\n      Test::Deep::Regexp 1.204\n      Test::Deep::RegexpMatches 1.204\n      Test::Deep::RegexpOnly 1.204\n      Test::Deep::RegexpRef 1.204\n      Test::Deep::RegexpRefOnly 1.204\n      Test::Deep::RegexpVersion 1.204\n      Test::Deep::ScalarRef 1.204\n      Test::Deep::ScalarRefOnly 1.204\n      Test::Deep::Set 1.204\n      Test::Deep::Shallow 1.204\n      Test::Deep::Stack 1.204\n      Test::Deep::String 1.204\n      Test::Deep::SubHash 1.204\n      Test::Deep::SubHashElements 1.204\n      Test::Deep::SubHashKeys 1.204\n      Test::Deep::SubHashKeysOnly 1.204\n      Test::Deep::SuperHash 1.204\n      Test::Deep::SuperHashElements 1.204\n      Test::Deep::SuperHashKeys 1.204\n      Test::Deep::SuperHashKeysOnly 1.204\n    requirements:\n      ExtUtils::MakeMaker 6.78\n      List::Util 1.09\n      Scalar::Util 1.09\n      Test::Builder 0\n      Test::More 0.96\n      perl 5.012\n  Test-Exception-0.43\n    pathname: E/EX/EXODIST/Test-Exception-0.43.tar.gz\n    provides:\n      Test::Exception 0.43\n    requirements:\n      Carp 0\n      Exporter 0\n      ExtUtils::MakeMaker 0\n      Sub::Uplevel 0.18\n      Test::Builder 0.7\n      Test::Builder::Tester 1.07\n      Test::Harness 2.03\n      base 0\n      perl 5.006001\n      strict 0\n      warnings 0\n  Test-Fatal-0.017\n    pathname: R/RJ/RJBS/Test-Fatal-0.017.tar.gz\n    provides:\n      Test::Fatal 0.017\n    requirements:\n      Carp 0\n      Exporter 5.57\n      ExtUtils::MakeMaker 6.78\n      Test::Builder 0\n      Try::Tiny 0.07\n      strict 0\n      warnings 0\n  Test-LWP-UserAgent-0.036\n    pathname: E/ET/ETHER/Test-LWP-UserAgent-0.036.tar.gz\n    provides:\n      Test::LWP::UserAgent 0.036\n    requirements:\n      CPAN::Meta::Requirements 2.120620\n      Carp 0\n      ExtUtils::MakeMaker 0\n      HTTP::Date 0\n      HTTP::Request 0\n      HTTP::Response 0\n      HTTP::Status 0\n      LWP::UserAgent 0\n      Module::Metadata 0\n      Safe::Isa 0\n      Scalar::Util 0\n      Storable 0\n      Try::Tiny 0\n      URI 1.62\n      namespace::clean 0.19\n      parent 0\n      perl 5.006\n      strict 0\n      warnings 0\n  Test-Memory-Cycle-1.06\n    pathname: P/PE/PETDANCE/Test-Memory-Cycle-1.06.tar.gz\n    provides:\n      Test::Memory::Cycle 1.06\n    requirements:\n      Devel::Cycle 1.07\n      ExtUtils::MakeMaker 0\n      Getopt::Long 0\n      PadWalker 0\n      Test::Builder 0\n      Test::Builder::Tester 0\n      Test::More 0\n      Test::Simple 0.62\n  Test-MockObject-1.20200122\n    pathname: C/CH/CHROMATIC/Test-MockObject-1.20200122.tar.gz\n    provides:\n      Test::MockObject 1.20200122\n      Test::MockObject::Extends 1.20200122\n    requirements:\n      Carp 0\n      Devel::Peek 0\n      ExtUtils::MakeMaker 0\n      Scalar::Util 0\n      Test::Builder 0\n      UNIVERSAL::can 1.20110617\n      UNIVERSAL::isa 1.20110614\n      constant 0\n      perl 5.008\n      strict 0\n      warnings 0\n  Test-Output-1.034\n    pathname: B/BD/BDFOY/Test-Output-1.034.tar.gz\n    provides:\n      Test::Output 1.034\n    requirements:\n      Capture::Tiny 0.17\n      ExtUtils::MakeMaker 6.64\n      File::Spec::Functions 0\n      File::Temp 0.17\n      perl 5.008\n  Test-Pod-Coverage-1.10\n    pathname: N/NE/NEILB/Test-Pod-Coverage-1.10.tar.gz\n    provides:\n      Test::Pod::Coverage 1.10\n    requirements:\n      ExtUtils::MakeMaker 0\n      Pod::Coverage 0\n      Test::Builder 0\n      perl 5.006\n      strict 0\n      warnings 0\n  Test-Warnings-0.032\n    pathname: E/ET/ETHER/Test-Warnings-0.032.tar.gz\n    provides:\n      Test::Warnings 0.032\n    requirements:\n      Carp 0\n      Exporter 0\n      ExtUtils::MakeMaker 0\n      Test::Builder 0\n      parent 0\n      perl 5.006\n      strict 0\n      warnings 0\n  Text-Soundex-3.05\n    pathname: R/RJ/RJBS/Text-Soundex-3.05.tar.gz\n    provides:\n      Text::Soundex 3.05\n    requirements:\n      ExtUtils::MakeMaker 0\n      if 0\n  Text-Trim-1.04\n    pathname: R/RJ/RJT/Text-Trim-1.04.tar.gz\n    provides:\n      Text::Trim 1.04\n    requirements:\n      ExtUtils::MakeMaker 0\n      perl 5.006\n  Time-Duration-1.21\n    pathname: N/NE/NEILB/Time-Duration-1.21.tar.gz\n    provides:\n      Time::Duration 1.21\n    requirements:\n      Exporter 0\n      ExtUtils::MakeMaker 0\n      constant 0\n      perl 5.006\n      strict 0\n      warnings 0\n  Time-Duration-Parse-0.16\n    pathname: N/NE/NEILB/Time-Duration-Parse-0.16.tar.gz\n    provides:\n      Time::Duration::Parse 0.16\n    requirements:\n      Carp 0\n      Exporter 5.57\n      ExtUtils::MakeMaker 0\n      perl 5.006\n      strict 0\n      warnings 0\n  TimeDate-2.33\n    pathname: A/AT/ATOOMIC/TimeDate-2.33.tar.gz\n    provides:\n      Date::Format 2.24\n      Date::Format::Generic 2.24\n      Date::Language 1.10\n      Date::Language::Afar 0.99\n      Date::Language::Amharic 1.00\n      Date::Language::Austrian 1.01\n      Date::Language::Brazilian 1.01\n      Date::Language::Bulgarian 1.01\n      Date::Language::Chinese 1.00\n      Date::Language::Chinese_GB 1.01\n      Date::Language::Czech 1.01\n      Date::Language::Danish 1.01\n      Date::Language::Dutch 1.02\n      Date::Language::English 1.01\n      Date::Language::Finnish 1.01\n      Date::Language::French 1.04\n      Date::Language::Gedeo 0.99\n      Date::Language::German 1.02\n      Date::Language::Greek 1.00\n      Date::Language::Hungarian 1.01\n      Date::Language::Icelandic 1.01\n      Date::Language::Italian 1.01\n      Date::Language::Norwegian 1.01\n      Date::Language::Occitan 1.04\n      Date::Language::Oromo 0.99\n      Date::Language::Romanian 1.01\n      Date::Language::Russian 1.01\n      Date::Language::Russian_cp1251 1.01\n      Date::Language::Russian_koi8r 1.01\n      Date::Language::Sidama 0.99\n      Date::Language::Somali 0.99\n      Date::Language::Spanish 1.00\n      Date::Language::Swedish 1.01\n      Date::Language::Tigrinya 1.00\n      Date::Language::TigrinyaEritrean 1.00\n      Date::Language::TigrinyaEthiopian 1.00\n      Date::Language::Turkish 1.0\n      Date::Parse 2.33\n      Time::Zone 2.24\n      TimeDate 1.21\n    requirements:\n      ExtUtils::MakeMaker 0\n  Try-Tiny-0.31\n    pathname: E/ET/ETHER/Try-Tiny-0.31.tar.gz\n    provides:\n      Try::Tiny 0.31\n    requirements:\n      Carp 0\n      Exporter 5.57\n      ExtUtils::MakeMaker 0\n      constant 0\n      perl 5.006\n      strict 0\n      warnings 0\n  Types-Serialiser-1.01\n    pathname: M/ML/MLEHMANN/Types-Serialiser-1.01.tar.gz\n    provides:\n      JSON::PP::Boolean 1.01\n      Types::Serialiser 1.01\n      Types::Serialiser::BooleanBase 1.01\n      Types::Serialiser::Error 1.01\n    requirements:\n      ExtUtils::MakeMaker 0\n      common::sense 0\n  UNIVERSAL-can-1.20140328\n    pathname: C/CH/CHROMATIC/UNIVERSAL-can-1.20140328.tar.gz\n    provides:\n      UNIVERSAL::can 1.20140328\n    requirements:\n      ExtUtils::MakeMaker 6.30\n      Scalar::Util 0\n      strict 0\n      vars 0\n      warnings 0\n      warnings::register 0\n  UNIVERSAL-isa-1.20171012\n    pathname: E/ET/ETHER/UNIVERSAL-isa-1.20171012.tar.gz\n    provides:\n      UNIVERSAL::isa 1.20171012\n    requirements:\n      ExtUtils::MakeMaker 0\n      Scalar::Util 0\n      perl 5.006002\n      strict 0\n      warnings 0\n      warnings::register 0\n  URI-5.21\n    pathname: O/OA/OALDERS/URI-5.21.tar.gz\n    provides:\n      URI 5.21\n      URI::Escape 5.21\n      URI::Heuristic 5.21\n      URI::IRI 5.21\n      URI::QueryParam 5.21\n      URI::Split 5.21\n      URI::URL 5.21\n      URI::WithBase 5.21\n      URI::data 5.21\n      URI::file 5.21\n      URI::file::Base 5.21\n      URI::file::FAT 5.21\n      URI::file::Mac 5.21\n      URI::file::OS2 5.21\n      URI::file::QNX 5.21\n      URI::file::Unix 5.21\n      URI::file::Win32 5.21\n      URI::ftp 5.21\n      URI::gopher 5.21\n      URI::http 5.21\n      URI::https 5.21\n      URI::icap 5.21\n      URI::icaps 5.21\n      URI::ldap 5.21\n      URI::ldapi 5.21\n      URI::ldaps 5.21\n      URI::mailto 5.21\n      URI::mms 5.21\n      URI::news 5.21\n      URI::nntp 5.21\n      URI::nntps 5.21\n      URI::pop 5.21\n      URI::rlogin 5.21\n      URI::rsync 5.21\n      URI::rtsp 5.21\n      URI::rtspu 5.21\n      URI::sftp 5.21\n      URI::sip 5.21\n      URI::sips 5.21\n      URI::snews 5.21\n      URI::ssh 5.21\n      URI::telnet 5.21\n      URI::tn3270 5.21\n      URI::urn 5.21\n      URI::urn::isbn 5.21\n      URI::urn::oid 5.21\n    requirements:\n      Carp 0\n      Cwd 0\n      Data::Dumper 0\n      Encode 0\n      Exporter 5.57\n      ExtUtils::MakeMaker 0\n      MIME::Base64 2\n      Net::Domain 0\n      Scalar::Util 0\n      constant 0\n      integer 0\n      overload 0\n      parent 0\n      perl 5.008001\n      strict 0\n      utf8 0\n      warnings 0\n  URI-Nested-0.10\n    pathname: D/DW/DWHEELER/URI-Nested-0.10.tar.gz\n    provides:\n      URI::Nested 0.10\n    requirements:\n      Module::Build 0.30\n      Test::More 0.88\n      URI 1.40\n      perl 5.008001\n  URI-db-0.21\n    pathname: D/DW/DWHEELER/URI-db-0.21.tar.gz\n    provides:\n      URI::cassandra 0.21\n      URI::cockroach 0.21\n      URI::cockroachdb 0.21\n      URI::couch 0.21\n      URI::couchdb 0.21\n      URI::cubrid 0.21\n      URI::db 0.21\n      URI::db2 0.21\n      URI::derby 0.21\n      URI::exasol 0.21\n      URI::firebird 0.21\n      URI::hive 0.21\n      URI::impala 0.21\n      URI::informix 0.21\n      URI::ingres 0.21\n      URI::interbase 0.21\n      URI::ldapdb 0.21\n      URI::maria 0.21\n      URI::mariadb 0.21\n      URI::max 0.21\n      URI::maxdb 0.21\n      URI::monet 0.21\n      URI::monetdb 0.21\n      URI::mongo 0.21\n      URI::mongodb 0.21\n      URI::mssql 0.21\n      URI::mysql 0.21\n      URI::oracle 0.21\n      URI::pg 0.21\n      URI::pgsql 0.21\n      URI::pgxc 0.21\n      URI::postgres 0.21\n      URI::postgresql 0.21\n      URI::postgresxc 0.21\n      URI::redshift 0.21\n      URI::snowflake 0.21\n      URI::sqlite 0.21\n      URI::sqlite3 0.21\n      URI::sqlserver 0.21\n      URI::sybase 0.21\n      URI::teradata 0.21\n      URI::unify 0.21\n      URI::vertica 0.21\n      URI::yugabyte 0.21\n      URI::yugabytedb 0.21\n    requirements:\n      Module::Build 0.30\n      Test::More 0.88\n      URI 1.40\n      URI::Nested 0.10\n      perl 5.008001\n  Variable-Magic-0.63\n    pathname: V/VP/VPIT/Variable-Magic-0.63.tar.gz\n    provides:\n      Variable::Magic 0.63\n    requirements:\n      Carp 0\n      Config 0\n      Exporter 0\n      ExtUtils::MakeMaker 0\n      IO::Handle 0\n      IO::Select 0\n      IPC::Open3 0\n      POSIX 0\n      Socket 0\n      Test::More 0\n      XSLoader 0\n      base 0\n      lib 0\n      perl 5.008\n  WWW-RobotRules-6.02\n    pathname: G/GA/GAAS/WWW-RobotRules-6.02.tar.gz\n    provides:\n      WWW::RobotRules 6.02\n      WWW::RobotRules::AnyDBM_File 6.00\n      WWW::RobotRules::InCore 6.02\n    requirements:\n      AnyDBM_File 0\n      ExtUtils::MakeMaker 0\n      Fcntl 0\n      URI 1.10\n      perl 5.008001\n  YAML-LibYAML-0.88\n    pathname: I/IN/INGY/YAML-LibYAML-0.88.tar.gz\n    provides:\n      YAML::LibYAML 0.88\n      YAML::XS 0.88\n      YAML::XS::LibYAML undef\n    requirements:\n      ExtUtils::MakeMaker 0\n      perl 5.008001\n  YAML-Tiny-1.74\n    pathname: E/ET/ETHER/YAML-Tiny-1.74.tar.gz\n    provides:\n      YAML::Tiny 1.74\n    requirements:\n      B 0\n      Carp 0\n      Exporter 0\n      ExtUtils::MakeMaker 0\n      Fcntl 0\n      Scalar::Util 0\n      perl 5.008001\n      strict 0\n      warnings 0\n  common-sense-3.75\n    pathname: M/ML/MLEHMANN/common-sense-3.75.tar.gz\n    provides:\n      common::sense 3.75\n    requirements:\n      ExtUtils::MakeMaker 0\n  libwww-perl-6.72\n    pathname: O/OA/OALDERS/libwww-perl-6.72.tar.gz\n    provides:\n      LWP 6.72\n      LWP::Authen::Basic 6.72\n      LWP::Authen::Digest 6.72\n      LWP::Authen::Ntlm 6.72\n      LWP::ConnCache 6.72\n      LWP::Debug 6.72\n      LWP::Debug::TraceHTTP 6.72\n      LWP::DebugFile 6.72\n      LWP::MemberMixin 6.72\n      LWP::Protocol 6.72\n      LWP::Protocol::cpan 6.72\n      LWP::Protocol::data 6.72\n      LWP::Protocol::file 6.72\n      LWP::Protocol::ftp 6.72\n      LWP::Protocol::gopher 6.72\n      LWP::Protocol::http 6.72\n      LWP::Protocol::loopback 6.72\n      LWP::Protocol::mailto 6.72\n      LWP::Protocol::nntp 6.72\n      LWP::Protocol::nogo 6.72\n      LWP::RobotUA 6.72\n      LWP::Simple 6.72\n      LWP::UserAgent 6.72\n    requirements:\n      Digest::MD5 0\n      Encode 2.12\n      Encode::Locale 0\n      ExtUtils::MakeMaker 0\n      File::Copy 0\n      File::Listing 6\n      File::Temp 0\n      Getopt::Long 0\n      HTML::Entities 0\n      HTML::HeadParser 3.71\n      HTTP::CookieJar::LWP 0\n      HTTP::Cookies 6\n      HTTP::Date 6\n      HTTP::Negotiate 6\n      HTTP::Request 6.18\n      HTTP::Request::Common 6.18\n      HTTP::Response 6.18\n      HTTP::Status 6.18\n      IO::Select 0\n      IO::Socket 0\n      LWP::MediaTypes 6\n      MIME::Base64 2.1\n      Module::Load 0\n      Net::FTP 2.58\n      Net::HTTP 6.18\n      Scalar::Util 0\n      Try::Tiny 0\n      URI 1.10\n      URI::Escape 0\n      WWW::RobotRules 6\n      parent 0.217\n      perl 5.008001\n      strict 0\n      warnings 0\n  namespace-clean-0.27\n    pathname: R/RI/RIBASUSHI/namespace-clean-0.27.tar.gz\n    provides:\n      namespace::clean 0.27\n    requirements:\n      B::Hooks::EndOfScope 0.12\n      ExtUtils::MakeMaker 0\n      Package::Stash 0.23\n      perl 5.008001\n  perl-ldap-0.68\n    pathname: M/MA/MARSCHAP/perl-ldap-0.68.tar.gz\n    provides:\n      Bundle::Net::LDAP 0.03\n      LWP::Protocol::ldap 1.25\n      LWP::Protocol::ldapi undef\n      LWP::Protocol::ldaps undef\n      Net::LDAP 0.68\n      Net::LDAP::ASN 0.13\n      Net::LDAP::Bind 1.05\n      Net::LDAP::Constant 0.24\n      Net::LDAP::Control 0.20\n      Net::LDAP::Control::Assertion 0.02\n      Net::LDAP::Control::DontUseCopy 0.02\n      Net::LDAP::Control::EntryChange 0.02\n      Net::LDAP::Control::ManageDsaIT 0.04\n      Net::LDAP::Control::MatchedValues 0.02\n      Net::LDAP::Control::NoOp 0.01\n      Net::LDAP::Control::Paged 0.05\n      Net::LDAP::Control::PasswordPolicy 0.04\n      Net::LDAP::Control::PersistentSearch 0.04\n      Net::LDAP::Control::PostRead 0.03\n      Net::LDAP::Control::PreRead 0.04\n      Net::LDAP::Control::ProxyAuth 1.09\n      Net::LDAP::Control::Relax 0.03\n      Net::LDAP::Control::Sort 0.04\n      Net::LDAP::Control::SortResult 0.03\n      Net::LDAP::Control::Subentries 0.01\n      Net::LDAP::Control::SyncDone 0.03\n      Net::LDAP::Control::SyncRequest 0.03\n      Net::LDAP::Control::SyncState 0.04\n      Net::LDAP::Control::TreeDelete 0.01\n      Net::LDAP::Control::VLV 0.07\n      Net::LDAP::Control::VLVResponse 0.04\n      Net::LDAP::DSML 0.17\n      Net::LDAP::DSML::output 0.17\n      Net::LDAP::DSML::pp 0.17\n      Net::LDAP::Entry 0.29\n      Net::LDAP::Extension 1.04\n      Net::LDAP::Extension::Cancel 0.02\n      Net::LDAP::Extension::Refresh 0.04\n      Net::LDAP::Extension::SetPassword 0.06\n      Net::LDAP::Extension::WhoAmI 0.02\n      Net::LDAP::Extra 0.02\n      Net::LDAP::Extra::AD 0.05\n      Net::LDAP::Extra::eDirectory 0.03\n      Net::LDAP::Filter 0.20\n      Net::LDAP::FilterList 0.02\n      Net::LDAP::FilterMatch 0.27\n      Net::LDAP::Intermediate 0.04\n      Net::LDAP::Intermediate::SyncInfo 0.03\n      Net::LDAP::LDIF 0.27\n      Net::LDAP::Message 1.12\n      Net::LDAP::Message::Dummy 1.12\n      Net::LDAP::Reference 0.14\n      Net::LDAP::RootDSE 0.02\n      Net::LDAP::Schema 0.9908\n      Net::LDAP::Search 0.14\n      Net::LDAP::Util 0.20\n      Net::LDAPI 0.04\n      Net::LDAPS 0.06\n    requirements:\n      Authen::SASL 2.00\n      Convert::ASN1 0.2\n      Digest::HMAC_MD5 0\n      Digest::MD5 0\n      ExtUtils::MakeMaker 6.59\n      File::Basename 0\n      File::Compare 0\n      File::Path 0\n      HTTP::Negotiate 0\n      HTTP::Response 0\n      HTTP::Status 0\n      IO::File 0\n      IO::Socket::SSL 1.26\n      JSON 0\n      LWP 0\n      LWP::MediaTypes 0\n      LWP::Protocol 0\n      MIME::Base64 0\n      Test::More 0\n      Text::Soundex 0\n      Time::Local 0\n      URI::ldap 1.1\n      perl 5.008001\n"
  },
  {
    "path": "docker/entrypoint.sh",
    "content": "#!/bin/sh\n\nset -eu\n\ncd ~lstu\n\nif [ \"${1:-}\" == \"dev\" ]\nthen\n    echo \"\"\n    echo \"\"\n    echo \"Container started in dev mode. Connect to the container with the following command:\"\n    echo \"    docker-compose -f docker-compose.dev.yml exec -u root app_dev sh\"\n    echo \"\"\n    echo \"\"\n    echo \"You can then install the build dependencies with this command\"\n    echo \"    apk --update add vim build-base perl-utils perl-dev make sudo zlib-dev libpng-dev postgresql-dev mariadb-dev\"\n    \n    tail -f /dev/null\n    exit 0\nfi\n\n# If MySQL/PostgreSQL, wait for database to be up\nDB_TYPE=$(perl utilities/read_conf.pl dbtype)\nDB_HOST=\nDB_PORT=\nif [ \"$DB_TYPE\" == \"mysql\" ]\nthen\n    DB_HOST=$(perl utilities/read_conf.pl mysqldb/host db)\n    DB_PORT=$(perl utilities/read_conf.pl mysqldb/port 3306)\nfi\nif [ \"$DB_TYPE\" == \"postgresql\" ]\nthen\n    DB_HOST=$(perl utilities/read_conf.pl pgdb/host db)\n    DB_PORT=$(perl utilities/read_conf.pl pgdb/port 5432)\nfi\nif [ -n \"$DB_HOST\" -a -n \"$DB_PORT\" ]\nthen\n    while ! nc -vz \"${DB_HOST}\" \"${DB_PORT}\"; do\n        echo \"Waiting for database...\"\n        sleep 1;\n    done\nfi\n\nif [ \"${1:-}\" == \"minion\" ]\nthen\n    exec carton exec script/application minion worker\nfi\n\nexec carton exec hypnotoad -f script/lstu"
  },
  {
    "path": "docker-compose.dev.yml",
    "content": "version: '3.3'\n\nservices:\n    app_dev:\n        build: .\n        ports:\n            - 8080:8080\n        volumes:\n            - .:/home/lstu\n        command: dev\n    mariadb_dev:\n        image: mariadb:10.2\n        environment:\n            MYSQL_ROOT_PASSWORD: password\n            MYSQL_DATABASE: lstu\n    postgres_dev:\n        image: postgres:10.3-alpine\n        environment:\n            POSTGRES_PASSWORD: password\n            POSTGRES_USER: lstu\n            POSTGRES_DB: lstu\n    memcached:\n        image: memcached:1.5-alpine\n    adminer:\n        image: dehy/adminer\n        ports:\n            - 8081:80"
  },
  {
    "path": "docker-compose.yml",
    "content": "version: '3.3'\n\nservices:\n    app:\n        build: .\n        ports:\n            - 8080:8080\n        volumes:\n            - ./lstu.conf:/home/lstu/lstu.conf:ro\n    db:\n        image: mariadb:10.2\n        environment:\n            MYSQL_ROOT_PASSWORD: password\n            MYSQL_DATABASE: lstu\n    cache:\n        image: memcached:1.5-alpine\n    minion:\n        build: .\n        command: minion\n        volumes:\n            - ./lstu.conf:/home/lstu/lstu.conf:ro\n    minion_db:\n        image: mariadb:10.2\n        environment:\n            MYSQL_ROOT_PASSWORD: password\n            MYSQL_DATABASE: lstu_minion"
  },
  {
    "path": "docker-stack.yml",
    "content": "version: '3.3'\n\nservices:\n    app:\n        image: aquinum/lstu\n        configs:\n            - source: lstu.conf\n              target: /home/lstu/lstu.conf\n              uid: '1000'\n              gid: '1000'\n              mode: 0440\n        deploy:\n            replicas: 1\n    db:\n        image: mariadb:10.2\n        environment:\n            MYSQL_ROOT_PASSWORD: <changeme>\n            MYSQL_DATABASE: lstu\n    cache:\n        image: memcached:1.5-alpine\n    minion:\n        image: aquinum/lstu\n        command: minion\n        configs:\n            - source: lstu.conf\n              target: /home/lstu/lstu.conf\n              uid: '1000'\n              gid: '1000'\n              mode: 0440\n    minion_db:\n        image: mariadb:10.2\n        environment:\n            MYSQL_ROOT_PASSWORD: <changeme>\n            MYSQL_DATABASE: lstu_minion\n\nconfigs:\n    lstu.conf:\n        file: ./lstu.conf"
  },
  {
    "path": "hooks/build",
    "content": "#!/bin/bash\n\n# https://medium.com/microscaling-systems/labelling-automated-builds-on-docker-hub-f3d073fb8e1#.yldbwesu7\n\nif [ -z \"${IMAGE_NAME}\" ]; then\n    echo ! \"IMAGE_NAME\" variable missing.\n    echo eg. IMAGE_NAME=\"aquinum/lstu:local\" sh $0\n    exit 1\nfi\n\nfunction evil_git_dirty {\n    [[ $(git diff --shortstat 2> /dev/null | tail -n1) != \"\" ]] && echo \"-dirty\"\n}\n\nfunction last_tag {\n    git describe --abbrev=0\n}\n\nfunction version_number_plus {\n    [[ $(git rev-list --count ${1}..HEAD) -gt 0 ]] && echo \"+\"\n}\n\nVERSION=$(last_tag)\nVERSION=${VERSION}$(version_number_plus ${VERSION})\nVCS_REF=$(git rev-parse --short HEAD)$(evil_git_dirty)\nBUILD_DATE=$(date -u +\"%Y-%m-%dT%H:%M:%SZ\")\n\ndocker build --build-arg VCS_REF=${VCS_REF} \\\n             --build-arg BUILD_DATE=${BUILD_DATE} \\\n             --build-arg VERSION=${VERSION} \\\n             -t $IMAGE_NAME .\n"
  },
  {
    "path": "lib/Lstu/Command/ban.pm",
    "content": "# vim:set sw=4 ts=4 sts=4 ft=perl expandtab:\npackage Lstu::Command::ban;\nuse Mojo::Base 'Mojolicious::Command';\nuse FindBin qw($Bin);\nuse File::Spec qw(catfile);\nuse Mojo::Util qw(getopt);\nuse Lstu::DB::Ban;\n\nhas description => 'Ban IPs addresses for ten years, or unban them';\nhas usage => sub { shift->extract_usage };\n\nsub run {\n    my $c = shift;\n    my @args = @_;\n\n\n    getopt \\@args,\n      'b|ban=s{1,}'   => \\my @ban_ips,\n      'u|unban=s{1,}' => \\my @unban_ips;\n\n    for my $ip (@ban_ips) {\n        Lstu::DB::Ban->new(\n            app    => $c->app,\n            ip     => $ip\n        )->ban_ten_years;\n    }\n    say sprintf(\"%d banned IP addresses\", scalar(@ban_ips)) if (@ban_ips);\n\n    for my $ip (@unban_ips) {\n        Lstu::DB::Ban->new(\n            app    => $c->app,\n            ip     => $ip\n        )->unban;\n    }\n    say sprintf(\"%d unbanned IP addresses\", scalar(@unban_ips)) if (@unban_ips);\n\n    say $c->extract_usage unless (scalar(@ban_ips) || scalar(@unban_ips));\n}\n\n=encoding utf8\n\n=head1 NAME\n\nLstu::Command::ban - Ban IPs addresses for ten years, or unban them\n\n=head1 SYNOPSIS\n\n  Usage:\n      carton exec script/lstu ban -b|--ban <ip> <ip>    Ban the space separated IP addresses for ten years\n      carton exec script/lstu ban -u|--unban <ip> <ip>  Unban the space separated IP addresses\n\n  Please note that you can pass the --ban and --unban options at the same time.\n\n=cut\n\n1;\n"
  },
  {
    "path": "lib/Lstu/Command/safebrowsingcheck.pm",
    "content": "# vim:set sw=4 ts=4 sts=4 ft=perl expandtab:\npackage Lstu::Command::safebrowsingcheck;\nuse Mojo::Base 'Mojolicious::Command';\nuse FindBin qw($Bin);\nuse File::Spec qw(catfile);\nuse Term::ProgressBar::Quiet;\nuse Mojo::Util qw(getopt);\nuse Mojo::Collection 'c';\nuse Lstu::DB::URL;\nuse Lstu::DB::Ban;\n\nhas description => 'Checks all URLs in database against Google Safe Browsing database (local copy)';\nhas usage => sub { shift->extract_usage };\n\nsub run {\n    my $c = shift;\n    my @args = @_;\n\n    getopt \\@args,\n      'u|url=s{1,}'  => \\my @urls_to_check,\n      't|test=s{1,}' => \\my @urls_to_test,\n      's|seconds=i'  => \\my $delay,\n      'r|remove'     => \\my $remove,\n      'a|all'        => \\my $all,\n      'b|ban'        => \\my $ban;\n\n    if ($c->app->gsb) {\n        my $urls;\n        if (@urls_to_check) {\n            $urls = c(get_shorts($c, @urls_to_check));\n        } elsif ($delay) {\n            $urls = Lstu::DB::URL->new(app => $c->app)->get_all_urls_created_ago($delay);\n        } elsif (@urls_to_test) {\n            $urls = c(@urls_to_test);\n        } else {\n            $urls = Lstu::DB::URL->new(app => $c->app)->get_all_urls;\n        }\n\n        unless ($urls->size) {\n            say 'No URLs to check.';\n            exit;\n        }\n\n        my $progress = Term::ProgressBar::Quiet->new(\n            { name => 'Scanning '.$urls->size.' URLs', count => $urls->size, ETA => 'linear' }\n        );\n        my (@bad, %bad_ips, @bad_from_ips);\n        my $gsb     = $c->app->gsb;\n        my $disabled = 0;\n        my @testing_results;\n        $urls->each(sub {\n            my ($e, $num) = @_;\n            my $u = (@urls_to_test) ? $e : $e->{url};\n\n            $progress->update($num);\n\n            my @matches = $gsb->lookup(url => $u);\n\n            if (@matches) {\n                if (@urls_to_test) {\n                    push @testing_results, sprintf('%s is in GSB base!', $e);\n                } else {\n                    push @bad, $e->{short};\n                    $bad_ips{$e->{created_by}} = 1 if $e->{created_by};\n                    $disabled += Lstu::DB::URL->new(\n                        app => $c->app,\n                        short => $e->{short}\n                    )->remove if $remove;\n                }\n            } elsif (@urls_to_test) {\n                push @testing_results, sprintf('%s is safe.', $e);\n            }\n        });\n        if (@urls_to_test) {\n            map {say $_;} @testing_results;\n            exit;\n        }\n\n        say sprintf('All URLs (%d) have been scanned.', $urls->size);\n        say sprintf('%d bad URLs detected.', scalar(@bad));\n\n        if ($remove) {\n            say sprintf('%d bad URLs disabled.', $disabled) if $disabled;\n        } else {\n            say sprintf(\"If you want to disable the detected bad URLs, please do:\\n  carton exec script/lstu url --remove %s\", join(' ', @bad)) if @bad;\n        }\n\n        $disabled = 0;\n        for my $ip (keys %bad_ips) {\n            my $u = Lstu::DB::URL->new(app => $c->app)->search_creator($ip);\n            $u->each(sub {\n                my ($e, $num) = @_;\n                push @bad_from_ips, $e->{short};\n                $disabled += Lstu::DB::URL->new(\n                    app => $c->app,\n                    short => $e->{short}\n                )->remove if ($remove && $all);\n            });\n        }\n        my @ips = keys %bad_ips;\n        say sprintf(\"Bad URLs creators' IP addresses: \\n  %s\", join(\", \", @ips)) if (@ips);\n\n        if ($ban) {\n            for my $ip (@ips) {\n                Lstu::DB::Ban->new(\n                    app    => $c->app,\n                    ip     => $ip\n                )->ban_ten_years;\n            }\n            say sprintf(\"%d banned IP addresses\", scalar(@ips)) if (@ips);\n        }\n\n        if ($remove && $all) {\n            say sprintf('%d URLs from same IPs disabled.', $disabled) if $disabled;\n        } else {\n            say sprintf(\"If you want to disable the URLs created by the same IPs than the detected bad URLs, please do:\\n  carton exec script/lstu url --remove %s\", join(' ', @bad_from_ips)) if @bad_from_ips;\n        }\n    } else {\n        say 'It seems that safebrowsing_api_key isn\\'t set. Please, check your configuration';\n    }\n}\n\nsub get_shorts {\n    my $c      = shift;\n    my @shorts = @_;\n\n    my @results;\n\n    for my $short (@shorts) {\n        my $u = Lstu::DB::URL->new(app => $c->app, short => $short);\n        if ($u->url && !$u->disabled) {\n            push @results, $u->to_hash;\n        } else {\n            say sprintf('Sorry, unable to find an URL with short = %s', $short);\n        }\n    }\n    return @results;\n}\n\n=encoding utf8\n\n=head1 NAME\n\nLstu::Command::safebrowsing - Checks all URLs in database against Google Safe Browsing database (local copy)\n\n=head1 SYNOPSIS\n\n  Usage:\n      carton exec script/lstu safebrowsingcheck                          Checks all URLs in database against Google Safe Browsing database\n      carton exec script/lstu safebrowsingcheck -u|--url <short> <short> Checks the space-separated URLs against Google Safe Browsing database\n      carton exec script/lstu safebrowsingcheck -s|--seconds <xxx>       Checks URLs created the last xxx seconds against Google Safe Browsing database\n      carton exec script/lstu safebrowsingcheck -t|--test <url> <url>    Checks URLs against Google Safe Browsing database\n\n  Options (available with all commands except --test):\n      -r|--remove  Remove bad URLs that have been found\n      -a|--all     Remove all URLs created by the same IP addresses that created bad URLs (only in combination with the `-r|--remove` option)\n      -b|--ban     Ban IP addresses that created bad URLs\n\n=cut\n\n1;\n"
  },
  {
    "path": "lib/Lstu/Command/theme.pm",
    "content": "# vim:set sw=4 ts=4 sts=4 ft=perl expandtab:\npackage Lstu::Command::theme;\nuse Mojo::Base 'Mojolicious::Commands';\nuse FindBin qw($Bin);\nuse File::Spec qw(catfile cat dir);\nuse File::Path qw(make_path);\n\nhas description => 'Create new theme skeleton.';\nhas usage => sub { shift->extract_usage };\nhas message    => sub { shift->extract_usage . \"\\nCreate new theme skeleton:\\n\" };\nhas namespaces => sub { ['Lstu::Command::theme'] };\n\nsub run {\n    my $c    = shift;\n    my $name = shift;\n\n    unless (defined $name) {\n        say $c->extract_usage;\n        exit 1;\n    }\n\n    my $home = File::Spec->catdir($Bin, '..', 'themes', $name);\n\n    unless (-d $home) {\n\n        # Create skeleton\n        mkdir $home;\n        mkdir File::Spec->catdir($home, 'public');\n        make_path(File::Spec->catdir($home, 'templates', 'layouts'));\n        make_path(File::Spec->catdir($home, 'lib', 'Lstu', 'I18N'));\n\n        my $i18n = <<EOF;\n# vim:set sw=4 ts=4 sts=4 ft=perl expandtab:\npackage Lstu::I18N;\n\nuse base 'Locale::Maketext';\nuse File::Basename qw/dirname/;\nuse Locale::Maketext::Lexicon {\n    _auto => 1,\n    _decode => 1,\n    _style  => 'gettext',\n    '*' => [\n        Gettext => dirname(__FILE__) . '/I18N/*.po',\n        Gettext => $app_dir . 'themes/default/lib/Lstu/I18N/*.po',\n    ]\n};\n\nuse vars qw($app_dir);\nBEGIN {\n    use Cwd;\n    my $app_dir = getcwd;\n}\n\n1;\nEOF\n\n        open my $f, '>', File::Spec->catfile($home, 'lib', 'Lstu', 'I18N.pm') or die \"Unable to open $home/lib/Lstu/I18N.pm: $!\";\n        print $f $i18n;\n        close $f;\n\n        my $makefile = <<EOF;\nPOT=lib/Lstu/I18N/$home.pot\nSEDOPTS=-e \"s\\@SOME DESCRIPTIVE TITLE\\@Lstu language file\\@\" \\\\\n\t\t-e \"s\\@YEAR THE PACKAGE'S COPYRIGHT HOLDER\\@2015 Luc Didry\\@\" \\\\\n\t\t-e \"s\\@CHARSET\\@utf8\\@\" \\\\\n\t\t-e \"s\\@the PACKAGE package\\@the Lstu package\\@\" \\\\\n\t\t-e '/^\\\\#\\\\. (/{N;/\\\\n\\\\#\\\\. (/{N;/\\\\n.*\\\\.\\\\.\\\\/default\\\\//{s/\\\\#\\\\..*\\\\n.*\\\\#\\\\./\\\\#. (/g}}}' \\\\\n\t\t-e '/^\\\\#\\\\. (/{N;/\\\\n.*\\\\.\\\\.\\\\/default\\\\//{s/\\\\n/ /}}'\nSEDOPTS2=-e '/^\\\\#.*\\\\.\\\\.\\\\/default\\\\//,+3d'\nXGETTEXT=carton exec ../../local/bin/xgettext.pl\nCARTON=carton exec\n\nlocales:\n\t\t$(XGETTEXT) -D templates -D ../default/templates -o $(POT) 2>/dev/null\n\t\tsed $(SEDOPTS) -i $(POT)\n\t\tsed $(SEDOPTS2) -i $(POT)\nEOF\n\n        open $f, '>', File::Spec->catfile($home, 'Makefile') or die \"Unable to open $home/Makefile: $!\";\n        print $f $makefile;\n        close $f;\n    } else {\n        say \"$name theme already exists. Aborting.\";\n        exit 1;\n    }\n}\n\n=encoding utf8\n\n=head1 NAME\n\nLstu::Command::theme - Create new theme skeleton.\n\n=head1 SYNOPSIS\n\n  Usage: script/lstu theme THEME_NAME\n\n  Your new theme will be available in the themes directory.\n\n=cut\n\n1;\n"
  },
  {
    "path": "lib/Lstu/Command/url.pm",
    "content": "# vim:set sw=4 ts=4 sts=4 ft=perl expandtab:\npackage Lstu::Command::url;\nuse Mojo::Base 'Mojolicious::Command';\nuse Mojo::Util qw(getopt);\nuse Mojo::Collection 'c';\nuse Lstu::DB::URL;\nuse FindBin qw($Bin);\nuse File::Spec qw(catfile);\n\nhas description => 'Manage stored URL';\nhas usage => sub { shift->extract_usage };\n\nsub run {\n    my $c = shift;\n    my @args = @_;\n\n    getopt \\@args,\n      'info=s{1,}'         => \\my @info,\n      'r|remove=s{1,}'     => \\my @remove,\n      's|search=s'         => \\my $search,\n      'ip=s{1,}'           => \\my @ips,\n      'y|yes'              => \\my $yes,\n      'e|even-if-disabled' => \\my $even_disabled;\n\n    if (scalar @info) {\n        c(@info)->each(\n            sub {\n                my ($e, $num) = @_;\n                my $u = get_short($c, $e, $even_disabled);\n                print_infos($u->to_hash) if $u;\n            }\n        );\n    }\n    if (scalar @remove) {\n        my @r_ips;\n        c(@remove)->each(\n            sub {\n                my ($e, $num) = @_;\n                my $u = get_short($c, $e, 1);\n                if ($u) {\n                    push @r_ips, $u->created_by if $u->created_by;\n                    print_infos($u->to_hash);\n                    if ($u->disabled) {\n                        say sprintf('%s URL is already disabled', $e);\n                    } else {\n                        my $confirm = ($yes) ? 'yes' : undef;\n                        unless (defined $confirm) {\n                            printf('Are you sure you want to remove this URL (%s)? [N/y] ', $e);\n                            $confirm = <STDIN>;\n                            chomp $confirm;\n                        }\n                        if ($confirm =~ m/^y(es)?$/i) {\n                            if ($u->remove) {\n                                say sprintf('Success: %s URL has been removed', $e);\n                            } else {\n                                say sprintf('Failure: %s URL has not been removed', $e);\n                            }\n                        } else {\n                            say 'Answer was not \"y\" or \"yes\". Aborting deletion.';\n                        }\n                    }\n                }\n            }\n        );\n        say sprintf(\"If you want to ban the uploaders' IPs, please do:\\n  carton exec script/lstu ban --ban %s\", join(' ', @r_ips)) if @r_ips;\n    }\n    if ($search) {\n        my $u = Lstu::DB::URL->new(app => $c->app)->search_url($search);\n        my @shorts;\n        my @s_ips;\n        $u->each(sub {\n            my ($e, $num) = @_;\n            push @shorts, $e->{short};\n            push @s_ips, $e->{created_by} if $e->{created_by};\n            print_infos($e);\n        });\n        say sprintf('%d matching URLs', $u->size);\n        say sprintf(\"If you want to delete those URLs, please do:\\n  carton exec script/lstu url --yes --remove %s\", join(' ', @shorts)) if @shorts;\n        say sprintf(\"If you want to ban those IPs, please do:\\n  carton exec script/lstu ban --ban %s\", join(' ', @s_ips)) if @s_ips;\n    }\n    if (scalar(@ips)) {\n        my @recap;\n        c(@ips)->each(sub {\n            my ($ip, $num) = @_;\n            my $u = Lstu::DB::URL->new(app => $c->app)->search_creator($ip);\n            my @shorts;\n            $u->each(sub {\n                my ($e, $num) = @_;\n                push @shorts, $e->{short};\n                print_infos($e);\n            });\n            say sprintf('[%s] %d matching URLs', $ip, $u->size);\n            if (@shorts) {\n                say sprintf(\"[%s] If you want to delete those URLs, please do:\\n  carton exec script/lstu url --yes --remove %s\", $ip, join(' ', @shorts));\n                push @recap, @shorts;\n            }\n        });\n        say sprintf(\"If you want to delete all those URLs, please do:\\n  carton exec script/lstu url --yes --remove %s\", join(' ', @recap)) if @recap;\n        say sprintf(\"If you want to ban those IPs, please do:\\n  carton exec script/lstu ban --ban %s\", join(' ', @ips)) if @ips;\n    }\n}\n\nsub get_short {\n    my $c                = shift;\n    my $short            = shift;\n    my $even_if_disabled = shift;\n\n    my $u = Lstu::DB::URL->new(app => $c->app, short => $short);\n    if ($u->url) {\n        return $u if !$u->disabled;\n        return $u if $even_if_disabled;\n    }\n    say sprintf('Sorry, unable to find an URL with short = %s', $short);\n    return undef;\n}\n\nsub print_infos {\n    my $u = shift;\n\n    if ($u) {\n        my $msg = <<EOF;\n%s\n    url        : %s\n    disabled   : %d\n    counter    : %d\n    created at : %s\n    timestamp  : %d\nEOF\n        my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = gmtime($u->{timestamp});\n        my $timestamp = sprintf('%d-%d-%d %d:%d:%d GMT', $year + 1900, ++$mon, $mday, $hour, $min, $sec);\n        if ($u->{created_by}) {\n            $msg .= '    created_by : %s';\n            say sprintf($msg, $u->{short}, $u->{url}, $u->{disabled}, $u->{counter}, $timestamp, $u->{timestamp}, $u->{created_by});\n        } else {\n            say sprintf($msg, $u->{short}, $u->{url}, $u->{disabled}, $u->{counter}, $timestamp, $u->{timestamp});\n        }\n    }\n}\n\n=encoding utf8\n\n=head1 NAME\n\nLstu::Command::url - Manage URL in Lstu's database\n\n=head1 SYNOPSIS\n\n  Usage:\n      carton exec script/lstu url --info <short> <short>           Print infos about the space-separated URLs\n      carton exec script/lstu url --remove <short> <short> [--yes] Remove the space-separated URLs (ask for confirmation unless --yes is given)\n                                                                   Will print infos about URL before confirmation\n      carton exec script/lstu url --search <url>                   Search URLs by its true URL (LIKE match)\n      carton exec script/lstu url --ip <ip address> <ip address>   Search URLs by the IP address of its creator (exact match)\n\n=cut\n\n1;\n"
  },
  {
    "path": "lib/Lstu/Controller/Admin.pm",
    "content": "# vim:set sw=4 ts=4 sts=4 ft=perl expandtab:\npackage Lstu::Controller::Admin;\nuse Mojo::Base 'Mojolicious::Controller';\nuse Digest::SHA qw(sha256_hex);\nuse Lstu::DB::URL;\nuse Lstu::DB::Ban;\nuse Lstu::DB::Session;\n\nsub login {\n    my $c    = shift;\n    my $pwd  = $c->param('adminpwd');\n    my $act  = $c->param('action');\n\n    $c->cleaning;\n\n    my $ip = $c->ip;\n\n    my $banned = Lstu::DB::Ban->new(\n        app    => $c,\n        ip     => $ip\n    )->is_banned($c->config('ban_min_strike'));\n    if (defined $banned) {\n        my $penalty = 3600;\n        if ($banned->strike >= 2 * $c->config('ban_min_strike')) {\n            $penalty = 3600 * 24 * 30; # 30 days of banishing\n        }\n        $banned->increment_ban_delay($penalty);\n\n        $c->flash('msg'    => $c->l('Too many bad passwords. You\\'re banned.'));\n        $c->flash('banned' => 1);\n        $c->redirect_to('stats');\n    } else {\n        if (\n            (defined($c->config('adminpwd')) && defined($pwd) && $pwd eq $c->config('adminpwd')) ||\n            (defined($c->config('hashed_adminpwd')) && defined($pwd) && sha256_hex($pwd) eq $c->config('hashed_adminpwd'))\n           ) {\n            my $token = $c->shortener(32);\n\n            Lstu::DB::Session->new(\n                app    => $c,\n                token  => $token,\n                until  => time + 3600\n            )->write;\n\n            $c->session('token' => $token);\n            $c->respond_to(\n                json => sub {\n                    my $c = shift;\n                    $c->render(\n                        json => {\n                            success => Mojo::JSON->true,\n                            msg     => $c->l('You have been successfully logged in.')\n                        }\n                    );\n                },\n                any => sub {\n                    my $c = shift;\n                    $c->redirect_to('stats');\n                }\n            );\n        } elsif (defined($act) && $act eq 'logout') {\n            Lstu::DB::Session->new(\n                app    => $c,\n                token  => $c->session('token')\n            )->remove;\n            delete $c->session->{token};\n            $c->respond_to(\n                json => sub {\n                    my $c = shift;\n                    $c->render(\n                        json => {\n                            success => Mojo::JSON->true,\n                            msg     => $c->l('You have been successfully logged out.')\n                        }\n                    );\n                },\n                any => sub {\n                    shift->redirect_to('stats');\n                }\n            );\n        } else {\n            Lstu::DB::Ban->new(\n                app    => $c,\n                ip     => $ip\n            )->increment_ban_delay(3600);\n\n            my $msg = $c->l('Bad password');\n            $c->respond_to(\n                json => sub {\n                    my $c = shift;\n                    $c->render(\n                        json => {\n                            success => Mojo::JSON->false,\n                            msg     => $msg\n                        }\n                    );\n                },\n                any => sub {\n                    my $c = shift;\n                    $c->flash('msg' => $msg);\n                    $c->redirect_to('stats');\n                }\n            );\n        }\n    }\n}\n\nsub delete {\n    my $c     = shift;\n    my $short = $c->param('short');\n\n    my $db_session = Lstu::DB::Session->new(\n        app    => $c,\n        token  => $c->session('token')\n    );\n    if (defined($c->session('token')) && $db_session->is_valid) {\n        my $db_url = Lstu::DB::URL->new(\n            app    => $c,\n            short  => $short\n        );\n        if ($db_url->url) {\n            my $deleted = $db_url->remove;\n            $c->respond_to(\n                json => { json => { success => Mojo::JSON->true, deleted => $deleted } },\n                any  => sub {\n                    my $c = shift;\n                    $c->redirect_to('stats');\n                }\n            );\n        } else {\n            my $msg = $c->l('The shortened URL %1 doesn\\'t exist.', $c->url_for('/')->to_abs.$short);\n            $c->respond_to(\n                json => { json => { success => Mojo::JSON->false, msg => $msg } },\n                any  => sub {\n                    my $c = shift;\n                    $c->flash('msg' => $msg);\n                    $c->redirect_to('stats');\n                }\n            );\n        }\n    } else {\n        $c->flash('msg' => $c->l('You\\'re not authenticated as the admin'));\n        $c->redirect_to('stats');\n    }\n}\n\n1;\n"
  },
  {
    "path": "lib/Lstu/Controller/Authent.pm",
    "content": "# vim:set sw=4 ts=4 sts=4 ft=perl expandtab:\npackage Lstu::Controller::Authent;\nuse Mojo::Base 'Mojolicious::Controller';\n\nsub index {\n    my $c = shift;\n    if ($c->is_user_authenticated) {\n        $c->redirect_to('index');\n    } else {\n        $c->render(template => 'login');\n    }\n}\n\nsub login {\n    my $c     = shift;\n    my $login = $c->param('login');\n    my $pwd   = $c->param('password');\n\n    if($c->authenticate($login, $pwd)) {\n        $c->respond_to(\n            json => sub {\n                my $c = shift;\n                $c->render(\n                    json => {\n                        success => Mojo::JSON->true,\n                        msg     => $c->l('You have been successfully logged in.')\n                    }\n                );\n            },\n            any => sub {\n                $c->redirect_to('index');\n            }\n        );\n    } else {\n        my $msg = $c->l('Please, check your credentials: unable to authenticate.');\n        $c->respond_to(\n            json => sub {\n                my $c = shift;\n                $c->render(\n                    json => {\n                        success => Mojo::JSON->false,\n                        msg     => $msg\n                    }\n                );\n            },\n            any => sub {\n                $c->stash(msg => $msg);\n                $c->render(template => 'login')\n            }\n        );\n    }\n}\n\nsub log_out {\n    my $c = shift;\n    if ($c->is_user_authenticated) {\n        $c->logout;\n    }\n    $c->respond_to(\n        json => sub {\n            my $c = shift;\n            $c->render(\n                json => {\n                    success => Mojo::JSON->true,\n                    msg     => $c->l('You have been successfully logged out.')\n                }\n            );\n        },\n        any => sub {\n            $c->render(template => 'logout');\n        }\n    );\n}\n\n1;\n"
  },
  {
    "path": "lib/Lstu/Controller/Stats.pm",
    "content": "# vim:set sw=4 ts=4 sts=4 ft=perl expandtab:\npackage Lstu::Controller::Stats;\nuse Mojo::Base 'Mojolicious::Controller';\nuse Lstu::DB::URL;\nuse Lstu::DB::Session;\nuse Mojo::JSON qw(to_json decode_json);\nuse Mojo::Util qw(b64_encode);\nuse Image::PNG::QRCode 'qrpng';\n\nsub export_cookie {\n    my $c = shift;\n\n    my $u = (defined($c->cookie('url'))) ? decode_json $c->cookie('url') : [];\n\n    $c->res->headers->add('Content-Disposition' => 'attachment;filename=lstu_export.json');\n    return $c->render(json => $u);\n}\n\nsub import_cookie {\n    my $c    = shift;\n    my $file = $c->param('file');\n\n    my $json = decode_json($file->slurp);\n\n    if (ref($json) eq 'ARRAY') {\n        # Get URLs from cookie\n        my $u = (defined($c->cookie('url'))) ? decode_json $c->cookie('url') : [];\n        # Add the new URL\n        push @{$u}, @{$json};\n        # Make the array contain only unique URLs\n        my %k = map { $_, 1 } @{$u};\n        @{$u} = keys %k;\n        # And set the cookie\n        my $cookie = to_json($u);\n        $c->cookie(\n            'url' => $cookie,\n            {\n                path => $c->config('prefix'),\n                expires => time + 142560000\n            }\n        ); # expires in 10 years\n\n        $c->flash(success_msg => $c->l('File imported'));\n    } else {\n        $c->flash(msg => $c->l('Sorry, unable to parse the provided file'));\n    }\n    return $c->redirect_to('stats');\n}\n\nsub fullstats {\n    my $c = shift;\n\n    my $url = Lstu::DB::URL->new(app => $c);\n    return $c->render(\n        json => {\n            empty     => $url->count_empty,\n            urls      => $url->total,\n            timestamp => time,\n        }\n    );\n}\n\nsub stats {\n    my $c     = shift;\n    my $order = $c->param('order') // 'counter';\n    my $dir   = $c->param('dir')   // '-desc';\n\n    my %orders = (\n        'short'      => 1,\n        'url'        => 1,\n        'counter'    => 1,\n        'created_by' => 1,\n    );\n    my %dirs = (-desc => 1, -asc => 1);\n\n    $order = 'counter' unless $orders{$order};\n    $dir   = '-desc'   unless $dirs{$dir};\n\n\n    if ((!defined($c->config('ldap')) && !defined($c->config('htpasswd'))) || $c->is_user_authenticated) {\n        my $db_session = Lstu::DB::Session->new(\n            app    => $c,\n            token  => $c->session('token')\n        );\n        if (defined($c->session('token')) && $db_session->is_valid) {\n            my $total = Lstu::DB::URL->new(app => $c)->total;\n            my $page  = $c->param('page') || 0;\n               $page  = 0 if ($page < 0);\n               $page  = $page - 1 if ($page * $c->config('page_offset') > $total);\n\n            my ($first, $last) = (!$page, ($page * $c->config('page_offset') <= $total && $total < ($page + 1) * $c->config('page_offset')));\n\n            my @urls  = Lstu::DB::URL->new(\n                app    => $c,\n            )->paginate($page, $c->config('page_offset'), $order, $dir);\n\n            $c->respond_to(\n                json => sub {\n                    my $c = shift;\n                    $c->render(\n                        json => {\n                            prefix   => $c->prefix,\n                            urls     => \\@urls,\n                            first    => $first,\n                            last     => $last,\n                            page     => $page,\n                            admin    => 1,\n                            total    => $total\n                        }\n                    );\n                },\n                any => sub {\n                    my $c = shift;\n                    $c->render(\n                        template => 'stats',\n                        prefix   => $c->prefix,\n                        urls     => \\@urls,\n                        first    => $first,\n                        last     => $last,\n                        page     => $page,\n                        admin    => 1,\n                        total    => $total\n                    )\n                }\n            );\n        } else {\n            my $u = (defined($c->cookie('url'))) ? decode_json $c->cookie('url') : [];\n\n            my @urls  = Lstu::DB::URL->new(\n                app    => $c\n            )->get_a_lot($u);\n\n            my $prefix = $c->prefix;\n\n            $c->respond_to(\n                json => sub {\n                    my @struct;\n                    for my $url (@urls) {\n                        push @struct, {\n                            short      => $prefix.$url->{short},\n                            url        => $url->{url},\n                            counter    => $url->{counter},\n                            created_at => $url->{timestamp},\n                            qrcode     => b64_encode(qrpng(text => $prefix.$url->{short}))\n                        };\n                    }\n                    $c->render( json => \\@struct );\n                },\n                any  => sub {\n                    my @struct;\n                    for my $url (@urls) {\n                        push @struct, {\n                            short     => $url->{short},\n                            url       => $url->{url},\n                            counter   => $url->{counter},\n                            timestamp => $url->{timestamp},\n                            qrcode    => b64_encode(qrpng(text => $prefix.$url->{short}))\n                        };\n                    }\n                    $c->render(\n                        template => 'stats',\n                        prefix   => $prefix,\n                        urls     => \\@struct\n                    )\n                }\n            )\n        }\n    } else {\n        $c->redirect_to('login');\n    }\n}\n\n\nsub stat_for_one_short {\n    my $c = shift;\n    my $short = $c->param('short');\n\n    my $url  = Lstu::DB::URL->new(\n        app    => $c,\n        short  => $short\n    );\n\n    if ($url->{url}) {\n        my $prefix = $c->prefix;\n\n        $c->render(\n            json => {\n                success    => Mojo::JSON->true,\n                short      => $prefix.$url->{short},\n                url        => $url->{url},\n                counter    => $url->{counter},\n                created_at => $url->{timestamp},\n                timestamp  => time\n            }\n        );\n    } else {\n        $c->render(\n            json => {\n                success => Mojo::JSON->false,\n                msg     => $c->l('The shortened URL %1 doesn\\'t exist.', $c->url_for('/')->to_abs.$short)\n            }\n        );\n    }\n}\n\n1;\n"
  },
  {
    "path": "lib/Lstu/Controller/URL.pm",
    "content": "# vim:set sw=4 ts=4 sts=4 ft=perl expandtab:\npackage Lstu::Controller::URL;\nuse Mojo::Base 'Mojolicious::Controller';\nuse Lstu::DB::URL;\nuse Lstu::DB::Ban;\nuse Data::Validate::URI qw(is_http_uri is_https_uri);\nuse Mojo::JSON qw(to_json decode_json);\nuse Mojo::URL;\nuse Mojo::Util qw(b64_encode slugify);\nuse Image::PNG::QRCode 'qrpng';\n\nsub add {\n    my $c = shift;\n\n    $c->cleaning;\n\n    # Is the user allowed to create a short URL?\n    if ((!defined($c->config('ldap')) && !defined($c->config('htpasswd'))) || $c->is_user_authenticated) {\n        my $ip = $c->ip;\n\n        # Check banning\n        my $banned = Lstu::DB::Ban->new(\n            app    => $c,\n            ip     => $ip\n        )->is_banned($c->config('ban_min_strike'));\n\n        my $disabled_api = 0;\n        if ($c->config('disable_api')) {\n            $disabled_api = 1 if $c->validation->csrf_protect->has_error('csrf_token');\n            $disabled_api = 1 if (!defined($c->req->headers->referrer) || Mojo::URL->new($c->req->headers->referrer)->host ne Mojo::URL->new('https://'.$c->req->headers->host)->host)\n        }\n\n        if (defined $banned) {\n            # Increase ban delay if necessary\n            my $penalty = 3600;\n            if ($banned->strike >= 2 * $c->config('ban_min_strike')) {\n                $penalty = 3600 * 24 * 30; # 30 days of banishing\n            }\n            $banned->increment_ban_delay($penalty);\n\n            my $msg = $c->l('You asked to shorten too many URLs too quickly. You\\'re banned for %1 hour(s).', $penalty/3600);\n            $c->respond_to(\n                json => { json => { success => Mojo::JSON->false, msg => $msg } },\n                any  => sub {\n                    shift->render(\n                        template => 'index',\n                        msg      => $msg,\n                        banned   => 1\n                    );\n                }\n            );\n        } elsif ($disabled_api) {\n            my $msg = $c->l('Sorry, the API is disabled.');\n            $c->app->log->info('Blocked API call for '.$ip);\n            $c->respond_to(\n                json => { json => { success => Mojo::JSON->false, msg => $msg } },\n                any  => sub {\n                    shift->render(\n                        template => 'index',\n                        msg      => $msg,\n                    );\n                }\n            );\n        } else {\n            my $lsturl     = $c->param('lsturl');\n            $lsturl        =~ s/^\\s+|\\s+$//g;\n            my $url        = Mojo::URL->new($lsturl);\n            my $custom_url = $c->param('lsturl-custom');\n            my $format     = $c->param('format');\n\n            $custom_url = undef if (defined($custom_url) && $custom_url eq '');\n\n            my ($msg, $short);\n            if (defined($custom_url) &&\n                       ($custom_url =~ m#^(a|d|cookie|stats|fullstats|login|logout|api)$# || $custom_url =~ m/\\.json$/)\n                ) {\n                $msg = $c->l('The shortened text can\\'t be \"a\", \"api\", \"d\", \"cookie\", \"stats\", \"fullstats\", \"login\" or \"logout\" or end with \".json\". Your URL to shorten: %1', $url);\n            } elsif (is_http_uri($url->to_string) || is_https_uri($url->to_string) || (defined($url->host) && $url->host =~ m/\\.onion$/)) {\n                my $res = ($url->host =~ m/\\.onion$/) ? {} : $c->is_spam($url, 0);\n\n                # Check if spam\n                if ($res->{is_spam}) {\n                    $msg = $res->{msg};\n                } else {\n                    # Not spam, let's go\n\n                    Lstu::DB::Ban->new(\n                        app    => $c,\n                        ip     => $ip\n                    )->increment_ban_delay(1);\n\n                    my $db_url = Lstu::DB::URL->new(\n                        app    => $c,\n                        url    => $url\n                    );\n\n                    if ($db_url->short && !defined($custom_url)) {\n                        # Already got this URL\n                        $short = $db_url->short;\n                    } else {\n                        if (defined($custom_url)) {\n                            $custom_url             = slugify $custom_url;\n                            my $suffix              = 2;\n                            my $original_custom_url = $custom_url;\n                            while (Lstu::DB::URL->new(app => $c)->exist($custom_url) > 0) {\n                                $custom_url = $original_custom_url.'-'.$suffix;\n                                $suffix++;\n                            }\n                            Lstu::DB::URL->new(\n                                app        => $c,\n                                short      => $custom_url,\n                                url        => $url,\n                                timestamp  => time(),\n                                created_by => ($c->config('log_creator_ip')) ? $ip : undef\n                            )->write;\n\n                            $short = $custom_url;\n                        } else {\n                            $db_url = Lstu::DB::URL->new(app => $c)->choose_empty;\n                            if (defined $db_url) {\n                                $db_url->url($url)->timestamp(time);\n\n                                $db_url->created_by($ip) if $c->config('log_creator_ip');\n\n                                $db_url->write;\n\n                                $short = $db_url->short;\n                            } else {\n                                # Houston, we have a problem\n                                $msg = $c->l('No shortened URL available. Please retry or contact the administrator at %1. Your URL to shorten: [_2]', $c->config('contact'), $url);\n                            }\n                        }\n                    }\n                }\n            } else {\n                $msg = $c->l('%1 is not a valid URL.', $url);\n            }\n            if ($msg) {\n                $c->respond_to(\n                    json => { json => { success => Mojo::JSON->false, msg => $msg } },\n                    any  => sub {\n                        shift->render(\n                            template => 'index',\n                            msg      => $msg\n                        );\n                    }\n                );\n            } else {\n                # Get URLs from cookie\n                my $u = (defined($c->cookie('url'))) ? decode_json $c->cookie('url') : [];\n\n                # Add the new URL\n                push @{$u}, $short;\n\n                # Make the array contain only unique URLs\n                my %k = map { $_, 1 } @{$u};\n                @{$u} = keys %k;\n\n                # And set the cookie\n                my $cookie = to_json($u);\n                $c->cookie(\n                    'url' => $cookie,\n                    {\n                        path => $c->config('prefix'),\n                        expires => time + 142560000\n                    }\n                ); # expires in 10 years\n\n                my $prefix = $c->prefix;\n\n                my $qrcode = b64_encode(qrpng(text => $prefix.$short, scale => $c->config('qrcode_size')));\n\n                $c->respond_to(\n                    json => { json => { success => Mojo::JSON->true, url => $url, short => $prefix.$short, qrcode => $qrcode } },\n                    any  => sub {\n                        shift->render(\n                            template => 'index',\n                            url      => $url,\n                            short    => $prefix.$short,\n                            qrcode   => $qrcode\n                        );\n                    }\n                );\n            }\n        }\n    } else {\n        # Not authorized\n        $c->redirect_to('login');\n    }\n}\n\nsub get {\n    my $c = shift;\n    my $short = $c->param('short');\n\n    if (defined($c->stash('format')) && $short eq 'robots' && $c->stash('format') eq 'txt') {\n        if ($c->app->static->file('robots.txt')) {\n            $c->res->headers->content_type('text/plain');\n            return $c->reply->static('robots.txt');\n        } else {\n            return $c->reply->not_found;\n        }\n    }\n\n    my $url;\n    my $disabled_url = 0;\n    if (scalar(@{$c->config('memcached_servers')})) {\n        $url = $c->chi('lstu_urls_cache')->compute($short, undef, sub {\n            my $db_url = Lstu::DB::URL->new(app => $c, short => $short);\n            if ($db_url->disabled) {\n                $disabled_url++;\n                return undef\n            } else {\n                return $db_url->url;\n            }\n        });\n    } else {\n        my $db_url = Lstu::DB::URL->new(app => $c, short => $short);\n        if ($db_url->disabled) {\n            $disabled_url++;\n        } else {\n            $url = $db_url->url;\n        }\n    }\n\n    if ($url) {\n        $c->respond_to(\n            json => { json => { success => Mojo::JSON->true, url => $url } },\n            any  => sub {\n                my $c = shift;\n                $c->res->code(301);\n                $c->redirect_to($url);\n            }\n        );\n        # Update counter\n        $c->on(finish => sub {\n            if ($c->config('minion')->{enabled} && $c->config('minion')->{db_path}) {\n                $c->app->minion->enqueue(increase_counter => [$short, $c->{url}]);\n            } else {\n                Lstu::DB::URL->new(app => $c, short => $short)->increment_counter;\n\n                my $piwik = $c->config('piwik');\n                if (defined($piwik) && $piwik->{idsite} && $piwik->{url}) {\n                    $c->piwik_api(\n                        'Track' => {\n                            idSite     => $piwik->{idsite},\n                            action_url => $c->{url},\n                            url        => $piwik->{url}\n                        }\n                    );\n                }\n\n            }\n        });\n    } else {\n        my $msg;\n        if ($disabled_url) {\n            $msg = $c->l('The shortened URL %1 no longer exists.', $c->url_for('/')->to_abs.$short);\n        } else {\n            $msg = $c->l('The shortened URL %1 doesn\\'t exist.', $c->url_for('/')->to_abs.$short);\n        }\n        $c->res->code(404);\n        $c->respond_to(\n            json => { json => { success => Mojo::JSON->false, msg => $msg } },\n            any  => sub {\n                my $c = shift;\n\n                $c->render(\n                    template => 'index',\n                    msg      => $msg\n                );\n            }\n        );\n    }\n}\n\n1;\n"
  },
  {
    "path": "lib/Lstu/DB/Ban/MySQL.pm",
    "content": "# vim:set sw=4 ts=4 sts=4 ft=perl expandtab:\npackage Lstu::DB::Ban::MySQL;\nuse Mojo::Base 'Lstu::DB::Ban';\n\nsub new {\n    my $c = shift;\n\n    $c = $c->SUPER::new(@_);\n\n    $c = $c->_slurp if ($c->ip);\n\n    return $c;\n}\n\n1;\n"
  },
  {
    "path": "lib/Lstu/DB/Ban/Pg.pm",
    "content": "# vim:set sw=4 ts=4 sts=4 ft=perl expandtab:\npackage Lstu::DB::Ban::Pg;\nuse Mojo::Base 'Lstu::DB::Ban';\n\nsub new {\n    my $c = shift;\n\n    $c = $c->SUPER::new(@_);\n\n    $c = $c->_slurp if ($c->ip);\n\n    return $c;\n}\n\nsub increment_ban_delay {\n    my $c       = shift;\n    my $penalty = shift;\n\n    my $until = time + $penalty;\n\n    my $h = {\n        strike => 1\n    };\n    if ($c->record) {\n        $h = $c->app->dbi->db->query('UPDATE ban SET until = ?, strike = strike + 1 WHERE ip = ? RETURNING strike', $until, $c->ip)->hashes->first;\n    } else {\n        $c->app->dbi->db->query('INSERT INTO ban (ip, until, strike) VALUES (?, ?, 1)', $c->ip, $until);\n        $c->record(1);\n    }\n\n    $c->strike($h->{strike});\n    $c->until($until);\n\n    return $c;\n}\n\nsub ban_ten_years {\n    my $c = shift;\n\n    my $until = time + 315360000;\n\n    my $h = {\n        strike => time\n    };\n    if ($c->record) {\n        $h = $c->app->dbi->db->query('UPDATE ban SET until = ?, strike = ? WHERE ip = ? RETURNING strike', $until, time, $c->ip)->hashes->first;\n    } else {\n        $c->app->dbi->db->query('INSERT INTO ban (ip, until, strike) VALUES (?, ?, ?)', $c->ip, $until, time);\n        $c->record(1);\n    }\n\n    $c->strike($h->{strike});\n    $c->until($until);\n\n    return $c;\n}\n\n1;\n"
  },
  {
    "path": "lib/Lstu/DB/Ban/SQLite.pm",
    "content": "# vim:set sw=4 ts=4 sts=4 ft=perl expandtab:\npackage Lstu::DB::Ban::SQLite;\nuse Mojo::Base 'Lstu::DB::Ban';\n\nsub new {\n    my $c = shift;\n\n    $c = $c->SUPER::new(@_);\n\n    $c = $c->_slurp if ($c->ip);\n\n    return $c;\n}\n\n1;\n"
  },
  {
    "path": "lib/Lstu/DB/Ban.pm",
    "content": "# vim:set sw=4 ts=4 sts=4 ft=perl expandtab:\npackage Lstu::DB::Ban;\nuse Mojo::Base -base;\nuse Mojo::Collection 'c';\n\nhas 'ip';\nhas 'until';\nhas 'strike' => 0;\nhas 'record' => 0;\nhas 'app';\n\n=head1 NAME\n\nLstu::DB::Ban - Abstraction layer for Lstu ban system\n\n=head1 Contributing\n\nWhen creating a new database accessor, make sure that it provides the following subroutines.\nAfter that, modify this file and modify the C<new> subroutine to allow to use your accessor.\n\nHave a look at Lstu::DB::Ban::SQLite's code: it's simple and may be more understandable that this doc.\n\n=head1 Attributes\n\n=over 1\n\n=item B<ip>     : string, an IP address\n\n=item B<until>  : unix timestamp\n\n=item B<strike> : integer\n\n=item B<app>    : a mojolicious object\n\n=back\n\n=head1 Sub routines\n\n=head2 new\n\n=over 1\n\n=item B<Usage>     : C<$c = Lstu::DB::Ban-E<gt>new(app =E<gt> $self);>\n\n=item B<Arguments> : any of the attribute above\n\n=item B<Purpose>   : construct a new Lstu::DB::Ban object. If the C<ip> attribute is provided, it have to load the informations from the database\n\n=item B<Returns>   : the Lstu::DB::Ban object\n\n=item B<Info>      : the app argument is used by Lstu::DB::Ban to choose which db accessor will be used, you don't need to use it in new(), but you can use it to access helpers or configuration settings in the other subroutines\n\n=back\n\n=cut\n\nsub new {\n    my $c = shift;\n\n    $c = $c->SUPER::new(@_);\n\n    if (ref($c) eq 'Lstu::DB::Ban') {\n        my $dbtype = $c->app->config('dbtype');\n        if ($dbtype eq 'sqlite') {\n            require Lstu::DB::Ban::SQLite;\n            $c = Lstu::DB::Ban::SQLite->new(@_);\n        } elsif ($dbtype eq 'postgresql') {\n            require Lstu::DB::Ban::Pg;\n            $c = Lstu::DB::Ban::Pg->new(@_);\n        } elsif ($dbtype eq 'mysql') {\n            require Lstu::DB::Ban::MySQL;\n            $c = Lstu::DB::Ban::MySQL->new(@_);\n        }\n    }\n\n    return $c;\n}\n\nsub to_hash {\n    my $c = shift;\n\n    return {\n        ip     => $c->ip,\n        until  => $c->until,\n        strike => $c->strike\n    };\n}\n\n=head2 is_whitelisted\n\n=over 1\n\n=item B<Usage>     : C<$c-E<gt>is_whitelisted>\n\n=item B<Arguments> : none\n\n=item B<Purpose>   : tells you if the current object is in the configured whitelisted IPs\n\n=item B<Returns>   : boolean\n\n=back\n\n=cut\n\nsub is_whitelisted {\n    my $c = shift;\n\n    my $ip = $c->ip;\n    return c(@{$c->app->config('ban_whitelist')})->grep(sub { $_ eq $ip })->size;\n}\n\n=head2 is_blacklisted\n\n=over 1\n\n=item B<Usage>     : C<$c-E<gt>is_blacklisted>\n\n=item B<Arguments> : none\n\n=item B<Purpose>   : tells you if the current object is in the configured blacklisted IPs\n\n=item B<Returns>   : boolean\n\n=back\n\n=cut\n\nsub is_blacklisted {\n    my $c = shift;\n\n    my $ip = $c->ip;\n    return c(@{$c->app->config('ban_blacklist')})->grep(sub { $_ eq $ip })->size;\n}\n\n=head2 is_banned\n\n=over 1\n\n=item B<Usage>     : C<$c-E<gt>is_banned(3)>\n\n=item B<Arguments> : an integer. Will be config('ban_min_strike'), which is the number of strike before being banned (default: 3)\n\n=item B<Purpose>   : check the db record with C<ip> equal to the object's ip attribute if C<until> is superior to current time and if C<strike> is superior or equal to the argument.\n\neg: C<WHERE ip = ? AND until E<gt> ? AND strike E<gt>= ?', $c->ip, time, $argument>\n\n=item B<Returns>   : the Lstu::DB::Ban object if the ip is banned, undef otherwise\n\n=item B<Info>      : if the IP is whitelisted (see C<is_whitelisted> above), it must return undef\n\n=back\n\n=cut\n\nsub is_banned {\n    my $c              = shift;\n    my $ban_min_strike = shift;\n\n    return undef if $c->is_whitelisted;\n\n    if ($c->is_blacklisted) {\n        $c->until(time + 3600);\n        $c->strike(1 + $c->app->config('ban_min_strike'));\n        return $c;\n    }\n\n    my $h = $c->app->dbi->db->query('SELECT * FROM ban WHERE ip = ? AND until > ? AND strike >= ?', $c->ip, time, $ban_min_strike)->hashes;\n\n    if ($h->size) {\n        $c->until($h->first->{until});\n        $c->strike($h->first->{strike});\n        $c->record(1);\n\n        return $c;\n    } else {\n        return undef;\n    }\n}\n\n=head2 increment_ban_delay\n\n=over 1\n\n=item B<Usage>     : C<$c-E<gt>increment_ban_delay(3600)>\n\n=item B<Arguments> : an integer. This number is a penalty (in second) that will be added to the C<until> attribute of the Lstu::DB::Ban object\n\n=item B<Purpose>   : add penalty to the C<until> attribute of the Lstu::DB::Ban object, increment the C<strike> attribute by one and write the Lstu::DB::Ban object's attribute to the database.\nUpdate the database record if one already exists, create one otherwise.\n\n=item B<Returns>   : the Lstu::DB::Ban object\n\n=back\n\n=cut\n\nsub increment_ban_delay {\n    my $c       = shift;\n    my $penalty = shift;\n\n    my $until = time + $penalty;\n\n    my $h = {\n        strike => 1\n    };\n    if ($c->record) {\n        $c->app->dbi->db->query('UPDATE ban SET until = ?, strike = strike + 1 WHERE ip = ?', $until, $c->ip);\n        $h = $c->app->dbi->db->query('SELECT strike FROM ban WHERE ip = ?', $c->ip)->hashes->first;\n    } else {\n        $c->app->dbi->db->query('INSERT INTO ban (ip, until, strike) VALUES (?, ?, 1)', $c->ip, $until);\n        $c->record(1);\n    }\n\n    $c->strike($h->{strike});\n    $c->until($until);\n\n    return $c;\n}\n\n=head2 clear\n\n=over 1\n\n=item B<Usage>     : C<$c-E<gt>clear>\n\n=item B<Arguments> : none\n\n=item B<Purpose>   : delete all ban records from database where until < time\n\neg: C<WHERE until E<lt> ?, time>\n\n=item B<Returns>   : nothing is expected\n\n=back\n\n=cut\n\nsub clear {\n    my $c = shift;\n\n    $c->app->dbi->db->query('DELETE FROM ban WHERE until < ?', time);\n}\n\n=head2 unban\n\n=over 1\n\n=item B<Usage>     : C<$c-E<gt>unban>\n\n=item B<Arguments> : none\n\n=item B<Purpose>   : unban IP address\n\n=item B<Returns>   : the Lstu::DB::Ban object\n\n=back\n\n=cut\n\nsub unban {\n    my $c       = shift;\n\n    $c->app->dbi->db->query('DELETE from ban WHERE ip = ?', $c->ip);\n\n    return $c;\n}\n\n=head2 delete_all\n\n=over 1\n\n=item B<Usage>     : C<$c-E<gt>delete_all>\n\n=item B<Arguments> : none\n\n=item B<Purpose>   : delete all ban records from database unconditionnally\n\n=item B<Returns>   : nothing is expected\n\n=back\n\n=cut\n\nsub delete_all {\n    my $c = shift;\n\n    $c->app->dbi->db->query('DELETE FROM ban');\n}\n\n=head2 ban_ten_years\n\n=over 1\n\n=item B<Usage>     : C<$c-E<gt>ban_ten_years>\n\n=item B<Arguments> : none\n\n=item B<Purpose>   : ban an IP address forever\n\n=item B<Returns>   : nothing is expected\n\n=back\n\n=cut\n\nsub ban_ten_years {\n    my $c       = shift;\n\n    my $until = time + 315360000;\n\n    my $h = {\n        strike => time\n    };\n    if ($c->record) {\n        $c->app->dbi->db->query('UPDATE ban SET until = ?, strike = ? WHERE ip = ?', $until, time, $c->ip);\n        $h = $c->app->dbi->db->query('SELECT strike FROM ban WHERE ip = ?', $c->ip)->hashes->first;\n    } else {\n        $c->app->dbi->db->query('INSERT INTO ban (ip, until, strike) VALUES (?, ?, 1)', $c->ip, $until);\n        $c->record(1);\n    }\n\n    $c->strike($h->{strike});\n    $c->until($until);\n\n    return $c;\n}\n\n=head2 _slurp\n\n=over 1\n\n=item B<Usage>     : C<$c-E<gt>_slurp>\n\n=item B<Arguments> : none\n\n=item B<Purpose>   : put a database record's columns into the Lstu::DB::Ban object's attributes\n\n=item B<Returns>   : the Lstu::DB::Ban object\n\n=back\n\n=cut\n\nsub _slurp {\n    my $c = shift;\n\n    my $h = $c->app->dbi->db->query('SELECT * FROM ban WHERE ip = ?', $c->ip)->hashes;\n    if ($h->size) {\n        $c->until($h->first->{until});\n        $c->strike($h->first->{strike});\n        $c->record(1);\n    }\n\n    return $c;\n}\n\n1;\n"
  },
  {
    "path": "lib/Lstu/DB/Session/MySQL.pm",
    "content": "# vim:set sw=4 ts=4 sts=4 ft=perl expandtab:\npackage Lstu::DB::Session::MySQL;\nuse Mojo::Base 'Lstu::DB::Session';\n\nsub new {\n    my $c = shift;\n\n    $c = $c->SUPER::new(@_);\n\n    $c = $c->_slurp if ($c->token);\n\n    return $c;\n}\n\n1;\n"
  },
  {
    "path": "lib/Lstu/DB/Session/Pg.pm",
    "content": "# vim:set sw=4 ts=4 sts=4 ft=perl expandtab:\npackage Lstu::DB::Session::Pg;\nuse Mojo::Base 'Lstu::DB::Session';\n\nsub new {\n    my $c = shift;\n\n    $c = $c->SUPER::new(@_);\n\n    $c = $c->_slurp if ($c->token);\n\n    return $c;\n}\n\nsub remove {\n    my $c = shift;\n\n    my $h = $c->app->dbi->db->query('DELETE FROM sessions WHERE token = ? RETURNING *', $c->token)->hashes;\n    if ($h->size) {\n        $c = Lstu::DB::Session->new(app => $c->app);\n    }\n\n    return $h->size;\n}\n\n1;\n"
  },
  {
    "path": "lib/Lstu/DB/Session/SQLite.pm",
    "content": "# vim:set sw=4 ts=4 sts=4 ft=perl expandtab:\npackage Lstu::DB::Session::SQLite;\nuse Mojo::Base 'Lstu::DB::Session';\n\nsub new {\n    my $c = shift;\n\n    $c = $c->SUPER::new(@_);\n\n    $c = $c->_slurp if ($c->token);\n\n    return $c;\n}\n\n1;\n"
  },
  {
    "path": "lib/Lstu/DB/Session.pm",
    "content": "# vim:set sw=4 ts=4 sts=4 ft=perl expandtab:\npackage Lstu::DB::Session;\nuse Mojo::Base -base;\n\nhas 'token';\nhas 'until';\nhas 'record' => 0;\nhas 'app';\n\n=head1 NAME\n\nLstu::DB::Session - Abstraction layer for Lstu session system\n\n=head1 Contributing\n\nWhen creating a new database accessor, make sure that it provides the following subroutines.\nAfter that, modify this file and modify the C<new> subroutine to allow to use your accessor.\n\nHave a look at Lstu::DB::Session::SQLite's code: it's simple and may be more understandable that this doc.\n\n=head1 Attributes\n\n=over 1\n\n=item B<token>  : random string\n\n=item B<until>  : unix timestamp\n\n=item B<app>    : a mojolicious object\n\n=back\n\n=head1 Sub routines\n\n=head2 new\n\n=over 1\n\n=item B<Usage>     : C<$c = Lstu::DB::Session-E<gt>new(app =E<gt> $self);>\n\n=item B<Arguments> : any of the attribute above\n\n=item B<Purpose>   : construct a new Lstu::DB::Session object. If the C<token> attribute is provided, it have to load the informations from the database\n\n=item B<Returns>   : the Lstu::DB::Session object\n\n=item B<Info>      : the app argument is used by Lstu::DB::Session to choose which db accessor will be used, you don't need to use it in new(), but you can use it to access helpers or configuration settings in the other subroutines\n\n=back\n\n=cut\n\nsub new {\n    my $c = shift;\n\n    $c = $c->SUPER::new(@_);\n\n    if (ref($c) eq 'Lstu::DB::Session') {\n        my $dbtype = $c->app->config('dbtype');\n        if ($dbtype eq 'sqlite') {\n            require Lstu::DB::Session::SQLite;\n            $c = Lstu::DB::Session::SQLite->new(@_);\n        } elsif ($dbtype eq 'postgresql') {\n            require Lstu::DB::Session::Pg;\n            $c = Lstu::DB::Session::Pg->new(@_);\n        } elsif ($dbtype eq 'mysql') {\n            require Lstu::DB::Session::MySQL;\n            $c = Lstu::DB::Session::MySQL->new(@_);\n        }\n    }\n\n    return $c;\n}\n\nsub is_valid {\n    my $c = shift;\n\n    return 0 unless defined $c->until;\n    return ($c->until > time);\n}\n\nsub to_hash {\n    my $c = shift;\n\n    return {\n        token => $c->token,\n        until => $c->until\n    }\n}\n\n=head2 remove\n\n=over 1\n\n=item B<Usage>     : C<$c-E<gt>remove>\n\n=item B<Arguments> : none\n\n=item B<Purpose>   : remove the session record from the database\n\n=item B<Returns>   : the Lstu::DB::Session object\n\n=back\n\n=cut\n\nsub remove {\n    my $c = shift;\n\n    $c->app->dbi->db->query('DELETE FROM sessions WHERE token = ?', $c->token);\n    my $h = $c->app->dbi->db->query('SELECT * FROM sessions WHERE token = ?', $c->token)->hashes;\n    if ($h->size) {\n        # We found the session, it hasn't been removed\n        return 0;\n    } else {\n        $c = Lstu::DB::Session->new(app => $c->app);\n        # We didn't found the session, it has been removed\n        return 1;\n    }\n}\n\n=head2 write\n\n=over 1\n\n=item B<Usage>     : C<$c-E<gt>write>\n\n=item B<Arguments> : none\n\n=item B<Purpose>   : create or update the object in the database\n\n=item B<Returns>   : the Lstu::DB::Session object\n\n=back\n\n=cut\n\nsub write {\n    my $c     = shift;\n\n    if ($c->record) {\n        $c->app->dbi->db->query('UPDATE sessions SET until = ? WHERE token = ?', $c->until, $c->token);\n    } else {\n        $c->app->dbi->db->query('INSERT INTO sessions (token, until) VALUES (?, ?)', $c->token, $c->until);\n        $c->record(1);\n    }\n\n    return $c;\n}\n\n=head2 clear\n\n=over 1\n\n=item B<Usage>     : C<$c-E<gt>clear>\n\n=item B<Arguments> : none\n\n=item B<Purpose>   : delete all session records from database where until < time\n\neg: C<WHERE until E<lt> ?, time>\n\n=item B<Returns>   : nothing is expected\n\n=back\n\n=cut\n\nsub clear {\n    my $c = shift;\n\n    $c->app->dbi->db->query('DELETE FROM sessions WHERE until < ?', time);\n}\n\n=head2 delete_all\n\n=over 1\n\n=item B<Usage>     : C<$c-E<gt>delete_all>\n\n=item B<Arguments> : none\n\n=item B<Purpose>   : delete all session records from database unconditionnally\n\n=item B<Returns>   : nothing is expected\n\n=back\n\n=cut\n\nsub delete_all {\n    my $c = shift;\n\n    $c->app->dbi->db->query('DELETE FROM sessions');\n}\n\n=head2 _slurp\n\n=over 1\n\n=item B<Usage>     : C<$c-E<gt>_slurp>\n\n=item B<Arguments> : none\n\n=item B<Purpose>   : put a database record's columns into the Lstu::DB::Session object's attributes\n\n=item B<Returns>   : the Lstu::DB::Session object\n\n=back\n\n=cut\n\nsub _slurp {\n    my $c = shift;\n\n    my $h = $c->app->dbi->db->query('SELECT * FROM sessions WHERE token = ?', $c->token)->hashes;\n    if ($h->size) {\n        $c->token($h->first->{token});\n        $c->until($h->first->{until});\n        $c->record(1);\n    }\n\n    return $c;\n}\n\n1;\n"
  },
  {
    "path": "lib/Lstu/DB/URL/MySQL.pm",
    "content": "# vim:set sw=4 ts=4 sts=4 ft=perl expandtab:\npackage Lstu::DB::URL::MySQL;\nuse Mojo::Base 'Lstu::DB::URL';\n\nsub new {\n    my $c = shift;\n\n    $c = $c->SUPER::new(@_);\n\n    $c = $c->_slurp if ($c->short || $c->url);\n\n    return $c;\n}\n\n1;\n"
  },
  {
    "path": "lib/Lstu/DB/URL/Pg.pm",
    "content": "# vim:set sw=4 ts=4 sts=4 ft=perl expandtab:\npackage Lstu::DB::URL::Pg;\nuse Mojo::Base 'Lstu::DB::URL';\n\nsub new {\n    my $c = shift;\n\n    $c = $c->SUPER::new(@_);\n\n    $c = $c->_slurp if ($c->short || $c->url);\n\n    return $c;\n}\n\nsub increment_counter {\n    my $c = shift;\n\n    my $h = $c->app->dbi->db->query('UPDATE lstu SET counter = counter + 1 WHERE short = ? RETURNING counter', $c->short)->hashes->first;\n    $c->counter($h->{counter});\n\n    return $c;\n}\n\nsub remove {\n    my $c = shift;\n\n    my $removed = 0;\n\n    if ($c->app->config('really_delete_urls')) {\n        $removed = $c->app->dbi->db->query('DELETE FROM lstu WHERE short = ? RETURNING disabled', $c->short)->hashes->size;\n    } else {\n        $removed = $c->app->dbi->db->query('UPDATE lstu SET disabled = 1 WHERE short = ? RETURNING disabled', $c->short)->hashes->first->{disabled};\n    }\n    if ($removed) {\n        if (scalar(@{$c->app->config('memcached_servers')})) {\n            $c->app->chi('lstu_urls_cache')->remove($c->short);\n        }\n        $c = Lstu::DB::URL->new(app => $c->app);\n    }\n    return $removed;\n}\n\n1;\n"
  },
  {
    "path": "lib/Lstu/DB/URL/SQLite.pm",
    "content": "# vim:set sw=4 ts=4 sts=4 ft=perl expandtab:\npackage Lstu::DB::URL::SQLite;\nuse Mojo::Base 'Lstu::DB::URL';\n\nsub new {\n    my $c = shift;\n\n    $c = $c->SUPER::new(@_);\n\n    $c = $c->_slurp if ($c->short || $c->url);\n\n    return $c;\n}\n\nsub paginate {\n    my $c           = shift;\n    my $page        = shift;\n    my $page_offset = shift;\n    my $order       = shift // 'counter';\n    my $dir         = shift // '-desc';\n    $dir =~ s/^-//;\n\n    return @{$c->app->dbi->db->query(\"SELECT * FROM lstu WHERE url IS NOT NULL AND disabled = 0 ORDER BY $order $dir LIMIT ? OFFSET ?\", $page_offset, $page * $page_offset)->hashes->to_array};\n}\n\n1;\n"
  },
  {
    "path": "lib/Lstu/DB/URL.pm",
    "content": "# vim:set sw=4 ts=4 sts=4 ft=perl expandtab:\npackage Lstu::DB::URL;\nuse Mojo::Base -base;\n\nhas 'short';\nhas 'url';\nhas 'counter' => 0;\nhas 'timestamp';\nhas 'created_by';\nhas 'disabled' => 0;\nhas 'record' => 0;\nhas 'app';\n\n=head1 NAME\n\nLstu::DB::URL - Abstraction layer for Lstu session system\n\n=head1 Contributing\n\nWhen creating a new database accessor, make sure that it provides the following subroutines.\nAfter that, modify this file and modify the C<new> subroutine to allow to use your accessor.\n\nHave a look at Lstu::DB::URL::SQLite's code: it's simple and may be more understandable that this doc.\n\n=head1 Attributes\n\n=over 1\n\n=item B<short>      : random string\n\n=item B<url>        : string, valid URL\n\n=item B<counter>    : integer\n\n=item B<timestamp>  : unix timestamp\n\n=item B<created_by> : the IP address of the creator\n\n=item B<disabled>   : boolean (0 or 1), is the URL active?\n\n=item B<app>        : a mojolicious object\n\n=back\n\n=head1 Sub routines\n\n=head2 new\n\n=over 1\n\n=item B<Usage>     : C<$c = Lstu::DB::URL-E<gt>new(app =E<gt> $self);>\n\n=item B<Arguments> : any of the attribute above\n\n=item B<Purpose>   : construct a new Lstu::DB::URL object. If the C<short> or the C<url> attribute is provided, it have to load the informations from the database. In the case of multiple records for the same C<url>, choose the first.\n\n=item B<Returns>   : the Lstu::DB::URL object\n\n=item B<Info>      : the app argument is used by Lstu::DB::URL to choose which db accessor will be used, you don't need to use it in new(), but you can use it to access helpers or configuration settings in the other subroutines\n\n=back\n\n=cut\n\nsub new {\n    my $c = shift;\n\n    $c = $c->SUPER::new(@_);\n\n    if (ref($c) eq 'Lstu::DB::URL') {\n        my $dbtype = $c->app->config('dbtype');\n        if ($dbtype eq 'sqlite') {\n            require Lstu::DB::URL::SQLite;\n            $c = Lstu::DB::URL::SQLite->new(@_);\n        } elsif ($dbtype eq 'postgresql') {\n            require Lstu::DB::URL::Pg;\n            $c = Lstu::DB::URL::Pg->new(@_);\n        } elsif ($dbtype eq 'mysql') {\n            require Lstu::DB::URL::MySQL;\n            $c = Lstu::DB::URL::MySQL->new(@_);\n        }\n    }\n\n    return $c;\n}\n\nsub to_hash {\n    my $c = shift;\n\n    return {\n        short      => $c->short,\n        url        => $c->url,\n        disabled   => $c->disabled,\n        counter    => $c->counter,\n        timestamp  => $c->timestamp,\n        created_by => $c->created_by\n    };\n}\n\n=head2 increment_counter\n\n=over 1\n\n=item B<Usage>     : C<$c-E<gt>increment_counter>\n\n=item B<Arguments> : none\n\n=item B<Purpose>   : increment the C<counter> attribute of the Lstu::DB::URL object and update the database record\n\n=item B<Returns>   : the Lstu::DB::URL object\n\n=back\n\n=cut\n\nsub increment_counter {\n    my $c = shift;\n\n    $c->app->dbi->db->query('UPDATE lstu SET counter = counter + 1 WHERE short = ?', $c->short);\n    my $h = $c->app->dbi->db->query('SELECT counter FROM lstu WHERE short = ?', $c->short)->hashes->first;\n    $c->counter($h->{counter});\n\n    return $c;\n}\n\n=head2 write\n\n=over 1\n\n=item B<Usage>     : C<$c-E<gt>write>\n\n=item B<Arguments> : none\n\n=item B<Purpose>   : create or update the object in the database\n\n=item B<Returns>   : the Lstu::DB::URL object\n\n=back\n\n=cut\n\nsub write {\n    my $c     = shift;\n\n    if ($c->record) {\n        $c->app->dbi->db->query('UPDATE lstu SET url = ?, counter = ?, timestamp = ?, created_by = ?, disabled = ? WHERE short = ?', $c->url, $c->counter, $c->timestamp, $c->created_by, $c->disabled, $c->short);\n    } else {\n        $c->app->dbi->db->query('INSERT INTO lstu (short, url, counter, timestamp, created_by, disabled) VALUES (?, ?, ?, ?, ?, ?)', $c->short, $c->url, $c->counter, $c->timestamp, $c->created_by, $c->disabled);\n        $c->record(1);\n    }\n\n    return $c;\n}\n\n=head2 remove\n\n=over 1\n\n=item B<Usage>     : C<$c-E<gt>remove>\n\n=item B<Arguments> : none\n\n=item B<Purpose>   : remove the URL record from the database\n\n=item B<Returns>   : 1 for success, 0 for failure\n\n=back\n\n=cut\n\nsub remove {\n    my $c = shift;\n\n    my $removed = 0;\n\n    if ($c->app->config('really_delete_urls')) {\n        $c->app->dbi->db->query('DELETE FROM lstu WHERE short = ?', $c->short);\n        my $count = $c->app->dbi->db->query('SELECT count(*) FROM lstu WHERE short = ?', $c->short)->hashes->first->{count};\n        $removed = ($count == 0) ? 1 : 0;\n    } else {\n        $c->app->dbi->db->query('UPDATE lstu SET disabled = 1 WHERE short = ?', $c->short);\n        $removed = $c->app->dbi->db->query('SELECT disabled FROM lstu WHERE short = ?', $c->short)->hashes->first->{disabled};\n    }\n    if ($removed) {\n        if (scalar(@{$c->app->config('memcached_servers')})) {\n            $c->app->chi('lstu_urls_cache')->remove($c->short);\n        }\n        $c = Lstu::DB::URL->new(app => $c->app);\n    }\n    return $removed;\n}\n\n=head2 exist\n\n=over 1\n\n=item B<Usage>     : C<$c-E<gt>exist('short')>\n\n=item B<Arguments> : string\n\n=item B<Purpose>   : count how many database record there is with C<short> equal to the argument.\n\neg: COUNT(short) WHERE short = ?, $argument\n\n=item B<Returns>   : integer. Should be 0 or 1\n\n=back\n\n=cut\n\nsub exist {\n    my $c     = shift;\n    my $short = shift;\n\n    return undef unless $short;\n\n    return $c->app->dbi->db->query('SELECT count(short) AS count FROM lstu WHERE short = ?', $short)->hashes->first->{count};\n}\n\n=head2 choose_empty\n\n=over 1\n\n=item B<Usage>     : C<$c-E<gt>choose_empty>\n\n=item B<Arguments> : none\n\n=item B<Purpose>   : choose an unassigned short string in the database\n\n=item B<Returns>   : string, an unassigned short string\n\n=back\n\n=cut\n\nsub choose_empty {\n    my $c = shift;\n\n    my $h = $c->app->dbi->db->query('SELECT * FROM lstu WHERE url IS NULL')->hashes->shuffle;\n\n    if ($h->size) {\n        $c->short($h->first->{short});\n        $c->record(1);\n        return $c;\n    } else {\n        return undef;\n    }\n}\n\n=head2 count_empty\n\n=over 1\n\n=item B<Usage>     : C<$c-E<gt>count_empty>\n\n=item B<Arguments> : none\n\n=item B<Purpose>   : count how many unassigned short string there is in the database\n\neg: C<COUNT(short) WHERE url IS NULL>\n\n=item B<Returns>   : integer\n\n=back\n\n=cut\n\nsub count_empty {\n    my $c = shift;\n\n    return $c->app->dbi->db->query('SELECT count(short) AS count FROM lstu WHERE url IS NULL')->hashes->first->{count};\n}\n\n=head2 paginate\n\n=over 1\n\n=item B<Usage>     : C<$c-E<gt>paginate($page, $page_offset)>\n\n=item B<Arguments> : two integers.\n\n=over 2\n\n=item B<$page>        : the number of the page you want\n\n=item B<$page_offset> : the number of records per page.\n\n=back\n\n=item B<Purpose>   : returns all the URL records, page per page, ordered by the C<counter> attribute\n\neg: SELECT * WHERE url IS NOT NULL ORDER BY counter DESC LIMIT ? OFFSET ?, $page_offset, $page * $page_offset\n\n=item B<Returns>   : an array of hash references, containing all the Lstu::DB::URL attributes, except C<dbtype>\n\n=back\n\n=cut\n\nsub paginate {\n    my $c           = shift;\n    my $page        = shift;\n    my $page_offset = shift;\n    my $order       = shift // 'counter';\n    my $dir         = shift // '-desc';\n\n    return @{$c->app->dbi->db->select('lstu', undef, { url => { '!=', undef }, disabled => 0 }, { order_by => { $dir => $order }, limit => $page_offset, offset => $page * $page_offset })->hashes->to_array};\n}\n\n=head2 get_a_lot\n\n=over 1\n\n=item B<Usage>     : C<$c-E<gt>get_a_lot(['short1', 'short2'])>\n\n=item B<Arguments> : an array reference of strings, which are C<short> attributes\n\n=item B<Purpose>   : returns all the URL records which C<short> attribute are in the array ref\n\n=item B<Returns>   : an array of hash references, containing all the Lstu::DB::URL attributes, except C<dbtype>\n\n=back\n\n=cut\n\nsub get_a_lot {\n    my $c = shift;\n    my $u = shift;\n\n    if (scalar @{$u}) {\n        my $p = join \",\", (('?') x @{$u});\n        return @{$c->app->dbi->db->query('SELECT * FROM lstu WHERE short IN ('.$p.') ORDER BY counter DESC', @{$u})->hashes->to_array};\n    } else {\n        return ();\n    }\n}\n\n=head2 total\n\n=over 1\n\n=item B<Usage>     : C<$c-E<gt>total>\n\n=item B<Arguments> : none\n\n=item B<Purpose>   : count how many shorten links there is in the database.\n\neg: C<COUNT(short) WHERE url IS NOT NULL>\n\n=item B<Returns>   : integer\n\n=back\n\n=cut\n\nsub total {\n    my $c = shift;\n\n    return $c->app->dbi->db->query('SELECT count(short) AS count FROM lstu WHERE url IS NOT NULL AND disabled = 0')->hashes->first->{count};\n}\n\n=head2 delete_all\n\n=over 1\n\n=item B<Usage>     : C<$c-E<gt>delete_all>\n\n=item B<Arguments> : none\n\n=item B<Purpose>   : delete all URL records from database unconditionnally\n\n=item B<Returns>   : nothing is expected\n\n=back\n\n=cut\n\nsub delete_all {\n    my $c = shift;\n\n    $c->app->dbi->db->query('DELETE FROM lstu');\n}\n\n=head2 search_url\n\n=over 1\n\n=item B<Usage>     : C<$c-E<gt>search_url($string)>\n\n=item B<Arguments> : string, part of URL to search\n\n=item B<Purpose>   : search records which real url matches the given string\n\n=item B<Returns>   : a Mojo::Collection containing hashes of the matching records\n\n=back\n\n=cut\n\nsub search_url {\n    my $c = shift;\n    my $s = shift;\n\n    $c->app->dbi->db->select('lstu', undef, { url => {-like => '%'.$s.'%'}})->hashes;\n}\n\n=head2 search_creator\n\n=over 1\n\n=item B<Usage>     : C<$c-E<gt>search_creator($string)>\n\n=item B<Arguments> : string, IP address to search\n\n=item B<Purpose>   : search records which creator's IP address matches the given string\n\n=item B<Returns>   : a Mojo::Collection containing hashes of the matching records\n\n=back\n\n=cut\n\nsub search_creator {\n    my $c = shift;\n    my $s = shift;\n\n    $c->app->dbi->db->select('lstu', undef, { created_by => $s })->hashes;\n}\n\n=head2 get_all_urls\n\n=over 1\n\n=item B<Usage>     : C<$c-E<gt>get_all_urls()>\n\n=item B<Arguments> : none\n\n=item B<Purpose>   : return all non-empty records\n\n=item B<Returns>   : a Mojo::Collection containing hashes of all non-empty records\n\n=back\n\n=cut\n\nsub get_all_urls {\n    my $c = shift;\n\n    $c->app->dbi->db->select('lstu', undef, { url => { '!=', undef } })->hashes;\n}\n\n=head2 get_all_urls_created_ago\n\n=over 1\n\n=item B<Usage>     : C<$c-E<gt>get_all_urls_created_ago($seconds)>\n\n=item B<Arguments> : integer, number of seconds\n\n=item B<Purpose>   : return all non-empty records created less than $seconds agog\n\n=item B<Returns>   : a Mojo::Collection containing hashes of matching records\n\n=back\n\n=cut\n\nsub get_all_urls_created_ago {\n    my $c     = shift;\n    my $delay = shift;\n\n    $c->app->dbi->db->select('lstu', undef, { url => { '!=', undef }, timestamp => { '>=', time - $delay } })->hashes;\n}\n\n=head2 _slurp\n\n=over 1\n\n=item B<Usage>     : C<$c-E<gt>_slurp>\n\n=item B<Arguments> : none\n\n=item B<Purpose>   : put a database record's columns into the Lstu::DB::URL object's attributes\n\n=item B<Returns>   : the Lstu::DB::URL object\n\n=back\n\n=cut\n\nsub _slurp {\n    my $c = shift;\n\n    my $h;\n    if ($c->short) {\n       $h = $c->app->dbi->db->query('SELECT * FROM lstu WHERE short = ?', $c->short)->hashes;\n   } else {\n       $h = $c->app->dbi->db->query('SELECT * FROM lstu WHERE url = ?', $c->url)->hashes;\n   }\n    if ($h->size) {\n        $c->url($h->first->{url});\n        $c->short($h->first->{short});\n        $c->counter($h->first->{counter});\n        $c->timestamp($h->first->{timestamp});\n        $c->created_by($h->first->{created_by});\n        $c->disabled($h->first->{disabled});\n        $c->record(1);\n    }\n\n    return $c;\n}\n\n1;\n"
  },
  {
    "path": "lib/Lstu/DefaultConfig.pm",
    "content": "# vim:set sw=4 ts=4 sts=4 ft=perl expandtab:\npackage Lstu::DefaultConfig;\nrequire Exporter;\n@ISA = qw(Exporter);\n@EXPORT_OK = qw($default_config);\nour $default_config = {\n    prefix                 => '/',\n    provisioning           => 100,\n    provis_step            => 5,\n    length                 => 8,\n    secret                 => ['hfudsifdsih'],\n    really_delete_urls     => 0,\n    page_offset            => 10,\n    theme                  => 'default',\n    ban_min_strike         => 3,\n    ban_whitelist          => [],\n    ban_blacklist          => [],\n    minion                 => {\n        enabled => 0,\n        db_path => 'minion.db'\n    },\n    session_duration       => 3600,\n    disable_api            => 0,\n    dbtype                 => 'sqlite',\n    db_path                => 'lstu.db',\n    max_redir              => 2,\n    skip_spamhaus          => 0,\n    safebrowsing_api_key   => '',\n    memcached_servers      => [],\n    x_frame_options        => 'DENY',\n    x_content_type_options => 'nosniff',\n    x_xss_protection       => '1; mode=block',\n    log_creator_ip         => 0,\n    qrcode_size            => 3,\n};\n\n1;\n"
  },
  {
    "path": "lib/Lstu/Plugin/Headers.pm",
    "content": "package Lstu::Plugin::Headers;\nuse Mojo::Base 'Mojolicious::Plugin';\n\nsub register {\n    my ($self, $app) = @_;\n\n    # Assets Cache headers\n    $app->plugin('StaticCache' => { even_in_dev => 1, max_age => 2592000 });\n\n    # Add CSP Header\n    if (!defined($app->config('csp')) || (defined($app->config('csp')) && $app->config('csp') ne '')) {\n        my $directives = {\n            'default-src'     => \"'none'\",\n            'script-src'      => \"'self'\",\n            'style-src'       => \"'self'\",\n            'img-src'         => \"'self' data:\",\n            'font-src'        => \"'self'\",\n            'form-action'     => \"'self'\",\n            'base-uri'        => \"'self'\",\n        };\n\n        my $frame_ancestors = '';\n        $frame_ancestors = \"'none'\" if $app->config('x_frame_options') eq 'DENY';\n        $frame_ancestors = \"'self'\" if $app->config('x_frame_options') eq 'SAMEORIGIN';\n        if ($app->config('x_frame_options') =~ m#^ALLOW-FROM#) {\n            $frame_ancestors = $app->config('x_frame_options');\n            $frame_ancestors =~ s#ALLOW-FROM +##;\n        }\n        $directives->{'frame-ancestors'} = $frame_ancestors if $frame_ancestors;\n\n        $app->plugin('CSPHeader',\n            csp        => $app->config('csp'),\n            directives => $directives\n        );\n    }\n\n    # Add other headers\n    $app->hook(\n        before_dispatch => sub {\n            my $c = shift;\n\n            $c->res->headers->header('X-Frame-Options'        => $app->config('x_frame_options'))        if $app->config('x_frame_options');\n            $c->res->headers->header('X-Content-Type-Options' => $app->config('x_content_type_options')) if $app->config('x_content_type_options');\n            $c->res->headers->header('X-XSS-Protection'       => $app->config('x_xss_protection'))       if $app->config('x_xss_protection');\n        }\n    );\n\n}\n\n1;\n"
  },
  {
    "path": "lib/Lstu/Plugin/Helpers.pm",
    "content": "package Lstu::Plugin::Helpers;\nuse Mojo::Base 'Mojolicious::Plugin';\nuse Mojo::URL;\nuse Net::Abuse::Utils::Spamhaus qw(check_fqdn);\nuse Lstu::DB::URL;\nuse Lstu::DB::Ban;\nuse Lstu::DB::Session;\nuse FindBin qw($Bin);\n\nsub register {\n    my ($self, $app) = @_;\n\n    # PgURL helper\n    if ($app->config('dbtype') eq 'postgresql' || $app->config('dbtype') eq 'mysql') {\n        $app->plugin('PgURLHelper');\n    }\n\n    # DB migrations\n    if ($app->config('dbtype') eq 'sqlite') {\n        require Mojo::SQLite;\n        $app->helper(dbi => \\&_sqlite);\n\n        # Database migration\n        # Have to create $sql before using its migrations attribute, otherwise, it won't work\n        my $sql        = Mojo::SQLite->new('sqlite:'.$app->config('db_path'));\n        my $migrations = $sql->migrations;\n        if ($app->mode eq 'development' && $ENV{LSTU_DEBUG}) {\n            $migrations->from_file('utilities/migrations/sqlite.sql')->migrate(0)->migrate($migrations->latest);\n        } else {\n            $migrations->from_file('utilities/migrations/sqlite.sql')->migrate($migrations->latest);\n        }\n    } elsif ($app->config('dbtype') eq 'postgresql') {\n        require Mojo::Pg;\n        $app->helper(dbi => \\&_pg);\n\n        # Database migration\n        my $migrations = Mojo::Pg::Migrations->new(pg => $app->dbi);\n        if ($app->mode eq 'development' && $ENV{LSTU_DEBUG}) {\n            $migrations->from_file('utilities/migrations/postgresql.sql')->migrate(0)->migrate($migrations->latest);\n        } else {\n            $migrations->from_file('utilities/migrations/postgresql.sql')->migrate($migrations->latest);\n        }\n    } elsif ($app->config('dbtype') eq 'mysql') {\n        require Mojo::mysql;\n        $app->helper(dbi => \\&_mysql);\n\n        # Database migration\n        my $migrations = Mojo::mysql::Migrations->new(mysql => $app->dbi);\n        if ($app->mode eq 'development' && $ENV{LSTU_DEBUG}) {\n            $migrations->from_file('utilities/migrations/mysql.sql')->migrate(0)->migrate($migrations->latest);\n        } else {\n            $migrations->from_file('utilities/migrations/mysql.sql')->migrate($migrations->latest);\n        }\n    }\n\n    # Helpers\n    $app->helper(ip           => \\&_ip);\n    $app->helper(provisioning => \\&_provisioning);\n    $app->helper(prefix       => \\&_prefix);\n    $app->helper(shortener    => \\&_shortener);\n    $app->helper(is_spam      => \\&_is_spam);\n    $app->helper(cleaning     => \\&_cleaning);\n    $app->helper(gsb          => \\&_gsb);\n    $app->helper(gsb_update   => \\&_gsb_update);\n}\n\nsub _sqlite {\n    my $c = shift;\n\n    state $sqlite = Mojo::SQLite->new('sqlite:'.$c->app->config('db_path'));\n    return $sqlite;\n}\n\nsub _pg {\n    my $c     = shift;\n\n    my $pgdb  = $c->config('pgdb');\n    my $port  = (defined $pgdb->{port}) ? $pgdb->{port}: 5432;\n    my $addr  = $c->pg_url({\n        host => $pgdb->{host}, port => $port, database => $pgdb->{database}, user => $pgdb->{user}, pwd => $pgdb->{pwd}\n    });\n    state $pg = Mojo::Pg->new($addr);\n    $pg->max_connections($pgdb->{max_connections}) if defined $pgdb->{max_connections};\n    return $pg;\n}\n\nsub _mysql {\n    my $c     = shift;\n\n    my $mysqldb  = $c->config('mysqldb');\n    my $port  = (defined $mysqldb->{port}) ? $mysqldb->{port}: 3306;\n    my $addr  = $c->pg_url({\n        host => $mysqldb->{host}, port => $port, database => $mysqldb->{database}, user => $mysqldb->{user}, pwd => $mysqldb->{pwd}\n    });\n    $addr =~ s/postgresql/mysql/;\n    state $mysql = Mojo::mysql->new($addr);\n    $mysql->max_connections($mysqldb->{max_connections}) if defined $mysqldb->{max_connections};\n    return $mysql;\n}\n\nsub _ip {\n    my $c     = shift;\n\n    my $proxy = $c->req->headers->header('X-Forwarded-For');\n    my $ip    = ($proxy) ? $proxy : $c->tx->remote_address;\n\n    return $ip;\n}\n\nsub _provisioning {\n     my $c = shift;\n\n     # Create some short patterns for provisioning\n     my $db_url = Lstu::DB::URL->new(app => $c);\n     if ($db_url->count_empty < $c->config('provisioning')) {\n         for (my $i = 0; $i < $c->config('provis_step'); $i++) {\n             my $short;\n             do {\n                 $short = $c->shortener($c->config('length'));\n             } while ($db_url->exist($short) || $short =~ m#^(a|d|cookie|stats|fullstats|login|logout|api)$#);\n\n             $db_url->short($short)->write;\n         }\n     }\n}\n\nsub _prefix {\n    my $c = shift;\n\n    my $prefix = $c->url_for('index')->to_abs;\n    # Forced domain\n    $prefix->host($c->config('fixed_domain')) if (defined($c->config('fixed_domain')) && $c->config('fixed_domain') ne '');\n    # Hack for prefix (subdir) handling\n    $prefix .= '/' unless ($prefix =~ m#/$#);\n    return $prefix;\n}\n\nsub _shortener {\n    my $c      = shift;\n    my $length = shift;\n\n    my @chars  = ('a'..'h', 'j', 'k', 'm'..'z','A'..'H', 'J'..'N', 'P'..'Z','0'..'9', '-', '_');\n    my $result = '';\n    foreach (1..$length) {\n        $result .= $chars[rand scalar(@chars)];\n    }\n    return $result;\n}\n\nsub _is_spam {\n    my $c        = shift;\n    my $url      = shift;\n    my $nb_redir = shift;\n\n    my $ip = $c->ip;\n    return { is_spam => 0 } if scalar(grep {/$ip/} @{$c->config('ban_whitelist')});\n    my $wl = $c->config('spam_whitelist_regex');\n    return { is_spam => 0 } if (defined($wl) && $url->host =~ m/$wl/);\n\n    my $bl      = $c->config('spam_blacklist_regex');\n    my $path_bl = $c->config('spam_path_blacklist_regex');\n    return {\n       is_spam => 1,\n       msg     => $c->l('The URL you want to shorten comes from a domain (%1) that is blacklisted on this server (usually because of spammers that use this domain).', $url->host)\n    } if ((defined($bl) && $url->host =~ m/$bl/) || (defined($path_bl) && $url->path =~ m/$path_bl/));\n\n    if ($nb_redir++ <= $c->config('max_redir')) {\n        my $res = ($c->config('skip_spamhaus')) ? undef : check_fqdn($url->host);\n        if (defined $res) {\n           return {\n               is_spam => 1,\n               msg     => $c->l('The URL host or one of its redirection(s) (%1) is blacklisted at Spamhaus. I refuse to shorten it.', $url->host)\n           }\n        } else {\n            if ($c->config('safebrowsing_api_key') && scalar($c->gsb->lookup(url => $url->to_string))) {\n                return {\n                    is_spam => 1,\n                    msg     => $c->l('The URL or one of its redirection(s) (%1) is blacklisted in Google Safe Browsing database. I refuse to shorten it.', $url)\n                }\n            }\n            my $res = $c->ua->head($url)->res;\n            if (defined($res->code) && $res->code >= 300 && $res->code < 400) {\n                my $new_url = Mojo::URL->new($res->headers->location);\n                $new_url->host($url->host)     unless $new_url->host;\n                $new_url->scheme($url->scheme) unless $new_url->scheme;\n                return $c->is_spam($new_url, $nb_redir);\n            } else {\n                return { is_spam => 0 };\n            }\n        }\n    } else {\n       return {\n           is_spam => 1,\n           msg     => $c->l('The URL redirects %1 times or most. It\\'s most likely a dangerous URL (spam, phishing, etc.). I refuse to shorten it.', $c->config('max_redir'))\n       }\n    }\n}\n\nsub _cleaning {\n    my $c = shift;\n\n    # Delete old sessions\n    Lstu::DB::Session->new(app => $c)->clear();\n    # Delete old bans\n    Lstu::DB::Ban->new(app => $c)->clear();\n}\n\nsub _gsb {\n    my $c     = shift;\n    my $check = shift;\n\n    # Google safebrowsing (if configured)\n    if ($c->config('safebrowsing_api_key')) {\n        use Net::Google::SafeBrowsing4;\n        use Net::Google::SafeBrowsing4::Storage::File;\n\n        my $force_update = (!-e Mojo::File->new($Bin, '..' , 'safebrowsing_db'));\n\n        state $gsb = Net::Google::SafeBrowsing4->new(\n            key     => $c->config('safebrowsing_api_key'),\n            storage => Net::Google::SafeBrowsing4::Storage::File->new(path => Mojo::File->new($Bin, '..' , 'safebrowsing_db')),\n        );\n\n        my $lock_file = Mojo::File->new($Bin, '..', 'gsb.lock');\n        if ($force_update) {\n            $lock_file->touch;\n            $gsb->update();\n            $lock_file->remove_tree;\n        } elsif ($check) {\n            if (! -e $lock_file->to_string) {\n                $lock_file->touch;\n                my $update = Mojo::File->new($Bin, '..' , 'safebrowsing_db')->to_string;\n                my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,$ctime,$blksize,$blocks) = stat($update);\n                $gsb->update() if $mtime < time - 86400;\n                $lock_file->remove_tree;\n            }\n        }\n\n        return $gsb;\n    } else {\n        return undef;\n    }\n}\n\n1;\n"
  },
  {
    "path": "lib/Lstu.pm",
    "content": "# vim:set sw=4 ts=4 sts=4 ft=perl expandtab:\npackage Lstu;\nuse Mojo::Base 'Mojolicious';\nuse Mojo::JSON;\nuse Lstu::DB::URL;\nuse Lstu::DefaultConfig qw($default_config);\n\n$ENV{MOJO_REVERSE_PROXY} = 1;\n\n# This method will run once at server start\nsub startup {\n    my $self = shift;\n\n    my $config = $self->plugin('Config' => {\n        default => $default_config\n    });\n\n    $config->{provisioning} = $config->{provisionning} if (defined($config->{provisionning}));\n\n    die \"You need to provide a contact information in lstu.conf!\" unless (defined($config->{contact}));\n\n    # qrcode_size correction if needed;\n    $self->config('qrcode_size', 100) if $self->config('qrcode_size') > 100;\n    $self->config('qrcode_size', 1  ) if $self->config('qrcode_size') < 1;\n    $self->config('qrcode_size', sprintf('%d', $self->config('qrcode_size')));\n\n    # Themes handling\n    shift @{$self->renderer->paths};\n    shift @{$self->static->paths};\n    if ($config->{theme} ne 'default') {\n        my $theme = $self->home->rel_file('themes/'.$config->{theme});\n        push @{$self->renderer->paths}, $theme.'/templates' if -d $theme.'/templates';\n        push @{$self->static->paths}, $theme.'/public' if -d $theme.'/public';\n    }\n    push @{$self->renderer->paths}, $self->home->rel_file('themes/default/templates');\n    push @{$self->static->paths}, $self->home->rel_file('themes/default/public');\n\n    # Internationalization\n    my $lib = $self->home->rel_file('themes/'.$config->{theme}.'/lib');\n    eval qq(use lib \"$lib\");\n    $self->plugin('I18N');\n\n    # Debug\n    $self->plugin('DebugDumperHelper');\n\n    # Piwik\n    $self->plugin('Piwik');\n\n    # Static assets gzipping\n    $self->plugin('GzipStatic');\n\n    # URL cache\n    if (scalar(@{$config->{memcached_servers}})) {\n        $self->plugin(CHI => {\n            lstu_urls_cache => {\n                driver             => 'Memcached',\n                servers            => $config->{memcached_servers},\n                expires_in         => '1 day',\n                expires_on_backend => 1,\n            }\n        });\n    }\n\n    # Headers\n    $self->plugin('Lstu::Plugin::Headers');\n\n    # Lstu Helpers\n    $self->plugin('Lstu::Plugin::Helpers');\n\n    # Authentication (if configured)\n    if (defined($self->config('ldap')) || defined($self->config('htpasswd'))) {\n        if (defined($self->config('ldap'))) {\n            require Net::LDAP;\n        }\n        if (defined($self->config('htpasswd'))) {\n            require Apache::Htpasswd;\n        }\n        die 'Unable to read '.$self->config('htpasswd') if (defined($self->config('htpasswd')) && !-r $self->config('htpasswd'));\n        $self->plugin('Authentication' =>\n            {\n                autoload_user => 1,\n                session_key   => 'Lstu',\n                load_user     => sub {\n                    my ($c, $username) = @_;\n\n                    return $username;\n                },\n                validate_user => sub {\n                    my ($c, $username, $password, $extradata) = @_;\n\n                    if (defined($c->config('ldap'))) {\n                        my $ldap = Net::LDAP->new($c->config->{ldap}->{uri});\n\n                        my $mesg;\n                        if (defined($c->config->{ldap}->{bind_dn}) && defined($c->config->{ldap}->{bind_pwd})) {\n                            # connect to the ldap server using the bind credentials\n                            $mesg = $ldap->bind(\n                                $c->config->{ldap}->{bind_dn},\n                                password => $c->config->{ldap}->{bind_pwd}\n                            );\n                        } else {\n                            # anonymous bind\n                            $mesg = $ldap->bind\n                        }\n\n                        if ($mesg->code) {\n                            $c->app->log->info('[LDAP INFO] Authenticated bind failed - Login: '.$c->config->{ldap}->{bind_dn}) if defined($c->config->{ldap}->{bind_dn});\n                            $c->app->log->error('[LDAP ERROR] Error on bind: '.$mesg->error);\n                            return undef;\n                        }\n\n                        my $ldap_user_attr   = $c->config->{ldap}->{user_attr};\n                        my $ldap_user_filter = $c->config->{ldap}->{user_filter};\n\n                        # search the ldap database for the user who is trying to login\n                        $mesg = $ldap->search(\n                            base   => $c->config->{ldap}->{user_tree},\n                            filter => \"(&($ldap_user_attr=$username)$ldap_user_filter)\"\n                        );\n\n                        if ($mesg->code) {\n                            $c->app->log->error('[LDAP ERROR] Error on search: '.$mesg->error);\n                            return undef;\n                        }\n\n                        # check to make sure that the ldap search returned at least one entry\n                        my @entries = $mesg->entries;\n                        my $entry   = $entries[0];\n\n                        unless (defined $entry) {\n                            $c->app->log->info(\"[LDAP INFO] Authentication failed - User $username filtered out, IP: \".$c->ip);\n                            return undef;\n                        }\n\n                        # retrieve the first user returned by the search\n                        $c->app->log->debug(\"[LDAP DEBUG] Found user dn: \".$entry->dn);\n\n                        # Now we know that the user exists\n                        $mesg = $ldap->bind($entry->dn,\n                            password => $password\n                        );\n\n                        if ($mesg->code) {\n                            $c->app->log->info(\"[LDAP INFO] Authentication failed - Login: $username, IP: \".$c->ip);\n                            $c->app->log->error('[LDAP ERROR] Authentication failed '.$mesg->error);\n                            return undef;\n                        }\n\n                        $c->app->log->info(\"[LDAP INFO] Authentication successful - Login: $username, IP: \".$c->ip);\n                    } elsif (defined($c->config('htpasswd'))) {\n                        my $htpasswd = new Apache::Htpasswd(\n                            {\n                                passwdFile => $c->config('htpasswd'),\n                                ReadOnly   => 1\n                            }\n                        );\n                        if (!$htpasswd->htCheckPassword($username, $password)) {\n                            return undef;\n                        }\n                        $c->app->log->info(\"[Simple authentication successful] login: $username, IP: \".$c->ip);\n                    }\n\n                    return $username;\n                }\n            }\n        );\n        $self->app->sessions->default_expiration($self->config('session_duration'));\n    }\n\n    # Minion\n    if ($config->{minion}->{enabled}) {\n        if ($config->{dbtype} eq 'sqlite') {\n            $self->plugin('Minion' => { SQLite => 'sqlite:'.$config->{minion}->{db_path} }) if $config->{minion}->{db_path};\n        } elsif ($config->{dbtype} eq 'postgresql') {\n            my $pgdb  = $config->{minion}->{pgdb};\n            my $port  = (defined $pgdb->{port}) ? $pgdb->{port}: 5432;\n            my $addr  = $self->pg_url({\n                host => $pgdb->{host}, port => $port, database => $pgdb->{database}, user => $pgdb->{user}, pwd => $pgdb->{pwd}\n            });\n\n            $self->plugin('Minion' => { Pg => $addr });\n        } elsif ($config->{dbtype} eq 'mysql') {\n            my $mysqldb = $config->{minion}->{mysqldb};\n            my $port    = (defined $mysqldb->{port}) ? $mysqldb->{port}: 3306;\n            my $addr    = $self->pg_url({\n                host => $mysqldb->{host}, port => $port, database => $mysqldb->{database}, user => $mysqldb->{user}, pwd => $mysqldb->{pwd}\n            });\n\n            $addr =~ s/postgresql/mysql/;\n\n            $self->plugin('Minion' => { mysql => $addr });\n        }\n    }\n\n    # Secrets\n    $self->secrets($config->{secret});\n\n    # Hooks\n    $self->hook(\n        before_dispatch => sub {\n            my $c = shift;\n\n            # API allowed domains\n            if (defined($c->config('allowed_domains')) && scalar @{$c->config('allowed_domains')}) {\n                if ($c->config('allowed_domains')->[0] eq '*') {\n                    $c->res->headers->header('Access-Control-Allow-Origin' => '*');\n                } elsif (my $origin = $c->req->headers->origin) {\n                    for my $domain (@{$c->config('allowed_domains')}) {\n                        if ($domain eq $origin) {\n                            $c->res->headers->header('Access-Control-Allow-Origin' => $origin);\n                            last;\n                        }\n                    }\n                }\n            }\n        }\n    );\n\n    # Recurrent tasks\n    Mojo::IOLoop->recurring(2 => sub {\n        my $loop = shift;\n\n        $self->provisioning();\n    });\n    if ($self->config('safebrowsing_api_key')) {\n        $self->gsb(1);\n        Mojo::IOLoop->recurring(86400 => sub {\n            my $loop = shift;\n\n            $self->gsb(1);\n        });\n    }\n\n    # Minion\n    if ($config->{minion}->{enabled}) {\n        $self->app->minion->add_task(\n            increase_counter => sub {\n                my $job   = shift;\n                my $short = shift;\n                my $url   = shift;\n\n                my $db_url = Lstu::DB::URL->new(\n                    app    => $job->app,\n                    short  => $short\n                )->increment_counter;\n\n                my $piwik = $job->app->config('piwik');\n                if (defined($piwik) && $piwik->{idsite} && $piwik->{url}) {\n                    $job->app->piwik_api(\n                        'Track' => {\n                            idSite     => $piwik->{idsite},\n                            action_url => $url,\n                            url        => $piwik->{url}\n                        }\n                    );\n                }\n            }\n        );\n    }\n\n    # For the first launch (after, this isn't really useful)\n    $self->provisioning();\n\n    # Default layout\n    $self->defaults(layout => 'default');\n\n    # Router\n    my $r = $self->routes;\n\n    # Normal route to controller\n    $r->get('/' => sub {\n        my $c = shift;\n        if ((!defined($c->config('ldap')) && !defined($c->config('htpasswd'))) || $c->is_user_authenticated) {\n            $c->render(template => 'index');\n        } else {\n            $c->redirect_to('login');\n        }\n    })->name('index');\n\n    if (defined $self->config('ldap') || defined $self->config('htpasswd')) {\n        # Login page\n        $r->get('/login')\n            ->to('Authent#index')\n            ->name('login');\n\n        # Authentication\n        $r->post('/login')\n            ->to('Authent#login');\n\n        # Logout page\n        $r->get('/logout')\n            ->to('Authent#log_out')\n            ->name('logout');\n    }\n\n    $r->get('/api' => sub {\n        shift->render(template => 'api');\n    })->name('api');\n\n    $r->get('/partial/lstu.js' => sub {\n        my $c = shift;\n        $c->render(\n            template => 'partial/lstu',\n            format   => 'js'\n        );\n    })->name('lstu.js');\n\n    $r->post('/stats')\n        ->to('Admin#login');\n\n    $r->get('/d/:short')\n        ->to('Admin#delete')\n        ->name('delete');\n\n    $r->post('/a')\n        ->to('URL#add')\n        ->name('add');\n\n    $r->get('/cookie')\n        ->to('Stats#export_cookie')\n        ->name('export_cookie');\n\n    $r->post('/cookie')\n        ->to('Stats#import_cookie')\n        ->name('import_cookie');\n\n    $r->get('/stats')\n        ->to('Stats#stats')\n        ->name('stats');\n\n    $r->get('/stats/:short')\n        ->to('Stats#stat_for_one_short')\n        ->name('stat_for_one_short');\n\n    $r->get('/fullstats')\n        ->to('Stats#fullstats')\n        ->name('fullstats');\n\n    $r->get('/:short')\n        ->to('URL#get')\n        ->name('short');\n}\n\n1;\n"
  },
  {
    "path": "lib/Mounter.pm",
    "content": "package Mounter;\nuse Mojo::Base 'Mojolicious';\nuse Mojo::File;\nuse FindBin qw($Bin);\nuse File::Spec qw(catfile);\nuse Lstu::DefaultConfig qw($default_config);\n\n# This method will run once at server start\nsub startup {\n    my $self = shift;\n\n    push @{$self->commands->namespaces}, 'Lstu::Command';\n\n    my $cfile = Mojo::File->new($Bin, '..' , 'lstu.conf');\n    if (defined $ENV{MOJO_CONFIG}) {\n        $cfile = Mojo::File->new($ENV{MOJO_CONFIG});\n        unless (-e $cfile->to_abs) {\n            $cfile = Mojo::File->new($Bin, '..', $ENV{MOJO_CONFIG});\n        }\n    }\n    my $config = $self->plugin('Config' =>\n        {\n            file    => $cfile,\n            default => $default_config\n        }\n    );\n\n    # Themes handling\n    shift @{$self->static->paths};\n    if ($config->{theme} ne 'default') {\n        my $theme = $self->home->rel_file('themes/'.$config->{theme});\n        push @{$self->static->paths}, $theme.'/public' if -d $theme.'/public';\n    }\n    push @{$self->static->paths}, $self->home->rel_file('themes/default/public');\n\n    # Static assets gzipping\n    $self->plugin('GzipStatic');\n\n    # Headers\n    $self->plugin('Lstu::Plugin::Headers');\n\n    # Helpers\n    $self->plugin('Lstu::Plugin::Helpers');\n\n    # URL cache\n    if (scalar(@{$config->{memcached_servers}})) {\n        $self->plugin(CHI => {\n            lstu_urls_cache => {\n                driver             => 'Memcached',\n                servers            => $config->{memcached_servers},\n                expires_in         => '1 day',\n                expires_on_backend => 1,\n            }\n        });\n    }\n\n    $self->plugin('Mount' => {$config->{prefix} => File::Spec->catfile($Bin, '..', 'script', 'application')});\n}\n\n1;\n"
  },
  {
    "path": "lstu.conf.template",
    "content": "# vim:set sw=4 ts=4 sts=4 ft=perl expandtab:\n{\n    ####################\n    # Hypnotoad settings\n    ####################\n    # see http://mojolicio.us/perldoc/Mojo/Server/Hypnotoad for a full list of settings\n    hypnotoad => {\n        # array of IP addresses and ports you want to listen to\n        listen => ['http://127.0.0.1:8080'],\n        # if you use Lstu behind a reverse proxy like Nginx, you want to set proxy to 1\n        # if you use Lstu directly, let it commented\n        #proxy  => 1,\n    },\n\n    # put a way to contact you here and uncomment it\n    # MANDATORY\n    #contact       => 'admin[at]example.com',\n\n    # array of random strings used to encrypt cookies\n    # optional, default is ['fdjsofjoihrei'], PLEASE, CHANGE IT\n    #secret        => ['fdjsofjoihrei'],\n\n    # secret passphrase to access some admin features\n    # If you don't want to have a plain text password in configuration,\n    # use hashed_adminpwd instead\n    # optional, but you won't have access to admin /stats if not set and if hashed_adminpwd is not set either\n    #adminpwd      => 's3cr3T',\n\n    # secret hashed passphrase to access some admin features\n    # Hash your password by issuing `echo -n s3cr3T | sha256sum` on your terminal\n    # optional, but you won't have access to admin /stats if not set and if adminpwd is not set either\n    #hashed_adminpwd => '94b2feede6ea5e2eec62f457ecb7d3f719b24d19c29d4e5466246a31908fc23b',\n\n    # indicates if you want to really delete URLs from admin page (/stats)\n    # or just want to deactivate the shorten URL (won’t redirect anymore, can’t be used anymore)\n    # optional, default to 0 (false)\n    #really_delete_urls => 0,\n\n    # choose a theme. See the available themes in `themes` directory\n    # optional, default is 'default'\n    #theme         => 'default',\n\n    # number of URLs to be displayed per page in /stats\n    # optional, default is 10\n    #page_offset   => 10,\n\n    # length of the random URL\n    # optional, default is 8\n    #length            => 8,\n\n    # how many URLs will be provisioned in a batch ?\n    # optional, default is 5\n    #provis_step       => 5,\n\n    # max number of URLs to be provisioned\n    # optional, default is 100\n    #provisioning      => 100,\n\n    # URL sub-directory in which you want Lstu to be accessible\n    # example: you want to have Lstu under https://example.org/lstu/\n    # => set prefix to '/lstu' or to '/lstu/', it doesn't matter\n    # optional, defaut is /\n    #prefix        => '/',\n\n    # array of authorized domains for API calls.\n    # if you want to authorize everyone to use the API: ['*']\n    # optional, no domains allowed by default\n    #allowed_domains   => ['http://1.example.com', 'http://2.example.com'],\n\n    # if set, the shortened URLs will use this domain\n    # optional\n    #fixed_domain => 'example.org',\n\n    # if set to 1, Lstu will try to prevent its use without using the web interface\n    # optional, default is 0\n    #disable_api => 0,\n\n    # choose what database you want to use\n    # valid choices are sqlite, postgresql and mysql (all lowercase)\n    # optional, default is sqlite\n    #dbtype => 'sqlite',\n\n    # SQLite ONLY - only used if dbtype is set to sqlite\n    # define a path to the SQLite database\n    # you can define it relative to lstu directory or set an absolute path\n    # remember that it has to be in a directory writable by Lstu user\n    # optional, default is lstu.db\n    #db_path           => 'lstu.db',\n\n    # PostgreSQL ONLY - only used if dbtype is set to postgresql\n    # these are the credentials to access the PostgreSQL database\n    # mandatory if you choosed postgresql as dbtype\n    #pgdb => {\n    #    database => 'lstu',\n    #    host     => 'localhost',\n    #    # optional, default is 5432\n    #    #port     => 5432,\n    #    user     => 'DBUSER',\n    #    pwd      => 'DBPASSWORD',\n    #    # optional, default is 1\n    #    #max_connections => 1,\n    #},\n\n    # MySQL ONLY - only used if dbtype is set to mysql\n    # these are the credentials to access the MySQL database\n    # mandatory if you choosed mysql as dbtype\n    #mysqldb => {\n    #    database => 'lstu',\n    #    host     => 'localhost',\n    #    # optional, default is 3306\n    #    #port     => 3306,\n    #    user     => 'DBUSER',\n    #    pwd      => 'DBPASSWORD',\n    #    # optional, default is 5 (set to 0 to disable persistent connections)\n    #    #max_connections => 5,\n    #},\n\n    # Rate-limiting for the API\n    # After ban_min_strike requests in a second, the IP address will be\n    # banned for one hour.\n    # If it continues to query the API during this ban time at least\n    # ban_min_strike times, it will be banned for a month.\n    # optional, default is 3\n    #ban_min_strike    => 3,\n\n    # Ban whitelist\n    # You can whitelist IP addresses to prevent you from being banned\n    # Be careful, the IP addresses are compared as string, not as IP addresses\n    # a network range will not work\n    # Example of valid input: ban_whitelist => ['198.51.100.42', '2001:0DB8::42'],¬\n    # optional, default is an empty array\n    #ban_whitelist => [],\n\n    # Ban blacklist\n    # You can blacklist IP addresses to always ban those IP addresses\n    # Be careful, the IP addresses are compared as string, not as IP addresses\n    # a network range will not work\n    # Example of valid input: ban_blacklist => ['198.51.100.42', '2001:0DB8::42'],¬\n    # optional, default is an empty array\n    #ban_blacklist => [],\n\n    # define an URL to the Piwik instance and the ID of a website to track\n    # set if you want to track views in Piwik\n    # optional, Piwik tracking is disabled by default\n    #piwik => {\n    #    url    => 'http://piwik.example.com',\n    #    idsite => '1',\n    #},\n\n    # use Minion instead of directly increase counters\n    # need to launch a minion worker service if enabled\n    # optional, Minion is disabled by default\n    # It will use the same DB type as Lstu: sqlite if you choose sqlite for `dbtype`,\n    # postgresql for postgresql, etc.\n    #minion => {\n    #    enabled => 0,\n    #    # SQLite ONLY - only used if if you choose sqlite as DB type,\n    #    # define the path to the minion database\n    #    # you can define it relative to lstu directory or set an absolute path\n    #    # remember that it has to be in a directory writable by Lutim user\n    #    # optional, default is minion.db\n    #    db_path => 'minion.db',\n    #    # PostgreSQL ONLY - only used if you choose postgresql as DB type\n    #    # these are the credentials to access the Minion's PostgreSQL database\n    #    # mandatory if you choosed postgresql as DB type, no default\n    #    pgdb => {\n    #        database => 'lstu_minion',\n    #        host     => 'localhost',\n    #        # optional, default is 5432\n    #        #port     => 5432,\n    #        user     => 'DBUSER',\n    #        pwd      => 'DBPASSWORD'\n    #    },\n    #    # MySQL ONLY - only used if you choose mysql as DB type\n    #    # these are the credentials to access the Minion's MySQL database\n    #    # mandatory if you choosed mysql as DB type, no default\n    #    mysqldb => {\n    #        database => 'lstu_minion',\n    #        host     => 'localhost',\n    #        # optional, default is 3306\n    #        #port     => 3306,\n    #        user     => 'DBUSER',\n    #        pwd      => 'DBPASSWORD',\n    #    },\n    #},\n\n    # set `ldap` if you want that only authenticated users can shorten URLs\n    # please note that everybody can still use shortend URLs\n    # optional, no default\n    #ldap => {\n    #    uri         => 'ldaps://ldap.example.org',                 # server URI\n    #    user_tree   => 'ou=users,dc=example,dc=org',               # search base DN\n    #    bind_dn     => 'uid=ldap_user,ou=users,dc=example,dc=org', # search bind DN\n    #    bind_pwd    => 'secr3t',                                   # search bind password\n    #    user_attr   => 'uid',                                      # user attribute (uid, mail, sAMAccountName, etc.)\n    #    user_filter => '(!(uid=ldap_user))',                       # user filter (to exclude some users, etc.)\n    #},\n\n    # set `htpasswd` if you want to use an htpasswd file instead of ldap\n    # create the file with `htpasswd -c lstu.passwd user`, update it with `htpasswd lstu.passwd user2`\n    # make sure that lstu can read the file!\n    # optional, no default\n    #htpasswd => 'lstu.passwd',\n\n    # if you've set ldap or htpasswd above, the session will last `session_duration` seconds before\n    # the user needs to reauthenticate\n    # optional, default is 3600\n    #session_duration => 3600,\n\n    # how many redirections are allowed for the shortened URL before considering it as a spam?\n    # optional, default is 2. Set to -1 to allow infinite redirections (not recommended)\n    #max_redir => 2,\n\n    # spam blacklist regex. All URLs (or redirection) whose host part matches this regex are considered as spam\n    # optional, no default\n    #spam_blacklist_regex => 'foo|bar',\n\n    # spam path blacklist regex. All URLs (or redirection) whose path part matches this regex are considered as spam\n    # optional, no default\n    #spam_path_blacklist_regex => 'foo|bar',\n\n    # spam whitelist regex. All URLs (or redirection) whose host part matches this regex will never be considered as spam\n    # optional, no default\n    #spam_whitelist_regex => 'foo|bar',\n\n    # set to 1 to skip SpamHaus check (not recommended)\n    # optional, default is 0\n    #skip_spamhaus => 0,\n\n    # put your Google API key to enable Google safebrowsing check\n    # This will allow Lstu to download the Google safebrowsing database and use a local copy to check the URLs.\n    # Google does not get the URLs that are checked.\n    # Instructions to get a key: https://developers.google.com/safe-browsing/v4/get-started\n    # TL;DR: https://console.developers.google.com/projectselector/apis/library\n    # optional, no default\n    #safebrowsing_api_key => '',\n\n    # array of memcached servers to cache URL in order to accelerate responses to often-viewed URL.\n    # If set to [], the cache is disabled\n    # optional, default is []\n    #memcached_servers => [],\n\n    # Content-Security-Policy header that will be sent by Lstu\n    # Set to '' to disable CSP header\n    # https://content-security-policy.com/ provides a good documentation about CSP.\n    # https://report-uri.com/home/generate provides a tool to generate a CSP header.\n    # optional, default is \"default-src 'none'; script-src 'self'; style-src 'self'; img-src 'self' data:; font-src 'self'; form-action 'self'; base-uri 'self'\"\n    # the default value is good for `default` and `milligram` themes\n    #csp => \"default-src 'none'; script-src 'self'; style-src 'self'; img-src 'self' data:; font-src 'self'; form-action 'self'; base-uri 'self'\",\n\n    # X-Frame-Options header that will be sent by Lstu\n    # Valid values are: 'DENY', 'SAMEORIGIN', 'ALLOW-FROM https://example.com/'\n    # Set to '' to disable X-Frame-Options header\n    # See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options\n    # Please note that this will add a \"frame-ancestors\" directive to the CSP header (see above) accordingly\n    # to the chosen setting (See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/frame-ancestors)\n    # optional, default is 'DENY'\n    #x_frame_options => 'DENY',\n\n    # X-Content-Type-Options that will be sent by Lstu\n    # See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Content-Type-Options\n    # Set to '' to disable X-Content-Type-Options header\n    # optional, default is 'nosniff'\n    #x_content_type_options => 'nosniff',\n\n    # X-XSS-Protection that will be sent by Lstu\n    # See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-XSS-Protection\n    # Set to '' to disable X-XSS-Protection header\n    # optional, default is '1; mode=block'\n    #x_xss_protection => '1; mode=block',\n\n    # Log creator's IP address\n    # Set to 1 if you want to register the IP addresses of URL creators\n    # optional, default is 0\n    #log_creator_ip => 0,\n\n    # Positive integer which specifies how many pixels one \"module\" (one block of the QR code) occupies.\n    # You can't use fractional values. An arbitrary upper limit of 100 is imposed by Image::PNG::QRCode module.\n    # optional, default is 3\n    #qrcode_size => 3,\n};\n"
  },
  {
    "path": "script/application",
    "content": "#!/usr/bin/env perl\n\nuse strict;\nuse warnings;\n\nuse FindBin;\nBEGIN { unshift @INC, \"$FindBin::Bin/../lib\" }\n\n# Start command line interface for application\nrequire Mojolicious::Commands;\nMojolicious::Commands->start_app('Lstu');\n"
  },
  {
    "path": "script/lstu",
    "content": "#!/usr/bin/env perl\n\nuse strict;\nuse warnings;\n\nuse FindBin;\nBEGIN { unshift @INC, \"$FindBin::Bin/../lib\" }\n\n# Start command line interface for application\nrequire Mojolicious::Commands;\nMojolicious::Commands->start_app('Mounter');\n"
  },
  {
    "path": "t/lstu.passwd",
    "content": "luc:$apr1$zG4UAKGa$FqSi4widrkVH/pT3qPawd.\n"
  },
  {
    "path": "t/mysql1.conf",
    "content": "# vim:set sw=4 ts=4 sts=4 ft=perl expandtab:\n{\n    ####################\n    # Hypnotoad settings\n    ####################\n    # see http://mojolicio.us/perldoc/Mojo/Server/Hypnotoad for a full list of settings\n    hypnotoad => {\n        # array of IP addresses and ports you want to listen to\n        listen => ['http://127.0.0.1:8080'],\n        # if you use Lstu behind a reverse proxy like Nginx, you want to set proxy to 1\n        # if you use Lstu directly, let it commented\n        #proxy  => 1,\n    },\n\n    # put a way to contact you here and uncomment it\n    # MANDATORY\n    contact       => 'admin[at]example.com',\n\n    # array of random strings used to encrypt cookies\n    # optional, default is ['fdjsofjoihrei'], PLEASE, CHANGE IT\n    #secret        => ['fdjsofjoihrei'],\n\n    # secret passphrase to access some admin features\n    # If you don't want to have a plain text password in configuration,\n    # use hashed_adminpwd instead\n    # optional, but you won't have access to admin /stats if not set and if hashed_adminpwd is not set either\n    adminpwd => 'toto',\n\n    # secret hashed passphrase to access some admin features\n    # Hash your password by issuing `echo -n s3cr3T | sha256sum` on your terminal\n    # optional, but you won't have access to admin /stats if not set and if adminpwd is not set either\n    #hashed_adminpwd => '94b2feede6ea5e2eec62f457ecb7d3f719b24d19c29d4e5466246a31908fc23b',\n\n    # choose a theme. See the available themes in `themes` directory\n    # optional, default is 'default'\n    #theme         => 'default',\n\n    # number of URLs to be displayed per page in /stats\n    # optional, default is 10\n    #page_offset   => 10,\n\n    # length of the random URL\n    # optional, default is 8\n    #length            => 8,\n\n    # how many URLs will be provisioned in a batch ?\n    # optional, default is 5\n    #provis_step       => 5,\n\n    # max number of URLs to be provisioned\n    # optional, default is 100\n    #provisioning      => 100,\n\n    # URL sub-directory in which you want Lstu to be accessible\n    # example: you want to have Lstu under https://example.org/lstu/\n    # => set prefix to '/lstu' or to '/lstu/', it doesn't matter\n    # optional, defaut is /\n    #prefix        => '/',\n\n    # array of authorized domains for API calls.\n    # if you want to authorize everyone to use the API: ['*']\n    # optional, no domains allowed by default\n    #allowed_domains   => ['http://1.example.com', 'http://2.example.com'],\n\n    # if set, the shortened URLs will use this domain\n    # optional\n    #fixed_domain => 'example.org',\n\n    # choose what database you want to use\n    # valid choices are sqlite and postgresql (all lowercase)\n    # optional, default is sqlite\n    dbtype => 'mysql',\n\n    # SQLite ONLY - only used if dbtype is set to sqlite\n    # define a path to the SQLite database\n    # you can define it relative to lstu directory or set an absolute path\n    # remember that it has to be in a directory writable by Lstu user\n    # optional, default is lstu.db\n    #db_path           => 'lstu.db',\n\n    # PostgreSQL ONLY - only used if dbtype is set to postgresql\n    # these are the credentials to access the PostgreSQL database\n    # mandatory if you choosed postgresql as dbtype\n    #pgdb => {\n    #    database => 'lstu',\n    #    host     => 'localhost',\n    #    # optional, default is 5432\n    #    #port     => 5432,\n    #    #user     => 'DBUSER',\n    #    #pwd      => 'DBPASSWORD',\n    #    # optional, default is 1\n    #    #max_connections => 1,\n    #},\n\n    # MySQL ONLY - only used if dbtype is set to mysql\n    # these are the credentials to access the MySQL database\n    # mandatory if you choosed mysql as dbtype\n    mysqldb => {\n        database => 'lstu_db',\n        host     => 'mariadb',\n    #    # optional, default is 3306\n    #    #port     => 3306,\n        user     => 'lstu',\n        pwd      => 'lstu_pwd'\n    #    # optional, default is 5 (set to 0 to disable persistent connections)\n    #    #max_connections => 5,\n    },\n\n    # Rate-limiting for the API\n    # After ban_min_strike requests in a second, the IP address will be\n    # banned for one hour.\n    # If it continues to query the API during this ban time at least\n    # ban_min_strike times, it will be banned for a month.\n    # optional, default is 3\n    #ban_min_strike    => 3,\n\n    # Ban whitelist\n    # You can whitelist IP addresses to prevent you from being banned\n    # Be careful, the IP addresses are compared as string, not as IP addresses\n    # a network range will not work\n    # Example of valid input: ban_whitelist => ['198.51.100.42', '2001:0DB8::42'],¬\n    # optional, default is an empty array\n    #ban_whitelist => [],\n\n    # Ban blacklist\n    # You can blacklist IP addresses to always ban those IP addresses\n    # Be careful, the IP addresses are compared as string, not as IP addresses\n    # a network range will not work\n    # Example of valid input: ban_blacklist => ['198.51.100.42', '2001:0DB8::42'],¬\n    # optional, default is an empty array\n    #ban_blacklist => [],\n\n    # define an URL to the Piwik instance and the ID of a website to track\n    # set if you want to track views in Piwik\n    # optional, Piwik tracking is disabled by default\n    #piwik => {\n    #    url    => 'http://piwik.example.com',\n    #    idsite => '1',\n    #},\n\n    # use Minion instead of directly increase counters\n    # need to launch a minion worker service if enabled\n    # optional, Minion is disabled by default\n    # It will use the same DB type as Lstu: sqlite if you choose sqlite for `dbtype`,\n    # postgresql for postgresql, etc.\n    #minion => {\n    #    enabled => 0,\n    #    # SQLite ONLY - only used if if you choose sqlite as DB type,\n    #    # define the path to the minion database\n    #    # you can define it relative to lstu directory or set an absolute path\n    #    # remember that it has to be in a directory writable by Lutim user\n    #    # optional, default is minion.db\n    #    db_path => 'minion.db',\n    #    # PostgreSQL ONLY - only used if you choose postgresql as DB type\n    #    # these are the credentials to access the Minion's PostgreSQL database\n    #    # mandatory if you choosed postgresql as DB type, no default\n    #    pgdb => {\n    #        database => 'lstu_minion',\n    #        host     => 'localhost',\n    #        # optional, default is 5432\n    #        #port     => 5432,\n    #        #user     => 'DBUSER',\n    #        #pwd      => 'DBPASSWORD'\n    #    },\n    #    # MySQL ONLY - only used if you choose mysql as DB type\n    #    # these are the credentials to access the Minion's MySQL database\n    #    # mandatory if you choosed mysql as DB type, no default\n    #    mysqldb => {\n    #        database => 'lstu',\n    #        host     => 'localhost',\n    #        # optional, default is 3306\n    #        #port     => 3306,\n    #        #user     => 'DBUSER',\n    #        #pwd      => 'DBPASSWORD',\n    #    },\n    #},\n\n    # set `ldap` if you want that only authenticated users can shorten URLs\n    # please note that everybody can still use shortend URLs\n    # optional, no default\n    #ldap => { uri => 'ldap://rroemhild-test-openldap:10389', user_tree => 'ou=people,dc=planetexpress,dc=com', bind_dn => 'cn=admin,dc=planetexpress,dc=com', bind_pwd => 'GoodNewsEveryone', user_attr => 'uid', user_filter => '(!(uid=admin))', },\n    #ldap => {\n    #    uri         => 'ldaps://ldap.example.org',                 # server URI\n    #    user_tree   => 'ou=users,dc=example,dc=org',               # search base DN\n    #    bind_dn     => 'uid=ldap_user,ou=users,dc=example,dc=org', # search bind DN\n    #    bind_pwd    => 'secr3t',                                   # search bind password\n    #    user_attr   => 'uid',                                      # user attribute (uid, mail, sAMAccountName, etc.)\n    #    user_filter => '(!(uid=ldap_user))',                       # user filter (to exclude some users, etc.)\n    #},\n\n    # set `htpasswd` if you want to use an htpasswd file instead of ldap\n    # create the file with `htpasswd -c lstu.passwd user`, update it with `htpasswd lstu.passwd user2`\n    # make sure that lstu can read the file!\n    # optional, no default\n    #htpasswd => 'lstu.passwd',\n\n    # if you've set ldap or htpasswd above, the session will last `session_duration` seconds before\n    # the user needs to reauthenticate\n    # optional, default is 3600\n    #session_duration => 3600,\n\n    # how many redirections are allowed for the shortened URL before considering it as a spam?\n    # optional, default is 2. Set to -1 to allow infinite redirections (not recommended)\n    #max_redir => 2,\n\n    # spam blacklist regex. All URLs (or redirection) whose host part matches this regex are considered as spam\n    # optional, no default\n    #spam_blacklist_regex => 'foo|bar',\n\n    # spam path blacklist regex. All URLs (or redirection) whose path part matches this regex are considered as spam\n    # optional, no default\n    #spam_path_blacklist_regex => 'foo|bar',\n\n    # spam whitelist regex. All URLs (or redirection) whose host part matches this regex will never be considered as spam\n    # optional, no default\n    #spam_whitelist_regex => 'foo|bar',\n\n    # set to 1 to skip SpamHaus check (not recommended)\n    # optional, default is 0\n    #skip_spamhaus => 0,\n\n    # put your Google API key to enable Google safebrowsing check\n    # This will allow Lstu to download the Google safebrowsing database and use a local copy to check the URLs.\n    # Google does not get the URLs that are checked.\n    # Instructions to get a key: https://developers.google.com/safe-browsing/v4/get-started\n    # TL;DR: https://console.developers.google.com/projectselector/apis/library\n    # optional, no default\n    #safebrowsing_api_key => '',\n\n    # array of memcached servers to cache URL in order to accelerate responses to often-viewed URL.\n    # If set to [], the cache is disabled\n    # optional, default is []\n    #memcached_servers => [],\n\n    # Content-Security-Policy header that will be sent by Lstu\n    # Set to '' to disable CSP header\n    # https://content-security-policy.com/ provides a good documentation about CSP.\n    # https://report-uri.com/home/generate provides a tool to generate a CSP header.\n    # optional, default is \"default-src 'none'; script-src 'self'; style-src 'self'; img-src 'self' data:; font-src 'self'; form-action 'self'; base-uri 'self'\"\n    # the default value is good for `default` and `milligram` themes\n    #csp => \"default-src 'none'; script-src 'self'; style-src 'self'; img-src 'self' data:; font-src 'self'; form-action 'self'; base-uri 'self'\",\n\n    # X-Frame-Options header that will be sent by Lstu\n    # Valid values are: 'DENY', 'SAMEORIGIN', 'ALLOW-FROM https://example.com/'\n    # Set to '' to disable X-Frame-Options header\n    # See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options\n    # Please note that this will add a \"frame-ancestors\" directive to the CSP header (see above) accordingly\n    # to the chosen setting (See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/frame-ancestors)\n    # optional, default is 'DENY'\n    #x_frame_options => 'DENY',\n\n    # X-Content-Type-Options that will be sent by Lstu\n    # See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Content-Type-Options\n    # Set to '' to disable X-Content-Type-Options header\n    # optional, default is 'nosniff'\n    #x_content_type_options => 'nosniff',\n\n    # X-XSS-Protection that will be sent by Lstu\n    # See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-XSS-Protection\n    # Set to '' to disable X-XSS-Protection header\n    # optional, default is '1; mode=block'\n    #x_xss_protection => '1; mode=block',\n\n    # Log creator's IP address\n    # Set to 1 if you want to register the IP addresses of URL creators\n    # optional, default is 0\n    #log_creator_ip => 0,\n};\n"
  },
  {
    "path": "t/mysql2.conf",
    "content": "# vim:set sw=4 ts=4 sts=4 ft=perl expandtab:\n{\n    ####################\n    # Hypnotoad settings\n    ####################\n    # see http://mojolicio.us/perldoc/Mojo/Server/Hypnotoad for a full list of settings\n    hypnotoad => {\n        # array of IP addresses and ports you want to listen to\n        listen => ['http://127.0.0.1:8080'],\n        # if you use Lstu behind a reverse proxy like Nginx, you want to set proxy to 1\n        # if you use Lstu directly, let it commented\n        #proxy  => 1,\n    },\n\n    # put a way to contact you here and uncomment it\n    # MANDATORY\n    contact       => 'admin[at]example.com',\n\n    # array of random strings used to encrypt cookies\n    # optional, default is ['fdjsofjoihrei'], PLEASE, CHANGE IT\n    #secret        => ['fdjsofjoihrei'],\n\n    # secret passphrase to access some admin features\n    # If you don't want to have a plain text password in configuration,\n    # use hashed_adminpwd instead\n    # optional, but you won't have access to admin /stats if not set and if hashed_adminpwd is not set either\n    #adminpwd      => 's3cr3T',\n\n    # secret hashed passphrase to access some admin features\n    # Hash your password by issuing `echo -n s3cr3T | sha256sum` on your terminal\n    # optional, but you won't have access to admin /stats if not set and if adminpwd is not set either\n    hashed_adminpwd => '31f7a65e315586ac198bd798b6629ce4903d0899476d5741a9f32e2e521b6a66',\n\n    # choose a theme. See the available themes in `themes` directory\n    # optional, default is 'default'\n    #theme         => 'default',\n\n    # number of URLs to be displayed per page in /stats\n    # optional, default is 10\n    #page_offset   => 10,\n\n    # length of the random URL\n    # optional, default is 8\n    #length            => 8,\n\n    # how many URLs will be provisioned in a batch ?\n    # optional, default is 5\n    #provis_step       => 5,\n\n    # max number of URLs to be provisioned\n    # optional, default is 100\n    #provisioning      => 100,\n\n    # URL sub-directory in which you want Lstu to be accessible\n    # example: you want to have Lstu under https://example.org/lstu/\n    # => set prefix to '/lstu' or to '/lstu/', it doesn't matter\n    # optional, defaut is /\n    #prefix        => '/',\n\n    # array of authorized domains for API calls.\n    # if you want to authorize everyone to use the API: ['*']\n    # optional, no domains allowed by default\n    #allowed_domains   => ['http://1.example.com', 'http://2.example.com'],\n\n    # if set, the shortened URLs will use this domain\n    # optional\n    #fixed_domain => 'example.org',\n\n    # choose what database you want to use\n    # valid choices are sqlite, postgresql and mysql (all lowercase)\n    # optional, default is sqlite\n    dbtype => 'mysql',\n\n    # SQLite ONLY - only used if dbtype is set to sqlite\n    # define a path to the SQLite database\n    # you can define it relative to lstu directory or set an absolute path\n    # remember that it has to be in a directory writable by Lstu user\n    # optional, default is lstu.db\n    #db_path           => 'lstu.db',\n\n    # PostgreSQL ONLY - only used if dbtype is set to postgresql\n    # these are the credentials to access the PostgreSQL database\n    # mandatory if you choosed postgresql as dbtype\n    #pgdb => {\n    #    database => 'lstu',\n    #    host     => 'localhost',\n    #    # optional, default is 5432\n    #    #port     => 5432,\n    #    #user     => 'DBUSER',\n    #    #pwd      => 'DBPASSWORD',\n    #    # optional, default is 1\n    #    #max_connections => 1,\n    #},\n\n    # MySQL ONLY - only used if dbtype is set to mysql\n    # these are the credentials to access the MySQL database\n    # mandatory if you choosed mysql as dbtype\n    mysqldb => {\n        database => 'lstu_db',\n        host     => 'mariadb',\n    #    # optional, default is 3306\n    #    #port     => 3306,\n        user     => 'lstu',\n        pwd      => 'lstu_pwd'\n    #    # optional, default is 5 (set to 0 to disable persistent connections)\n    #    #max_connections => 5,\n    },\n\n    # Rate-limiting for the API\n    # After ban_min_strike requests in a second, the IP address will be\n    # banned for one hour.\n    # If it continues to query the API during this ban time at least\n    # ban_min_strike times, it will be banned for a month.\n    # optional, default is 3\n    #ban_min_strike    => 3,\n\n    # Ban whitelist\n    # You can whitelist IP addresses to prevent you from being banned\n    # Be careful, the IP addresses are compared as string, not as IP addresses\n    # a network range will not work\n    # Example of valid input: ban_whitelist => ['198.51.100.42', '2001:0DB8::42'],¬\n    # optional, default is an empty array\n    #ban_whitelist => [],\n\n    # Ban blacklist\n    # You can blacklist IP addresses to always ban those IP addresses\n    # Be careful, the IP addresses are compared as string, not as IP addresses\n    # a network range will not work\n    # Example of valid input: ban_blacklist => ['198.51.100.42', '2001:0DB8::42'],¬\n    # optional, default is an empty array\n    #ban_blacklist => [],\n\n    # define an URL to the Piwik instance and the ID of a website to track\n    # set if you want to track views in Piwik\n    # optional, Piwik tracking is disabled by default\n    #piwik => {\n    #    url    => 'http://piwik.example.com',\n    #    idsite => '1',\n    #},\n\n    # use Minion instead of directly increase counters\n    # need to launch a minion worker service if enabled\n    # optional, Minion is disabled by default\n    # It will use the same DB type as Lstu: sqlite if you choose sqlite for `dbtype`,\n    # postgresql for postgresql, etc.\n    #minion => {\n    #    enabled => 0,\n    #    # SQLite ONLY - only used if if you choose sqlite as DB type,\n    #    # define the path to the minion database\n    #    # you can define it relative to lstu directory or set an absolute path\n    #    # remember that it has to be in a directory writable by Lutim user\n    #    # optional, default is minion.db\n    #    db_path => 'minion.db',\n    #    # PostgreSQL ONLY - only used if you choose postgresql as DB type\n    #    # these are the credentials to access the Minion's PostgreSQL database\n    #    # mandatory if you choosed postgresql as DB type, no default\n    #    pgdb => {\n    #        database => 'lstu_minion',\n    #        host     => 'localhost',\n    #        # optional, default is 5432\n    #        #port     => 5432,\n    #        #user     => 'DBUSER',\n    #        #pwd      => 'DBPASSWORD'\n    #    },\n    #    # MySQL ONLY - only used if you choose mysql as DB type\n    #    # these are the credentials to access the Minion's MySQL database\n    #    # mandatory if you choosed mysql as DB type, no default\n    #    mysqldb => {\n    #        database => 'lstu',\n    #        host     => 'localhost',\n    #        # optional, default is 3306\n    #        #port     => 3306,\n    #        #user     => 'DBUSER',\n    #        #pwd      => 'DBPASSWORD',\n    #    },\n    #},\n\n    # set `ldap` if you want that only authenticated users can shorten URLs\n    # please note that everybody can still use shortend URLs\n    # optional, no default\n    #ldap => { uri => 'ldap://rroemhild-test-openldap:10389', user_tree => 'ou=people,dc=planetexpress,dc=com', bind_dn => 'cn=admin,dc=planetexpress,dc=com', bind_pwd => 'GoodNewsEveryone', user_attr => 'uid', user_filter => '(!(uid=admin))', },\n    #ldap => {\n    #    uri         => 'ldaps://ldap.example.org',                 # server URI\n    #    user_tree   => 'ou=users,dc=example,dc=org',               # search base DN\n    #    bind_dn     => 'uid=ldap_user,ou=users,dc=example,dc=org', # search bind DN\n    #    bind_pwd    => 'secr3t',                                   # search bind password\n    #    user_attr   => 'uid',                                      # user attribute (uid, mail, sAMAccountName, etc.)\n    #    user_filter => '(!(uid=ldap_user))',                       # user filter (to exclude some users, etc.)\n    #},\n\n    # set `htpasswd` if you want to use an htpasswd file instead of ldap\n    # create the file with `htpasswd -c lstu.passwd user`, update it with `htpasswd lstu.passwd user2`\n    # make sure that lstu can read the file!\n    # optional, no default\n    #htpasswd => 'lstu.passwd',\n\n    # if you've set ldap or htpasswd above, the session will last `session_duration` seconds before\n    # the user needs to reauthenticate\n    # optional, default is 3600\n    #session_duration => 3600,\n\n    # how many redirections are allowed for the shortened URL before considering it as a spam?\n    # optional, default is 2. Set to -1 to allow infinite redirections (not recommended)\n    #max_redir => 2,\n\n    # spam blacklist regex. All URLs (or redirection) whose host part matches this regex are considered as spam\n    # optional, no default\n    #spam_blacklist_regex => 'foo|bar',\n\n    # spam path blacklist regex. All URLs (or redirection) whose path part matches this regex are considered as spam\n    # optional, no default\n    #spam_path_blacklist_regex => 'foo|bar',\n\n    # spam whitelist regex. All URLs (or redirection) whose host part matches this regex will never be considered as spam\n    # optional, no default\n    #spam_whitelist_regex => 'foo|bar',\n\n    # set to 1 to skip SpamHaus check (not recommended)\n    # optional, default is 0\n    #skip_spamhaus => 0,\n\n    # put your Google API key to enable Google safebrowsing check\n    # This will allow Lstu to download the Google safebrowsing database and use a local copy to check the URLs.\n    # Google does not get the URLs that are checked.\n    # Instructions to get a key: https://developers.google.com/safe-browsing/v4/get-started\n    # TL;DR: https://console.developers.google.com/projectselector/apis/library\n    # optional, no default\n    #safebrowsing_api_key => '',\n\n    # array of memcached servers to cache URL in order to accelerate responses to often-viewed URL.\n    # If set to [], the cache is disabled\n    # optional, default is []\n    #memcached_servers => [],\n\n    # Content-Security-Policy header that will be sent by Lstu\n    # Set to '' to disable CSP header\n    # https://content-security-policy.com/ provides a good documentation about CSP.\n    # https://report-uri.com/home/generate provides a tool to generate a CSP header.\n    # optional, default is \"default-src 'none'; script-src 'self'; style-src 'self'; img-src 'self' data:; font-src 'self'; form-action 'self'; base-uri 'self'\"\n    # the default value is good for `default` and `milligram` themes\n    #csp => \"default-src 'none'; script-src 'self'; style-src 'self'; img-src 'self' data:; font-src 'self'; form-action 'self'; base-uri 'self'\",\n\n    # X-Frame-Options header that will be sent by Lstu\n    # Valid values are: 'DENY', 'SAMEORIGIN', 'ALLOW-FROM https://example.com/'\n    # Set to '' to disable X-Frame-Options header\n    # See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options\n    # Please note that this will add a \"frame-ancestors\" directive to the CSP header (see above) accordingly\n    # to the chosen setting (See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/frame-ancestors)\n    # optional, default is 'DENY'\n    #x_frame_options => 'DENY',\n\n    # X-Content-Type-Options that will be sent by Lstu\n    # See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Content-Type-Options\n    # Set to '' to disable X-Content-Type-Options header\n    # optional, default is 'nosniff'\n    #x_content_type_options => 'nosniff',\n\n    # X-XSS-Protection that will be sent by Lstu\n    # See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-XSS-Protection\n    # Set to '' to disable X-XSS-Protection header\n    # optional, default is '1; mode=block'\n    #x_xss_protection => '1; mode=block',\n\n    # Log creator's IP address\n    # Set to 1 if you want to register the IP addresses of URL creators\n    # optional, default is 0\n    #log_creator_ip => 0,\n};\n"
  },
  {
    "path": "t/mysql3.conf",
    "content": "# vim:set sw=4 ts=4 sts=4 ft=perl expandtab:\n{\n    ####################\n    # Hypnotoad settings\n    ####################\n    # see http://mojolicio.us/perldoc/Mojo/Server/Hypnotoad for a full list of settings\n    hypnotoad => {\n        # array of IP addresses and ports you want to listen to\n        listen => ['http://127.0.0.1:8080'],\n        # if you use Lstu behind a reverse proxy like Nginx, you want to set proxy to 1\n        # if you use Lstu directly, let it commented\n        #proxy  => 1,\n    },\n\n    # put a way to contact you here and uncomment it\n    # MANDATORY\n    contact       => 'admin[at]example.com',\n\n    # array of random strings used to encrypt cookies\n    # optional, default is ['fdjsofjoihrei'], PLEASE, CHANGE IT\n    #secret        => ['fdjsofjoihrei'],\n\n    # secret passphrase to access some admin features\n    # If you don't want to have a plain text password in configuration,\n    # use hashed_adminpwd instead\n    # optional, but you won't have access to admin /stats if not set and if hashed_adminpwd is not set either\n    #adminpwd      => 's3cr3T',\n\n    # secret hashed passphrase to access some admin features\n    # Hash your password by issuing `echo -n s3cr3T | sha256sum` on your terminal\n    # optional, but you won't have access to admin /stats if not set and if adminpwd is not set either\n    hashed_adminpwd => '31f7a65e315586ac198bd798b6629ce4903d0899476d5741a9f32e2e521b6a66',\n\n    # choose a theme. See the available themes in `themes` directory\n    # optional, default is 'default'\n    #theme         => 'default',\n\n    # number of URLs to be displayed per page in /stats\n    # optional, default is 10\n    #page_offset   => 10,\n\n    # length of the random URL\n    # optional, default is 8\n    #length            => 8,\n\n    # how many URLs will be provisioned in a batch ?\n    # optional, default is 5\n    #provis_step       => 5,\n\n    # max number of URLs to be provisioned\n    # optional, default is 100\n    #provisioning      => 100,\n\n    # URL sub-directory in which you want Lstu to be accessible\n    # example: you want to have Lstu under https://example.org/lstu/\n    # => set prefix to '/lstu' or to '/lstu/', it doesn't matter\n    # optional, defaut is /\n    #prefix        => '/',\n\n    # array of authorized domains for API calls.\n    # if you want to authorize everyone to use the API: ['*']\n    # optional, no domains allowed by default\n    #allowed_domains   => ['http://1.example.com', 'http://2.example.com'],\n\n    # if set, the shortened URLs will use this domain\n    # optional\n    #fixed_domain => 'example.org',\n\n    # choose what database you want to use\n    # valid choices are sqlite, postgresql and mysql (all lowercase)\n    # optional, default is sqlite\n    dbtype => 'mysql',\n\n    # SQLite ONLY - only used if dbtype is set to sqlite\n    # define a path to the SQLite database\n    # you can define it relative to lstu directory or set an absolute path\n    # remember that it has to be in a directory writable by Lstu user\n    # optional, default is lstu.db\n    #db_path           => 'lstu.db',\n\n    # PostgreSQL ONLY - only used if dbtype is set to postgresql\n    # these are the credentials to access the PostgreSQL database\n    # mandatory if you choosed postgresql as dbtype\n    #pgdb => {\n    #    database => 'lstu',\n    #    host     => 'localhost',\n    #    # optional, default is 5432\n    #    #port     => 5432,\n    #    #user     => 'DBUSER',\n    #    #pwd      => 'DBPASSWORD',\n    #    # optional, default is 1\n    #    #max_connections => 1,\n    #},\n\n    # MySQL ONLY - only used if dbtype is set to mysql\n    # these are the credentials to access the MySQL database\n    # mandatory if you choosed mysql as dbtype\n    mysqldb => {\n        database => 'lstu_db',\n        host     => 'mariadb',\n    #    # optional, default is 3306\n    #    #port     => 3306,\n        user     => 'lstu',\n        pwd      => 'lstu_pwd'\n    #    # optional, default is 5 (set to 0 to disable persistent connections)\n    #    #max_connections => 5,\n    },\n\n    # Rate-limiting for the API\n    # After ban_min_strike requests in a second, the IP address will be\n    # banned for one hour.\n    # If it continues to query the API during this ban time at least\n    # ban_min_strike times, it will be banned for a month.\n    # optional, default is 3\n    #ban_min_strike    => 3,\n\n    # Ban whitelist\n    # You can whitelist IP addresses to prevent you from being banned\n    # Be careful, the IP addresses are compared as string, not as IP addresses\n    # a network range will not work\n    # Example of valid input: ban_whitelist => ['198.51.100.42', '2001:0DB8::42'],¬\n    # optional, default is an empty array\n    #ban_whitelist => [],\n\n    # Ban blacklist\n    # You can blacklist IP addresses to always ban those IP addresses\n    # Be careful, the IP addresses are compared as string, not as IP addresses\n    # a network range will not work\n    # Example of valid input: ban_blacklist => ['198.51.100.42', '2001:0DB8::42'],¬\n    # optional, default is an empty array\n    #ban_blacklist => [],\n\n    # define an URL to the Piwik instance and the ID of a website to track\n    # set if you want to track views in Piwik\n    # optional, Piwik tracking is disabled by default\n    #piwik => {\n    #    url    => 'http://piwik.example.com',\n    #    idsite => '1',\n    #},\n\n    # use Minion instead of directly increase counters\n    # need to launch a minion worker service if enabled\n    # optional, Minion is disabled by default\n    # It will use the same DB type as Lstu: sqlite if you choose sqlite for `dbtype`,\n    # postgresql for postgresql, etc.\n    minion => {\n        enabled => 1,\n    #    # SQLite ONLY - only used if if you choose sqlite as DB type,\n    #    # define the path to the minion database\n    #    # you can define it relative to lstu directory or set an absolute path\n    #    # remember that it has to be in a directory writable by Lutim user\n    #    # optional, default is minion.db\n    #    db_path => 'minion.db',\n    #    # PostgreSQL ONLY - only used if you choose postgresql as DB type\n    #    # these are the credentials to access the Minion's PostgreSQL database\n    #    # mandatory if you choosed postgresql as DB type, no default\n    #    pgdb => {\n    #        database => 'lstu_minion',\n    #        host     => 'localhost',\n    #        # optional, default is 5432\n    #        #port     => 5432,\n    #        #user     => 'DBUSER',\n    #        #pwd      => 'DBPASSWORD'\n    #    },\n    #    # MySQL ONLY - only used if you choose mysql as DB type\n    #    # these are the credentials to access the Minion's MySQL database\n    #    # mandatory if you choosed mysql as DB type, no default\n        mysqldb => {\n            database => 'lstu_minion',\n            host     => 'mariadb',\n            # optional, default is 3306\n            #port     => 3306,\n            user     => 'lstu',\n            pwd      => 'lstu_pwd',\n        },\n    },\n\n    # set `ldap` if you want that only authenticated users can shorten URLs\n    # please note that everybody can still use shortend URLs\n    # optional, no default\n    #ldap => { uri => 'ldap://rroemhild-test-openldap:10389', user_tree => 'ou=people,dc=planetexpress,dc=com', bind_dn => 'cn=admin,dc=planetexpress,dc=com', bind_pwd => 'GoodNewsEveryone', user_attr => 'uid', user_filter => '(!(uid=admin))', },\n    #ldap => {\n    #    uri         => 'ldaps://ldap.example.org',                 # server URI\n    #    user_tree   => 'ou=users,dc=example,dc=org',               # search base DN\n    #    bind_dn     => 'uid=ldap_user,ou=users,dc=example,dc=org', # search bind DN\n    #    bind_pwd    => 'secr3t',                                   # search bind password\n    #    user_attr   => 'uid',                                      # user attribute (uid, mail, sAMAccountName, etc.)\n    #    user_filter => '(!(uid=ldap_user))',                       # user filter (to exclude some users, etc.)\n    #},\n\n    # set `htpasswd` if you want to use an htpasswd file instead of ldap\n    # create the file with `htpasswd -c lstu.passwd user`, update it with `htpasswd lstu.passwd user2`\n    # make sure that lstu can read the file!\n    # optional, no default\n    #htpasswd => 'lstu.passwd',\n\n    # if you've set ldap or htpasswd above, the session will last `session_duration` seconds before\n    # the user needs to reauthenticate\n    # optional, default is 3600\n    #session_duration => 3600,\n\n    # how many redirections are allowed for the shortened URL before considering it as a spam?\n    # optional, default is 2. Set to -1 to allow infinite redirections (not recommended)\n    #max_redir => 2,\n\n    # spam blacklist regex. All URLs (or redirection) whose host part matches this regex are considered as spam\n    # optional, no default\n    #spam_blacklist_regex => 'foo|bar',\n\n    # spam path blacklist regex. All URLs (or redirection) whose path part matches this regex are considered as spam\n    # optional, no default\n    #spam_path_blacklist_regex => 'foo|bar',\n\n    # spam whitelist regex. All URLs (or redirection) whose host part matches this regex will never be considered as spam\n    # optional, no default\n    #spam_whitelist_regex => 'foo|bar',\n\n    # set to 1 to skip SpamHaus check (not recommended)\n    # optional, default is 0\n    #skip_spamhaus => 0,\n\n    # put your Google API key to enable Google safebrowsing check\n    # This will allow Lstu to download the Google safebrowsing database and use a local copy to check the URLs.\n    # Google does not get the URLs that are checked.\n    # Instructions to get a key: https://developers.google.com/safe-browsing/v4/get-started\n    # TL;DR: https://console.developers.google.com/projectselector/apis/library\n    # optional, no default\n    #safebrowsing_api_key => '',\n\n    # array of memcached servers to cache URL in order to accelerate responses to often-viewed URL.\n    # If set to [], the cache is disabled\n    # optional, default is []\n    #memcached_servers => [],\n\n    # Content-Security-Policy header that will be sent by Lstu\n    # Set to '' to disable CSP header\n    # https://content-security-policy.com/ provides a good documentation about CSP.\n    # https://report-uri.com/home/generate provides a tool to generate a CSP header.\n    # optional, default is \"default-src 'none'; script-src 'self'; style-src 'self'; img-src 'self' data:; font-src 'self'; form-action 'self'; base-uri 'self'\"\n    # the default value is good for `default` and `milligram` themes\n    #csp => \"default-src 'none'; script-src 'self'; style-src 'self'; img-src 'self' data:; font-src 'self'; form-action 'self'; base-uri 'self'\",\n\n    # X-Frame-Options header that will be sent by Lstu\n    # Valid values are: 'DENY', 'SAMEORIGIN', 'ALLOW-FROM https://example.com/'\n    # Set to '' to disable X-Frame-Options header\n    # See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options\n    # Please note that this will add a \"frame-ancestors\" directive to the CSP header (see above) accordingly\n    # to the chosen setting (See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/frame-ancestors)\n    # optional, default is 'DENY'\n    #x_frame_options => 'DENY',\n\n    # X-Content-Type-Options that will be sent by Lstu\n    # See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Content-Type-Options\n    # Set to '' to disable X-Content-Type-Options header\n    # optional, default is 'nosniff'\n    #x_content_type_options => 'nosniff',\n\n    # X-XSS-Protection that will be sent by Lstu\n    # See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-XSS-Protection\n    # Set to '' to disable X-XSS-Protection header\n    # optional, default is '1; mode=block'\n    #x_xss_protection => '1; mode=block',\n\n    # Log creator's IP address\n    # Set to 1 if you want to register the IP addresses of URL creators\n    # optional, default is 0\n    #log_creator_ip => 0,\n};\n"
  },
  {
    "path": "t/postgresql1.conf",
    "content": "# vim:set sw=4 ts=4 sts=4 ft=perl expandtab:\n{\n    ####################\n    # Hypnotoad settings\n    ####################\n    # see http://mojolicio.us/perldoc/Mojo/Server/Hypnotoad for a full list of settings\n    hypnotoad => {\n        # array of IP addresses and ports you want to listen to\n        listen => ['http://127.0.0.1:8080'],\n        # if you use Lstu behind a reverse proxy like Nginx, you want to set proxy to 1\n        # if you use Lstu directly, let it commented\n        #proxy  => 1,\n    },\n\n    # put a way to contact you here and uncomment it\n    # MANDATORY\n    contact       => 'admin[at]example.com',\n\n    # array of random strings used to encrypt cookies\n    # optional, default is ['fdjsofjoihrei'], PLEASE, CHANGE IT\n    #secret        => ['fdjsofjoihrei'],\n\n    # secret passphrase to access some admin features\n    # If you don't want to have a plain text password in configuration,\n    # use hashed_adminpwd instead\n    # optional, but you won't have access to admin /stats if not set and if hashed_adminpwd is not set either\n    adminpwd => 'toto',\n\n    # secret hashed passphrase to access some admin features\n    # Hash your password by issuing `echo -n s3cr3T | sha256sum` on your terminal\n    # optional, but you won't have access to admin /stats if not set and if adminpwd is not set either\n    #hashed_adminpwd => '94b2feede6ea5e2eec62f457ecb7d3f719b24d19c29d4e5466246a31908fc23b',\n\n    # choose a theme. See the available themes in `themes` directory\n    # optional, default is 'default'\n    #theme         => 'default',\n\n    # number of URLs to be displayed per page in /stats\n    # optional, default is 10\n    #page_offset   => 10,\n\n    # length of the random URL\n    # optional, default is 8\n    #length            => 8,\n\n    # how many URLs will be provisioned in a batch ?\n    # optional, default is 5\n    #provis_step       => 5,\n\n    # max number of URLs to be provisioned\n    # optional, default is 100\n    #provisioning      => 100,\n\n    # URL sub-directory in which you want Lstu to be accessible\n    # example: you want to have Lstu under https://example.org/lstu/\n    # => set prefix to '/lstu' or to '/lstu/', it doesn't matter\n    # optional, defaut is /\n    #prefix        => '/',\n\n    # array of authorized domains for API calls.\n    # if you want to authorize everyone to use the API: ['*']\n    # optional, no domains allowed by default\n    #allowed_domains   => ['http://1.example.com', 'http://2.example.com'],\n\n    # if set, the shortened URLs will use this domain\n    # optional\n    #fixed_domain => 'example.org',\n\n    # choose what database you want to use\n    # valid choices are sqlite, postgresql and mysql (all lowercase)\n    # optional, default is sqlite\n    dbtype => 'postgresql',\n\n    # SQLite ONLY - only used if dbtype is set to sqlite\n    # define a path to the SQLite database\n    # you can define it relative to lstu directory or set an absolute path\n    # remember that it has to be in a directory writable by Lstu user\n    # optional, default is lstu.db\n    #db_path           => 'lstu.db',\n\n    # PostgreSQL ONLY - only used if dbtype is set to postgresql\n    # these are the credentials to access the PostgreSQL database\n    # mandatory if you choosed postgresql as dbtype\n    pgdb => {\n        database => 'lstu_db',\n        host     => 'postgres',\n    #    # optional, default is 5432\n    #    #port     => 5432,\n        user     => 'lstu',\n        pwd      => 'lstu_pwd'\n    #    # optional, default is 1\n    #    #max_connections => 1,\n    },\n\n    # MySQL ONLY - only used if dbtype is set to mysql\n    # these are the credentials to access the MySQL database\n    # mandatory if you choosed mysql as dbtype\n    #mysqldb => {\n    #    database => 'lstu',\n    #    host     => 'localhost',\n    #    # optional, default is 3306\n    #    #port     => 3306,\n    #    #user     => 'DBUSER',\n    #    #pwd      => 'DBPASSWORD',\n    #    # optional, default is 5 (set to 0 to disable persistent connections)\n    #    #max_connections => 5,\n    #},\n\n    # Rate-limiting for the API\n    # After ban_min_strike requests in a second, the IP address will be\n    # banned for one hour.\n    # If it continues to query the API during this ban time at least\n    # ban_min_strike times, it will be banned for a month.\n    # optional, default is 3\n    #ban_min_strike    => 3,\n\n    # Ban whitelist\n    # You can whitelist IP addresses to prevent you from being banned\n    # Be careful, the IP addresses are compared as string, not as IP addresses\n    # a network range will not work\n    # Example of valid input: ban_whitelist => ['198.51.100.42', '2001:0DB8::42'],¬\n    # optional, default is an empty array\n    #ban_whitelist => [],\n\n    # Ban blacklist\n    # You can blacklist IP addresses to always ban those IP addresses\n    # Be careful, the IP addresses are compared as string, not as IP addresses\n    # a network range will not work\n    # Example of valid input: ban_blacklist => ['198.51.100.42', '2001:0DB8::42'],¬\n    # optional, default is an empty array\n    #ban_blacklist => [],\n\n    # define an URL to the Piwik instance and the ID of a website to track\n    # set if you want to track views in Piwik\n    # optional, Piwik tracking is disabled by default\n    #piwik => {\n    #    url    => 'http://piwik.example.com',\n    #    idsite => '1',\n    #},\n\n    # use Minion instead of directly increase counters\n    # need to launch a minion worker service if enabled\n    # optional, Minion is disabled by default\n    # It will use the same DB type as Lstu: sqlite if you choose sqlite for `dbtype`,\n    # postgresql for postgresql, etc.\n    #minion => {\n    #    enabled => 0,\n    #    # SQLite ONLY - only used if if you choose sqlite as DB type,\n    #    # define the path to the minion database\n    #    # you can define it relative to lstu directory or set an absolute path\n    #    # remember that it has to be in a directory writable by Lutim user\n    #    # optional, default is minion.db\n    #    db_path => 'minion.db',\n    #    # PostgreSQL ONLY - only used if you choose postgresql as DB type\n    #    # these are the credentials to access the Minion's PostgreSQL database\n    #    # mandatory if you choosed postgresql as DB type, no default\n    #    pgdb => {\n    #        database => 'lstu_minion',\n    #        host     => 'localhost',\n    #        # optional, default is 5432\n    #        #port     => 5432,\n    #        #user     => 'DBUSER',\n    #        #pwd      => 'DBPASSWORD'\n    #    },\n    #    # MySQL ONLY - only used if you choose mysql as DB type\n    #    # these are the credentials to access the Minion's MySQL database\n    #    # mandatory if you choosed mysql as DB type, no default\n    #    mysqldb => {\n    #        database => 'lstu',\n    #        host     => 'localhost',\n    #        # optional, default is 3306\n    #        #port     => 3306,\n    #        #user     => 'DBUSER',\n    #        #pwd      => 'DBPASSWORD',\n    #    },\n    #},\n\n    # set `ldap` if you want that only authenticated users can shorten URLs\n    # please note that everybody can still use shortend URLs\n    # optional, no default\n    #ldap => { uri => 'ldap://rroemhild-test-openldap:10389', user_tree => 'ou=people,dc=planetexpress,dc=com', bind_dn => 'cn=admin,dc=planetexpress,dc=com', bind_pwd => 'GoodNewsEveryone', user_attr => 'uid', user_filter => '(!(uid=admin))', },\n    #ldap => {\n    #    uri         => 'ldaps://ldap.example.org',                 # server URI\n    #    user_tree   => 'ou=users,dc=example,dc=org',               # search base DN\n    #    bind_dn     => 'uid=ldap_user,ou=users,dc=example,dc=org', # search bind DN\n    #    bind_pwd    => 'secr3t',                                   # search bind password\n    #    user_attr   => 'uid',                                      # user attribute (uid, mail, sAMAccountName, etc.)\n    #    user_filter => '(!(uid=ldap_user))',                       # user filter (to exclude some users, etc.)\n    #},\n\n    # set `htpasswd` if you want to use an htpasswd file instead of ldap\n    # create the file with `htpasswd -c lstu.passwd user`, update it with `htpasswd lstu.passwd user2`\n    # make sure that lstu can read the file!\n    # optional, no default\n    #htpasswd => 'lstu.passwd',\n\n    # if you've set ldap or htpasswd above, the session will last `session_duration` seconds before\n    # the user needs to reauthenticate\n    # optional, default is 3600\n    #session_duration => 3600,\n\n    # how many redirections are allowed for the shortened URL before considering it as a spam?\n    # optional, default is 2. Set to -1 to allow infinite redirections (not recommended)\n    #max_redir => 2,\n\n    # spam blacklist regex. All URLs (or redirection) whose host part matches this regex are considered as spam\n    # optional, no default\n    #spam_blacklist_regex => 'foo|bar',\n\n    # spam path blacklist regex. All URLs (or redirection) whose path part matches this regex are considered as spam\n    # optional, no default\n    #spam_path_blacklist_regex => 'foo|bar',\n\n    # spam whitelist regex. All URLs (or redirection) whose host part matches this regex will never be considered as spam\n    # optional, no default\n    #spam_whitelist_regex => 'foo|bar',\n\n    # set to 1 to skip SpamHaus check (not recommended)\n    # optional, default is 0\n    #skip_spamhaus => 0,\n\n    # put your Google API key to enable Google safebrowsing check\n    # This will allow Lstu to download the Google safebrowsing database and use a local copy to check the URLs.\n    # Google does not get the URLs that are checked.\n    # Instructions to get a key: https://developers.google.com/safe-browsing/v4/get-started\n    # TL;DR: https://console.developers.google.com/projectselector/apis/library\n    # optional, no default\n    #safebrowsing_api_key => '',\n\n    # array of memcached servers to cache URL in order to accelerate responses to often-viewed URL.\n    # If set to [], the cache is disabled\n    # optional, default is []\n    #memcached_servers => [],\n\n    # Content-Security-Policy header that will be sent by Lstu\n    # Set to '' to disable CSP header\n    # https://content-security-policy.com/ provides a good documentation about CSP.\n    # https://report-uri.com/home/generate provides a tool to generate a CSP header.\n    # optional, default is \"default-src 'none'; script-src 'self'; style-src 'self'; img-src 'self' data:; font-src 'self'; form-action 'self'; base-uri 'self'\"\n    # the default value is good for `default` and `milligram` themes\n    #csp => \"default-src 'none'; script-src 'self'; style-src 'self'; img-src 'self' data:; font-src 'self'; form-action 'self'; base-uri 'self'\",\n\n    # X-Frame-Options header that will be sent by Lstu\n    # Valid values are: 'DENY', 'SAMEORIGIN', 'ALLOW-FROM https://example.com/'\n    # Set to '' to disable X-Frame-Options header\n    # See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options\n    # Please note that this will add a \"frame-ancestors\" directive to the CSP header (see above) accordingly\n    # to the chosen setting (See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/frame-ancestors)\n    # optional, default is 'DENY'\n    #x_frame_options => 'DENY',\n\n    # X-Content-Type-Options that will be sent by Lstu\n    # See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Content-Type-Options\n    # Set to '' to disable X-Content-Type-Options header\n    # optional, default is 'nosniff'\n    #x_content_type_options => 'nosniff',\n\n    # X-XSS-Protection that will be sent by Lstu\n    # See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-XSS-Protection\n    # Set to '' to disable X-XSS-Protection header\n    # optional, default is '1; mode=block'\n    #x_xss_protection => '1; mode=block',\n\n    # Log creator's IP address\n    # Set to 1 if you want to register the IP addresses of URL creators\n    # optional, default is 0\n    #log_creator_ip => 0,\n};\n"
  },
  {
    "path": "t/postgresql2.conf",
    "content": "# vim:set sw=4 ts=4 sts=4 ft=perl expandtab:\n{\n    ####################\n    # Hypnotoad settings\n    ####################\n    # see http://mojolicio.us/perldoc/Mojo/Server/Hypnotoad for a full list of settings\n    hypnotoad => {\n        # array of IP addresses and ports you want to listen to\n        listen => ['http://127.0.0.1:8080'],\n        # if you use Lstu behind a reverse proxy like Nginx, you want to set proxy to 1\n        # if you use Lstu directly, let it commented\n        #proxy  => 1,\n    },\n\n    # put a way to contact you here and uncomment it\n    # MANDATORY\n    contact       => 'admin[at]example.com',\n\n    # array of random strings used to encrypt cookies\n    # optional, default is ['fdjsofjoihrei'], PLEASE, CHANGE IT\n    #secret        => ['fdjsofjoihrei'],\n\n    # secret passphrase to access some admin features\n    # If you don't want to have a plain text password in configuration,\n    # use hashed_adminpwd instead\n    # optional, but you won't have access to admin /stats if not set and if hashed_adminpwd is not set either\n    #adminpwd      => 's3cr3T',\n\n    # secret hashed passphrase to access some admin features\n    # Hash your password by issuing `echo -n s3cr3T | sha256sum` on your terminal\n    # optional, but you won't have access to admin /stats if not set and if adminpwd is not set either\n    hashed_adminpwd => '31f7a65e315586ac198bd798b6629ce4903d0899476d5741a9f32e2e521b6a66',\n\n    # choose a theme. See the available themes in `themes` directory\n    # optional, default is 'default'\n    #theme         => 'default',\n\n    # number of URLs to be displayed per page in /stats\n    # optional, default is 10\n    #page_offset   => 10,\n\n    # length of the random URL\n    # optional, default is 8\n    #length            => 8,\n\n    # how many URLs will be provisioned in a batch ?\n    # optional, default is 5\n    #provis_step       => 5,\n\n    # max number of URLs to be provisioned\n    # optional, default is 100\n    #provisioning      => 100,\n\n    # URL sub-directory in which you want Lstu to be accessible\n    # example: you want to have Lstu under https://example.org/lstu/\n    # => set prefix to '/lstu' or to '/lstu/', it doesn't matter\n    # optional, defaut is /\n    #prefix        => '/',\n\n    # array of authorized domains for API calls.\n    # if you want to authorize everyone to use the API: ['*']\n    # optional, no domains allowed by default\n    #allowed_domains   => ['http://1.example.com', 'http://2.example.com'],\n\n    # if set, the shortened URLs will use this domain\n    # optional\n    #fixed_domain => 'example.org',\n\n    # choose what database you want to use\n    # valid choices are sqlite, postgresql and mysql (all lowercase)\n    # optional, default is sqlite\n    dbtype => 'postgresql',\n\n    # SQLite ONLY - only used if dbtype is set to sqlite\n    # define a path to the SQLite database\n    # you can define it relative to lstu directory or set an absolute path\n    # remember that it has to be in a directory writable by Lstu user\n    # optional, default is lstu.db\n    #db_path           => 'lstu.db',\n\n    # PostgreSQL ONLY - only used if dbtype is set to postgresql\n    # these are the credentials to access the PostgreSQL database\n    # mandatory if you choosed postgresql as dbtype\n    pgdb => {\n        database => 'lstu_db',\n        host     => 'postgres',\n    #    host     => 'localhost',\n    #    # optional, default is 5432\n        user     => 'lstu',\n        pwd      => 'lstu_pwd'\n    #    #max_connections => 1,\n    #},\n    },\n\n    # MySQL ONLY - only used if dbtype is set to mysql\n    # these are the credentials to access the MySQL database\n    # mandatory if you choosed mysql as dbtype\n    #mysqldb => {\n    #    database => 'lstu',\n    #    host     => 'localhost',\n    #    # optional, default is 3306\n    #    #port     => 3306,\n    #    #user     => 'DBUSER',\n    #    #pwd      => 'DBPASSWORD',\n    #    # optional, default is 5 (set to 0 to disable persistent connections)\n    #    #max_connections => 5,\n    #},\n\n    # Rate-limiting for the API\n    # After ban_min_strike requests in a second, the IP address will be\n    # banned for one hour.\n    # If it continues to query the API during this ban time at least\n    # ban_min_strike times, it will be banned for a month.\n    # optional, default is 3\n    #ban_min_strike    => 3,\n\n    # Ban whitelist\n    # You can whitelist IP addresses to prevent you from being banned\n    # Be careful, the IP addresses are compared as string, not as IP addresses\n    # a network range will not work\n    # Example of valid input: ban_whitelist => ['198.51.100.42', '2001:0DB8::42'],¬\n    # optional, default is an empty array\n    #ban_whitelist => [],\n\n    # Ban blacklist\n    # You can blacklist IP addresses to always ban those IP addresses\n    # Be careful, the IP addresses are compared as string, not as IP addresses\n    # a network range will not work\n    # Example of valid input: ban_blacklist => ['198.51.100.42', '2001:0DB8::42'],¬\n    # optional, default is an empty array\n    #ban_blacklist => [],\n\n    # define an URL to the Piwik instance and the ID of a website to track\n    # set if you want to track views in Piwik\n    # optional, Piwik tracking is disabled by default\n    #piwik => {\n    #    url    => 'http://piwik.example.com',\n    #    idsite => '1',\n    #},\n\n    # use Minion instead of directly increase counters\n    # need to launch a minion worker service if enabled\n    # optional, Minion is disabled by default\n    # It will use the same DB type as Lstu: sqlite if you choose sqlite for `dbtype`,\n    # postgresql for postgresql, etc.\n    #minion => {\n    #    enabled => 0,\n    #    # SQLite ONLY - only used if if you choose sqlite as DB type,\n    #    # define the path to the minion database\n    #    # you can define it relative to lstu directory or set an absolute path\n    #    # remember that it has to be in a directory writable by Lutim user\n    #    # optional, default is minion.db\n    #    db_path => 'minion.db',\n    #    # PostgreSQL ONLY - only used if you choose postgresql as DB type\n    #    # these are the credentials to access the Minion's PostgreSQL database\n    #    # mandatory if you choosed postgresql as DB type, no default\n    #    pgdb => {\n    #        database => 'lstu_minion',\n    #        host     => 'localhost',\n    #        # optional, default is 5432\n    #        #port     => 5432,\n    #        #user     => 'DBUSER',\n    #        #pwd      => 'DBPASSWORD'\n    #    },\n    #    # MySQL ONLY - only used if you choose mysql as DB type\n    #    # these are the credentials to access the Minion's MySQL database\n    #    # mandatory if you choosed mysql as DB type, no default\n    #    mysqldb => {\n    #        database => 'lstu',\n    #        host     => 'localhost',\n    #        # optional, default is 3306\n    #        #port     => 3306,\n    #        #user     => 'DBUSER',\n    #        #pwd      => 'DBPASSWORD',\n    #    },\n    #},\n\n    # set `ldap` if you want that only authenticated users can shorten URLs\n    # please note that everybody can still use shortend URLs\n    # optional, no default\n    #ldap => { uri => 'ldap://rroemhild-test-openldap:10389', user_tree => 'ou=people,dc=planetexpress,dc=com', bind_dn => 'cn=admin,dc=planetexpress,dc=com', bind_pwd => 'GoodNewsEveryone', user_attr => 'uid', user_filter => '(!(uid=admin))', },\n    #ldap => {\n    #    uri         => 'ldaps://ldap.example.org',                 # server URI\n    #    user_tree   => 'ou=users,dc=example,dc=org',               # search base DN\n    #    bind_dn     => 'uid=ldap_user,ou=users,dc=example,dc=org', # search bind DN\n    #    bind_pwd    => 'secr3t',                                   # search bind password\n    #    user_attr   => 'uid',                                      # user attribute (uid, mail, sAMAccountName, etc.)\n    #    user_filter => '(!(uid=ldap_user))',                       # user filter (to exclude some users, etc.)\n    #},\n\n    # set `htpasswd` if you want to use an htpasswd file instead of ldap\n    # create the file with `htpasswd -c lstu.passwd user`, update it with `htpasswd lstu.passwd user2`\n    # make sure that lstu can read the file!\n    # optional, no default\n    #htpasswd => 'lstu.passwd',\n\n    # if you've set ldap or htpasswd above, the session will last `session_duration` seconds before\n    # the user needs to reauthenticate\n    # optional, default is 3600\n    #session_duration => 3600,\n\n    # how many redirections are allowed for the shortened URL before considering it as a spam?\n    # optional, default is 2. Set to -1 to allow infinite redirections (not recommended)\n    #max_redir => 2,\n\n    # spam blacklist regex. All URLs (or redirection) whose host part matches this regex are considered as spam\n    # optional, no default\n    #spam_blacklist_regex => 'foo|bar',\n\n    # spam path blacklist regex. All URLs (or redirection) whose path part matches this regex are considered as spam\n    # optional, no default\n    #spam_path_blacklist_regex => 'foo|bar',\n\n    # spam whitelist regex. All URLs (or redirection) whose host part matches this regex will never be considered as spam\n    # optional, no default\n    #spam_whitelist_regex => 'foo|bar',\n\n    # set to 1 to skip SpamHaus check (not recommended)\n    # optional, default is 0\n    #skip_spamhaus => 0,\n\n    # put your Google API key to enable Google safebrowsing check\n    # This will allow Lstu to download the Google safebrowsing database and use a local copy to check the URLs.\n    # Google does not get the URLs that are checked.\n    # Instructions to get a key: https://developers.google.com/safe-browsing/v4/get-started\n    # TL;DR: https://console.developers.google.com/projectselector/apis/library\n    # optional, no default\n    #safebrowsing_api_key => '',\n\n    # array of memcached servers to cache URL in order to accelerate responses to often-viewed URL.\n    # If set to [], the cache is disabled\n    # optional, default is []\n    #memcached_servers => [],\n\n    # Content-Security-Policy header that will be sent by Lstu\n    # Set to '' to disable CSP header\n    # https://content-security-policy.com/ provides a good documentation about CSP.\n    # https://report-uri.com/home/generate provides a tool to generate a CSP header.\n    # optional, default is \"default-src 'none'; script-src 'self'; style-src 'self'; img-src 'self' data:; font-src 'self'; form-action 'self'; base-uri 'self'\"\n    # the default value is good for `default` and `milligram` themes\n    #csp => \"default-src 'none'; script-src 'self'; style-src 'self'; img-src 'self' data:; font-src 'self'; form-action 'self'; base-uri 'self'\",\n\n    # X-Frame-Options header that will be sent by Lstu\n    # Valid values are: 'DENY', 'SAMEORIGIN', 'ALLOW-FROM https://example.com/'\n    # Set to '' to disable X-Frame-Options header\n    # See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options\n    # Please note that this will add a \"frame-ancestors\" directive to the CSP header (see above) accordingly\n    # to the chosen setting (See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/frame-ancestors)\n    # optional, default is 'DENY'\n    #x_frame_options => 'DENY',\n\n    # X-Content-Type-Options that will be sent by Lstu\n    # See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Content-Type-Options\n    # Set to '' to disable X-Content-Type-Options header\n    # optional, default is 'nosniff'\n    #x_content_type_options => 'nosniff',\n\n    # X-XSS-Protection that will be sent by Lstu\n    # See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-XSS-Protection\n    # Set to '' to disable X-XSS-Protection header\n    # optional, default is '1; mode=block'\n    #x_xss_protection => '1; mode=block',\n\n    # Log creator's IP address\n    # Set to 1 if you want to register the IP addresses of URL creators\n    # optional, default is 0\n    #log_creator_ip => 0,\n};\n"
  },
  {
    "path": "t/postgresql3.conf",
    "content": "# vim:set sw=4 ts=4 sts=4 ft=perl expandtab:\n{\n    ####################\n    # Hypnotoad settings\n    ####################\n    # see http://mojolicio.us/perldoc/Mojo/Server/Hypnotoad for a full list of settings\n    hypnotoad => {\n        # array of IP addresses and ports you want to listen to\n        listen => ['http://127.0.0.1:8080'],\n        # if you use Lstu behind a reverse proxy like Nginx, you want to set proxy to 1\n        # if you use Lstu directly, let it commented\n        #proxy  => 1,\n    },\n\n    # put a way to contact you here and uncomment it\n    # MANDATORY\n    contact       => 'admin[at]example.com',\n\n    # array of random strings used to encrypt cookies\n    # optional, default is ['fdjsofjoihrei'], PLEASE, CHANGE IT\n    #secret        => ['fdjsofjoihrei'],\n\n    # secret passphrase to access some admin features\n    # If you don't want to have a plain text password in configuration,\n    # use hashed_adminpwd instead\n    # optional, but you won't have access to admin /stats if not set and if hashed_adminpwd is not set either\n    #adminpwd      => 's3cr3T',\n\n    # secret hashed passphrase to access some admin features\n    # Hash your password by issuing `echo -n s3cr3T | sha256sum` on your terminal\n    # optional, but you won't have access to admin /stats if not set and if adminpwd is not set either\n    hashed_adminpwd => '31f7a65e315586ac198bd798b6629ce4903d0899476d5741a9f32e2e521b6a66',\n\n    # choose a theme. See the available themes in `themes` directory\n    # optional, default is 'default'\n    #theme         => 'default',\n\n    # number of URLs to be displayed per page in /stats\n    # optional, default is 10\n    #page_offset   => 10,\n\n    # length of the random URL\n    # optional, default is 8\n    #length            => 8,\n\n    # how many URLs will be provisioned in a batch ?\n    # optional, default is 5\n    #provis_step       => 5,\n\n    # max number of URLs to be provisioned\n    # optional, default is 100\n    #provisioning      => 100,\n\n    # URL sub-directory in which you want Lstu to be accessible\n    # example: you want to have Lstu under https://example.org/lstu/\n    # => set prefix to '/lstu' or to '/lstu/', it doesn't matter\n    # optional, defaut is /\n    #prefix        => '/',\n\n    # array of authorized domains for API calls.\n    # if you want to authorize everyone to use the API: ['*']\n    # optional, no domains allowed by default\n    #allowed_domains   => ['http://1.example.com', 'http://2.example.com'],\n\n    # if set, the shortened URLs will use this domain\n    # optional\n    #fixed_domain => 'example.org',\n\n    # choose what database you want to use\n    # valid choices are sqlite, postgresql and mysql (all lowercase)\n    # optional, default is sqlite\n    dbtype => 'postgresql',\n\n    # SQLite ONLY - only used if dbtype is set to sqlite\n    # define a path to the SQLite database\n    # you can define it relative to lstu directory or set an absolute path\n    # remember that it has to be in a directory writable by Lstu user\n    # optional, default is lstu.db\n    #db_path           => 'lstu.db',\n\n    # PostgreSQL ONLY - only used if dbtype is set to postgresql\n    # these are the credentials to access the PostgreSQL database\n    # mandatory if you choosed postgresql as dbtype\n    pgdb => {\n        database => 'lstu_db',\n        host     => 'postgres',\n    #    # optional, default is 5432\n    #    #port     => 5432,\n        user     => 'lstu',\n        pwd      => 'lstu_pwd'\n    #    # optional, default is 1\n    #    #max_connections => 1,\n    },\n\n    # MySQL ONLY - only used if dbtype is set to mysql\n    # these are the credentials to access the MySQL database\n    # mandatory if you choosed mysql as dbtype\n    #mysqldb => {\n    #    database => 'lstu',\n    #    host     => 'localhost',\n    #    # optional, default is 3306\n    #    #port     => 3306,\n    #    #user     => 'DBUSER',\n    #    #pwd      => 'DBPASSWORD',\n    #    # optional, default is 5 (set to 0 to disable persistent connections)\n    #    #max_connections => 5,\n    #},\n\n    # Rate-limiting for the API\n    # After ban_min_strike requests in a second, the IP address will be\n    # banned for one hour.\n    # If it continues to query the API during this ban time at least\n    # ban_min_strike times, it will be banned for a month.\n    # optional, default is 3\n    #ban_min_strike    => 3,\n\n    # Ban whitelist\n    # You can whitelist IP addresses to prevent you from being banned\n    # Be careful, the IP addresses are compared as string, not as IP addresses\n    # a network range will not work\n    # Example of valid input: ban_whitelist => ['198.51.100.42', '2001:0DB8::42'],¬\n    # optional, default is an empty array\n    #ban_whitelist => [],\n\n    # Ban blacklist\n    # You can blacklist IP addresses to always ban those IP addresses\n    # Be careful, the IP addresses are compared as string, not as IP addresses\n    # a network range will not work\n    # Example of valid input: ban_blacklist => ['198.51.100.42', '2001:0DB8::42'],¬\n    # optional, default is an empty array\n    #ban_blacklist => [],\n\n    # define an URL to the Piwik instance and the ID of a website to track\n    # set if you want to track views in Piwik\n    # optional, Piwik tracking is disabled by default\n    #piwik => {\n    #    url    => 'http://piwik.example.com',\n    #    idsite => '1',\n    #},\n\n    # use Minion instead of directly increase counters\n    # need to launch a minion worker service if enabled\n    # optional, Minion is disabled by default\n    # It will use the same DB type as Lstu: sqlite if you choose sqlite for `dbtype`,\n    # postgresql for postgresql, etc.\n    minion => {\n        enabled => 1,\n    #    # SQLite ONLY - only used if if you choose sqlite as DB type,\n    #    # define the path to the minion database\n    #    # you can define it relative to lstu directory or set an absolute path\n    #    # remember that it has to be in a directory writable by Lutim user\n    #    # optional, default is minion.db\n    #    db_path => 'minion.db',\n    #    # PostgreSQL ONLY - only used if you choose postgresql as DB type\n    #    # these are the credentials to access the Minion's PostgreSQL database\n    #    # mandatory if you choosed postgresql as DB type, no default\n        pgdb => {\n            database => 'lstu_minion',\n            host     => 'postgres',\n    #        # optional, default is 5432\n    #        #port     => 5432,\n            user     => 'lstu',\n            pwd      => 'lstu_pwd'\n        },\n    #    # MySQL ONLY - only used if you choose mysql as DB type\n    #    # these are the credentials to access the Minion's MySQL database\n    #    # mandatory if you choosed mysql as DB type, no default\n    #    mysqldb => {\n    #        database => 'lstu',\n    #        host     => 'localhost',\n    #        # optional, default is 3306\n    #        #port     => 3306,\n    #        #user     => 'DBUSER',\n    #        #pwd      => 'DBPASSWORD',\n    #    },\n    },\n\n    # set `ldap` if you want that only authenticated users can shorten URLs\n    # please note that everybody can still use shortend URLs\n    # optional, no default\n    #ldap => { uri => 'ldap://rroemhild-test-openldap:10389', user_tree => 'ou=people,dc=planetexpress,dc=com', bind_dn => 'cn=admin,dc=planetexpress,dc=com', bind_pwd => 'GoodNewsEveryone', user_attr => 'uid', user_filter => '(!(uid=admin))', },\n    #ldap => {\n    #    uri         => 'ldaps://ldap.example.org',                 # server URI\n    #    user_tree   => 'ou=users,dc=example,dc=org',               # search base DN\n    #    bind_dn     => 'uid=ldap_user,ou=users,dc=example,dc=org', # search bind DN\n    #    bind_pwd    => 'secr3t',                                   # search bind password\n    #    user_attr   => 'uid',                                      # user attribute (uid, mail, sAMAccountName, etc.)\n    #    user_filter => '(!(uid=ldap_user))',                       # user filter (to exclude some users, etc.)\n    #},\n\n    # set `htpasswd` if you want to use an htpasswd file instead of ldap\n    # create the file with `htpasswd -c lstu.passwd user`, update it with `htpasswd lstu.passwd user2`\n    # make sure that lstu can read the file!\n    # optional, no default\n    #htpasswd => 'lstu.passwd',\n\n    # if you've set ldap or htpasswd above, the session will last `session_duration` seconds before\n    # the user needs to reauthenticate\n    # optional, default is 3600\n    #session_duration => 3600,\n\n    # how many redirections are allowed for the shortened URL before considering it as a spam?\n    # optional, default is 2. Set to -1 to allow infinite redirections (not recommended)\n    #max_redir => 2,\n\n    # spam blacklist regex. All URLs (or redirection) whose host part matches this regex are considered as spam\n    # optional, no default\n    #spam_blacklist_regex => 'foo|bar',\n\n    # spam path blacklist regex. All URLs (or redirection) whose path part matches this regex are considered as spam\n    # optional, no default\n    #spam_path_blacklist_regex => 'foo|bar',\n\n    # spam whitelist regex. All URLs (or redirection) whose host part matches this regex will never be considered as spam\n    # optional, no default\n    #spam_whitelist_regex => 'foo|bar',\n\n    # set to 1 to skip SpamHaus check (not recommended)\n    # optional, default is 0\n    #skip_spamhaus => 0,\n\n    # put your Google API key to enable Google safebrowsing check\n    # This will allow Lstu to download the Google safebrowsing database and use a local copy to check the URLs.\n    # Google does not get the URLs that are checked.\n    # Instructions to get a key: https://developers.google.com/safe-browsing/v4/get-started\n    # TL;DR: https://console.developers.google.com/projectselector/apis/library\n    # optional, no default\n    #safebrowsing_api_key => '',\n\n    # array of memcached servers to cache URL in order to accelerate responses to often-viewed URL.\n    # If set to [], the cache is disabled\n    # optional, default is []\n    #memcached_servers => [],\n\n    # Content-Security-Policy header that will be sent by Lstu\n    # Set to '' to disable CSP header\n    # https://content-security-policy.com/ provides a good documentation about CSP.\n    # https://report-uri.com/home/generate provides a tool to generate a CSP header.\n    # optional, default is \"default-src 'none'; script-src 'self'; style-src 'self'; img-src 'self' data:; font-src 'self'; form-action 'self'; base-uri 'self'\"\n    # the default value is good for `default` and `milligram` themes\n    #csp => \"default-src 'none'; script-src 'self'; style-src 'self'; img-src 'self' data:; font-src 'self'; form-action 'self'; base-uri 'self'\",\n\n    # X-Frame-Options header that will be sent by Lstu\n    # Valid values are: 'DENY', 'SAMEORIGIN', 'ALLOW-FROM https://example.com/'\n    # Set to '' to disable X-Frame-Options header\n    # See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options\n    # Please note that this will add a \"frame-ancestors\" directive to the CSP header (see above) accordingly\n    # to the chosen setting (See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/frame-ancestors)\n    # optional, default is 'DENY'\n    #x_frame_options => 'DENY',\n\n    # X-Content-Type-Options that will be sent by Lstu\n    # See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Content-Type-Options\n    # Set to '' to disable X-Content-Type-Options header\n    # optional, default is 'nosniff'\n    #x_content_type_options => 'nosniff',\n\n    # X-XSS-Protection that will be sent by Lstu\n    # See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-XSS-Protection\n    # Set to '' to disable X-XSS-Protection header\n    # optional, default is '1; mode=block'\n    #x_xss_protection => '1; mode=block',\n\n    # Log creator's IP address\n    # Set to 1 if you want to register the IP addresses of URL creators\n    # optional, default is 0\n    #log_creator_ip => 0,\n};\n"
  },
  {
    "path": "t/sqlite1.conf",
    "content": "# vim:set sw=4 ts=4 sts=4 ft=perl expandtab:\n{\n    ####################\n    # Hypnotoad settings\n    ####################\n    # see http://mojolicio.us/perldoc/Mojo/Server/Hypnotoad for a full list of settings\n    hypnotoad => {\n        # array of IP addresses and ports you want to listen to\n        listen => ['http://127.0.0.1:8080'],\n        # if you use Lstu behind a reverse proxy like Nginx, you want to set proxy to 1\n        # if you use Lstu directly, let it commented\n        #proxy  => 1,\n    },\n\n    # put a way to contact you here and uncomment it\n    # MANDATORY\n    contact       => 'admin[at]example.com',\n\n    # array of random strings used to encrypt cookies\n    # optional, default is ['fdjsofjoihrei'], PLEASE, CHANGE IT\n    #secret        => ['fdjsofjoihrei'],\n\n    # secret passphrase to access some admin features\n    # If you don't want to have a plain text password in configuration,\n    # use hashed_adminpwd instead\n    # optional, but you won't have access to admin /stats if not set and if hashed_adminpwd is not set either\n    adminpwd => 'toto',\n\n    # secret hashed passphrase to access some admin features\n    # Hash your password by issuing `echo -n s3cr3T | sha256sum` on your terminal\n    # optional, but you won't have access to admin /stats if not set and if adminpwd is not set either\n    #hashed_adminpwd => '94b2feede6ea5e2eec62f457ecb7d3f719b24d19c29d4e5466246a31908fc23b',\n\n    # choose a theme. See the available themes in `themes` directory\n    # optional, default is 'default'\n    #theme         => 'default',\n\n    # number of URLs to be displayed per page in /stats\n    # optional, default is 10\n    #page_offset   => 10,\n\n    # length of the random URL\n    # optional, default is 8\n    #length            => 8,\n\n    # how many URLs will be provisioned in a batch ?\n    # optional, default is 5\n    #provis_step       => 5,\n\n    # max number of URLs to be provisioned\n    # optional, default is 100\n    #provisioning      => 100,\n\n    # URL sub-directory in which you want Lstu to be accessible\n    # example: you want to have Lstu under https://example.org/lstu/\n    # => set prefix to '/lstu' or to '/lstu/', it doesn't matter\n    # optional, defaut is /\n    #prefix        => '/',\n\n    # array of authorized domains for API calls.\n    # if you want to authorize everyone to use the API: ['*']\n    # optional, no domains allowed by default\n    #allowed_domains   => ['http://1.example.com', 'http://2.example.com'],\n\n    # if set, the shortened URLs will use this domain\n    # optional\n    #fixed_domain => 'example.org',\n\n    # choose what database you want to use\n    # valid choices are sqlite and postgresql (all lowercase)\n    # optional, default is sqlite\n    #dbtype => 'sqlite',\n\n    # SQLite ONLY - only used if dbtype is set to sqlite\n    # define a path to the SQLite database\n    # you can define it relative to lstu directory or set an absolute path\n    # remember that it has to be in a directory writable by Lstu user\n    # optional, default is lstu.db\n    db_path => 'test1.db',\n\n    # PostgreSQL ONLY - only used if dbtype is set to postgresql\n    # these are the credentials to access the PostgreSQL database\n    # mandatory if you choosed postgresql as dbtype\n    #pgdb => {\n    #    database => 'lstu',\n    #    host     => 'localhost',\n    #    # optional, default is 5432\n    #    #port     => 5432,\n    #    #user     => 'DBUSER',\n    #    #pwd      => 'DBPASSWORD',\n    #    # optional, default is 1\n    #    #max_connections => 1,\n    #},\n\n    # MySQL ONLY - only used if dbtype is set to mysql\n    # these are the credentials to access the MySQL database\n    # mandatory if you choosed mysql as dbtype\n    #mysqldb => {\n    #    database => 'lstu',\n    #    host     => 'localhost',\n    #    # optional, default is 3306\n    #    #port     => 3306,\n    #    #user     => 'DBUSER',\n    #    #pwd      => 'DBPASSWORD',\n    #    # optional, default is 5 (set to 0 to disable persistent connections)\n    #    #max_connections => 5,\n    #},\n\n    # Rate-limiting for the API\n    # After ban_min_strike requests in a second, the IP address will be\n    # banned for one hour.\n    # If it continues to query the API during this ban time at least\n    # ban_min_strike times, it will be banned for a month.\n    # optional, default is 3\n    #ban_min_strike    => 3,\n\n    # Ban whitelist\n    # You can whitelist IP addresses to prevent you from being banned\n    # Be careful, the IP addresses are compared as string, not as IP addresses\n    # a network range will not work\n    # Example of valid input: ban_whitelist => ['198.51.100.42', '2001:0DB8::42'],¬\n    # optional, default is an empty array\n    #ban_whitelist => [],\n\n    # Ban blacklist\n    # You can blacklist IP addresses to always ban those IP addresses\n    # Be careful, the IP addresses are compared as string, not as IP addresses\n    # a network range will not work\n    # Example of valid input: ban_blacklist => ['198.51.100.42', '2001:0DB8::42'],¬\n    # optional, default is an empty array\n    #ban_blacklist => [],\n\n    # define an URL to the Piwik instance and the ID of a website to track\n    # set if you want to track views in Piwik\n    # optional, Piwik tracking is disabled by default\n    #piwik => {\n    #    url    => 'http://piwik.example.com',\n    #    idsite => '1',\n    #},\n\n    # use Minion instead of directly increase counters\n    # need to launch a minion worker service if enabled\n    # optional, Minion is disabled by default\n    # It will use the same DB type as Lstu: sqlite if you choose sqlite for `dbtype`,\n    # postgresql for postgresql, etc.\n    #minion => {\n    #    enabled => 0,\n    #    # SQLite ONLY - only used if if you choose sqlite as DB type,\n    #    # define the path to the minion database\n    #    # you can define it relative to lstu directory or set an absolute path\n    #    # remember that it has to be in a directory writable by Lutim user\n    #    # optional, default is minion.db\n    #    db_path => 'minion.db',\n    #    # PostgreSQL ONLY - only used if you choose postgresql as DB type\n    #    # these are the credentials to access the Minion's PostgreSQL database\n    #    # mandatory if you choosed postgresql as DB type, no default\n    #    pgdb => {\n    #        database => 'lstu_minion',\n    #        host     => 'localhost',\n    #        # optional, default is 5432\n    #        #port     => 5432,\n    #        #user     => 'DBUSER',\n    #        #pwd      => 'DBPASSWORD'\n    #    },\n    #    # MySQL ONLY - only used if you choose mysql as DB type\n    #    # these are the credentials to access the Minion's MySQL database\n    #    # mandatory if you choosed mysql as DB type, no default\n    #    mysqldb => {\n    #        database => 'lstu',\n    #        host     => 'localhost',\n    #        # optional, default is 3306\n    #        #port     => 3306,\n    #        #user     => 'DBUSER',\n    #        #pwd      => 'DBPASSWORD',\n    #    },\n    #},\n\n    # set `ldap` if you want that only authenticated users can shorten URLs\n    # please note that everybody can still use shortend URLs\n    # optional, no default\n    #ldap => { uri => 'ldap://rroemhild-test-openldap:10389', user_tree => 'ou=people,dc=planetexpress,dc=com', bind_dn => 'cn=admin,dc=planetexpress,dc=com', bind_pwd => 'GoodNewsEveryone', user_attr => 'uid', user_filter => '(!(uid=admin))', },\n    #ldap => {\n    #    uri         => 'ldaps://ldap.example.org',                 # server URI\n    #    user_tree   => 'ou=users,dc=example,dc=org',               # search base DN\n    #    bind_dn     => 'uid=ldap_user,ou=users,dc=example,dc=org', # search bind DN\n    #    bind_pwd    => 'secr3t',                                   # search bind password\n    #    user_attr   => 'uid',                                      # user attribute (uid, mail, sAMAccountName, etc.)\n    #    user_filter => '(!(uid=ldap_user))',                       # user filter (to exclude some users, etc.)\n    #},\n\n    # set `htpasswd` if you want to use an htpasswd file instead of ldap\n    # create the file with `htpasswd -c lstu.passwd user`, update it with `htpasswd lstu.passwd user2`\n    # make sure that lstu can read the file!\n    # optional, no default\n    #htpasswd => 'lstu.passwd',\n\n    # if you've set ldap or htpasswd above, the session will last `session_duration` seconds before\n    # the user needs to reauthenticate\n    # optional, default is 3600\n    #session_duration => 3600,\n\n    # how many redirections are allowed for the shortened URL before considering it as a spam?\n    # optional, default is 2. Set to -1 to allow infinite redirections (not recommended)\n    #max_redir => 2,\n\n    # spam blacklist regex. All URLs (or redirection) whose host part matches this regex are considered as spam\n    # optional, no default\n    #spam_blacklist_regex => 'foo|bar',\n\n    # spam path blacklist regex. All URLs (or redirection) whose path part matches this regex are considered as spam\n    # optional, no default\n    #spam_path_blacklist_regex => 'foo|bar',\n\n    # spam whitelist regex. All URLs (or redirection) whose host part matches this regex will never be considered as spam\n    # optional, no default\n    #spam_whitelist_regex => 'foo|bar',\n\n    # set to 1 to skip SpamHaus check (not recommended)\n    # optional, default is 0\n    #skip_spamhaus => 0,\n\n    # put your Google API key to enable Google safebrowsing check\n    # This will allow Lstu to download the Google safebrowsing database and use a local copy to check the URLs.\n    # Google does not get the URLs that are checked.\n    # Instructions to get a key: https://developers.google.com/safe-browsing/v4/get-started\n    # TL;DR: https://console.developers.google.com/projectselector/apis/library\n    # optional, no default\n    #safebrowsing_api_key => '',\n\n    # array of memcached servers to cache URL in order to accelerate responses to often-viewed URL.\n    # If set to [], the cache is disabled\n    # optional, default is []\n    #memcached_servers => [],\n\n    # Content-Security-Policy header that will be sent by Lstu\n    # Set to '' to disable CSP header\n    # https://content-security-policy.com/ provides a good documentation about CSP.\n    # https://report-uri.com/home/generate provides a tool to generate a CSP header.\n    # optional, default is \"default-src 'none'; script-src 'self'; style-src 'self'; img-src 'self' data:; font-src 'self'; form-action 'self'; base-uri 'self'\"\n    # the default value is good for `default` and `milligram` themes\n    #csp => \"default-src 'none'; script-src 'self'; style-src 'self'; img-src 'self' data:; font-src 'self'; form-action 'self'; base-uri 'self'\",\n\n    # X-Frame-Options header that will be sent by Lstu\n    # Valid values are: 'DENY', 'SAMEORIGIN', 'ALLOW-FROM https://example.com/'\n    # Set to '' to disable X-Frame-Options header\n    # See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options\n    # Please note that this will add a \"frame-ancestors\" directive to the CSP header (see above) accordingly\n    # to the chosen setting (See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/frame-ancestors)\n    # optional, default is 'DENY'\n    #x_frame_options => 'DENY',\n\n    # X-Content-Type-Options that will be sent by Lstu\n    # See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Content-Type-Options\n    # Set to '' to disable X-Content-Type-Options header\n    # optional, default is 'nosniff'\n    #x_content_type_options => 'nosniff',\n\n    # X-XSS-Protection that will be sent by Lstu\n    # See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-XSS-Protection\n    # Set to '' to disable X-XSS-Protection header\n    # optional, default is '1; mode=block'\n    #x_xss_protection => '1; mode=block',\n\n    # Log creator's IP address\n    # Set to 1 if you want to register the IP addresses of URL creators\n    # optional, default is 0\n    #log_creator_ip => 0,\n};\n"
  },
  {
    "path": "t/sqlite2.conf",
    "content": "# vim:set sw=4 ts=4 sts=4 ft=perl expandtab:\n{\n    ####################\n    # Hypnotoad settings\n    ####################\n    # see http://mojolicio.us/perldoc/Mojo/Server/Hypnotoad for a full list of settings\n    hypnotoad => {\n        # array of IP addresses and ports you want to listen to\n        listen => ['http://127.0.0.1:8080'],\n        # if you use Lstu behind a reverse proxy like Nginx, you want to set proxy to 1\n        # if you use Lstu directly, let it commented\n        #proxy  => 1,\n    },\n\n    # put a way to contact you here and uncomment it\n    # MANDATORY\n    contact       => 'admin[at]example.com',\n\n    # array of random strings used to encrypt cookies\n    # optional, default is ['fdjsofjoihrei'], PLEASE, CHANGE IT\n    #secret        => ['fdjsofjoihrei'],\n\n    # secret passphrase to access some admin features\n    # If you don't want to have a plain text password in configuration,\n    # use hashed_adminpwd instead\n    # optional, but you won't have access to admin /stats if not set and if hashed_adminpwd is not set either\n    #adminpwd      => 's3cr3T',\n\n    # secret hashed passphrase to access some admin features\n    # Hash your password by issuing `echo -n s3cr3T | sha256sum` on your terminal\n    # optional, but you won't have access to admin /stats if not set and if adminpwd is not set either\n    hashed_adminpwd => '31f7a65e315586ac198bd798b6629ce4903d0899476d5741a9f32e2e521b6a66',\n\n    # choose a theme. See the available themes in `themes` directory\n    # optional, default is 'default'\n    #theme         => 'default',\n\n    # number of URLs to be displayed per page in /stats\n    # optional, default is 10\n    #page_offset   => 10,\n\n    # length of the random URL\n    # optional, default is 8\n    #length            => 8,\n\n    # how many URLs will be provisioned in a batch ?\n    # optional, default is 5\n    #provis_step       => 5,\n\n    # max number of URLs to be provisioned\n    # optional, default is 100\n    #provisioning      => 100,\n\n    # URL sub-directory in which you want Lstu to be accessible\n    # example: you want to have Lstu under https://example.org/lstu/\n    # => set prefix to '/lstu' or to '/lstu/', it doesn't matter\n    # optional, defaut is /\n    #prefix        => '/',\n\n    # array of authorized domains for API calls.\n    # if you want to authorize everyone to use the API: ['*']\n    # optional, no domains allowed by default\n    #allowed_domains   => ['http://1.example.com', 'http://2.example.com'],\n\n    # if set, the shortened URLs will use this domain\n    # optional\n    #fixed_domain => 'example.org',\n\n    # choose what database you want to use\n    # valid choices are sqlite and postgresql (all lowercase)\n    # optional, default is sqlite\n    #dbtype => 'sqlite',\n\n    # SQLite ONLY - only used if dbtype is set to sqlite\n    # define a path to the SQLite database\n    # you can define it relative to lstu directory or set an absolute path\n    # remember that it has to be in a directory writable by Lstu user\n    # optional, default is lstu.db\n    db_path => 'test2.db',\n\n    # PostgreSQL ONLY - only used if dbtype is set to postgresql\n    # these are the credentials to access the PostgreSQL database\n    # mandatory if you choosed postgresql as dbtype\n    #pgdb => {\n    #    database => 'lstu',\n    #    host     => 'localhost',\n    #    # optional, default is 5432\n    #    #port     => 5432,\n    #    #user     => 'DBUSER',\n    #    #pwd      => 'DBPASSWORD',\n    #    # optional, default is 1\n    #    #max_connections => 1,\n    #},\n\n    # MySQL ONLY - only used if dbtype is set to mysql\n    # these are the credentials to access the MySQL database\n    # mandatory if you choosed mysql as dbtype\n    #mysqldb => {\n    #    database => 'lstu',\n    #    host     => 'localhost',\n    #    # optional, default is 3306\n    #    #port     => 3306,\n    #    #user     => 'DBUSER',\n    #    #pwd      => 'DBPASSWORD',\n    #    # optional, default is 5 (set to 0 to disable persistent connections)\n    #    #max_connections => 5,\n    #},\n\n    # Rate-limiting for the API\n    # After ban_min_strike requests in a second, the IP address will be\n    # banned for one hour.\n    # If it continues to query the API during this ban time at least\n    # ban_min_strike times, it will be banned for a month.\n    # optional, default is 3\n    #ban_min_strike    => 3,\n\n    # Ban whitelist\n    # You can whitelist IP addresses to prevent you from being banned\n    # Be careful, the IP addresses are compared as string, not as IP addresses\n    # a network range will not work\n    # Example of valid input: ban_whitelist => ['198.51.100.42', '2001:0DB8::42'],¬\n    # optional, default is an empty array\n    #ban_whitelist => [],\n\n    # Ban blacklist\n    # You can blacklist IP addresses to always ban those IP addresses\n    # Be careful, the IP addresses are compared as string, not as IP addresses\n    # a network range will not work\n    # Example of valid input: ban_blacklist => ['198.51.100.42', '2001:0DB8::42'],¬\n    # optional, default is an empty array\n    #ban_blacklist => [],\n\n    # define an URL to the Piwik instance and the ID of a website to track\n    # set if you want to track views in Piwik\n    # optional, Piwik tracking is disabled by default\n    #piwik => {\n    #    url    => 'http://piwik.example.com',\n    #    idsite => '1',\n    #},\n\n    # use Minion instead of directly increase counters\n    # need to launch a minion worker service if enabled\n    # optional, Minion is disabled by default\n    # It will use the same DB type as Lstu: sqlite if you choose sqlite for `dbtype`,\n    # postgresql for postgresql, etc.\n    #minion => {\n    #    enabled => 0,\n    #    # SQLite ONLY - only used if if you choose sqlite as DB type,\n    #    # define the path to the minion database\n    #    # you can define it relative to lstu directory or set an absolute path\n    #    # remember that it has to be in a directory writable by Lutim user\n    #    # optional, default is minion.db\n    #    db_path => 'minion.db',\n    #    # PostgreSQL ONLY - only used if you choose postgresql as DB type\n    #    # these are the credentials to access the Minion's PostgreSQL database\n    #    # mandatory if you choosed postgresql as DB type, no default\n    #    pgdb => {\n    #        database => 'lstu_minion',\n    #        host     => 'localhost',\n    #        # optional, default is 5432\n    #        #port     => 5432,\n    #        #user     => 'DBUSER',\n    #        #pwd      => 'DBPASSWORD'\n    #    },\n    #    # MySQL ONLY - only used if you choose mysql as DB type\n    #    # these are the credentials to access the Minion's MySQL database\n    #    # mandatory if you choosed mysql as DB type, no default\n    #    mysqldb => {\n    #        database => 'lstu',\n    #        host     => 'localhost',\n    #        # optional, default is 3306\n    #        #port     => 3306,\n    #        #user     => 'DBUSER',\n    #        #pwd      => 'DBPASSWORD',\n    #    },\n    #},\n\n    # set `ldap` if you want that only authenticated users can shorten URLs\n    # please note that everybody can still use shortend URLs\n    # optional, no default\n    #ldap => { uri => 'ldap://rroemhild-test-openldap:10389', user_tree => 'ou=people,dc=planetexpress,dc=com', bind_dn => 'cn=admin,dc=planetexpress,dc=com', bind_pwd => 'GoodNewsEveryone', user_attr => 'uid', user_filter => '(!(uid=admin))', },\n    #ldap => {\n    #    uri         => 'ldaps://ldap.example.org',                 # server URI\n    #    user_tree   => 'ou=users,dc=example,dc=org',               # search base DN\n    #    bind_dn     => 'uid=ldap_user,ou=users,dc=example,dc=org', # search bind DN\n    #    bind_pwd    => 'secr3t',                                   # search bind password\n    #    user_attr   => 'uid',                                      # user attribute (uid, mail, sAMAccountName, etc.)\n    #    user_filter => '(!(uid=ldap_user))',                       # user filter (to exclude some users, etc.)\n    #},\n\n    # set `htpasswd` if you want to use an htpasswd file instead of ldap\n    # create the file with `htpasswd -c lstu.passwd user`, update it with `htpasswd lstu.passwd user2`\n    # make sure that lstu can read the file!\n    # optional, no default\n    #htpasswd => 'lstu.passwd',\n\n    # if you've set ldap or htpasswd above, the session will last `session_duration` seconds before\n    # the user needs to reauthenticate\n    # optional, default is 3600\n    #session_duration => 3600,\n\n    # how many redirections are allowed for the shortened URL before considering it as a spam?\n    # optional, default is 2. Set to -1 to allow infinite redirections (not recommended)\n    #max_redir => 2,\n\n    # spam blacklist regex. All URLs (or redirection) whose host part matches this regex are considered as spam\n    # optional, no default\n    #spam_blacklist_regex => 'foo|bar',\n\n    # spam path blacklist regex. All URLs (or redirection) whose path part matches this regex are considered as spam\n    # optional, no default\n    #spam_path_blacklist_regex => 'foo|bar',\n\n    # spam whitelist regex. All URLs (or redirection) whose host part matches this regex will never be considered as spam\n    # optional, no default\n    #spam_whitelist_regex => 'foo|bar',\n\n    # set to 1 to skip SpamHaus check (not recommended)\n    # optional, default is 0\n    #skip_spamhaus => 0,\n\n    # put your Google API key to enable Google safebrowsing check\n    # This will allow Lstu to download the Google safebrowsing database and use a local copy to check the URLs.\n    # Google does not get the URLs that are checked.\n    # Instructions to get a key: https://developers.google.com/safe-browsing/v4/get-started\n    # TL;DR: https://console.developers.google.com/projectselector/apis/library\n    # optional, no default\n    #safebrowsing_api_key => '',\n\n    # array of memcached servers to cache URL in order to accelerate responses to often-viewed URL.\n    # If set to [], the cache is disabled\n    # optional, default is []\n    #memcached_servers => [],\n\n    # Content-Security-Policy header that will be sent by Lstu\n    # Set to '' to disable CSP header\n    # https://content-security-policy.com/ provides a good documentation about CSP.\n    # https://report-uri.com/home/generate provides a tool to generate a CSP header.\n    # optional, default is \"default-src 'none'; script-src 'self'; style-src 'self'; img-src 'self' data:; font-src 'self'; form-action 'self'; base-uri 'self'\"\n    # the default value is good for `default` and `milligram` themes\n    #csp => \"default-src 'none'; script-src 'self'; style-src 'self'; img-src 'self' data:; font-src 'self'; form-action 'self'; base-uri 'self'\",\n\n    # X-Frame-Options header that will be sent by Lstu\n    # Valid values are: 'DENY', 'SAMEORIGIN', 'ALLOW-FROM https://example.com/'\n    # Set to '' to disable X-Frame-Options header\n    # See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options\n    # Please note that this will add a \"frame-ancestors\" directive to the CSP header (see above) accordingly\n    # to the chosen setting (See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/frame-ancestors)\n    # optional, default is 'DENY'\n    #x_frame_options => 'DENY',\n\n    # X-Content-Type-Options that will be sent by Lstu\n    # See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Content-Type-Options\n    # Set to '' to disable X-Content-Type-Options header\n    # optional, default is 'nosniff'\n    #x_content_type_options => 'nosniff',\n\n    # X-XSS-Protection that will be sent by Lstu\n    # See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-XSS-Protection\n    # Set to '' to disable X-XSS-Protection header\n    # optional, default is '1; mode=block'\n    #x_xss_protection => '1; mode=block',\n\n    # Log creator's IP address\n    # Set to 1 if you want to register the IP addresses of URL creators\n    # optional, default is 0\n    #log_creator_ip => 0,\n};\n"
  },
  {
    "path": "t/sqlite3.conf",
    "content": "# vim:set sw=4 ts=4 sts=4 ft=perl expandtab:\n{\n    ####################\n    # Hypnotoad settings\n    ####################\n    # see http://mojolicio.us/perldoc/Mojo/Server/Hypnotoad for a full list of settings\n    hypnotoad => {\n        # array of IP addresses and ports you want to listen to\n        listen => ['http://127.0.0.1:8080'],\n        # if you use Lstu behind a reverse proxy like Nginx, you want to set proxy to 1\n        # if you use Lstu directly, let it commented\n        #proxy  => 1,\n    },\n\n    # put a way to contact you here and uncomment it\n    # MANDATORY\n    contact       => 'admin[at]example.com',\n\n    # array of random strings used to encrypt cookies\n    # optional, default is ['fdjsofjoihrei'], PLEASE, CHANGE IT\n    #secret        => ['fdjsofjoihrei'],\n\n    # secret passphrase to access some admin features\n    # If you don't want to have a plain text password in configuration,\n    # use hashed_adminpwd instead\n    # optional, but you won't have access to admin /stats if not set and if hashed_adminpwd is not set either\n    #adminpwd      => 's3cr3T',\n\n    # secret hashed passphrase to access some admin features\n    # Hash your password by issuing `echo -n s3cr3T | sha256sum` on your terminal\n    # optional, but you won't have access to admin /stats if not set and if adminpwd is not set either\n    hashed_adminpwd => '31f7a65e315586ac198bd798b6629ce4903d0899476d5741a9f32e2e521b6a66',\n\n    # choose a theme. See the available themes in `themes` directory\n    # optional, default is 'default'\n    #theme         => 'default',\n\n    # number of URLs to be displayed per page in /stats\n    # optional, default is 10\n    #page_offset   => 10,\n\n    # length of the random URL\n    # optional, default is 8\n    #length            => 8,\n\n    # how many URLs will be provisioned in a batch ?\n    # optional, default is 5\n    #provis_step       => 5,\n\n    # max number of URLs to be provisioned\n    # optional, default is 100\n    #provisioning      => 100,\n\n    # URL sub-directory in which you want Lstu to be accessible\n    # example: you want to have Lstu under https://example.org/lstu/\n    # => set prefix to '/lstu' or to '/lstu/', it doesn't matter\n    # optional, defaut is /\n    #prefix        => '/',\n\n    # array of authorized domains for API calls.\n    # if you want to authorize everyone to use the API: ['*']\n    # optional, no domains allowed by default\n    #allowed_domains   => ['http://1.example.com', 'http://2.example.com'],\n\n    # if set, the shortened URLs will use this domain\n    # optional\n    #fixed_domain => 'example.org',\n\n    # choose what database you want to use\n    # valid choices are sqlite and postgresql (all lowercase)\n    # optional, default is sqlite\n    #dbtype => 'sqlite',\n\n    # SQLite ONLY - only used if dbtype is set to sqlite\n    # define a path to the SQLite database\n    # you can define it relative to lstu directory or set an absolute path\n    # remember that it has to be in a directory writable by Lstu user\n    # optional, default is lstu.db\n    db_path => 'test3.db',\n\n    # PostgreSQL ONLY - only used if dbtype is set to postgresql\n    # these are the credentials to access the PostgreSQL database\n    # mandatory if you choosed postgresql as dbtype\n    #pgdb => {\n    #    database => 'lstu',\n    #    host     => 'localhost',\n    #    # optional, default is 5432\n    #    #port     => 5432,\n    #    #user     => 'DBUSER',\n    #    #pwd      => 'DBPASSWORD',\n    #    # optional, default is 1\n    #    #max_connections => 1,\n    #},\n\n    # MySQL ONLY - only used if dbtype is set to mysql\n    # these are the credentials to access the MySQL database\n    # mandatory if you choosed mysql as dbtype\n    #mysqldb => {\n    #    database => 'lstu',\n    #    host     => 'localhost',\n    #    # optional, default is 3306\n    #    #port     => 3306,\n    #    #user     => 'DBUSER',\n    #    #pwd      => 'DBPASSWORD',\n    #    # optional, default is 5 (set to 0 to disable persistent connections)\n    #    #max_connections => 5,\n    #},\n\n    # Rate-limiting for the API\n    # After ban_min_strike requests in a second, the IP address will be\n    # banned for one hour.\n    # If it continues to query the API during this ban time at least\n    # ban_min_strike times, it will be banned for a month.\n    # optional, default is 3\n    #ban_min_strike    => 3,\n\n    # Ban whitelist\n    # You can whitelist IP addresses to prevent you from being banned\n    # Be careful, the IP addresses are compared as string, not as IP addresses\n    # a network range will not work\n    # Example of valid input: ban_whitelist => ['198.51.100.42', '2001:0DB8::42'],¬\n    # optional, default is an empty array\n    #ban_whitelist => [],\n\n    # Ban blacklist\n    # You can blacklist IP addresses to always ban those IP addresses\n    # Be careful, the IP addresses are compared as string, not as IP addresses\n    # a network range will not work\n    # Example of valid input: ban_blacklist => ['198.51.100.42', '2001:0DB8::42'],¬\n    # optional, default is an empty array\n    #ban_blacklist => [],\n\n    # define an URL to the Piwik instance and the ID of a website to track\n    # set if you want to track views in Piwik\n    # optional, Piwik tracking is disabled by default\n    #piwik => {\n    #    url    => 'http://piwik.example.com',\n    #    idsite => '1',\n    #},\n\n    # use Minion instead of directly increase counters\n    # need to launch a minion worker service if enabled\n    # optional, Minion is disabled by default\n    minion => {\n        enabled => 1,\n        db_path => 'minion.db'\n    },\n\n    # set `ldap` if you want that only authenticated users can shorten URLs\n    # please note that everybody can still use shortend URLs\n    # optional, no default\n    #ldap => { uri => 'ldap://rroemhild-test-openldap:10389', user_tree => 'ou=people,dc=planetexpress,dc=com', bind_dn => 'cn=admin,dc=planetexpress,dc=com', bind_pwd => 'GoodNewsEveryone', user_attr => 'uid', user_filter => '(!(uid=admin))', },\n    #ldap => {\n    #    uri         => 'ldaps://ldap.example.org',                 # server URI\n    #    user_tree   => 'ou=users,dc=example,dc=org',               # search base DN\n    #    bind_dn     => 'uid=ldap_user,ou=users,dc=example,dc=org', # search bind DN\n    #    bind_pwd    => 'secr3t',                                   # search bind password\n    #    user_attr   => 'uid',                                      # user attribute (uid, mail, sAMAccountName, etc.)\n    #    user_filter => '(!(uid=ldap_user))',                       # user filter (to exclude some users, etc.)\n    #},\n\n    # set `htpasswd` if you want to use an htpasswd file instead of ldap\n    # create the file with `htpasswd -c lstu.passwd user`, update it with `htpasswd lstu.passwd user2`\n    # make sure that lstu can read the file!\n    # optional, no default\n    #htpasswd => 'lstu.passwd',\n\n    # if you've set ldap or htpasswd above, the session will last `session_duration` seconds before\n    # the user needs to reauthenticate\n    # optional, default is 3600\n    #session_duration => 3600,\n\n    # how many redirections are allowed for the shortened URL before considering it as a spam?\n    # optional, default is 2. Set to -1 to allow infinite redirections (not recommended)\n    #max_redir => 2,\n\n    # spam blacklist regex. All URLs (or redirection) whose host part matches this regex are considered as spam\n    # optional, no default\n    #spam_blacklist_regex => 'foo|bar',\n\n    # spam path blacklist regex. All URLs (or redirection) whose path part matches this regex are considered as spam\n    # optional, no default\n    #spam_path_blacklist_regex => 'foo|bar',\n\n    # spam whitelist regex. All URLs (or redirection) whose host part matches this regex will never be considered as spam\n    # optional, no default\n    #spam_whitelist_regex => 'foo|bar',\n\n    # set to 1 to skip SpamHaus check (not recommended)\n    # optional, default is 0\n    #skip_spamhaus => 0,\n\n    # put your Google API key to enable Google safebrowsing check\n    # This will allow Lstu to download the Google safebrowsing database and use a local copy to check the URLs.\n    # Google does not get the URLs that are checked.\n    # Instructions to get a key: https://developers.google.com/safe-browsing/v4/get-started\n    # TL;DR: https://console.developers.google.com/projectselector/apis/library\n    # optional, no default\n    #safebrowsing_api_key => '',\n\n    # array of memcached servers to cache URL in order to accelerate responses to often-viewed URL.\n    # If set to [], the cache is disabled\n    # optional, default is []\n    #memcached_servers => [],\n\n    # Content-Security-Policy header that will be sent by Lstu\n    # Set to '' to disable CSP header\n    # https://content-security-policy.com/ provides a good documentation about CSP.\n    # https://report-uri.com/home/generate provides a tool to generate a CSP header.\n    # optional, default is \"default-src 'none'; script-src 'self'; style-src 'self'; img-src 'self' data:; font-src 'self'; form-action 'self'; base-uri 'self'\"\n    # the default value is good for `default` and `milligram` themes\n    #csp => \"default-src 'none'; script-src 'self'; style-src 'self'; img-src 'self' data:; font-src 'self'; form-action 'self'; base-uri 'self'\",\n\n    # X-Frame-Options header that will be sent by Lstu\n    # Valid values are: 'DENY', 'SAMEORIGIN', 'ALLOW-FROM https://example.com/'\n    # Set to '' to disable X-Frame-Options header\n    # See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options\n    # Please note that this will add a \"frame-ancestors\" directive to the CSP header (see above) accordingly\n    # to the chosen setting (See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/frame-ancestors)\n    # optional, default is 'DENY'\n    #x_frame_options => 'DENY',\n\n    # X-Content-Type-Options that will be sent by Lstu\n    # See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Content-Type-Options\n    # Set to '' to disable X-Content-Type-Options header\n    # optional, default is 'nosniff'\n    #x_content_type_options => 'nosniff',\n\n    # X-XSS-Protection that will be sent by Lstu\n    # See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-XSS-Protection\n    # Set to '' to disable X-XSS-Protection header\n    # optional, default is '1; mode=block'\n    #x_xss_protection => '1; mode=block',\n\n    # Log creator's IP address\n    # Set to 1 if you want to register the IP addresses of URL creators\n    # optional, default is 0\n    #log_creator_ip => 0,\n};\n"
  },
  {
    "path": "t/test.t",
    "content": "# vim:set sw=4 ts=4 sts=4 ft=perl expandtab:\nuse Mojo::Base -strict;\nuse Mojo::JSON qw(true false);\nuse Mojo::File;\nuse Mojo::URL;\nuse Mojolicious;\n\nuse Test::More;\nuse Test::Mojo;\n\nuse Lstu::DB::URL;\nuse Lstu::DB::Ban;\nuse Lstu::DB::Session;\nuse Lstu::DefaultConfig qw($default_config);\nuse FindBin qw($Bin);\nuse File::Spec::Functions;\n\nmy ($m, $cfile);\n\nBEGIN {\n    use lib 'lib';\n    $m = Mojolicious->new;\n    $cfile = Mojo::File->new($Bin, '..' , 'lstu.conf');\n    if (defined $ENV{MOJO_CONFIG}) {\n        $cfile = Mojo::File->new($ENV{MOJO_CONFIG});\n        unless (-e $cfile->to_abs) {\n            $cfile = Mojo::File->new($Bin, '..', $ENV{MOJO_CONFIG});\n        }\n    }\n    my $config = $m->plugin('Config' =>\n        {\n            file    => $cfile->to_abs->to_string,\n            default => $default_config\n        }\n    );\n    $m->plugin('Lstu::Plugin::Helpers');\n    $m->plugin('DebugDumperHelper');\n}\n\nLstu::DB::URL->new(app => $m)->delete_all;\nLstu::DB::Ban->new(app => $m)->delete_all;\n\nmy $t = Test::Mojo->new('Lstu');\n\n# Give time to provision some short URLs\nsleep 3;\n\n# Home page\n$t->get_ok('/')\n    ->status_is(200)\n    ->header_is('X-Frame-Options' => 'DENY')\n    ->header_is('X-XSS-Protection' => '1; mode=block')\n    ->header_is('X-Content-Type-Options' => 'nosniff')\n    ->header_is('Content-Security-Policy' => \"base-uri 'self'; default-src 'none'; font-src 'self'; form-action 'self'; frame-ancestors 'none'; img-src 'self' data:; script-src 'self'; style-src 'self'\")\n    ->content_like(qr/Lstu/i);\n\n# Test robots.txt\n$t->get_ok('/robots.txt')\n    ->status_is(404);\n$t->get_ok('/robots')\n    ->status_is(404);\n\n\n# Create short URL\n$t->post_ok('/a' => form => { lsturl => 'https://lstu.fr', _format => 'json' })\n    ->status_is(200)\n    ->json_has('/url', '/short', '/success', '/qrcode')\n    ->json_is('/success' => true, '/url' => 'https://lstu.fr')\n    ->json_like('/short' => qr#http://127\\.0\\.0\\.1:\\d+/[-_a-zA-Z0-9]{8}#);\n\n# Create short URL with a .onion URL\n$t->post_ok('/a' => form => { lsturl => 'http://lstupiioqgxmq66f.onion', 'lsturl-custom' => 'onion', _format => 'json' })\n    ->status_is(200)\n    ->json_has('/url', '/short', '/success', '/qrcode')\n    ->json_is('/success' => true, '/url' => 'https://lstupiioqgxmq66f.onion', '/short' => 'http://127.0.0.1/onion');\n\nLstu::DB::Ban->new(app => $m)->delete_all; # prevents ban\n\n# Create short URL with robots custom short\n$t->post_ok('/a' => form => { lsturl => 'http://robots-txt.com/', 'lsturl-custom' => 'robots', _format => 'json' })\n    ->status_is(200)\n    ->json_has('/url', '/short', '/success', '/qrcode')\n    ->json_is('/success' => true, '/url' => 'https://lstu.fr', '/short' => 'http://127.0.0.1/robots');\n\n# Test robots.txt even after creating a robots short URL\n$t->get_ok('/robots.txt')\n    ->status_is(404);\n$t->get_ok('/robots')\n    ->status_is(301);\n\n# Create short URL, with invalid argument\n# Create short URL, with invalid argument\n$t->post_ok('/a' => form => { lsturl => 'truc', _format => 'json' })\n    ->status_is(200)\n    ->json_has('/msg', '/success')\n    ->json_is({success => false, msg => 'truc is not a valid URL.'});\n\nLstu::DB::Ban->new(app => $m)->delete_all; # prevents ban\n\n# Give time to provision some short URLs\nsleep 5;\n\n# Create short URL\nmy $a = $t->ua->post('/a' => form => { lsturl => 'https://lstu.fr', _format => 'json' })->res->json('/short');\n\n# Test redirection\n$t->get_ok($a)\n    ->status_is(301);\n\n# Test JSON answer\n$t->get_ok($a.'?_format=json')\n    ->status_is(200)\n    ->json_is({success => true, url => 'https://lstu.fr'});\n\n# Extract the path of the short URL\nmy $short = Mojo::URL->new($a)->path();\n\n# Get stats about the short URL\n$t->get_ok('/stats'.$short)\n    ->status_is(200)\n    ->json_has('/success', '/short', '/url', '/counter', '/created_at', '/timestamp')\n    ->json_is('/success' => true, '/url' => 'https://lstu.fr', '/short' => $a, '/counter' => 1)\n    ->json_like('/created_at' => qr#[0-9]{10}#, '/timestamp' => qr#[0-9]{10}#);\n\n# Test JSON answer on invalid short URL\n$t->get_ok($a.'i?_format=json')\n    ->status_is(404)\n    ->json_is({success => false, msg => 'The shortened URL '.$a.'i doesn\\'t exist.'});\n\n# Get stats about an invalid short URL\n$t->get_ok('/stats'.$short.'i')\n    ->status_is(200)\n    ->json_is({success => false, msg => 'The shortened URL '.$a.'i doesn\\'t exist.'});\n\n# Test full stats\n$t->get_ok('/fullstats')\n    ->status_is(200)\n    ->json_has('/urls', '/empty', '/timestamp')\n    ->json_is('/urls' => 3)\n    ->json_like('/empty' => qr#\\d+#, '/timestamp' => qr#[0-9]{10}#);\n\n# Needed if we use Minion for increasing counters\n$t->app->minion->perform_jobs if ($t->app->config('minion') && $t->app->config('minion')->{enabled});\n\n# Get stats in JSON format\n$t->get_ok('/stats?_format=json')\n    ->status_is(200)\n    ->json_has('/0/created_at', '/0/counter', '/0/short', '/0/url', '/0/qrcode')\n    ->json_is('/0/url' => 'https://lstu.fr', '/0/short' => $a)\n    ->json_is('/0/counter' => 2)\n    ->json_like('/0/created_at' => qr#\\d+#);\n\n# Extract the path of the short URL\nmy $b = $a;\n$b = Mojo::URL->new($a)->path();\n\n$t->ua->max_redirects(1);\n\n# Try to delete short URL while not admin\n$t->get_ok('/d'.$b)\n    ->status_is(200)\n    ->content_like(qr/You&#39;re not authenticated as the admin/);\n\n# Login as admin\n$t->post_ok('/stats' => form => { adminpwd => 'toto', page => 0 })\n    ->status_is(200)\n    ->content_like(qr/$a/);\n\n# Delete short URL while admin\n$t->get_ok('/d'.$b)\n    ->status_is(200)\n    ->content_like(qr/WTFPL/);\n\n# Verify that short URL does not exists anymore\n$t->get_ok($a.'?_format=json')\n    ->status_is(404)\n    ->json_is({success => false, msg => 'The shortened URL '.$a.' no longer exists.'});\n\n# Create short URL\n$a = $t->ua->post('/a' => form => { lsturl => 'https://lstu.fr', _format => 'json' })->res->json('/short');\n\n# Extract the path of the short URL\n$a = Mojo::URL->new($a)->path();\n\n# Delete short URL while admin, JSON format\n$t->get_ok('/d'.$a.'?_format=json')\n    ->status_is(200)\n    ->json_is({success => true, deleted => 1});\n\n# Logout\n$t->post_ok('/stats' => form => { adminpwd => 'toto', action => 'logout' })\n    ->status_is(200);\n\n# Test admin ban\nLstu::DB::Ban->new(app => $m)->delete_all;\nfor my $i (1..3) {\n    # Login three times with a bad password\n    $t->post_ok('/stats' => form => { adminpwd => 'totoi' })\n        ->status_is(200)\n        ->content_like(qr/Bad password/);\n}\n\n# Login with a bad password, should be banned now\n$t->post_ok('/stats' => form => { adminpwd => 'totoi' })\n    ->status_is(200)\n    ->content_like(qr/Too many bad passwords\\./);\n\n# Test user ban\nLstu::DB::Ban->new(app => $m)->delete_all; # reset ban\nLstu::DB::URL->new(app => $m)->delete_all;\n$t->ua->post('/a' => form => { lsturl => 'https://lstu.fr', _format => 'json' });\n$t->ua->post('/a' => form => { lsturl => 'https://lstu.fr', _format => 'json' });\n$t->ua->post('/a' => form => { lsturl => 'https://lstu.fr', _format => 'json' });\n$t->ua->post('/a' => form => { lsturl => 'https://lstu.fr', _format => 'json' });\n$t->ua->post('/a' => form => { lsturl => 'https://lstu.fr', _format => 'json' });\n\n$t->post_ok('/a' => form => { lsturl => 'https://lstu.fr', _format => 'json' })\n    ->status_is(200)\n    ->json_has('/msg', '/success')\n    ->json_is('/success' => false)\n    ->json_like('/msg' => qr#You asked to shorten too many URLs too quickly\\. You're banned for \\d+ hour\\(s\\)\\.#);\n\nLstu::DB::Ban->new(app => $m)->delete_all; # reset ban\n\n# Give time to provision some short URLs\nsleep 3;\n\n# Create short URL, JSON format\n$t->post_ok('/a' => form => { lsturl => ' https://fiat-tux.fr', _format => 'json' })\n    ->status_is(200)\n    ->json_has('/url', '/short', '/success', '/qrcode')\n    ->json_is('/success' => true, '/url' => 'https://fiat-tux.fr')\n    ->json_like('/short' => qr#http://127\\.0\\.0\\.1:\\d+/[-_a-zA-Z0-9]{8}#);\n\n# Test htpasswd\nmy $config_file    = Mojo::File->new($cfile->to_abs->to_string);\nmy $config_content = $config_file->slurp;\nmy $config_orig    = $config_content;\n   $config_content =~ s/#?htpasswd.*/htpasswd => 't\\/lstu.passwd',/gm;\n$config_file->spew($config_content);\n\nLstu::DB::Ban->new(app => $m)->delete_all; # reset ban\nLstu::DB::URL->new(app => $m)->delete_all;\n\n$t = Test::Mojo->new('Lstu');\n\n# Give time to provision some short URLs\nsleep 3;\n\n$t->get_ok('/')\n    ->status_is(302);\n\n$t->get_ok('/login')\n    ->status_is(200)\n    ->content_like(qr/Login/);\n\n$t->post_ok('/login' => form => { login => 'luc', password => 'titi' })\n    ->status_is(200)\n    ->content_like(qr/Please, check your credentials: unable to authenticate\\./);\n\n$t->post_ok('/a' => form => { lsturl => 'https://lstu.fr', _format => 'json' })\n    ->status_is(302);\n\n$t->post_ok('/login' => form => { login => 'luc', password => 'toto' })\n    ->status_is(302);\n\n$t->post_ok('/a' => form => { lsturl => 'https://lstu.fr', _format => 'json' })\n    ->status_is(200)\n    ->json_has('/url', '/short', '/success', '/qrcode')\n    ->json_is('/success' => true, '/url' => 'https://lstu.fr')\n    ->json_like('/short' => qr#http://127\\.0\\.0\\.1:\\d+/[-_a-zA-Z0-9]{8}#);\n\n$t->get_ok('/logout')\n    ->status_is(200)\n    ->content_like(qr/You have been successfully logged out\\./);\n\n# Test IP whitelisting\n$config_content = $config_orig;\n$config_content =~ s/^( +)#?ban_whitelist.*/$1ban_whitelist => ['::1', '127.0.0.1'],/gm;\n$config_file->spew($config_content);\n\n$t = Test::Mojo->new('Lstu');\n\n# Give time to provision some short URLs\nsleep 3;\n\n$t->ua->post('/a' => form => { lsturl => 'https://lstu.fr', _format => 'json' });\n$t->ua->post('/a' => form => { lsturl => 'https://lstu.fr', _format => 'json' });\n$t->ua->post('/a' => form => { lsturl => 'https://lstu.fr', _format => 'json' });\n$t->ua->post('/a' => form => { lsturl => 'https://lstu.fr', _format => 'json' });\n$t->ua->post('/a' => form => { lsturl => 'https://lstu.fr', _format => 'json' });\n\n$t->post_ok('/a' => form => { lsturl => 'https://lstu.fr', _format => 'json' })\n    ->status_is(200)\n    ->json_has('/url', '/short', '/success', '/qrcode')\n    ->json_is('/success' => true, '/url' => 'https://lstu.fr')\n    ->json_like('/short' => qr#http://127\\.0\\.0\\.1:\\d+/[-_a-zA-Z0-9]{8}#);\n\n$config_file->spew($config_orig);\n\n# Test IP blacklisting\n$config_content = $config_orig;\n$config_content =~ s/^( +)#?ban_blacklist.*/$1ban_blacklist => ['::1', '127.0.0.1'],/gm;\n$config_file->spew($config_content);\n\n$t = Test::Mojo->new('Lstu');\n\n# Give time to provision some short URLs\nsleep 3;\n\n$t->ua->post('/a' => form => { lsturl => 'https://lstu.fr', _format => 'json' });\n$t->ua->post('/a' => form => { lsturl => 'https://lstu.fr', _format => 'json' });\n$t->ua->post('/a' => form => { lsturl => 'https://lstu.fr', _format => 'json' });\n$t->ua->post('/a' => form => { lsturl => 'https://lstu.fr', _format => 'json' });\n$t->ua->post('/a' => form => { lsturl => 'https://lstu.fr', _format => 'json' });\n\n$t->post_ok('/a' => form => { lsturl => 'https://lstu.fr', _format => 'json' })\n    ->status_is(200)\n    ->json_has('/msg', '/success')\n    ->json_is('/success' => false)\n    ->json_like('/msg' => qr#You asked to shorten too many URLs too quickly\\. You're banned for \\d+ hour\\(s\\)\\.#);\n\n$config_file->spew($config_orig);\n\n# Test domain blacklisting\nLstu::DB::Ban->new(app => $m)->delete_all;\n$config_content = $config_orig;\n$config_content =~ s/^( +)#?spam_blacklist_regex.*/$1spam_blacklist_regex => 'google\\\\.(fr|com)',/gm;\n$config_file->spew($config_content);\n\n$t = Test::Mojo->new('Lstu');\n\n# Give time to provision some short URLs\nsleep 3;\n\n$t->post_ok('/a' => form => { lsturl => 'https://google.fr', _format => 'json' })\n    ->status_is(200)\n    ->json_has('/msg', '/success')\n    ->json_is({success => false, msg => 'The URL you want to shorten comes from a domain (google.fr) that is blacklisted on this server (usually because of spammers that use this domain).'});\n\n$t->post_ok('/a' => form => { lsturl => 'https://google.com', _format => 'json' })\n    ->status_is(200)\n    ->json_has('/msg', '/success')\n    ->json_is({success => false, msg => 'The URL you want to shorten comes from a domain (google.com) that is blacklisted on this server (usually because of spammers that use this domain).'});\n\n$t->post_ok('/a' => form => { lsturl => 'https://google.de', _format => 'json' })\n    ->status_is(200)\n    ->json_has('/url', '/short', '/success', '/qrcode')\n    ->json_is('/success' => true, '/url' => 'https://google.de')\n    ->json_like('/short' => qr#http://127\\.0\\.0\\.1:\\d+/[-_a-zA-Z0-9]{8}#);\n\n# Test domain whitelisting\nLstu::DB::Ban->new(app => $m)->delete_all;\n$config_content =~ s/^( +)#?spam_whitelist_regex.*/$1spam_whitelist_regex => 'google\\.fr',/gm;\n$config_file->spew($config_content);\n\n$t = Test::Mojo->new('Lstu');\n\n# Give time to provision some short URLs\nsleep 3;\n\n$t->post_ok('/a' => form => { lsturl => 'https://google.fr', _format => 'json' })\n    ->status_is(200)\n    ->json_has('/url', '/short', '/success', '/qrcode')\n    ->json_is('/success' => true, '/url' => 'https://google.fr')\n    ->json_like('/short' => qr#http://127\\.0\\.0\\.1:\\d+/[-_a-zA-Z0-9]{8}#);\n\n$t->post_ok('/a' => form => { lsturl => 'https://google.com', _format => 'json' })\n    ->status_is(200)\n    ->json_has('/msg', '/success')\n    ->json_is({success => false, msg => 'The URL you want to shorten comes from a domain (google.com) that is blacklisted on this server (usually because of spammers that use this domain).'});\n\n# Test Cache system\n$config_content =~ s/^( +)#?memcached_servers => \\[\\],/memcached_servers => ['127.0.0.1:11211'],/gm;\n$config_file->spew($config_content);\n\n$t = Test::Mojo->new('Lstu');\n\n# Give time to provision some short URLs\nsleep 3;\n\n$a = $t->ua->post('/a' => form => { lsturl => 'https://lstu.fr', _format => 'json' })->res->json('/short');\n$t->get_ok($a)\n    ->status_is(301);\n\n# Test command\nmy $help = `carton exec script/lstu help url`;\nlike($help, qr/Print infos about the space-separated URLs/m, 'Test help url command');\n\n# Create short URL\n$a = $t->ua->post('/a' => form => { lsturl => 'https://lstu.fr', _format => 'json' })->res->json('/short');\n\n# Extract the path of the short URL\n$a =~ s#.*/##;\n\nmy $info = `MOJO_CONFIG=$cfile carton exec script/lstu url --info $a`;\nlike($info, qr/lstu\\.fr/m, 'Test url --info command');\n\nmy $search = `MOJO_CONFIG=$cfile carton exec script/lstu url --search lstu.fr`;\nlike($search, qr/$a/m, 'Test url --search command');\n\nmy $remove = `MOJO_CONFIG=$cfile carton exec script/lstu url --remove $a --yes`;\nlike($remove, qr/Success/m, 'Test url --remove command');\n\n# Restore configuration\n$config_file->spew($config_orig);\n\n## Test LDAP\n$config_content = $config_orig;\n$config_content =~ s/^( +)#?ldap => \\{ uri/$1ldap => { uri/gm;\n$config_file->spew($config_content);\n\nLstu::DB::URL->new(app => $m)->delete_all;\n$t = Test::Mojo->new('Lstu');\n\n# Give time to provision some short URLs\nsleep 3;\n\n$t->get_ok('/')\n    ->status_is(302);\n\n$t->get_ok('/login')\n    ->status_is(200)\n    ->content_like(qr/Signin/i);\n\n$t->post_ok('/a' => form => { lsturl => 'https://google.com', _format => 'json' })\n    ->status_is(302);\n\n$t->post_ok('/login' => form => { login => 'zoidberg', password => 'zoidberg' })\n    ->status_is(302);\n#\n# Create short URL\n$t->post_ok('/a' => form => { lsturl => 'https://lstu.fr', _format => 'json' })\n    ->status_is(200)\n    ->json_has('/url', '/short', '/success', '/qrcode')\n    ->json_is('/success' => true, '/url' => 'https://lstu.fr')\n    ->json_like('/short' => qr#http://127\\.0\\.0\\.1:\\d+/[-_a-zA-Z0-9]{8}#);\n\n$a = $t->ua->post('/a' => form => { lsturl => 'https://lstu.fr', _format => 'json' })->res->json('/short');\n\n# Test redirection\n$t->get_ok($a)\n    ->status_is(301);\n\n$t->get_ok('/logout')\n    ->status_is(200)\n    ->content_like(qr/You have been successfully logged out\\./);\n\n$t->get_ok('/')\n    ->status_is(302);\n\n$t->get_ok('/login')\n    ->status_is(200)\n    ->content_like(qr/Signin/i);\n\n# Test redirection\n$t->get_ok($a)\n    ->status_is(301);\n\n# Restore configuration\n$config_file->spew($config_orig);\n\n## Test headers modifications\n$config_content = $config_orig;\n$config_content =~ s/^( +)#?x_frame_options => 'DENY',/$1x_frame_options => 'SAMEORIGIN',/gm;\n$config_content =~ s/^( +)#?x_xss_protection => '1; mode=block',/$1x_xss_protection => '1',/gm;\n$config_content =~ s/^( +)#?x_content_type_options => 'nosniff',/$1x_content_type_options => '',/gm;\n$config_file->spew($config_content);\n\n$t = Test::Mojo->new('Lstu');\n\n# Home page\n$t->get_ok('/')\n    ->status_is(200)\n    ->header_is('X-Frame-Options' => 'SAMEORIGIN')\n    ->header_is('X-XSS-Protection' => '1')\n    ->header_isnt('X-Content-Type-Options' => 'nosniff')\n    ->header_is('Content-Security-Policy' => \"base-uri 'self'; default-src 'none'; font-src 'self'; form-action 'self'; frame-ancestors 'self'; img-src 'self' data:; script-src 'self'; style-src 'self'\");\n\n# Restore configuration\n$config_file->spew($config_orig);\n\ndone_testing();\n"
  },
  {
    "path": "themes/default/lib/Lstu/I18N/br.po",
    "content": "# Lstu\n# Copyright (C) 2013 - 2015 Luc Didry\n# This file is distributed under the same license as the Lstu package.\n# \n# Translators:\n# Translators:\n# Gwenn M <tornoz@laposte.net>, 2016\n# Luc Didry <luc@framasoft.org>, 2018. #zanata\nmsgid \"\"\nmsgstr \"\"\n\"Project-Id-Version: PACKAGE VERSION\\n\"\n\"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\\n\"\n\"PO-Revision-Date: 2023-11-23 10:03+0000\\n\"\n\"Last-Translator: Florent Grouin <florent.grouin@gmail.com>\\n\"\n\"Language-Team: Breton <https://weblate.framasoft.org/projects/lstu/\"\n\"development/br/>\\n\"\n\"Language: br\\n\"\n\"MIME-Version: 1.0\\n\"\n\"Content-Type: text/plain; charset=UTF-8\\n\"\n\"Content-Transfer-Encoding: 8bit\\n\"\n\"Plural-Forms: nplurals=2; plural=n > 1;\\n\"\n\"X-Generator: Weblate 5.2\\n\"\n\"X-Poedit-SourceCharset: UTF-8\\n\"\n\n#. ($url)\n#: lib/Lstu/Controller/URL.pm:118\nmsgid \"%1 is not a valid URL.\"\nmsgstr \"%1 n'eo ket un URL talvoudek.\"\n\n#: themes/default/templates/api.html.ep:96\nmsgid \"\"\n\"A page with a table containing the same informations that the JSON response\"\nmsgstr \"\"\n\n#: themes/default/templates/layouts/default.html.ep:38\nmsgid \"About\"\nmsgstr \"A-zivout\"\n\n#: themes/default/templates/stats.html.ep:13 themes/default/templates/stats.html.ep:14\nmsgid \"Admin password\"\nmsgstr \"Ger-tremen ar merour\"\n\n#: lib/Lstu/Controller/Admin.pm:87 themes/default/templates/api.html.ep:122\nmsgid \"Bad password\"\nmsgstr \"Ger-tremen didalvoudek\"\n\n#: themes/default/templates/index.html.ep:21\nmsgid \"Copy to clipboard\"\nmsgstr \"Eilañ er golver\"\n\n#: themes/default/templates/stats.html.ep:46\nmsgid \"Counter\"\nmsgstr \"Konter\"\n\n#: themes/default/templates/stats.html.ep:47\nmsgid \"Created\"\nmsgstr \"Krouet\"\n\n#: themes/default/templates/api.html.ep:44 themes/default/templates/index.html.ep:10 themes/default/templates/index.html.ep:9\nmsgid \"Custom shortened text\"\nmsgstr \"Testenn verr personelaet\"\n\n#: themes/default/templates/stats.html.ep:52\nmsgid \"Delete\"\nmsgstr \"Dilemel\"\n\n#: themes/default/templates/stats.html.ep:36\nmsgid \"Export your URLs\"\nmsgstr \"Ezporzhiañ hoc’h URLoù\"\n\n#: themes/default/templates/api.html.ep:105 themes/default/templates/api.html.ep:145 themes/default/templates/api.html.ep:53 themes/default/templates/api.html.ep:71\nmsgid \"Failure reason\"\nmsgstr \"Abeg ar c'hwitadenn\"\n\n#: lib/Lstu/Controller/Stats.pm:43\nmsgid \"File imported\"\nmsgstr \"Restr bet emporzhiet\"\n\n#: themes/default/templates/api.html.ep:101\nmsgid \"\"\n\"Get the details (visit counter, creation date, etc.) of a shortened URL.\"\nmsgstr \"\"\n\n#: themes/default/templates/index.html.ep:12 themes/default/templates/stats.html.ep:17\nmsgid \"Go!\"\nmsgstr \"Deomp !\"\n\n#: themes/default/templates/partial/lstu.js.ep:30\nmsgid \"Hit Enter, then Ctrl+C to copy the short link\"\nmsgstr \"Pouezit war Enankañ, ha Reol+C evit eilañ an ere berr\"\n\n#: themes/default/templates/stats.html.ep:89\nmsgid \"Home\"\nmsgstr \"Degemer\"\n\n#: themes/default/templates/api.html.ep:126\nmsgid \"If \\\"action\\\" is defined to \\\"logout\\\":\"\nmsgstr \"\"\n\n#: themes/default/templates/api.html.ep:119\nmsgid \"If \\\"adminpwd\\\" is defined:\"\nmsgstr \"Ma 'z eo termenet \\\"adminpwd\\\" :\"\n\n#: themes/default/templates/api.html.ep:115 themes/default/templates/api.html.ep:13 themes/default/templates/api.html.ep:140 themes/default/templates/api.html.ep:27 themes/default/templates/api.html.ep:45 themes/default/templates/api.html.ep:88\nmsgid \"\"\n\"If equal to \\\"json\\\", response will be in JSON format, HTML format otherwise\"\nmsgstr \"\"\n\"M'eo kevatal da \\\"json\\\" e vo ar respont er mentrezh JSON, e mod all e vo e \"\n\"HTML\"\n\n#. (config('page_offset')\n#: themes/default/templates/api.html.ep:81\nmsgid \"\"\n\"If you are logged in as admin (\\\"adminpwd\\\" or \\\"hashed_adminpwd\\\" setting), \"\n\"it will give you statistics for all URLs, sorted by the most visited first, \"\n\"paginated with pages containing %1 records.\"\nmsgstr \"\"\n\n#: themes/default/templates/api.html.ep:86\nmsgid \"If you are logged in as admin, you can provide a \\\"page\\\" parameter\"\nmsgstr \"\"\n\n#: themes/default/templates/stats.html.ep:32 themes/default/templates/stats.html.ep:35\nmsgid \"Import URLs\"\nmsgstr \"Enporzhiañ URLoù\"\n\n#: themes/default/templates/api.html.ep:79\nmsgid \"\"\n\"It will use Lstu's cookies to know which shortened URL it will return \"\n\"statistics for.\"\nmsgstr \"\"\n\n#: themes/default/templates/api.html.ep:105 themes/default/templates/api.html.ep:122 themes/default/templates/api.html.ep:145 themes/default/templates/api.html.ep:18 themes/default/templates/api.html.ep:53 themes/default/templates/api.html.ep:71\nmsgid \"JSON: failure\"\nmsgstr \"JSON : c'hwitadenn\"\n\n#: themes/default/templates/api.html.ep:104 themes/default/templates/api.html.ep:121 themes/default/templates/api.html.ep:129 themes/default/templates/api.html.ep:144 themes/default/templates/api.html.ep:17 themes/default/templates/api.html.ep:31 themes/default/templates/api.html.ep:52 themes/default/templates/api.html.ep:70\nmsgid \"JSON: success\"\nmsgstr \"JSON : berzh\"\n\n#: themes/default/templates/layouts/default.html.ep:37\nmsgid \"License:\"\nmsgstr \"Lañvaz :\"\n\n#: themes/default/templates/login.html.ep:8\nmsgid \"Login\"\nmsgstr \"Kevreañ\"\n\n#: themes/default/templates/layouts/default.html.ep:43\nmsgid \"Logout\"\nmsgstr \"Digevreañ\"\n\n#: themes/default/templates/stats.html.ep:10\nmsgid \"Logout from admin stats\"\nmsgstr \"Digennaskañ eus stadegoù an ardoer\"\n\n#: themes/default/templates/stats.html.ep:84\nmsgid \"Next\"\nmsgstr \"Da-heul\"\n\n#. ($c->config('contact')\n#: lib/Lstu/Controller/URL.pm:112\nmsgid \"\"\n\"No shortened URL available. Please retry or contact the administrator at %1. \"\n\"Your URL to shorten: %2\"\nmsgstr \"\"\n\"N'eus URL berr ebet hegerz. Klaskit en-dro pe kit e darempred gant an ardoer \"\n\"e %1. Hoc'h URL da verraat : %2\"\n\n#: themes/default/templates/api.html.ep:111 themes/default/templates/api.html.ep:138 themes/default/templates/api.html.ep:25 themes/default/templates/api.html.ep:41 themes/default/templates/api.html.ep:83 themes/default/templates/api.html.ep:9\nmsgid \"Parameters:\"\nmsgstr \"Arventennoù :\"\n\n#: themes/default/templates/login.html.ep:12\nmsgid \"Password\"\nmsgstr \"Ger-tremen\"\n\n#: lib/Lstu/Controller/Authent.pm:35 themes/default/templates/api.html.ep:18\nmsgid \"Please, check your credentials: unable to authenticate.\"\nmsgstr \"\"\n\n#: themes/default/templates/stats.html.ep:82\nmsgid \"Previous\"\nmsgstr \"Kent\"\n\n#: themes/default/templates/stats.html.ep:50\nmsgid \"QRCode\"\nmsgstr \"Kod QR\"\n\n#: themes/default/templates/api.html.ep:123 themes/default/templates/api.html.ep:130 themes/default/templates/api.html.ep:146 themes/default/templates/api.html.ep:19 themes/default/templates/api.html.ep:32 themes/default/templates/api.html.ep:54 themes/default/templates/api.html.ep:96\nmsgid \"Response for HTML format\"\nmsgstr \"Respont evit ar mentrezh HTML\"\n\n#: themes/default/templates/api.html.ep:95\nmsgid \"Response for JSON format\"\nmsgstr \"Respont evit ar furmad JSON\"\n\n#: themes/default/templates/api.html.ep:102 themes/default/templates/api.html.ep:117 themes/default/templates/api.html.ep:142 themes/default/templates/api.html.ep:15 themes/default/templates/api.html.ep:29 themes/default/templates/api.html.ep:47 themes/default/templates/api.html.ep:59 themes/default/templates/api.html.ep:68 themes/default/templates/api.html.ep:90\nmsgid \"Response:\"\nmsgstr \"Respont :\"\n\n#: themes/default/templates/stats.html.ep:45\nmsgid \"Shortened URL\"\nmsgstr \"URL berraet\"\n\n#: themes/default/templates/api.html.ep:127 themes/default/templates/api.html.ep:24\nmsgid \"Should always be successful\"\nmsgstr \"Rankout a rafe kas en-dro un disoc'h gant berzh\"\n\n#: themes/default/templates/layouts/default.html.ep:45 themes/default/templates/login.html.ep:16 themes/default/templates/logout.html.ep:5\nmsgid \"Signin\"\nmsgstr \"Lugañ\"\n\n#: lib/Lstu/Controller/Stats.pm:45\nmsgid \"Sorry, unable to parse the provided file\"\nmsgstr \"\"\n\n#: themes/default/templates/layouts/default.html.ep:42 themes/default/templates/layouts/default.html.ep:48 themes/default/templates/stats.html.ep:4\nmsgid \"Statistics\"\nmsgstr \"Stadegoù\"\n\n#. ($url->host)\n#: lib/Lstu/Plugin/Helpers.pm:172\nmsgid \"\"\n\"The URL host or one of its redirection(s) (%1) is blacklisted at Spamhaus. I \"\n\"refuse to shorten it.\"\nmsgstr \"\"\n\"Ostiz an URL pe unan eus e adheñchadennoù (%1) a zo e roll du Spamhaus. Ne \"\n\"fell ket din e verraat.\"\n\n#. ($url)\n#: lib/Lstu/Plugin/Helpers.pm:178\nmsgid \"\"\n\"The URL or one of its redirection(s) (%1) is blacklisted in Google Safe \"\n\"Browsing database. I refuse to shorten it.\"\nmsgstr \"\"\n\n#. ($c->config('max_redir')\n#: lib/Lstu/Plugin/Helpers.pm:194\nmsgid \"\"\n\"The URL redirects %1 times or most. It's most likely a dangerous URL (spam, \"\n\"phishing, etc.). I refuse to shorten it.\"\nmsgstr \"\"\n\"Adheñchet eo an URL %1 gwech pe ouzhpenn. Moarvat eo un URL arvarus (spam, \"\n\"phishing...). Ne fell ket din e verraat.\"\n\n#. ($url->host)\n#: lib/Lstu/Plugin/Helpers.pm:164\nmsgid \"\"\n\"The URL you want to shorten comes from a domain (%1) that is blacklisted on \"\n\"this server (usually because of spammers that use this domain).\"\nmsgstr \"\"\n\n#. ($c->url_for('/')\n#: lib/Lstu/Controller/Admin.pm:131 lib/Lstu/Controller/Stats.pm:184 lib/Lstu/Controller/URL.pm:226\nmsgid \"The shortened URL %1 doesn't exist.\"\nmsgstr \"N'eus ket eus an URL berraet %1.\"\n\n#. ($url)\n#: lib/Lstu/Controller/URL.pm:59\nmsgid \"\"\n\"The shortened text can't be \\\"a\\\", \\\"api\\\", \\\"d\\\", \\\"cookie\\\", \\\"stats\\\", \"\n\"\\\"fullstats\\\", \\\"login\\\" or \\\"logout\\\" or end with \\\".json\\\". Your URL to \"\n\"shorten: %1\"\nmsgstr \"\"\n\n#: themes/default/templates/api.html.ep:113\nmsgid \"\"\n\"To do an admin login, set it to the password defined in the settings \"\n\"(\\\"adminpwd\\\" or \\\"hashed_adminpwd\\\")\"\nmsgstr \"\"\n\n#: themes/default/templates/api.html.ep:114\nmsgid \"To do an admin logout, set it to \\\"logout\\\".\"\nmsgstr \"\"\n\n#: lib/Lstu/Controller/Admin.pm:29\nmsgid \"Too many bad passwords. You're banned.\"\nmsgstr \"Re a ger-tremen didalvoudek. Forbannet oc'h.\"\n\n#: themes/default/templates/api.html.ep:104 themes/default/templates/api.html.ep:95 themes/default/templates/stats.html.ep:44\nmsgid \"URL\"\nmsgstr \"URL\"\n\n#: themes/default/templates/api.html.ep:43 themes/default/templates/index.html.ep:5 themes/default/templates/index.html.ep:6\nmsgid \"URL to shorten\"\nmsgstr \"URL da verraat\"\n\n#. ($penalty/3600)\n#: lib/Lstu/Controller/URL.pm:35\nmsgid \"\"\n\"You asked to shorten too many URLs too quickly. You're banned for %1 hour(s).\"\n\"\"\nmsgstr \"\"\n\"Goulennet hoc'h eus da verraat re a URLoù en un amzer re verr. Forbannet \"\n\"hoc'h e-pad %1 eur.\"\n\n#: lib/Lstu/Controller/Admin.pm:52 lib/Lstu/Controller/Authent.pm:26 themes/default/templates/api.html.ep:121 themes/default/templates/api.html.ep:17\nmsgid \"You have been successfully logged in.\"\nmsgstr \"\"\n\n#: lib/Lstu/Controller/Admin.pm:73 lib/Lstu/Controller/Authent.pm:65 themes/default/templates/api.html.ep:129 themes/default/templates/api.html.ep:31 themes/default/templates/logout.html.ep:3\nmsgid \"You have been successfully logged out.\"\nmsgstr \"\"\n\n#: themes/default/templates/api.html.ep:137\nmsgid \"\"\n\"You must be logged in as admin (\\\"adminpwd\\\" or \\\"hashed_adminpwd\\\" setting) \"\n\"to use it.\"\nmsgstr \"\"\n\n#: themes/default/templates/api.html.ep:39 themes/default/templates/api.html.ep:77\nmsgid \"You must be logged in to use it.\"\nmsgstr \"\"\n\n#: themes/default/templates/api.html.ep:130\nmsgid \"You will be redirected to Lstu statistics page\"\nmsgstr \"\"\n\n#: themes/default/templates/api.html.ep:146\nmsgid \"\"\n\"You will be redirected to Lstu statistics page with a message in case of \"\n\"failure\"\nmsgstr \"\"\n\n#: themes/default/templates/api.html.ep:32\nmsgid \"You will be redirected to Lstu successfully logged out interface\"\nmsgstr \"\"\n\n#: themes/default/templates/api.html.ep:19\nmsgid \"\"\n\"You will be redirected to the Lstu classic interface where you will be able \"\n\"to shorten URLs\"\nmsgstr \"\"\n\n#: themes/default/templates/api.html.ep:54\nmsgid \"\"\n\"You will be redirected to the Lstu classic interface with a message giving \"\n\"the shortened URL\"\nmsgstr \"\"\n\n#: themes/default/templates/api.html.ep:62\nmsgid \"\"\n\"You will be redirected to the targeted URL or to the Lstu interface with a \"\n\"message giving the failure reason\"\nmsgstr \"\"\n\"Adheñchet e viot davet an URL bukenn pe ketal Ltsu gant ur gemennadenn a \"\n\"roio abeg ar c'hwitadenn\"\n\n#: themes/default/templates/api.html.ep:123\nmsgid \"\"\n\"You will have the statistics page with the admin stats if you're succesfully \"\n\"logged in, or your stats and a failure message otherwise\"\nmsgstr \"\"\n\n#: lib/Lstu/Controller/Admin.pm:142\nmsgid \"You're not authenticated as the admin\"\nmsgstr \"\"\n\n#: themes/default/templates/api.html.ep:11\nmsgid \"Your login\"\nmsgstr \"\"\n\n#: themes/default/templates/api.html.ep:12\nmsgid \"Your password\"\nmsgstr \"\"\n\n#: themes/default/templates/api.html.ep:104 themes/default/templates/api.html.ep:95\nmsgid \"integer, how many unique visits of the shortened URL\"\nmsgstr \"\"\n\n#: themes/default/templates/api.html.ep:11 themes/default/templates/api.html.ep:12 themes/default/templates/api.html.ep:43\nmsgid \"mandatory\"\nmsgstr \"ret\"\n\n#: themes/default/templates/api.html.ep:113 themes/default/templates/api.html.ep:114 themes/default/templates/api.html.ep:115 themes/default/templates/api.html.ep:13 themes/default/templates/api.html.ep:140 themes/default/templates/api.html.ep:27 themes/default/templates/api.html.ep:44 themes/default/templates/api.html.ep:45 themes/default/templates/api.html.ep:86 themes/default/templates/api.html.ep:88\nmsgid \"optional\"\nmsgstr \"diret\"\n\n#: themes/default/templates/api.html.ep:135 themes/default/templates/api.html.ep:57 themes/default/templates/api.html.ep:66 themes/default/templates/api.html.ep:92 themes/default/templates/api.html.ep:99\nmsgid \"shortened_url\"\nmsgstr \"url_berraet\"\n"
  },
  {
    "path": "themes/default/lib/Lstu/I18N/de.po",
    "content": "# Nico Domino <yo@iamnico.xyz>, 2018. #zanata\nmsgid \"\"\nmsgstr \"\"\n\"Project-Id-Version: PACKAGE VERSION\\n\"\n\"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\\n\"\n\"PO-Revision-Date: 2021-04-28 09:40+0000\\n\"\n\"Last-Translator: Luc Didry <luc@framasoft.org>\\n\"\n\"Language-Team: German <https://weblate.framasoft.org/projects/lstu/\"\n\"development/de/>\\n\"\n\"Language: de\\n\"\n\"MIME-Version: 1.0\\n\"\n\"Content-Type: text/plain; charset=UTF-8\\n\"\n\"Content-Transfer-Encoding: 8bit\\n\"\n\"Plural-Forms: nplurals=2; plural=n != 1;\\n\"\n\"X-Generator: Weblate 4.6\\n\"\n\n#. ($url)\n#: lib/Lstu/Controller/URL.pm:118\nmsgid \"%1 is not a valid URL.\"\nmsgstr \"%1 ist keine gültige URL.\"\n\n#: themes/default/templates/api.html.ep:96\nmsgid \"\"\n\"A page with a table containing the same informations that the JSON response\"\nmsgstr \"\"\n\"Eine Seite mit einer Tabelle mit derselben Info als in der JSON Antwort\"\n\n#: themes/default/templates/layouts/default.html.ep:38\nmsgid \"About\"\nmsgstr \"Über\"\n\n#: themes/default/templates/stats.html.ep:13\n#: themes/default/templates/stats.html.ep:14\nmsgid \"Admin password\"\nmsgstr \"Admin Passwort\"\n\n#: lib/Lstu/Controller/Admin.pm:87 themes/default/templates/api.html.ep:122\nmsgid \"Bad password\"\nmsgstr \"Falsches Passwort\"\n\n#: themes/default/templates/index.html.ep:21\nmsgid \"Copy to clipboard\"\nmsgstr \"Zu Zwischenablage Speichern\"\n\n#: themes/default/templates/stats.html.ep:46\nmsgid \"Counter\"\nmsgstr \"Zähler\"\n\n#: themes/default/templates/stats.html.ep:47\nmsgid \"Created\"\nmsgstr \"Erstellt\"\n\n#: themes/default/templates/api.html.ep:44\n#: themes/default/templates/index.html.ep:10\n#: themes/default/templates/index.html.ep:9\nmsgid \"Custom shortened text\"\nmsgstr \"Benutzerdefinierter verkürzter Text\"\n\n#: themes/default/templates/stats.html.ep:52\nmsgid \"Delete\"\nmsgstr \"Löschen\"\n\n#: themes/default/templates/stats.html.ep:36\nmsgid \"Export your URLs\"\nmsgstr \"URLs exportieren\"\n\n#: themes/default/templates/api.html.ep:105\n#: themes/default/templates/api.html.ep:145\n#: themes/default/templates/api.html.ep:53\n#: themes/default/templates/api.html.ep:71\nmsgid \"Failure reason\"\nmsgstr \"Fehlergrund\"\n\n#: lib/Lstu/Controller/Stats.pm:43\nmsgid \"File imported\"\nmsgstr \"Datei wurde importiert\"\n\n#: themes/default/templates/api.html.ep:101\nmsgid \"\"\n\"Get the details (visit counter, creation date, etc.) of a shortened URL.\"\nmsgstr \"\"\n\"Ermitteln Sie die Details (Besuchszähler, Erstellungsdatum usw.) einer \"\n\"verkürzten URL.\"\n\n#: themes/default/templates/index.html.ep:12\n#: themes/default/templates/stats.html.ep:17\nmsgid \"Go!\"\nmsgstr \"Go!\"\n\n#: themes/default/templates/partial/lstu.js.ep:30\nmsgid \"Hit Enter, then Ctrl+C to copy the short link\"\nmsgstr \"Enter drücken, dann Strg+C um den kurzen Link zu kopieren.\"\n\n#: themes/default/templates/stats.html.ep:89\nmsgid \"Home\"\nmsgstr \"Heim\"\n\n#: themes/default/templates/api.html.ep:126\nmsgid \"If \\\"action\\\" is defined to \\\"logout\\\":\"\nmsgstr \"Wenn \\\"aktion\\\" als \\\"logout\\\" definiert ist.\"\n\n#: themes/default/templates/api.html.ep:119\nmsgid \"If \\\"adminpwd\\\" is defined:\"\nmsgstr \"Wenn \\\"adminpwd\\\" definiert ist:\"\n\n#: themes/default/templates/api.html.ep:115\n#: themes/default/templates/api.html.ep:13\n#: themes/default/templates/api.html.ep:140\n#: themes/default/templates/api.html.ep:27\n#: themes/default/templates/api.html.ep:45\n#: themes/default/templates/api.html.ep:88\nmsgid \"\"\n\"If equal to \\\"json\\\", response will be in JSON format, HTML format otherwise\"\nmsgstr \"\"\n\n#. (config('page_offset')\n#: themes/default/templates/api.html.ep:81\nmsgid \"\"\n\"If you are logged in as admin (\\\"adminpwd\\\" or \\\"hashed_adminpwd\\\" setting), \"\n\"it will give you statistics for all URLs, sorted by the most visited first, \"\n\"paginated with pages containing %1 records.\"\nmsgstr \"\"\n\n#: themes/default/templates/api.html.ep:86\nmsgid \"If you are logged in as admin, you can provide a \\\"page\\\" parameter\"\nmsgstr \"\"\n\n#: themes/default/templates/stats.html.ep:32\n#: themes/default/templates/stats.html.ep:35\nmsgid \"Import URLs\"\nmsgstr \"URLs importieren\"\n\n#: themes/default/templates/api.html.ep:79\nmsgid \"\"\n\"It will use Lstu's cookies to know which shortened URL it will return \"\n\"statistics for.\"\nmsgstr \"\"\n\n#: themes/default/templates/api.html.ep:105\n#: themes/default/templates/api.html.ep:122\n#: themes/default/templates/api.html.ep:145\n#: themes/default/templates/api.html.ep:18\n#: themes/default/templates/api.html.ep:53\n#: themes/default/templates/api.html.ep:71\nmsgid \"JSON: failure\"\nmsgstr \"JSON: Fehler\"\n\n#: themes/default/templates/api.html.ep:104\n#: themes/default/templates/api.html.ep:121\n#: themes/default/templates/api.html.ep:129\n#: themes/default/templates/api.html.ep:144\n#: themes/default/templates/api.html.ep:17\n#: themes/default/templates/api.html.ep:31\n#: themes/default/templates/api.html.ep:52\n#: themes/default/templates/api.html.ep:70\nmsgid \"JSON: success\"\nmsgstr \"JSON: Erfolgreich\"\n\n#: themes/default/templates/layouts/default.html.ep:37\nmsgid \"License:\"\nmsgstr \"Lizenz:\"\n\n#: themes/default/templates/login.html.ep:8\nmsgid \"Login\"\nmsgstr \"Login\"\n\n#: themes/default/templates/layouts/default.html.ep:43\nmsgid \"Logout\"\nmsgstr \"Logout\"\n\n#: themes/default/templates/stats.html.ep:10\nmsgid \"Logout from admin stats\"\nmsgstr \"Von Admin Statistik Ausloggen\"\n\n#: themes/default/templates/stats.html.ep:84\nmsgid \"Next\"\nmsgstr \"Nächst\"\n\n#. ($c->config('contact')\n#: lib/Lstu/Controller/URL.pm:112\nmsgid \"\"\n\"No shortened URL available. Please retry or contact the administrator at %1. \"\n\"Your URL to shorten: %2\"\nmsgstr \"\"\n\n#: themes/default/templates/api.html.ep:111\n#: themes/default/templates/api.html.ep:138\n#: themes/default/templates/api.html.ep:25\n#: themes/default/templates/api.html.ep:41\n#: themes/default/templates/api.html.ep:83\n#: themes/default/templates/api.html.ep:9\nmsgid \"Parameters:\"\nmsgstr \"Parameter\"\n\n#: themes/default/templates/login.html.ep:12\nmsgid \"Password\"\nmsgstr \"Passwort\"\n\n#: lib/Lstu/Controller/Authent.pm:35 themes/default/templates/api.html.ep:18\nmsgid \"Please, check your credentials: unable to authenticate.\"\nmsgstr \"Bitte überprüfen Sie Ihre Logindaten: konnte nicht Authentifizieren.\"\n\n#: themes/default/templates/stats.html.ep:82\nmsgid \"Previous\"\nmsgstr \"Bisherige\"\n\n#: themes/default/templates/stats.html.ep:50\nmsgid \"QRCode\"\nmsgstr \"QR-Code\"\n\n#: themes/default/templates/api.html.ep:123\n#: themes/default/templates/api.html.ep:130\n#: themes/default/templates/api.html.ep:146\n#: themes/default/templates/api.html.ep:19\n#: themes/default/templates/api.html.ep:32\n#: themes/default/templates/api.html.ep:54\n#: themes/default/templates/api.html.ep:96\nmsgid \"Response for HTML format\"\nmsgstr \"Antwort zu HTML Format\"\n\n#: themes/default/templates/api.html.ep:95\nmsgid \"Response for JSON format\"\nmsgstr \"Antwort zu JSON Format\"\n\n#: themes/default/templates/api.html.ep:102\n#: themes/default/templates/api.html.ep:117\n#: themes/default/templates/api.html.ep:142\n#: themes/default/templates/api.html.ep:15\n#: themes/default/templates/api.html.ep:29\n#: themes/default/templates/api.html.ep:47\n#: themes/default/templates/api.html.ep:59\n#: themes/default/templates/api.html.ep:68\n#: themes/default/templates/api.html.ep:90\nmsgid \"Response:\"\nmsgstr \"Antwort:\"\n\n#: themes/default/templates/stats.html.ep:45\nmsgid \"Shortened URL\"\nmsgstr \"Verkürzte URL\"\n\n#: themes/default/templates/api.html.ep:127\n#: themes/default/templates/api.html.ep:24\nmsgid \"Should always be successful\"\nmsgstr \"Sollte immer erfolgreich sein\"\n\n#: themes/default/templates/layouts/default.html.ep:45\n#: themes/default/templates/login.html.ep:16\n#: themes/default/templates/logout.html.ep:5\nmsgid \"Signin\"\nmsgstr \"Einloggen\"\n\n#: lib/Lstu/Controller/Stats.pm:45\nmsgid \"Sorry, unable to parse the provided file\"\nmsgstr \"Entschuldigen Sie, das Lesen der Datei schlug fehl\"\n\n#: themes/default/templates/layouts/default.html.ep:42\n#: themes/default/templates/layouts/default.html.ep:48\n#: themes/default/templates/stats.html.ep:4\nmsgid \"Statistics\"\nmsgstr \"Statistiken\"\n\n#. ($url->host)\n#: lib/Lstu/Plugin/Helpers.pm:172\nmsgid \"\"\n\"The URL host or one of its redirection(s) (%1) is blacklisted at Spamhaus. I \"\n\"refuse to shorten it.\"\nmsgstr \"\"\n\n#. ($url)\n#: lib/Lstu/Plugin/Helpers.pm:178\nmsgid \"\"\n\"The URL or one of its redirection(s) (%1) is blacklisted in Google Safe \"\n\"Browsing database. I refuse to shorten it.\"\nmsgstr \"\"\n\n#. ($c->config('max_redir')\n#: lib/Lstu/Plugin/Helpers.pm:194\nmsgid \"\"\n\"The URL redirects %1 times or most. It's most likely a dangerous URL (spam, \"\n\"phishing, etc.). I refuse to shorten it.\"\nmsgstr \"\"\n\n#. ($url->host)\n#: lib/Lstu/Plugin/Helpers.pm:164\nmsgid \"\"\n\"The URL you want to shorten comes from a domain (%1) that is blacklisted on \"\n\"this server (usually because of spammers that use this domain).\"\nmsgstr \"\"\n\n#. ($c->url_for('/')\n#: lib/Lstu/Controller/Admin.pm:131 lib/Lstu/Controller/Stats.pm:184\n#: lib/Lstu/Controller/URL.pm:226\nmsgid \"The shortened URL %1 doesn't exist.\"\nmsgstr \"Die verkürzte URL %1 existiert nicht.\"\n\n#. ($url)\n#: lib/Lstu/Controller/URL.pm:59\nmsgid \"\"\n\"The shortened text can't be \\\"a\\\", \\\"api\\\", \\\"d\\\", \\\"cookie\\\", \\\"stats\\\", \"\n\"\\\"fullstats\\\", \\\"login\\\" or \\\"logout\\\" or end with \\\".json\\\". Your URL to \"\n\"shorten: %1\"\nmsgstr \"\"\n\n#: themes/default/templates/api.html.ep:113\nmsgid \"\"\n\"To do an admin login, set it to the password defined in the settings \"\n\"(\\\"adminpwd\\\" or \\\"hashed_adminpwd\\\")\"\nmsgstr \"\"\n\n#: themes/default/templates/api.html.ep:114\nmsgid \"To do an admin logout, set it to \\\"logout\\\".\"\nmsgstr \"\"\n\n#: lib/Lstu/Controller/Admin.pm:29\nmsgid \"Too many bad passwords. You're banned.\"\nmsgstr \"Zu viele fehlerhafte Passworte. Sie sind nun geblockt.\"\n\n#: themes/default/templates/api.html.ep:104\n#: themes/default/templates/api.html.ep:95\n#: themes/default/templates/stats.html.ep:44\nmsgid \"URL\"\nmsgstr \"URL\"\n\n#: themes/default/templates/api.html.ep:43\n#: themes/default/templates/index.html.ep:5\n#: themes/default/templates/index.html.ep:6\nmsgid \"URL to shorten\"\nmsgstr \"\"\n\n#. ($penalty/3600)\n#: lib/Lstu/Controller/URL.pm:35\nmsgid \"\"\n\"You asked to shorten too many URLs too quickly. You're banned for %1 hour(s).\"\nmsgstr \"\"\n\n#: lib/Lstu/Controller/Admin.pm:52 lib/Lstu/Controller/Authent.pm:26\n#: themes/default/templates/api.html.ep:121\n#: themes/default/templates/api.html.ep:17\nmsgid \"You have been successfully logged in.\"\nmsgstr \"\"\n\n#: lib/Lstu/Controller/Admin.pm:73 lib/Lstu/Controller/Authent.pm:65\n#: themes/default/templates/api.html.ep:129\n#: themes/default/templates/api.html.ep:31\n#: themes/default/templates/logout.html.ep:3\nmsgid \"You have been successfully logged out.\"\nmsgstr \"\"\n\n#: themes/default/templates/api.html.ep:137\nmsgid \"\"\n\"You must be logged in as admin (\\\"adminpwd\\\" or \\\"hashed_adminpwd\\\" setting) \"\n\"to use it.\"\nmsgstr \"\"\n\n#: themes/default/templates/api.html.ep:39\n#: themes/default/templates/api.html.ep:77\nmsgid \"You must be logged in to use it.\"\nmsgstr \"\"\n\n#: themes/default/templates/api.html.ep:130\nmsgid \"You will be redirected to Lstu statistics page\"\nmsgstr \"\"\n\n#: themes/default/templates/api.html.ep:146\nmsgid \"\"\n\"You will be redirected to Lstu statistics page with a message in case of \"\n\"failure\"\nmsgstr \"\"\n\n#: themes/default/templates/api.html.ep:32\nmsgid \"You will be redirected to Lstu successfully logged out interface\"\nmsgstr \"\"\n\n#: themes/default/templates/api.html.ep:19\nmsgid \"\"\n\"You will be redirected to the Lstu classic interface where you will be able \"\n\"to shorten URLs\"\nmsgstr \"\"\n\n#: themes/default/templates/api.html.ep:54\nmsgid \"\"\n\"You will be redirected to the Lstu classic interface with a message giving \"\n\"the shortened URL\"\nmsgstr \"\"\n\n#: themes/default/templates/api.html.ep:62\nmsgid \"\"\n\"You will be redirected to the targeted URL or to the Lstu interface with a \"\n\"message giving the failure reason\"\nmsgstr \"\"\n\n#: themes/default/templates/api.html.ep:123\nmsgid \"\"\n\"You will have the statistics page with the admin stats if you're succesfully \"\n\"logged in, or your stats and a failure message otherwise\"\nmsgstr \"\"\n\n#: lib/Lstu/Controller/Admin.pm:142\nmsgid \"You're not authenticated as the admin\"\nmsgstr \"\"\n\n#: themes/default/templates/api.html.ep:11\nmsgid \"Your login\"\nmsgstr \"\"\n\n#: themes/default/templates/api.html.ep:12\nmsgid \"Your password\"\nmsgstr \"\"\n\n#: themes/default/templates/api.html.ep:104\n#: themes/default/templates/api.html.ep:95\nmsgid \"integer, how many unique visits of the shortened URL\"\nmsgstr \"\"\n\n#: themes/default/templates/api.html.ep:11\n#: themes/default/templates/api.html.ep:12\n#: themes/default/templates/api.html.ep:43\nmsgid \"mandatory\"\nmsgstr \"\"\n\n#: themes/default/templates/api.html.ep:113\n#: themes/default/templates/api.html.ep:114\n#: themes/default/templates/api.html.ep:115\n#: themes/default/templates/api.html.ep:13\n#: themes/default/templates/api.html.ep:140\n#: themes/default/templates/api.html.ep:27\n#: themes/default/templates/api.html.ep:44\n#: themes/default/templates/api.html.ep:45\n#: themes/default/templates/api.html.ep:86\n#: themes/default/templates/api.html.ep:88\nmsgid \"optional\"\nmsgstr \"\"\n\n#: themes/default/templates/api.html.ep:135\n#: themes/default/templates/api.html.ep:57\n#: themes/default/templates/api.html.ep:66\n#: themes/default/templates/api.html.ep:92\n#: themes/default/templates/api.html.ep:99\nmsgid \"shortened_url\"\nmsgstr \"\"\n\n#: themes/default/templates/layouts/default.html.ep:50\nmsgid \"Browser extensions\"\nmsgstr \"Browser Erweiterung\"\n\n#. ($c->url_for('/')\n#: lib/Lstu/Controller/URL.pm:240\nmsgid \"The shortened URL %1 no longer exists.\"\nmsgstr \"Die verkürzte URL %1 existiert nicht mehr.\"\n"
  },
  {
    "path": "themes/default/lib/Lstu/I18N/en.po",
    "content": "# Luc Didry <luc@framasoft.org>, 2018. #zanata\nmsgid \"\"\nmsgstr \"\"\n\"Project-Id-Version: PACKAGE VERSION\\n\"\n\"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\\n\"\n\"MIME-Version: 1.0\\n\"\n\"Content-Type: text/plain; charset=UTF-8\\n\"\n\"Content-Transfer-Encoding: 8bit\\n\"\n\"PO-Revision-Date: 2018-11-22 02:48+0000\\n\"\n\"Last-Translator: Luc Didry <luc@framasoft.org>\\n\"\n\"Language-Team: English\\n\"\n\"Language: en\\n\"\n\"X-Generator: Zanata 4.6.2\\n\"\n\"Plural-Forms: nplurals=2; plural=(n != 1)\\n\"\n\n#. ($url)\n#: lib/Lstu/Controller/URL.pm:118\nmsgid \"%1 is not a valid URL.\"\nmsgstr \"%1 is not a valid URL.\"\n\n#: themes/default/templates/api.html.ep:96\nmsgid \"\"\n\"A page with a table containing the same informations that the JSON response\"\nmsgstr \"\"\n\"A page with a table containing the same informations that the JSON response\"\n\n#: themes/default/templates/layouts/default.html.ep:38\nmsgid \"About\"\nmsgstr \"About\"\n\n#: themes/default/templates/stats.html.ep:13 themes/default/templates/stats.html.ep:14\nmsgid \"Admin password\"\nmsgstr \"Admin password\"\n\n#: lib/Lstu/Controller/Admin.pm:87 themes/default/templates/api.html.ep:122\nmsgid \"Bad password\"\nmsgstr \"Bad password\"\n\n#: themes/default/templates/index.html.ep:21\nmsgid \"Copy to clipboard\"\nmsgstr \"Copy to clipboard\"\n\n#: themes/default/templates/stats.html.ep:46\nmsgid \"Counter\"\nmsgstr \"Counter\"\n\n#: themes/default/templates/stats.html.ep:47\nmsgid \"Created\"\nmsgstr \"Created\"\n\n#: themes/default/templates/api.html.ep:44 themes/default/templates/index.html.ep:10 themes/default/templates/index.html.ep:9\nmsgid \"Custom shortened text\"\nmsgstr \"Custom shortened text\"\n\n#: themes/default/templates/stats.html.ep:52\nmsgid \"Delete\"\nmsgstr \"Delete\"\n\n#: themes/default/templates/stats.html.ep:36\nmsgid \"Export your URLs\"\nmsgstr \"Export your URLs\"\n\n#: themes/default/templates/api.html.ep:105 themes/default/templates/api.html.ep:145 themes/default/templates/api.html.ep:53 themes/default/templates/api.html.ep:71\nmsgid \"Failure reason\"\nmsgstr \"Failure reason\"\n\n#: lib/Lstu/Controller/Stats.pm:43\nmsgid \"File imported\"\nmsgstr \"File imported\"\n\n#: themes/default/templates/api.html.ep:101\nmsgid \"\"\n\"Get the details (visit counter, creation date, etc.) of a shortened URL.\"\nmsgstr \"\"\n\"Get the details (visit counter, creation date, etc.) of a shortened URL.\"\n\n#: themes/default/templates/index.html.ep:12 themes/default/templates/stats.html.ep:17\nmsgid \"Go!\"\nmsgstr \"Go!\"\n\n#: themes/default/templates/partial/lstu.js.ep:30\nmsgid \"Hit Enter, then Ctrl+C to copy the short link\"\nmsgstr \"Hit Enter, then Ctrl+C to copy the short link\"\n\n#: themes/default/templates/stats.html.ep:89\nmsgid \"Home\"\nmsgstr \"Home\"\n\n#: themes/default/templates/api.html.ep:126\nmsgid \"If \\\"action\\\" is defined to \\\"logout\\\":\"\nmsgstr \"If \\\"action\\\" is defined to \\\"logout\\\":\"\n\n#: themes/default/templates/api.html.ep:119\nmsgid \"If \\\"adminpwd\\\" is defined:\"\nmsgstr \"If \\\"adminpwd\\\" is defined:\"\n\n#: themes/default/templates/api.html.ep:115 themes/default/templates/api.html.ep:13 themes/default/templates/api.html.ep:140 themes/default/templates/api.html.ep:27 themes/default/templates/api.html.ep:45 themes/default/templates/api.html.ep:88\nmsgid \"\"\n\"If equal to \\\"json\\\", response will be in JSON format, HTML format otherwise\"\nmsgstr \"\"\n\"If equal to \\\"json\\\", response will be in JSON format, HTML format otherwise\"\n\n#. (config('page_offset')\n#: themes/default/templates/api.html.ep:81\nmsgid \"\"\n\"If you are logged in as admin (\\\"adminpwd\\\" or \\\"hashed_adminpwd\\\" setting), \"\n\"it will give you statistics for all URLs, sorted by the most visited first, \"\n\"paginated with pages containing %1 records.\"\nmsgstr \"\"\n\"If you are logged in as admin (\\\"adminpwd\\\" or \\\"hashed_adminpwd\\\" setting), \"\n\"it will give you statistics for all URLs, sorted by the most visited first, \"\n\"paginated with pages containing %1 records.\"\n\n#: themes/default/templates/api.html.ep:86\nmsgid \"If you are logged in as admin, you can provide a \\\"page\\\" parameter\"\nmsgstr \"If you are logged in as admin, you can provide a \\\"page\\\" parameter\"\n\n#: themes/default/templates/stats.html.ep:32 themes/default/templates/stats.html.ep:35\nmsgid \"Import URLs\"\nmsgstr \"Import URLs\"\n\n#: themes/default/templates/api.html.ep:79\nmsgid \"\"\n\"It will use Lstu's cookies to know which shortened URL it will return \"\n\"statistics for.\"\nmsgstr \"\"\n\"It will use Lstu's cookies to know which shortened URL it will return \"\n\"statistics for.\"\n\n#: themes/default/templates/api.html.ep:105 themes/default/templates/api.html.ep:122 themes/default/templates/api.html.ep:145 themes/default/templates/api.html.ep:18 themes/default/templates/api.html.ep:53 themes/default/templates/api.html.ep:71\nmsgid \"JSON: failure\"\nmsgstr \"JSON: failure\"\n\n#: themes/default/templates/api.html.ep:104 themes/default/templates/api.html.ep:121 themes/default/templates/api.html.ep:129 themes/default/templates/api.html.ep:144 themes/default/templates/api.html.ep:17 themes/default/templates/api.html.ep:31 themes/default/templates/api.html.ep:52 themes/default/templates/api.html.ep:70\nmsgid \"JSON: success\"\nmsgstr \"JSON: success\"\n\n#: themes/default/templates/layouts/default.html.ep:37\nmsgid \"License:\"\nmsgstr \"License:\"\n\n#: themes/default/templates/login.html.ep:8\nmsgid \"Login\"\nmsgstr \"Login\"\n\n#: themes/default/templates/layouts/default.html.ep:43\nmsgid \"Logout\"\nmsgstr \"Logout\"\n\n#: themes/default/templates/stats.html.ep:10\nmsgid \"Logout from admin stats\"\nmsgstr \"Logout from admin stats\"\n\n#: themes/default/templates/stats.html.ep:84\nmsgid \"Next\"\nmsgstr \"Next\"\n\n#. ($c->config('contact')\n#: lib/Lstu/Controller/URL.pm:112\nmsgid \"\"\n\"No shortened URL available. Please retry or contact the administrator at %1. \"\n\"Your URL to shorten: %2\"\nmsgstr \"\"\n\"No shortened URL available. Please retry or contact the administrator at %1. \"\n\"Your URL to shorten: %2\"\n\n#: themes/default/templates/api.html.ep:111 themes/default/templates/api.html.ep:138 themes/default/templates/api.html.ep:25 themes/default/templates/api.html.ep:41 themes/default/templates/api.html.ep:83 themes/default/templates/api.html.ep:9\nmsgid \"Parameters:\"\nmsgstr \"Parameters:\"\n\n#: themes/default/templates/login.html.ep:12\nmsgid \"Password\"\nmsgstr \"Password\"\n\n#: lib/Lstu/Controller/Authent.pm:35 themes/default/templates/api.html.ep:18\nmsgid \"Please, check your credentials: unable to authenticate.\"\nmsgstr \"Please, check your credentials: unable to authenticate.\"\n\n#: themes/default/templates/stats.html.ep:82\nmsgid \"Previous\"\nmsgstr \"Previous\"\n\n#: themes/default/templates/stats.html.ep:50\nmsgid \"QRCode\"\nmsgstr \"QRCode\"\n\n#: themes/default/templates/api.html.ep:123 themes/default/templates/api.html.ep:130 themes/default/templates/api.html.ep:146 themes/default/templates/api.html.ep:19 themes/default/templates/api.html.ep:32 themes/default/templates/api.html.ep:54 themes/default/templates/api.html.ep:96\nmsgid \"Response for HTML format\"\nmsgstr \"Response for HTML format\"\n\n#: themes/default/templates/api.html.ep:95\nmsgid \"Response for JSON format\"\nmsgstr \"Response for JSON format\"\n\n#: themes/default/templates/api.html.ep:102 themes/default/templates/api.html.ep:117 themes/default/templates/api.html.ep:142 themes/default/templates/api.html.ep:15 themes/default/templates/api.html.ep:29 themes/default/templates/api.html.ep:47 themes/default/templates/api.html.ep:59 themes/default/templates/api.html.ep:68 themes/default/templates/api.html.ep:90\nmsgid \"Response:\"\nmsgstr \"Response:\"\n\n#: themes/default/templates/stats.html.ep:45\nmsgid \"Shortened URL\"\nmsgstr \"Shortened URL\"\n\n#: themes/default/templates/api.html.ep:127 themes/default/templates/api.html.ep:24\nmsgid \"Should always be successful\"\nmsgstr \"Should always be successful\"\n\n#: themes/default/templates/layouts/default.html.ep:45 themes/default/templates/login.html.ep:16 themes/default/templates/logout.html.ep:5\nmsgid \"Signin\"\nmsgstr \"Signin\"\n\n#: lib/Lstu/Controller/Stats.pm:45\nmsgid \"Sorry, unable to parse the provided file\"\nmsgstr \"Sorry, unable to parse the provided file\"\n\n#: themes/default/templates/layouts/default.html.ep:42 themes/default/templates/layouts/default.html.ep:48 themes/default/templates/stats.html.ep:4\nmsgid \"Statistics\"\nmsgstr \"Statistics\"\n\n#. ($url->host)\n#: lib/Lstu/Plugin/Helpers.pm:172\nmsgid \"\"\n\"The URL host or one of its redirection(s) (%1) is blacklisted at Spamhaus. I \"\n\"refuse to shorten it.\"\nmsgstr \"\"\n\"The URL host or one of its redirection(s) (%1) is blacklisted at Spamhaus. I \"\n\"refuse to shorten it.\"\n\n#. ($url)\n#: lib/Lstu/Plugin/Helpers.pm:178\nmsgid \"\"\n\"The URL or one of its redirection(s) (%1) is blacklisted in Google Safe \"\n\"Browsing database. I refuse to shorten it.\"\nmsgstr \"\"\n\"The URL or one of its redirection(s) (%1) is blacklisted in Google Safe \"\n\"Browsing database. I refuse to shorten it.\"\n\n#. ($c->config('max_redir')\n#: lib/Lstu/Plugin/Helpers.pm:194\nmsgid \"\"\n\"The URL redirects %1 times or most. It's most likely a dangerous URL (spam, \"\n\"phishing, etc.). I refuse to shorten it.\"\nmsgstr \"\"\n\"The URL redirects %1 times or most. It's most likely a dangerous URL (spam, \"\n\"phishing, etc.). I refuse to shorten it.\"\n\n#. ($url->host)\n#: lib/Lstu/Plugin/Helpers.pm:164\nmsgid \"\"\n\"The URL you want to shorten comes from a domain (%1) that is blacklisted on \"\n\"this server (usually because of spammers that use this domain).\"\nmsgstr \"\"\n\"The URL you want to shorten comes from a domain (%1) that is blacklisted on \"\n\"this server (usually because of spammers that use this domain).\"\n\n#. ($c->url_for('/')\n#: lib/Lstu/Controller/Admin.pm:131 lib/Lstu/Controller/Stats.pm:184 lib/Lstu/Controller/URL.pm:226\nmsgid \"The shortened URL %1 doesn't exist.\"\nmsgstr \"The shortened URL %1 doesn't exist.\"\n\n#. ($c->url_for('/')\n#: lib/Lstu/Controller/URL.pm:240\nmsgid \"The shortened URL %1 no longer exists.\"\nmsgstr \"The shortened URL %1 no longer exists.\"\n\n#. ($url)\n#: lib/Lstu/Controller/URL.pm:59\nmsgid \"\"\n\"The shortened text can't be \\\"a\\\", \\\"api\\\", \\\"d\\\", \\\"cookie\\\", \\\"stats\\\", \"\n\"\\\"fullstats\\\", \\\"login\\\" or \\\"logout\\\" or end with \\\".json\\\". Your URL to \"\n\"shorten: %1\"\nmsgstr \"\"\n\"The shortened text can't be \\\"a\\\", \\\"api\\\", \\\"d\\\", \\\"cookie\\\", \\\"stats\\\", \"\n\"\\\"fullstats\\\", \\\"login\\\" or \\\"logout\\\" or end with \\\".json\\\". Your URL to \"\n\"shorten: %1\"\n\n#: themes/default/templates/api.html.ep:113\nmsgid \"\"\n\"To do an admin login, set it to the password defined in the settings \"\n\"(\\\"adminpwd\\\" or \\\"hashed_adminpwd\\\")\"\nmsgstr \"\"\n\"To do an admin login, set it to the password defined in the settings \"\n\"(\\\"adminpwd\\\" or \\\"hashed_adminpwd\\\")\"\n\n#: themes/default/templates/api.html.ep:114\nmsgid \"To do an admin logout, set it to \\\"logout\\\".\"\nmsgstr \"To do an admin logout, set it to \\\"logout\\\".\"\n\n#: lib/Lstu/Controller/Admin.pm:29\nmsgid \"Too many bad passwords. You're banned.\"\nmsgstr \"Too many bad passwords. You're banned.\"\n\n#: themes/default/templates/api.html.ep:104 themes/default/templates/api.html.ep:95 themes/default/templates/stats.html.ep:44\nmsgid \"URL\"\nmsgstr \"URL\"\n\n#: themes/default/templates/api.html.ep:43 themes/default/templates/index.html.ep:5 themes/default/templates/index.html.ep:6\nmsgid \"URL to shorten\"\nmsgstr \"URL to shorten\"\n\n#. ($penalty/3600)\n#: lib/Lstu/Controller/URL.pm:35\nmsgid \"\"\n\"You asked to shorten too many URLs too quickly. You're banned for %1 hour(s).\"\n\"\"\nmsgstr \"\"\n\"You asked to shorten too many URLs too quickly. You're banned for %1 hour(s).\"\n\"\"\n\n#: lib/Lstu/Controller/Admin.pm:52 lib/Lstu/Controller/Authent.pm:26 themes/default/templates/api.html.ep:121 themes/default/templates/api.html.ep:17\nmsgid \"You have been successfully logged in.\"\nmsgstr \"You have been successfully logged in.\"\n\n#: lib/Lstu/Controller/Admin.pm:73 lib/Lstu/Controller/Authent.pm:65 themes/default/templates/api.html.ep:129 themes/default/templates/api.html.ep:31 themes/default/templates/logout.html.ep:3\nmsgid \"You have been successfully logged out.\"\nmsgstr \"You have been successfully logged out.\"\n\n#: themes/default/templates/api.html.ep:137\nmsgid \"\"\n\"You must be logged in as admin (\\\"adminpwd\\\" or \\\"hashed_adminpwd\\\" setting) \"\n\"to use it.\"\nmsgstr \"\"\n\"You must be logged in as admin (\\\"adminpwd\\\" or \\\"hashed_adminpwd\\\" setting) \"\n\"to use it.\"\n\n#: themes/default/templates/api.html.ep:39 themes/default/templates/api.html.ep:77\nmsgid \"You must be logged in to use it.\"\nmsgstr \"You must be logged in to use it.\"\n\n#: themes/default/templates/api.html.ep:130\nmsgid \"You will be redirected to Lstu statistics page\"\nmsgstr \"You will be redirected to Lstu statistics page\"\n\n#: themes/default/templates/api.html.ep:146\nmsgid \"\"\n\"You will be redirected to Lstu statistics page with a message in case of \"\n\"failure\"\nmsgstr \"\"\n\"You will be redirected to Lstu statistics page with a message in case of \"\n\"failure\"\n\n#: themes/default/templates/api.html.ep:32\nmsgid \"You will be redirected to Lstu successfully logged out interface\"\nmsgstr \"You will be redirected to Lstu successfully logged out interface\"\n\n#: themes/default/templates/api.html.ep:19\nmsgid \"\"\n\"You will be redirected to the Lstu classic interface where you will be able \"\n\"to shorten URLs\"\nmsgstr \"\"\n\"You will be redirected to the Lstu classic interface where you will be able \"\n\"to shorten URLs\"\n\n#: themes/default/templates/api.html.ep:54\nmsgid \"\"\n\"You will be redirected to the Lstu classic interface with a message giving \"\n\"the shortened URL\"\nmsgstr \"\"\n\"You will be redirected to the Lstu classic interface with a message giving \"\n\"the shortened URL\"\n\n#: themes/default/templates/api.html.ep:62\nmsgid \"\"\n\"You will be redirected to the targeted URL or to the Lstu interface with a \"\n\"message giving the failure reason\"\nmsgstr \"\"\n\"You will be redirected to the targeted URL or to the Lstu interface with a \"\n\"message giving the failure reason\"\n\n#: themes/default/templates/api.html.ep:123\nmsgid \"\"\n\"You will have the statistics page with the admin stats if you're succesfully \"\n\"logged in, or your stats and a failure message otherwise\"\nmsgstr \"\"\n\"You will have the statistics page with the admin stats if you're succesfully \"\n\"logged in, or your stats and a failure message otherwise\"\n\n#: lib/Lstu/Controller/Admin.pm:142\nmsgid \"You're not authenticated as the admin\"\nmsgstr \"You're not authenticated as the admin\"\n\n#: themes/default/templates/api.html.ep:11\nmsgid \"Your login\"\nmsgstr \"Your login\"\n\n#: themes/default/templates/api.html.ep:12\nmsgid \"Your password\"\nmsgstr \"Your password\"\n\n#: themes/default/templates/api.html.ep:104 themes/default/templates/api.html.ep:95\nmsgid \"integer, how many unique visits of the shortened URL\"\nmsgstr \"integer, how many unique visits of the shortened URL\"\n\n#: themes/default/templates/api.html.ep:11 themes/default/templates/api.html.ep:12 themes/default/templates/api.html.ep:43\nmsgid \"mandatory\"\nmsgstr \"mandatory\"\n\n#: themes/default/templates/api.html.ep:113 themes/default/templates/api.html.ep:114 themes/default/templates/api.html.ep:115 themes/default/templates/api.html.ep:13 themes/default/templates/api.html.ep:140 themes/default/templates/api.html.ep:27 themes/default/templates/api.html.ep:44 themes/default/templates/api.html.ep:45 themes/default/templates/api.html.ep:86 themes/default/templates/api.html.ep:88\nmsgid \"optional\"\nmsgstr \"optional\"\n\n#: themes/default/templates/api.html.ep:135 themes/default/templates/api.html.ep:57 themes/default/templates/api.html.ep:66 themes/default/templates/api.html.ep:92 themes/default/templates/api.html.ep:99\nmsgid \"shortened_url\"\nmsgstr \"shortened_url\"\n"
  },
  {
    "path": "themes/default/lib/Lstu/I18N/es.po",
    "content": "# SOME DESCRIPTIVE TITLE.\n# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER\n# This file is distributed under the same license as the PACKAGE package.\n# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.\n#\nmsgid \"\"\nmsgstr \"\"\n\"Project-Id-Version: PACKAGE VERSION\\n\"\n\"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\\n\"\n\"PO-Revision-Date: 2021-05-01 10:42+0000\\n\"\n\"Last-Translator: Berto Te <ateira@3fpj.com>\\n\"\n\"Language-Team: Spanish <https://weblate.framasoft.org/projects/lstu/\"\n\"development/es/>\\n\"\n\"Language: es\\n\"\n\"MIME-Version: 1.0\\n\"\n\"Content-Type: text/plain; charset=UTF-8\\n\"\n\"Content-Transfer-Encoding: 8bit\\n\"\n\"Plural-Forms: nplurals=2; plural=n != 1;\\n\"\n\"X-Generator: Weblate 4.6\\n\"\n\n#. ($url)\n#: lib/Lstu/Controller/URL.pm:118\nmsgid \"%1 is not a valid URL.\"\nmsgstr \"%1 no es una URL válida.\"\n\n#: themes/default/templates/api.html.ep:96\nmsgid \"A page with a table containing the same informations that the JSON response\"\nmsgstr \"\"\n\"Una página con una tabla que contiene la misma información que la respuesta \"\n\"JSON\"\n\n#: themes/default/templates/layouts/default.html.ep:54\nmsgid \"About\"\nmsgstr \"Acerca de\"\n\n#: themes/default/templates/stats.html.ep:13 themes/default/templates/stats.html.ep:14\nmsgid \"Admin password\"\nmsgstr \"Contraseña de administrador\"\n\n#: lib/Lstu/Controller/Admin.pm:87 themes/default/templates/api.html.ep:122\nmsgid \"Bad password\"\nmsgstr \"Contraseña incorrecta\"\n\n#: themes/default/templates/index.html.ep:21\nmsgid \"Copy to clipboard\"\nmsgstr \"Copiar al portapapeles\"\n\n#: themes/default/templates/stats.html.ep:46\nmsgid \"Counter\"\nmsgstr \"contador\"\n\n#: themes/default/templates/stats.html.ep:47\nmsgid \"Created\"\nmsgstr \"Creado en\"\n\n#: themes/default/templates/api.html.ep:44 themes/default/templates/index.html.ep:10 themes/default/templates/index.html.ep:9\nmsgid \"Custom shortened text\"\nmsgstr \"xto de acceso directo personalizado\"\n\n#: themes/default/templates/stats.html.ep:52\nmsgid \"Delete\"\nmsgstr \"Eliminar\"\n\n#: themes/default/templates/stats.html.ep:36\nmsgid \"Export your URLs\"\nmsgstr \"Exporta tus URL\"\n\n#: themes/default/templates/api.html.ep:105 themes/default/templates/api.html.ep:145 themes/default/templates/api.html.ep:53 themes/default/templates/api.html.ep:71\nmsgid \"Failure reason\"\nmsgstr \"Motivo del fallo\"\n\n#: lib/Lstu/Controller/Stats.pm:43\nmsgid \"File imported\"\nmsgstr \"Archivo importado\"\n\n#: themes/default/templates/api.html.ep:101\nmsgid \"Get the details (visit counter, creation date, etc.) of a shortened URL.\"\nmsgstr \"\"\n\"Obtenga los detalles (contador de visitas, fecha de creación, etc.) de una \"\n\"URL acortada.\"\n\n#: themes/default/templates/index.html.ep:12 themes/default/templates/stats.html.ep:17\nmsgid \"Go!\"\nmsgstr \"¡Vamos!\"\n\n#: themes/default/templates/partial/lstu.js.ep:30\nmsgid \"Hit Enter, then Ctrl+C to copy the short link\"\nmsgstr \"Presiona Enter, luego Ctrl C para copiar el enlace corto\"\n\n#: themes/default/templates/stats.html.ep:89\nmsgid \"Home\"\nmsgstr \"Inicio\"\n\n#: themes/default/templates/api.html.ep:126\nmsgid \"If \\\"action\\\" is defined to \\\"logout\\\":\"\nmsgstr \"Si \\\"action\\\" se establece en \\\"logout\\\":\"\n\n#: themes/default/templates/api.html.ep:119\nmsgid \"If \\\"adminpwd\\\" is defined:\"\nmsgstr \"Si se define \\\"adminpwd\\\":\"\n\n#: themes/default/templates/api.html.ep:115 themes/default/templates/api.html.ep:13 themes/default/templates/api.html.ep:140 themes/default/templates/api.html.ep:27 themes/default/templates/api.html.ep:45 themes/default/templates/api.html.ep:88\nmsgid \"If equal to \\\"json\\\", response will be in JSON format, HTML format otherwise\"\nmsgstr \"\"\n\"Si es igual a \\\"json\\\", la respuesta estará en formato JSON, formato HTML de \"\n\"lo contrario\"\n\n#. (config('page_offset')\n#: themes/default/templates/api.html.ep:81\nmsgid \"If you are logged in as admin (\\\"adminpwd\\\" or \\\"hashed_adminpwd\\\" setting), it will give you statistics for all URLs, sorted by the most visited first, paginated with pages containing %1 records.\"\nmsgstr \"\"\n\"Si ha iniciado sesión como administrador (configuración \\\"adminpwd\\\" o \\\"\"\n\"hashed_adminpwd\\\"), le proporcionará estadísticas para todas las URL, \"\n\"ordenadas primero por las más visitadas, paginadas con páginas que contienen%\"\n\" 1 registros.\"\n\n#: themes/default/templates/api.html.ep:86\nmsgid \"If you are logged in as admin, you can provide a \\\"page\\\" parameter\"\nmsgstr \"\"\n\"Si ha iniciado sesión como administrador, puede proporcionar un parámetro de \"\n\"\\\"page\\\"\"\n\n#: themes/default/templates/stats.html.ep:32 themes/default/templates/stats.html.ep:35\nmsgid \"Import URLs\"\nmsgstr \"Importar URL\"\n\n#: themes/default/templates/api.html.ep:79\nmsgid \"It will use Lstu's cookies to know which shortened URL it will return statistics for.\"\nmsgstr \"\"\n\"Utilizará las cookies de Lstu para saber para qué URL devolverá estadísticas.\"\n\n#: themes/default/templates/api.html.ep:105 themes/default/templates/api.html.ep:122 themes/default/templates/api.html.ep:145 themes/default/templates/api.html.ep:18 themes/default/templates/api.html.ep:53 themes/default/templates/api.html.ep:71\nmsgid \"JSON: failure\"\nmsgstr \"JSON: fallo\"\n\n#: themes/default/templates/api.html.ep:104 themes/default/templates/api.html.ep:121 themes/default/templates/api.html.ep:129 themes/default/templates/api.html.ep:144 themes/default/templates/api.html.ep:17 themes/default/templates/api.html.ep:31 themes/default/templates/api.html.ep:52 themes/default/templates/api.html.ep:70\nmsgid \"JSON: success\"\nmsgstr \"JSON: éxito\"\n\n#: themes/default/templates/layouts/default.html.ep:53\nmsgid \"License:\"\nmsgstr \"Licencia:\"\n\n#: themes/default/templates/login.html.ep:8\nmsgid \"Login\"\nmsgstr \"Iniciar sesión\"\n\n#: themes/default/templates/layouts/default.html.ep:59\nmsgid \"Logout\"\nmsgstr \"Cerrar sesión\"\n\n#: themes/default/templates/stats.html.ep:10\nmsgid \"Logout from admin stats\"\nmsgstr \"Cerrar sesión en las estadísticas de administrador\"\n\n#: themes/default/templates/stats.html.ep:84\nmsgid \"Next\"\nmsgstr \"Siguiente\"\n\n#. ($c->config('contact')\n#: lib/Lstu/Controller/URL.pm:112\nmsgid \"No shortened URL available. Please retry or contact the administrator at %1. Your URL to shorten: %2\"\nmsgstr \"\"\n\"No hay URL abreviada disponible. Vuelva a intentarlo o póngase en contacto \"\n\"con el administrador en %1. Su URL para acortar: %2\"\n\n#: themes/default/templates/api.html.ep:111 themes/default/templates/api.html.ep:138 themes/default/templates/api.html.ep:25 themes/default/templates/api.html.ep:41 themes/default/templates/api.html.ep:83 themes/default/templates/api.html.ep:9\nmsgid \"Parameters:\"\nmsgstr \"Parámetros:\"\n\n#: themes/default/templates/login.html.ep:12\nmsgid \"Password\"\nmsgstr \"Contraseña\"\n\n#: lib/Lstu/Controller/Authent.pm:35 themes/default/templates/api.html.ep:18\nmsgid \"Please, check your credentials: unable to authenticate.\"\nmsgstr \"Por favor, verifique sus credenciales: no se puede autenticar.\"\n\n#: themes/default/templates/stats.html.ep:82\nmsgid \"Previous\"\nmsgstr \"Anterior\"\n\n#: themes/default/templates/stats.html.ep:50\nmsgid \"QRCode\"\nmsgstr \"Código QR\"\n\n#: themes/default/templates/api.html.ep:123 themes/default/templates/api.html.ep:130 themes/default/templates/api.html.ep:146 themes/default/templates/api.html.ep:19 themes/default/templates/api.html.ep:32 themes/default/templates/api.html.ep:54 themes/default/templates/api.html.ep:96\nmsgid \"Response for HTML format\"\nmsgstr \"Respuesta para formato HTML\"\n\n#: themes/default/templates/api.html.ep:95\nmsgid \"Response for JSON format\"\nmsgstr \"Respuesta para formato JSON\"\n\n#: themes/default/templates/api.html.ep:102 themes/default/templates/api.html.ep:117 themes/default/templates/api.html.ep:142 themes/default/templates/api.html.ep:15 themes/default/templates/api.html.ep:29 themes/default/templates/api.html.ep:47 themes/default/templates/api.html.ep:59 themes/default/templates/api.html.ep:68 themes/default/templates/api.html.ep:90\nmsgid \"Response:\"\nmsgstr \"Respuesta:\"\n\n#: themes/default/templates/stats.html.ep:45\nmsgid \"Shortened URL\"\nmsgstr \"Acceso directo a URL\"\n\n#: themes/default/templates/api.html.ep:127 themes/default/templates/api.html.ep:24\nmsgid \"Should always be successful\"\nmsgstr \"Siempre debe ser exitoso\"\n\n#: themes/default/templates/layouts/default.html.ep:61 themes/default/templates/login.html.ep:16 themes/default/templates/logout.html.ep:5\nmsgid \"Signin\"\nmsgstr \"Registrarse\"\n\n#: lib/Lstu/Controller/Stats.pm:45\nmsgid \"Sorry, unable to parse the provided file\"\nmsgstr \"Lo sentimos, no se puede analizar el archivo proporcionado\"\n\n#: themes/default/templates/layouts/default.html.ep:58 themes/default/templates/layouts/default.html.ep:64 themes/default/templates/stats.html.ep:4\nmsgid \"Statistics\"\nmsgstr \"Estadísticas\"\n\n#. ($url->host)\n#: lib/Lstu/Plugin/Helpers.pm:172\nmsgid \"The URL host or one of its redirection(s) (%1) is blacklisted at Spamhaus. I refuse to shorten it.\"\nmsgstr \"\"\n\"El host de URL o una de sus redirecciones (%1) está en la lista negra de \"\n\"Spamhaus. Me niego a acortarlo.\"\n\n#. ($url)\n#: lib/Lstu/Plugin/Helpers.pm:178\nmsgid \"The URL or one of its redirection(s) (%1) is blacklisted in Google Safe Browsing database. I refuse to shorten it.\"\nmsgstr \"\"\n\"La URL o una de sus redirecciones (%1) está en la lista negra de la base de \"\n\"datos de Navegación segura de Google. Me niego a acortarlo.\"\n\n#. ($c->config('max_redir')\n#: lib/Lstu/Plugin/Helpers.pm:194\nmsgid \"The URL redirects %1 times or most. It's most likely a dangerous URL (spam, phishing, etc.). I refuse to shorten it.\"\nmsgstr \"\"\n\"La URL redirige %1 veces o la mayoría. Es muy probable que sea una URL \"\n\"peligrosa (spam, phishing, etc.). Me niego a acortarlo.\"\n\n#. ($url->host)\n#: lib/Lstu/Plugin/Helpers.pm:164\nmsgid \"The URL you want to shorten comes from a domain (%1) that is blacklisted on this server (usually because of spammers that use this domain).\"\nmsgstr \"\"\n\"La URL que desea acortar proviene de un dominio (%1) que está en la lista \"\n\"negra de este servidor (generalmente debido a los spammers que usan este \"\n\"dominio).\"\n\n#. ($c->url_for('/')\n#: lib/Lstu/Controller/Admin.pm:131 lib/Lstu/Controller/Stats.pm:184 lib/Lstu/Controller/URL.pm:229\nmsgid \"The shortened URL %1 doesn't exist.\"\nmsgstr \"La URL acortada %1 no existe.\"\n\n#. ($url)\n#: lib/Lstu/Controller/URL.pm:59\nmsgid \"The shortened text can't be \\\"a\\\", \\\"api\\\", \\\"d\\\", \\\"cookie\\\", \\\"stats\\\", \\\"fullstats\\\", \\\"login\\\" or \\\"logout\\\" or end with \\\".json\\\". Your URL to shorten: %1\"\nmsgstr \"\"\n\"El texto abreviado no puede ser \\\"a\\\", \\\"api\\\", \\\"d\\\", \\\"cookie\\\", \\\"stats\\\"\"\n\", \\\"fullstats\\\", \\\"login\\\" o \\\"logout\\\" o finalizar con \\\".json\\\". Su URL \"\n\"para acortar: %1\"\n\n#: themes/default/templates/api.html.ep:113\nmsgid \"To do an admin login, set it to the password defined in the settings (\\\"adminpwd\\\" or \\\"hashed_adminpwd\\\")\"\nmsgstr \"\"\n\"Para hacer un inicio de sesión de administrador, configúrelo con la \"\n\"contraseña definida en la configuración (\\\"adminpwd\\\" o \\\"hashed_adminpwd\\\")\"\n\n#: themes/default/templates/api.html.ep:114\nmsgid \"To do an admin logout, set it to \\\"logout\\\".\"\nmsgstr \"\"\n\"Para hacer un cierre de sesión de administrador, configúrelo en \\\"cerrar \"\n\"sesión\\\".\"\n\n#: lib/Lstu/Controller/Admin.pm:29\nmsgid \"Too many bad passwords. You're banned.\"\nmsgstr \"Demasiadas contraseñas malas. Estás prohibido.\"\n\n#: themes/default/templates/api.html.ep:104 themes/default/templates/api.html.ep:95 themes/default/templates/stats.html.ep:44\nmsgid \"URL\"\nmsgstr \"URL\"\n\n#: themes/default/templates/api.html.ep:43 themes/default/templates/index.html.ep:5 themes/default/templates/index.html.ep:6\nmsgid \"URL to shorten\"\nmsgstr \"URL para acortar\"\n\n#. ($penalty/3600)\n#: lib/Lstu/Controller/URL.pm:35\nmsgid \"You asked to shorten too many URLs too quickly. You're banned for %1 hour(s).\"\nmsgstr \"\"\n\"Solicitó acortar demasiadas URL demasiado rápido. Estás prohibido por %1 \"\n\"hora (s).\"\n\n#: lib/Lstu/Controller/Admin.pm:52 lib/Lstu/Controller/Authent.pm:26 themes/default/templates/api.html.ep:121 themes/default/templates/api.html.ep:17\nmsgid \"You have been successfully logged in.\"\nmsgstr \"Has ingresado exitosamente.\"\n\n#: lib/Lstu/Controller/Admin.pm:73 lib/Lstu/Controller/Authent.pm:65 themes/default/templates/api.html.ep:129 themes/default/templates/api.html.ep:31 themes/default/templates/logout.html.ep:3\nmsgid \"You have been successfully logged out.\"\nmsgstr \"Ha sido desconectado exitosamente.\"\n\n#: themes/default/templates/api.html.ep:137\nmsgid \"You must be logged in as admin (\\\"adminpwd\\\" or \\\"hashed_adminpwd\\\" setting) to use it.\"\nmsgstr \"\"\n\"Debe iniciar sesión como administrador (configuración \\\"adminpwd\\\" o \\\"\"\n\"hashed_adminpwd\\\") para usarlo.\"\n\n#: themes/default/templates/api.html.ep:39 themes/default/templates/api.html.ep:77\nmsgid \"You must be logged in to use it.\"\nmsgstr \"Debe iniciar sesión para usarlo.\"\n\n#: themes/default/templates/api.html.ep:130\nmsgid \"You will be redirected to Lstu statistics page\"\nmsgstr \"Serás redirigido a la página de estadísticas de Lstu\"\n\n#: themes/default/templates/api.html.ep:146\nmsgid \"You will be redirected to Lstu statistics page with a message in case of failure\"\nmsgstr \"\"\n\"Será redirigido a la página de estadísticas de Lstu con un mensaje en caso \"\n\"de falla\"\n\n#: themes/default/templates/api.html.ep:32\nmsgid \"You will be redirected to Lstu successfully logged out interface\"\nmsgstr \"Será redirigido a la interfaz de Lstu que cerró la sesión correctamente\"\n\n#: themes/default/templates/api.html.ep:19\nmsgid \"You will be redirected to the Lstu classic interface where you will be able to shorten URLs\"\nmsgstr \"\"\n\"Será redirigido a la interfaz clásica de Lstu, donde podrá acortar las URL\"\n\n#: themes/default/templates/api.html.ep:54\nmsgid \"You will be redirected to the Lstu classic interface with a message giving the shortened URL\"\nmsgstr \"\"\n\"Será redirigido a la interfaz clásica de Lstu con un mensaje con la URL \"\n\"acortada\"\n\n#: themes/default/templates/api.html.ep:62\nmsgid \"You will be redirected to the targeted URL or to the Lstu interface with a message giving the failure reason\"\nmsgstr \"\"\n\"Será redirigido a la URL de destino o a la interfaz Lstu con un mensaje que \"\n\"indique el motivo del erro\"\n\n#: themes/default/templates/api.html.ep:123\nmsgid \"You will have the statistics page with the admin stats if you're succesfully logged in, or your stats and a failure message otherwise\"\nmsgstr \"\"\n\"Tendrá la página de estadísticas con las estadísticas de administrador si ha \"\n\"iniciado sesión correctamente, o sus estadísticas y un mensaje de error de \"\n\"lo contrario\"\n\n#: lib/Lstu/Controller/Admin.pm:142\nmsgid \"You're not authenticated as the admin\"\nmsgstr \"No estás autenticado como administrado\"\n\n#: themes/default/templates/api.html.ep:11\nmsgid \"Your login\"\nmsgstr \"Tu nombre de usuario\"\n\n#: themes/default/templates/api.html.ep:12\nmsgid \"Your password\"\nmsgstr \"Tu contraseña\"\n\n#: themes/default/templates/api.html.ep:104 themes/default/templates/api.html.ep:95\nmsgid \"integer, how many unique visits of the shortened URL\"\nmsgstr \"entero, cuántas visitas únicas de la URL acortada\"\n\n#: themes/default/templates/api.html.ep:11 themes/default/templates/api.html.ep:12 themes/default/templates/api.html.ep:43\nmsgid \"mandatory\"\nmsgstr \"obligatorio\"\n\n#: themes/default/templates/api.html.ep:113 themes/default/templates/api.html.ep:114 themes/default/templates/api.html.ep:115 themes/default/templates/api.html.ep:13 themes/default/templates/api.html.ep:140 themes/default/templates/api.html.ep:27 themes/default/templates/api.html.ep:44 themes/default/templates/api.html.ep:45 themes/default/templates/api.html.ep:86 themes/default/templates/api.html.ep:88\nmsgid \"optional\"\nmsgstr \"Opcional\"\n\n#: themes/default/templates/api.html.ep:135 themes/default/templates/api.html.ep:57 themes/default/templates/api.html.ep:66 themes/default/templates/api.html.ep:92 themes/default/templates/api.html.ep:99\nmsgid \"shortened_url\"\nmsgstr \"URL_acceso-directo\"\n\n#. ($c->url_for('/')\n#: lib/Lstu/Controller/URL.pm:240\nmsgid \"The shortened URL %1 no longer exists.\"\nmsgstr \"La URL abreviada %1 ya no existe.\"\n"
  },
  {
    "path": "themes/default/lib/Lstu/I18N/fr.po",
    "content": "# Lstu\n# Copyright (C) 2013 Luc Didry\n# This file is distributed under the same license as the Lstu package.\n# \n# Translators:\n# Luc Didry <luc@didry.org>, 2015\n# Luc Didry <luc@framasoft.org>, 2018. #zanata\nmsgid \"\"\nmsgstr \"\"\n\"Project-Id-Version: PACKAGE VERSION\\n\"\n\"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\\n\"\n\"PO-Revision-Date: 2020-10-26 03:40+0000\\n\"\n\"Last-Translator: Gerold Rupprecht <geroldr@bluewin.ch>\\n\"\n\"Language-Team: French <https://weblate.framasoft.org/projects/lstu/\"\n\"development/fr/>\\n\"\n\"Language: fr\\n\"\n\"MIME-Version: 1.0\\n\"\n\"Content-Type: text/plain; charset=UTF-8\\n\"\n\"Content-Transfer-Encoding: 8bit\\n\"\n\"Plural-Forms: nplurals=2; plural=n > 1;\\n\"\n\"X-Generator: Weblate 4.1\\n\"\n\"X-POOTLE-MTIME: 1441357092.000000\\n\"\n\"X-Poedit-SourceCharset: UTF-8\\n\"\n\n#. ($url)\n#: lib/Lstu/Controller/URL.pm:118\nmsgid \"%1 is not a valid URL.\"\nmsgstr \"%1 n’est pas une URL valide.\"\n\n#: themes/default/templates/api.html.ep:96\nmsgid \"\"\n\"A page with a table containing the same informations that the JSON response\"\nmsgstr \"\"\n\"Une page avec un tableau contenant les mêmes informations que le message JSON\"\n\n#: themes/default/templates/layouts/default.html.ep:38\nmsgid \"About\"\nmsgstr \"À propos\"\n\n#: themes/default/templates/stats.html.ep:13 themes/default/templates/stats.html.ep:14\nmsgid \"Admin password\"\nmsgstr \"Mot de passe administrateur\"\n\n#: lib/Lstu/Controller/Admin.pm:87 themes/default/templates/api.html.ep:122\nmsgid \"Bad password\"\nmsgstr \"Mot de passe incorrect\"\n\n#: themes/default/templates/index.html.ep:21\nmsgid \"Copy to clipboard\"\nmsgstr \"Copier dans le presse-papier\"\n\n#: themes/default/templates/stats.html.ep:46\nmsgid \"Counter\"\nmsgstr \"Compteur\"\n\n#: themes/default/templates/stats.html.ep:47\nmsgid \"Created\"\nmsgstr \"Créé le\"\n\n#: themes/default/templates/api.html.ep:44 themes/default/templates/index.html.ep:10 themes/default/templates/index.html.ep:9\nmsgid \"Custom shortened text\"\nmsgstr \"Texte du raccourci personnalisé\"\n\n#: themes/default/templates/stats.html.ep:52\nmsgid \"Delete\"\nmsgstr \"Supprimer\"\n\n#: themes/default/templates/stats.html.ep:36\nmsgid \"Export your URLs\"\nmsgstr \"Exporter vos URL\"\n\n#: themes/default/templates/api.html.ep:105 themes/default/templates/api.html.ep:145 themes/default/templates/api.html.ep:53 themes/default/templates/api.html.ep:71\nmsgid \"Failure reason\"\nmsgstr \"Raison de l’échec\"\n\n#: lib/Lstu/Controller/Stats.pm:43\nmsgid \"File imported\"\nmsgstr \"Fichier importé\"\n\n#: themes/default/templates/api.html.ep:101\nmsgid \"\"\n\"Get the details (visit counter, creation date, etc.) of a shortened URL.\"\nmsgstr \"\"\n\"Obtenez les détails (compteur de visites, date de création, etc.) d’une URL \"\n\"raccourcie.\"\n\n#: themes/default/templates/index.html.ep:12 themes/default/templates/stats.html.ep:17\nmsgid \"Go!\"\nmsgstr \"Allons-y !\"\n\n#: themes/default/templates/partial/lstu.js.ep:30\nmsgid \"Hit Enter, then Ctrl+C to copy the short link\"\nmsgstr \"Appuyez sur Entrée puis faites Ctrl+C pour copier le lien\"\n\n#: themes/default/templates/stats.html.ep:89\nmsgid \"Home\"\nmsgstr \"Accueil\"\n\n#: themes/default/templates/api.html.ep:126\nmsgid \"If \\\"action\\\" is defined to \\\"logout\\\":\"\nmsgstr \"Si \\\"action\\\" est définie à \\\"logout\\\" :\"\n\n#: themes/default/templates/api.html.ep:119\nmsgid \"If \\\"adminpwd\\\" is defined:\"\nmsgstr \"Si \\\"adminpwd\\\" est défini :\"\n\n#: themes/default/templates/api.html.ep:115 themes/default/templates/api.html.ep:13 themes/default/templates/api.html.ep:140 themes/default/templates/api.html.ep:27 themes/default/templates/api.html.ep:45 themes/default/templates/api.html.ep:88\nmsgid \"\"\n\"If equal to \\\"json\\\", response will be in JSON format, HTML format otherwise\"\nmsgstr \"\"\n\"Si égal à \\\"json\\\", la réponse sera au format JSON, sinon ce sera une \"\n\"réponse en HTML\"\n\n#. (config('page_offset')\n#: themes/default/templates/api.html.ep:81\nmsgid \"\"\n\"If you are logged in as admin (\\\"adminpwd\\\" or \\\"hashed_adminpwd\\\" setting), \"\n\"it will give you statistics for all URLs, sorted by the most visited first, \"\n\"paginated with pages containing %1 records.\"\nmsgstr \"\"\n\"Si vous êtes connecté·e en tant qu’admin (paramètre \\\"adminpwd\\\" ou \"\n\"\\\"hashed_adminpwd\\\"), cela vous donnera les statistiques pour toutes les \"\n\"URL, triées selon le nombre de visites en ordre décroissant, de façon \"\n\"paginée avec des pages contenant %1 enregistrements.\"\n\n#: themes/default/templates/api.html.ep:86\nmsgid \"If you are logged in as admin, you can provide a \\\"page\\\" parameter\"\nmsgstr \"\"\n\"Si vous êtes connecté·e en tant qu’admin, vous pouvez fournir un paramètre \"\n\"\\\"page\\\"\"\n\n#: themes/default/templates/stats.html.ep:32 themes/default/templates/stats.html.ep:35\nmsgid \"Import URLs\"\nmsgstr \"Importer des URL\"\n\n#: themes/default/templates/api.html.ep:79\nmsgid \"\"\n\"It will use Lstu's cookies to know which shortened URL it will return \"\n\"statistics for.\"\nmsgstr \"\"\n\"Cela utilisera les cookies de Lstu pour savoir quelles sont les URL dont il \"\n\"faut fournir les statistiques.\"\n\n#: themes/default/templates/api.html.ep:105 themes/default/templates/api.html.ep:122 themes/default/templates/api.html.ep:145 themes/default/templates/api.html.ep:18 themes/default/templates/api.html.ep:53 themes/default/templates/api.html.ep:71\nmsgid \"JSON: failure\"\nmsgstr \"JSON : échec\"\n\n#: themes/default/templates/api.html.ep:104 themes/default/templates/api.html.ep:121 themes/default/templates/api.html.ep:129 themes/default/templates/api.html.ep:144 themes/default/templates/api.html.ep:17 themes/default/templates/api.html.ep:31 themes/default/templates/api.html.ep:52 themes/default/templates/api.html.ep:70\nmsgid \"JSON: success\"\nmsgstr \"JSON : succès\"\n\n#: themes/default/templates/layouts/default.html.ep:37\nmsgid \"License:\"\nmsgstr \"Licence :\"\n\n#: themes/default/templates/login.html.ep:8\nmsgid \"Login\"\nmsgstr \"Connexion\"\n\n#: themes/default/templates/layouts/default.html.ep:43\nmsgid \"Logout\"\nmsgstr \"Déconnexion\"\n\n#: themes/default/templates/stats.html.ep:10\nmsgid \"Logout from admin stats\"\nmsgstr \"Déconnexion des stats admin\"\n\n#: themes/default/templates/stats.html.ep:84\nmsgid \"Next\"\nmsgstr \"Suivant\"\n\n#. ($c->config('contact')\n#: lib/Lstu/Controller/URL.pm:112\nmsgid \"\"\n\"No shortened URL available. Please retry or contact the administrator at %1. \"\n\"Your URL to shorten: %2\"\nmsgstr \"\"\n\"Il n’y a plus d’URL raccourcie disponible. Veuillez réessayer ou contactez \"\n\"l’administrateur sur %1. Rappel de l’URL à raccourcir : %2\"\n\n#: themes/default/templates/api.html.ep:111 themes/default/templates/api.html.ep:138 themes/default/templates/api.html.ep:25 themes/default/templates/api.html.ep:41 themes/default/templates/api.html.ep:83 themes/default/templates/api.html.ep:9\nmsgid \"Parameters:\"\nmsgstr \"Paramètres :\"\n\n#: themes/default/templates/login.html.ep:12\nmsgid \"Password\"\nmsgstr \"Mot de passe\"\n\n#: lib/Lstu/Controller/Authent.pm:35 themes/default/templates/api.html.ep:18\nmsgid \"Please, check your credentials: unable to authenticate.\"\nmsgstr \"Impossible de s’authentifier, veuillez vérifier vos identifiants.\"\n\n#: themes/default/templates/stats.html.ep:82\nmsgid \"Previous\"\nmsgstr \"Précédent\"\n\n#: themes/default/templates/stats.html.ep:50\nmsgid \"QRCode\"\nmsgstr \"QRCode\"\n\n#: themes/default/templates/api.html.ep:123 themes/default/templates/api.html.ep:130 themes/default/templates/api.html.ep:146 themes/default/templates/api.html.ep:19 themes/default/templates/api.html.ep:32 themes/default/templates/api.html.ep:54 themes/default/templates/api.html.ep:96\nmsgid \"Response for HTML format\"\nmsgstr \"Réponse pour le format HTML\"\n\n#: themes/default/templates/api.html.ep:95\nmsgid \"Response for JSON format\"\nmsgstr \"Réponse pour le format JSON\"\n\n#: themes/default/templates/api.html.ep:102 themes/default/templates/api.html.ep:117 themes/default/templates/api.html.ep:142 themes/default/templates/api.html.ep:15 themes/default/templates/api.html.ep:29 themes/default/templates/api.html.ep:47 themes/default/templates/api.html.ep:59 themes/default/templates/api.html.ep:68 themes/default/templates/api.html.ep:90\nmsgid \"Response:\"\nmsgstr \"Réponse :\"\n\n#: themes/default/templates/stats.html.ep:45\nmsgid \"Shortened URL\"\nmsgstr \"URL raccourcie\"\n\n#: themes/default/templates/api.html.ep:127 themes/default/templates/api.html.ep:24\nmsgid \"Should always be successful\"\nmsgstr \"Devrait toujours retourner un succès\"\n\n#: themes/default/templates/layouts/default.html.ep:45 themes/default/templates/login.html.ep:16 themes/default/templates/logout.html.ep:5\nmsgid \"Signin\"\nmsgstr \"Connexion\"\n\n#: lib/Lstu/Controller/Stats.pm:45\nmsgid \"Sorry, unable to parse the provided file\"\nmsgstr \"Désolé, impossible d’analyser le fichier fourni\"\n\n#: themes/default/templates/layouts/default.html.ep:42 themes/default/templates/layouts/default.html.ep:48 themes/default/templates/stats.html.ep:4\nmsgid \"Statistics\"\nmsgstr \"Statistiques\"\n\n#. ($url->host)\n#: lib/Lstu/Plugin/Helpers.pm:172\nmsgid \"\"\n\"The URL host or one of its redirection(s) (%1) is blacklisted at Spamhaus. I \"\n\"refuse to shorten it.\"\nmsgstr \"\"\n\"L'hôte de l'URL ou d'une de ses redirections (%1) est considéré comme nocif \"\n\"par Spamhaus. Je refuse de la raccourcir.\"\n\n#. ($url)\n#: lib/Lstu/Plugin/Helpers.pm:178\nmsgid \"\"\n\"The URL or one of its redirection(s) (%1) is blacklisted in Google Safe \"\n\"Browsing database. I refuse to shorten it.\"\nmsgstr \"\"\n\"L’URL ou l’une de ses redirections (%1) est blacklistée dans la base de \"\n\"données Google Safe Browsing. Je refuse de la raccourcir.\"\n\n#. ($c->config('max_redir')\n#: lib/Lstu/Plugin/Helpers.pm:194\nmsgid \"\"\n\"The URL redirects %1 times or most. It's most likely a dangerous URL (spam, \"\n\"phishing, etc.). I refuse to shorten it.\"\nmsgstr \"\"\n\"L'URL redirige %1 fois ou plus vers un autre site. Il est probable qu'il \"\n\"s'agisse d'une URL dangereuse (pourriel, hameçonnage, etc.). Je refuse de la \"\n\"raccourcir.\"\n\n#. ($url->host)\n#: lib/Lstu/Plugin/Helpers.pm:164\nmsgid \"\"\n\"The URL you want to shorten comes from a domain (%1) that is blacklisted on \"\n\"this server (usually because of spammers that use this domain).\"\nmsgstr \"\"\n\"L’URL que vous souhaitez raccourcir provient d’un domaine (%1) qui est \"\n\"interdit sur ce serveur (généralement à cause de spammeurs qui utilisent ce \"\n\"domaine).\"\n\n#. ($c->url_for('/')\n#: lib/Lstu/Controller/Admin.pm:131 lib/Lstu/Controller/Stats.pm:184 lib/Lstu/Controller/URL.pm:226\nmsgid \"The shortened URL %1 doesn't exist.\"\nmsgstr \"L’URL raccourcie %1 n’existe pas.\"\n\n#. ($c->url_for('/')\n#: lib/Lstu/Controller/URL.pm:240\nmsgid \"The shortened URL %1 no longer exists.\"\nmsgstr \"L’URL raccourcie %1 n’existe plus.\"\n\n#. ($url)\n#: lib/Lstu/Controller/URL.pm:59\nmsgid \"\"\n\"The shortened text can't be \\\"a\\\", \\\"api\\\", \\\"d\\\", \\\"cookie\\\", \\\"stats\\\", \"\n\"\\\"fullstats\\\", \\\"login\\\" or \\\"logout\\\" or end with \\\".json\\\". Your URL to \"\n\"shorten: %1\"\nmsgstr \"\"\n\"Le texte du raccourci ne peut être \\\"a\\\", \\\"api\\\", \\\"d\\\", \\\"cookie\\\", \"\n\"\\\"stats\\\", \\\"fullstats\\\", \\\"login\\\" ou \\\"logout\\\" ou se terminer par \\\".\"\n\"json\\\". Rappel de l’URL à raccourcir : %1\"\n\n#: themes/default/templates/api.html.ep:113\nmsgid \"\"\n\"To do an admin login, set it to the password defined in the settings \"\n\"(\\\"adminpwd\\\" or \\\"hashed_adminpwd\\\")\"\nmsgstr \"\"\n\"Pour se connecter en tant qu’admin, mettez le mot de passe défini dans les \"\n\"paramètres de configuration (\\\"adminpwd\\\" ou \\\"hashed_adminpwd\\\")\"\n\n#: themes/default/templates/api.html.ep:114\nmsgid \"To do an admin logout, set it to \\\"logout\\\".\"\nmsgstr \"\"\n\"Pour se déconnecter de l’administration, définissez ce paramètre à \"\n\"\\\"logout\\\".\"\n\n#: lib/Lstu/Controller/Admin.pm:29\nmsgid \"Too many bad passwords. You're banned.\"\nmsgstr \"Trop de mauvais mots de passe. Vous êtes banni.\"\n\n#: themes/default/templates/api.html.ep:104 themes/default/templates/api.html.ep:95 themes/default/templates/stats.html.ep:44\nmsgid \"URL\"\nmsgstr \"URL\"\n\n#: themes/default/templates/api.html.ep:43 themes/default/templates/index.html.ep:5 themes/default/templates/index.html.ep:6\nmsgid \"URL to shorten\"\nmsgstr \"URL à raccourcir\"\n\n#. ($penalty/3600)\n#: lib/Lstu/Controller/URL.pm:35\nmsgid \"\"\n\"You asked to shorten too many URLs too quickly. You're banned for %1 hour(s).\"\n\"\"\nmsgstr \"\"\n\"Vous avez demandé à réduire trop d’URLs en trop peu de temps. Vous êtes \"\n\"banni pour %1 heure(s).\"\n\n#: lib/Lstu/Controller/Admin.pm:52 lib/Lstu/Controller/Authent.pm:26 themes/default/templates/api.html.ep:121 themes/default/templates/api.html.ep:17\nmsgid \"You have been successfully logged in.\"\nmsgstr \"Vous avez été connecté·e avec succès.\"\n\n#: lib/Lstu/Controller/Admin.pm:73 lib/Lstu/Controller/Authent.pm:65 themes/default/templates/api.html.ep:129 themes/default/templates/api.html.ep:31 themes/default/templates/logout.html.ep:3\nmsgid \"You have been successfully logged out.\"\nmsgstr \"Vous avez été déconnecté·e avec succès.\"\n\n#: themes/default/templates/api.html.ep:137\nmsgid \"\"\n\"You must be logged in as admin (\\\"adminpwd\\\" or \\\"hashed_adminpwd\\\" setting) \"\n\"to use it.\"\nmsgstr \"\"\n\"Vous devez être connecté·e en tant qu’admin (paramètre \\\"adminpwd\\\" ou \"\n\"\\\"hashed_adminpwd\\\") pour l'utiliser.\"\n\n#: themes/default/templates/api.html.ep:39 themes/default/templates/api.html.ep:77\nmsgid \"You must be logged in to use it.\"\nmsgstr \"Vous devez être connecté·e pour l’utiliser.\"\n\n#: themes/default/templates/api.html.ep:130\nmsgid \"You will be redirected to Lstu statistics page\"\nmsgstr \"Vous serez redirigé·e vers la page de statistiques de Lstu\"\n\n#: themes/default/templates/api.html.ep:146\nmsgid \"\"\n\"You will be redirected to Lstu statistics page with a message in case of \"\n\"failure\"\nmsgstr \"\"\n\"Vous serez redirigé·e vers la page de statistiques de Lstu avec un message \"\n\"en cas d’échec\"\n\n#: themes/default/templates/api.html.ep:32\nmsgid \"You will be redirected to Lstu successfully logged out interface\"\nmsgstr \"Vous serez redirigé vers l’interface de déconnexion réussie de Lstu\"\n\n#: themes/default/templates/api.html.ep:19\nmsgid \"\"\n\"You will be redirected to the Lstu classic interface where you will be able \"\n\"to shorten URLs\"\nmsgstr \"\"\n\"Vous serez redirigé vers l’interface normale de Lstu où vous pourrez \"\n\"raccourcirs des URL\"\n\n#: themes/default/templates/api.html.ep:54\nmsgid \"\"\n\"You will be redirected to the Lstu classic interface with a message giving \"\n\"the shortened URL\"\nmsgstr \"\"\n\"Vous aurez l’interface normale de Lstu avec un message indiquant l’URL \"\n\"raccourcie\"\n\n#: themes/default/templates/api.html.ep:62\nmsgid \"\"\n\"You will be redirected to the targeted URL or to the Lstu interface with a \"\n\"message giving the failure reason\"\nmsgstr \"\"\n\"Vous serez redirigé vers l’URL cible ou vers la page d’accueil de Lstu avec \"\n\"un message indiquant la raison de l’échec\"\n\n#: themes/default/templates/api.html.ep:123\nmsgid \"\"\n\"You will have the statistics page with the admin stats if you're succesfully \"\n\"logged in, or your stats and a failure message otherwise\"\nmsgstr \"\"\n\"Vous aurez la page de statistiques avec les statistiques admin si vous vous \"\n\"êtes connecté·e avec succès, ou sinon vos statistiques avec un message \"\n\"d’échec\"\n\n#: lib/Lstu/Controller/Admin.pm:142\nmsgid \"You're not authenticated as the admin\"\nmsgstr \"Vous n’êtes pas authentifié·e en tant qu’admin\"\n\n#: themes/default/templates/api.html.ep:11\nmsgid \"Your login\"\nmsgstr \"Votre identifiant\"\n\n#: themes/default/templates/api.html.ep:12\nmsgid \"Your password\"\nmsgstr \"Votre mot de passe\"\n\n#: themes/default/templates/api.html.ep:104 themes/default/templates/api.html.ep:95\nmsgid \"integer, how many unique visits of the shortened URL\"\nmsgstr \"entier, combien de visites uniques a reçu l'URL raccourcie\"\n\n#: themes/default/templates/api.html.ep:11 themes/default/templates/api.html.ep:12 themes/default/templates/api.html.ep:43\nmsgid \"mandatory\"\nmsgstr \"obligatoire\"\n\n#: themes/default/templates/api.html.ep:113 themes/default/templates/api.html.ep:114 themes/default/templates/api.html.ep:115 themes/default/templates/api.html.ep:13 themes/default/templates/api.html.ep:140 themes/default/templates/api.html.ep:27 themes/default/templates/api.html.ep:44 themes/default/templates/api.html.ep:45 themes/default/templates/api.html.ep:86 themes/default/templates/api.html.ep:88\nmsgid \"optional\"\nmsgstr \"facultatif\"\n\n#: themes/default/templates/api.html.ep:135 themes/default/templates/api.html.ep:57 themes/default/templates/api.html.ep:66 themes/default/templates/api.html.ep:92 themes/default/templates/api.html.ep:99\nmsgid \"shortened_url\"\nmsgstr \"url_raccourcie\"\n"
  },
  {
    "path": "themes/default/lib/Lstu/I18N/fr_FR.po",
    "content": "# Lstu\n# Copyright (C) 2013 Luc Didry\n# This file is distributed under the same license as the Lstu package.\n# \n# Translators:\n# Luc Didry <luc@didry.org>, 2015\n# Luc Didry <luc@framasoft.org>, 2018. #zanata\nmsgid \"\"\nmsgstr \"\"\n\"Project-Id-Version: PACKAGE VERSION\\n\"\n\"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\\n\"\n\"PO-Revision-Date: 2019-11-08 11:07+0000\\n\"\n\"Last-Translator: Framasoft <tech-sys@framalistes.org>\\n\"\n\"Language-Team: French (France) <https://weblate.framasoft.org/projects/lstu/\"\n\"master/fr_FR/>\\n\"\n\"Language: fr_FR\\n\"\n\"MIME-Version: 1.0\\n\"\n\"Content-Type: text/plain; charset=UTF-8\\n\"\n\"Content-Transfer-Encoding: 8bit\\n\"\n\"Plural-Forms: nplurals=2; plural=n > 1;\\n\"\n\"X-Generator: Weblate 3.9.1\\n\"\n\"X-POOTLE-MTIME: 1441357092.000000\\n\"\n\"X-Poedit-SourceCharset: UTF-8\\n\"\n\n#. ($url)\n#: lib/Lstu/Controller/URL.pm:118\nmsgid \"%1 is not a valid URL.\"\nmsgstr \"%1 n’est pas une URL valide.\"\n\n#: themes/default/templates/api.html.ep:96\nmsgid \"\"\n\"A page with a table containing the same informations that the JSON response\"\nmsgstr \"\"\n\"Une page avec un tableau contenant les mêmes informations que le message JSON\"\n\n#: themes/default/templates/layouts/default.html.ep:38\nmsgid \"About\"\nmsgstr \"À propos\"\n\n#: themes/default/templates/stats.html.ep:13 themes/default/templates/stats.html.ep:14\nmsgid \"Admin password\"\nmsgstr \"Mot de passe administrateur\"\n\n#: lib/Lstu/Controller/Admin.pm:87 themes/default/templates/api.html.ep:122\nmsgid \"Bad password\"\nmsgstr \"Mot de passe incorrect\"\n\n#: themes/default/templates/index.html.ep:21\nmsgid \"Copy to clipboard\"\nmsgstr \"Copier dans le presse-papier\"\n\n#: themes/default/templates/stats.html.ep:46\nmsgid \"Counter\"\nmsgstr \"Compteur\"\n\n#: themes/default/templates/stats.html.ep:47\nmsgid \"Created\"\nmsgstr \"Créé le\"\n\n#: themes/default/templates/api.html.ep:44 themes/default/templates/index.html.ep:10 themes/default/templates/index.html.ep:9\nmsgid \"Custom shortened text\"\nmsgstr \"Texte du raccourci personnalisé\"\n\n#: themes/default/templates/stats.html.ep:52\nmsgid \"Delete\"\nmsgstr \"Supprimer\"\n\n#: themes/default/templates/stats.html.ep:36\nmsgid \"Export your URLs\"\nmsgstr \"Exporter vos URL\"\n\n#: themes/default/templates/api.html.ep:105 themes/default/templates/api.html.ep:145 themes/default/templates/api.html.ep:53 themes/default/templates/api.html.ep:71\nmsgid \"Failure reason\"\nmsgstr \"Raison de l’échec\"\n\n#: lib/Lstu/Controller/Stats.pm:43\nmsgid \"File imported\"\nmsgstr \"Fichier importé\"\n\n#: themes/default/templates/api.html.ep:101\nmsgid \"\"\n\"Get the details (visit counter, creation date, etc.) of a shortened URL.\"\nmsgstr \"\"\n\"Obtenez les détails (compteur de visites, date de création, etc.) d’une URL \"\n\"raccourcie.\"\n\n#: themes/default/templates/index.html.ep:12 themes/default/templates/stats.html.ep:17\nmsgid \"Go!\"\nmsgstr \"Allons-y !\"\n\n#: themes/default/templates/partial/lstu.js.ep:30\nmsgid \"Hit Enter, then Ctrl+C to copy the short link\"\nmsgstr \"Appuyez sur Entrée puis faites Ctrl+C pour copier le lien\"\n\n#: themes/default/templates/stats.html.ep:89\nmsgid \"Home\"\nmsgstr \"Accueil\"\n\n#: themes/default/templates/api.html.ep:126\nmsgid \"If \\\"action\\\" is defined to \\\"logout\\\":\"\nmsgstr \"Si \\\"action\\\" est définie à \\\"logout\\\" :\"\n\n#: themes/default/templates/api.html.ep:119\nmsgid \"If \\\"adminpwd\\\" is defined:\"\nmsgstr \"Si \\\"adminpwd\\\" est défini :\"\n\n#: themes/default/templates/api.html.ep:115 themes/default/templates/api.html.ep:13 themes/default/templates/api.html.ep:140 themes/default/templates/api.html.ep:27 themes/default/templates/api.html.ep:45 themes/default/templates/api.html.ep:88\nmsgid \"\"\n\"If equal to \\\"json\\\", response will be in JSON format, HTML format otherwise\"\nmsgstr \"\"\n\"Si égal à \\\"json\\\", la réponse sera au format JSON, sinon ce sera une \"\n\"réponse en HTML\"\n\n#. (config('page_offset')\n#: themes/default/templates/api.html.ep:81\nmsgid \"\"\n\"If you are logged in as admin (\\\"adminpwd\\\" or \\\"hashed_adminpwd\\\" setting), \"\n\"it will give you statistics for all URLs, sorted by the most visited first, \"\n\"paginated with pages containing %1 records.\"\nmsgstr \"\"\n\"Si vous êtes connecté·e en tant qu’admin (paramètre \\\"adminpwd\\\" ou \"\n\"\\\"hashed_adminpwd\\\"), cela vous donnera les statistiques pour toutes les \"\n\"URL, triées selon le nombre de visites en ordre décroissant, de façon \"\n\"paginée avec des pages contenant %1 enregistrements.\"\n\n#: themes/default/templates/api.html.ep:86\nmsgid \"If you are logged in as admin, you can provide a \\\"page\\\" parameter\"\nmsgstr \"\"\n\"Si vous êtes connecté·e en tant qu’admin, vous pouvez fournir un paramètre \"\n\"\\\"page\\\"\"\n\n#: themes/default/templates/stats.html.ep:32 themes/default/templates/stats.html.ep:35\nmsgid \"Import URLs\"\nmsgstr \"Importer des URL\"\n\n#: themes/default/templates/api.html.ep:79\nmsgid \"\"\n\"It will use Lstu's cookies to know which shortened URL it will return \"\n\"statistics for.\"\nmsgstr \"\"\n\"Cela utilisera les cookies de Lstu pour savoir quelles sont les URL dont il \"\n\"faut fournir les statistiques.\"\n\n#: themes/default/templates/api.html.ep:105 themes/default/templates/api.html.ep:122 themes/default/templates/api.html.ep:145 themes/default/templates/api.html.ep:18 themes/default/templates/api.html.ep:53 themes/default/templates/api.html.ep:71\nmsgid \"JSON: failure\"\nmsgstr \"JSON : échec\"\n\n#: themes/default/templates/api.html.ep:104 themes/default/templates/api.html.ep:121 themes/default/templates/api.html.ep:129 themes/default/templates/api.html.ep:144 themes/default/templates/api.html.ep:17 themes/default/templates/api.html.ep:31 themes/default/templates/api.html.ep:52 themes/default/templates/api.html.ep:70\nmsgid \"JSON: success\"\nmsgstr \"JSON : succès\"\n\n#: themes/default/templates/layouts/default.html.ep:37\nmsgid \"License:\"\nmsgstr \"Licence :\"\n\n#: themes/default/templates/login.html.ep:8\nmsgid \"Login\"\nmsgstr \"Connexion\"\n\n#: themes/default/templates/layouts/default.html.ep:43\nmsgid \"Logout\"\nmsgstr \"Déconnexion\"\n\n#: themes/default/templates/stats.html.ep:10\nmsgid \"Logout from admin stats\"\nmsgstr \"Déconnexion des stats admin\"\n\n#: themes/default/templates/stats.html.ep:84\nmsgid \"Next\"\nmsgstr \"Suivant\"\n\n#. ($c->config('contact')\n#: lib/Lstu/Controller/URL.pm:112\nmsgid \"\"\n\"No shortened URL available. Please retry or contact the administrator at %1. \"\n\"Your URL to shorten: %2\"\nmsgstr \"\"\n\"Il n’y a plus d’URL raccourcie disponible. Veuillez réessayer ou contactez \"\n\"l’administrateur sur %1. Rappel de l’URL à raccourcir : %2\"\n\n#: themes/default/templates/api.html.ep:111 themes/default/templates/api.html.ep:138 themes/default/templates/api.html.ep:25 themes/default/templates/api.html.ep:41 themes/default/templates/api.html.ep:83 themes/default/templates/api.html.ep:9\nmsgid \"Parameters:\"\nmsgstr \"Paramètres :\"\n\n#: themes/default/templates/login.html.ep:12\nmsgid \"Password\"\nmsgstr \"Mot de passe\"\n\n#: lib/Lstu/Controller/Authent.pm:35 themes/default/templates/api.html.ep:18\nmsgid \"Please, check your credentials: unable to authenticate.\"\nmsgstr \"Impossible de s’authentifier, veuillez vérifier vos identifiants.\"\n\n#: themes/default/templates/stats.html.ep:82\nmsgid \"Previous\"\nmsgstr \"Précédent\"\n\n#: themes/default/templates/stats.html.ep:50\nmsgid \"QRCode\"\nmsgstr \"QRCode\"\n\n#: themes/default/templates/api.html.ep:123 themes/default/templates/api.html.ep:130 themes/default/templates/api.html.ep:146 themes/default/templates/api.html.ep:19 themes/default/templates/api.html.ep:32 themes/default/templates/api.html.ep:54 themes/default/templates/api.html.ep:96\nmsgid \"Response for HTML format\"\nmsgstr \"Réponse pour le format HTML\"\n\n#: themes/default/templates/api.html.ep:95\nmsgid \"Response for JSON format\"\nmsgstr \"Réponse pour le format JSON\"\n\n#: themes/default/templates/api.html.ep:102 themes/default/templates/api.html.ep:117 themes/default/templates/api.html.ep:142 themes/default/templates/api.html.ep:15 themes/default/templates/api.html.ep:29 themes/default/templates/api.html.ep:47 themes/default/templates/api.html.ep:59 themes/default/templates/api.html.ep:68 themes/default/templates/api.html.ep:90\nmsgid \"Response:\"\nmsgstr \"Réponse :\"\n\n#: themes/default/templates/stats.html.ep:45\nmsgid \"Shortened URL\"\nmsgstr \"URL raccourcie\"\n\n#: themes/default/templates/api.html.ep:127 themes/default/templates/api.html.ep:24\nmsgid \"Should always be successful\"\nmsgstr \"Devrait toujours retourner un succès\"\n\n#: themes/default/templates/layouts/default.html.ep:45 themes/default/templates/login.html.ep:16 themes/default/templates/logout.html.ep:5\nmsgid \"Signin\"\nmsgstr \"Connexion\"\n\n#: lib/Lstu/Controller/Stats.pm:45\nmsgid \"Sorry, unable to parse the provided file\"\nmsgstr \"Désolé, impossible d’analyser le fichier fourni\"\n\n#: themes/default/templates/layouts/default.html.ep:42 themes/default/templates/layouts/default.html.ep:48 themes/default/templates/stats.html.ep:4\nmsgid \"Statistics\"\nmsgstr \"Statistiques\"\n\n#. ($url->host)\n#: lib/Lstu/Plugin/Helpers.pm:172\nmsgid \"\"\n\"The URL host or one of its redirection(s) (%1) is blacklisted at Spamhaus. I \"\n\"refuse to shorten it.\"\nmsgstr \"\"\n\"L'hôte de l'URL ou d'une de ses redirections (%1) est considéré comme nocif \"\n\"par Spamhaus. Je refuse de la raccourcir.\"\n\n#. ($url)\n#: lib/Lstu/Plugin/Helpers.pm:178\nmsgid \"\"\n\"The URL or one of its redirection(s) (%1) is blacklisted in Google Safe \"\n\"Browsing database. I refuse to shorten it.\"\nmsgstr \"\"\n\"L’URL ou l’une de ses redirections (%1) est blacklistée dans la base de \"\n\"données Google Safe Browsing. Je refuse de la raccourcir.\"\n\n#. ($c->config('max_redir')\n#: lib/Lstu/Plugin/Helpers.pm:194\nmsgid \"\"\n\"The URL redirects %1 times or most. It's most likely a dangerous URL (spam, \"\n\"phishing, etc.). I refuse to shorten it.\"\nmsgstr \"\"\n\"L'URL redirige %1 fois ou plus vers un autre site. Il est probable qu'il \"\n\"s'agisse d'une URL dangereuse (pourriel, hameçonnage, etc.). Je refuse de la \"\n\"raccourcir.\"\n\n#. ($url->host)\n#: lib/Lstu/Plugin/Helpers.pm:164\nmsgid \"\"\n\"The URL you want to shorten comes from a domain (%1) that is blacklisted on \"\n\"this server (usually because of spammers that use this domain).\"\nmsgstr \"\"\n\"L’URL que vous souhaitez raccourcir provient d’un domaine (%1) qui est \"\n\"interdit sur ce serveur (généralement à cause de spammeurs qui utilisent ce \"\n\"domaine).\"\n\n#. ($c->url_for('/')\n#: lib/Lstu/Controller/Admin.pm:131 lib/Lstu/Controller/Stats.pm:184 lib/Lstu/Controller/URL.pm:226\nmsgid \"The shortened URL %1 doesn't exist.\"\nmsgstr \"L’URL raccourcie %1 n’existe pas.\"\n\n#. ($c->url_for('/')\n#: lib/Lstu/Controller/URL.pm:240\nmsgid \"The shortened URL %1 no longer exists.\"\nmsgstr \"L’URL raccourcie %1 n’existe plus.\"\n\n#. ($url)\n#: lib/Lstu/Controller/URL.pm:59\nmsgid \"\"\n\"The shortened text can't be \\\"a\\\", \\\"api\\\", \\\"d\\\", \\\"cookie\\\", \\\"stats\\\", \"\n\"\\\"fullstats\\\", \\\"login\\\" or \\\"logout\\\" or end with \\\".json\\\". Your URL to \"\n\"shorten: %1\"\nmsgstr \"\"\n\"Le texte du raccourci ne peut être \\\"a\\\", \\\"api\\\", \\\"d\\\", \\\"cookie\\\", \"\n\"\\\"stats\\\", \\\"fullstats\\\", \\\"login\\\" ou \\\"logout\\\" ou se terminer par \\\".\"\n\"json\\\". Rappel de l’URL à raccourcir : %1\"\n\n#: themes/default/templates/api.html.ep:113\nmsgid \"\"\n\"To do an admin login, set it to the password defined in the settings \"\n\"(\\\"adminpwd\\\" or \\\"hashed_adminpwd\\\")\"\nmsgstr \"\"\n\"Pour se connecter en tant qu’admin, mettez le mot de passe défini dans les \"\n\"paramètres de configuration (\\\"adminpwd\\\" ou \\\"hashed_adminpwd\\\")\"\n\n#: themes/default/templates/api.html.ep:114\nmsgid \"To do an admin logout, set it to \\\"logout\\\".\"\nmsgstr \"\"\n\"Pour se déconnecter de l’administration, définissez ce paramètre à \"\n\"\\\"logout\\\".\"\n\n#: lib/Lstu/Controller/Admin.pm:29\nmsgid \"Too many bad passwords. You're banned.\"\nmsgstr \"Trop de mauvais mots de passe. Vous êtes banni.\"\n\n#: themes/default/templates/api.html.ep:104 themes/default/templates/api.html.ep:95 themes/default/templates/stats.html.ep:44\nmsgid \"URL\"\nmsgstr \"URL\"\n\n#: themes/default/templates/api.html.ep:43 themes/default/templates/index.html.ep:5 themes/default/templates/index.html.ep:6\nmsgid \"URL to shorten\"\nmsgstr \"URL à raccourcir\"\n\n#. ($penalty/3600)\n#: lib/Lstu/Controller/URL.pm:35\nmsgid \"\"\n\"You asked to shorten too many URLs too quickly. You're banned for %1 hour(s).\"\n\"\"\nmsgstr \"\"\n\"Vous avez demandé à réduire trop d’URLs en trop peu de temps. Vous êtes \"\n\"banni pour %1 heure(s).\"\n\n#: lib/Lstu/Controller/Admin.pm:52 lib/Lstu/Controller/Authent.pm:26 themes/default/templates/api.html.ep:121 themes/default/templates/api.html.ep:17\nmsgid \"You have been successfully logged in.\"\nmsgstr \"Vous avez été connecté·e avec succès.\"\n\n#: lib/Lstu/Controller/Admin.pm:73 lib/Lstu/Controller/Authent.pm:65 themes/default/templates/api.html.ep:129 themes/default/templates/api.html.ep:31 themes/default/templates/logout.html.ep:3\nmsgid \"You have been successfully logged out.\"\nmsgstr \"Vous avez été déconnecté·e avec succès.\"\n\n#: themes/default/templates/api.html.ep:137\nmsgid \"\"\n\"You must be logged in as admin (\\\"adminpwd\\\" or \\\"hashed_adminpwd\\\" setting) \"\n\"to use it.\"\nmsgstr \"\"\n\"Vous devez être connecté·e en tant qu’admin (paramètre \\\"adminpwd\\\" ou \"\n\"\\\"hashed_adminpwd\\\") pour l'utiliser.\"\n\n#: themes/default/templates/api.html.ep:39 themes/default/templates/api.html.ep:77\nmsgid \"You must be logged in to use it.\"\nmsgstr \"Vous devez être connecté·e pour l’utiliser.\"\n\n#: themes/default/templates/api.html.ep:130\nmsgid \"You will be redirected to Lstu statistics page\"\nmsgstr \"Vous serez redirigé·e vers la page de statistiques de Lstu\"\n\n#: themes/default/templates/api.html.ep:146\nmsgid \"\"\n\"You will be redirected to Lstu statistics page with a message in case of \"\n\"failure\"\nmsgstr \"\"\n\"Vous serez redirigé·e vers la page de statistiques de Lstu avec un message \"\n\"en cas d’échec\"\n\n#: themes/default/templates/api.html.ep:32\nmsgid \"You will be redirected to Lstu successfully logged out interface\"\nmsgstr \"Vous serez redirigé vers l’interface de déconnexion réussie de Lstu\"\n\n#: themes/default/templates/api.html.ep:19\nmsgid \"\"\n\"You will be redirected to the Lstu classic interface where you will be able \"\n\"to shorten URLs\"\nmsgstr \"\"\n\"Vous serez redirigé vers l’interface normale de Lstu où vous pourrez \"\n\"raccourcirs des URL\"\n\n#: themes/default/templates/api.html.ep:54\nmsgid \"\"\n\"You will be redirected to the Lstu classic interface with a message giving \"\n\"the shortened URL\"\nmsgstr \"\"\n\"Vous aurez l’interface normale de Lstu avec un message indiquant l’URL \"\n\"raccourcie\"\n\n#: themes/default/templates/api.html.ep:62\nmsgid \"\"\n\"You will be redirected to the targeted URL or to the Lstu interface with a \"\n\"message giving the failure reason\"\nmsgstr \"\"\n\"Vous serez redirigé vers l’URL cible ou vers la page d’accueil de Lstu avec \"\n\"un message indiquant la raison de l’échec\"\n\n#: themes/default/templates/api.html.ep:123\nmsgid \"\"\n\"You will have the statistics page with the admin stats if you're succesfully \"\n\"logged in, or your stats and a failure message otherwise\"\nmsgstr \"\"\n\"Vous aurez la page de statistiques avec les statistiques admin si vous vous \"\n\"êtes connecté·e avec succès, ou sinon vos statistiques avec un message \"\n\"d’échec\"\n\n#: lib/Lstu/Controller/Admin.pm:142\nmsgid \"You're not authenticated as the admin\"\nmsgstr \"Vous n’êtes pas authentifié·e en tant qu’admin\"\n\n#: themes/default/templates/api.html.ep:11\nmsgid \"Your login\"\nmsgstr \"Votre identifiant\"\n\n#: themes/default/templates/api.html.ep:12\nmsgid \"Your password\"\nmsgstr \"Votre mot de passe\"\n\n#: themes/default/templates/api.html.ep:104 themes/default/templates/api.html.ep:95\nmsgid \"integer, how many unique visits of the shortened URL\"\nmsgstr \"entier, combien de visites uniques a reçu l'URL raccourcie\"\n\n#: themes/default/templates/api.html.ep:11 themes/default/templates/api.html.ep:12 themes/default/templates/api.html.ep:43\nmsgid \"mandatory\"\nmsgstr \"obligatoire\"\n\n#: themes/default/templates/api.html.ep:113 themes/default/templates/api.html.ep:114 themes/default/templates/api.html.ep:115 themes/default/templates/api.html.ep:13 themes/default/templates/api.html.ep:140 themes/default/templates/api.html.ep:27 themes/default/templates/api.html.ep:44 themes/default/templates/api.html.ep:45 themes/default/templates/api.html.ep:86 themes/default/templates/api.html.ep:88\nmsgid \"optional\"\nmsgstr \"facultatif\"\n\n#: themes/default/templates/api.html.ep:135 themes/default/templates/api.html.ep:57 themes/default/templates/api.html.ep:66 themes/default/templates/api.html.ep:92 themes/default/templates/api.html.ep:99\nmsgid \"shortened_url\"\nmsgstr \"url_raccourcie\"\n"
  },
  {
    "path": "themes/default/lib/Lstu/I18N/hr.po",
    "content": "# SOME DESCRIPTIVE TITLE.\n# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER\n# This file is distributed under the same license as the PACKAGE package.\n# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.\n#\nmsgid \"\"\nmsgstr \"\"\n\"Project-Id-Version: PACKAGE VERSION\\n\"\n\"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\\n\"\n\"PO-Revision-Date: 2022-07-26 23:36+0000\\n\"\n\"Last-Translator: Milo Ivir <mail@milotype.de>\\n\"\n\"Language-Team: Croatian <https://weblate.framasoft.org/projects/lstu/\"\n\"development/hr/>\\n\"\n\"Language: hr\\n\"\n\"MIME-Version: 1.0\\n\"\n\"Content-Type: text/plain; charset=UTF-8\\n\"\n\"Content-Transfer-Encoding: 8bit\\n\"\n\"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n\"\n\"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\\n\"\n\"X-Generator: Weblate 4.13.1\\n\"\n\n#. ($url)\n#: lib/Lstu/Controller/URL.pm:136\nmsgid \"%1 is not a valid URL.\"\nmsgstr \"%1 nije valjani URL.\"\n\n#: themes/default/templates/api.html.ep:104\nmsgid \"A page with a table containing the same informations that the JSON response\"\nmsgstr \"Stranica s tablicom koja sadrži iste informacije kao JSON odgovor\"\n\n#: themes/default/templates/layouts/default.html.ep:56\nmsgid \"About\"\nmsgstr \"Podaci\"\n\n#: themes/default/templates/stats.html.ep:18 themes/default/templates/stats.html.ep:19\nmsgid \"Admin password\"\nmsgstr \"Administratorska lozinka\"\n\n#: lib/Lstu/Controller/Admin.pm:87 themes/default/templates/api.html.ep:130\nmsgid \"Bad password\"\nmsgstr \"Kriva lozinka\"\n\n#: themes/default/templates/layouts/default.html.ep:68\nmsgid \"Browser extensions\"\nmsgstr \"Proširenja preglednika\"\n\n#: themes/default/templates/index.html.ep:22\nmsgid \"Copy to clipboard\"\nmsgstr \"Kopiraj u međuspremnik\"\n\n#: themes/default/templates/stats.html.ep:62 themes/default/templates/stats.html.ep:78\nmsgid \"Counter\"\nmsgstr \"Brojač\"\n\n#: themes/default/templates/stats.html.ep:67 themes/default/templates/stats.html.ep:81\nmsgid \"Created\"\nmsgstr \"Izrađeno\"\n\n#: themes/default/templates/api.html.ep:52 themes/default/templates/index.html.ep:10 themes/default/templates/index.html.ep:9\nmsgid \"Custom shortened text\"\nmsgstr \"Prilagođen skraćeni tekst\"\n\n#: themes/default/templates/stats.html.ep:88\nmsgid \"Delete\"\nmsgstr \"Brisanje\"\n\n#: themes/default/templates/stats.html.ep:41\nmsgid \"Export your URLs\"\nmsgstr \"Izvezi svoje URL-ove\"\n\n#: themes/default/templates/api.html.ep:113 themes/default/templates/api.html.ep:153 themes/default/templates/api.html.ep:61 themes/default/templates/api.html.ep:79\nmsgid \"Failure reason\"\nmsgstr \"Razlog neuspjeha\"\n\n#: lib/Lstu/Controller/Stats.pm:43\nmsgid \"File imported\"\nmsgstr \"Datoteka je uvezena\"\n\n#: themes/default/templates/api.html.ep:109\nmsgid \"Get the details (visit counter, creation date, etc.) of a shortened URL.\"\nmsgstr \"Dobij detalje (brojač posjeta, datum stvaranja itd.) skraćenog URL-a.\"\n\n#: themes/default/templates/index.html.ep:13 themes/default/templates/stats.html.ep:22\nmsgid \"Go!\"\nmsgstr \"Kreni!\"\n\n#: themes/default/templates/partial/lstu.js.ep:30\nmsgid \"Hit Enter, then Ctrl+C to copy the short link\"\nmsgstr \"Pritisni Enter, zatim Ctrl+C za kopiranje kratke poveznice\"\n\n#: themes/default/templates/stats.html.ep:125\nmsgid \"Home\"\nmsgstr \"Doma\"\n\n#: themes/default/templates/api.html.ep:134\nmsgid \"If \\\"action\\\" is defined to \\\"logout\\\":\"\nmsgstr \"Ako je „action” (radnja) definirana kao „logout” (odjava):\"\n\n#: themes/default/templates/api.html.ep:127\nmsgid \"If \\\"adminpwd\\\" is defined:\"\nmsgstr \"Ako je „adminpwd” (administratorska lozinka) definirana:\"\n\n#: themes/default/templates/api.html.ep:123 themes/default/templates/api.html.ep:148 themes/default/templates/api.html.ep:21 themes/default/templates/api.html.ep:35 themes/default/templates/api.html.ep:53 themes/default/templates/api.html.ep:96\nmsgid \"If equal to \\\"json\\\", response will be in JSON format, HTML format otherwise\"\nmsgstr \"\"\n\"Ako je jednako „json”, odgovor će biti u JSON formatu, inače u HTML formatu\"\n\n#. (config('page_offset')\n#: themes/default/templates/api.html.ep:89\nmsgid \"If you are logged in as admin (\\\"adminpwd\\\" or \\\"hashed_adminpwd\\\" setting), it will give you statistics for all URLs, sorted by the most visited first, paginated with pages containing %1 records.\"\nmsgstr \"\"\n\"Ako si prijavljen/a kao administrator (postavka „adminpwd” ili \"\n\"„hashed_adminpwd”), dobit ćeš statistiku za sve URL-ove, razvrstane po \"\n\"najposjećenijima, paginirane sa stranicama koje sadrže %1 zapisa.\"\n\n#: themes/default/templates/api.html.ep:94\nmsgid \"If you are logged in as admin, you can provide a \\\"page\\\" parameter\"\nmsgstr \"\"\n\"Ako si prijavljen/a kao administrator, možeš zadati parametar „page” \"\n\"(stranica)\"\n\n#: themes/default/templates/stats.html.ep:37 themes/default/templates/stats.html.ep:40\nmsgid \"Import URLs\"\nmsgstr \"Uvezi URL-ove\"\n\n#: themes/default/templates/api.html.ep:87\nmsgid \"It will use Lstu's cookies to know which shortened URL it will return statistics for.\"\nmsgstr \"\"\n\"Koristit će Lstu-ove kolačiće za određivanje statisktike skraćenih URL-ova.\"\n\n#: themes/default/templates/api.html.ep:113 themes/default/templates/api.html.ep:130 themes/default/templates/api.html.ep:153 themes/default/templates/api.html.ep:26 themes/default/templates/api.html.ep:61 themes/default/templates/api.html.ep:79\nmsgid \"JSON: failure\"\nmsgstr \"JSON: neuspjeh\"\n\n#: themes/default/templates/api.html.ep:112 themes/default/templates/api.html.ep:129 themes/default/templates/api.html.ep:137 themes/default/templates/api.html.ep:152 themes/default/templates/api.html.ep:25 themes/default/templates/api.html.ep:39 themes/default/templates/api.html.ep:60 themes/default/templates/api.html.ep:78\nmsgid \"JSON: success\"\nmsgstr \"JSON: uspjeh\"\n\n#: themes/default/templates/layouts/default.html.ep:55\nmsgid \"License:\"\nmsgstr \"Licenca:\"\n\n#: themes/default/templates/login.html.ep:8\nmsgid \"Login\"\nmsgstr \"Prijava\"\n\n#: themes/default/templates/layouts/default.html.ep:61\nmsgid \"Logout\"\nmsgstr \"Odjava\"\n\n#: themes/default/templates/stats.html.ep:15\nmsgid \"Logout from admin stats\"\nmsgstr \"Odjavi se iz statistike administratora\"\n\n#: themes/default/templates/stats.html.ep:120\nmsgid \"Next\"\nmsgstr \"Pored\"\n\n#. ($c->config('contact')\n#: lib/Lstu/Controller/URL.pm:130\nmsgid \"No shortened URL available. Please retry or contact the administrator at %1. Your URL to shorten: %2\"\nmsgstr \"\"\n\"Skraćeni URL nije dostupan. Pokušaj ponovo ili kontaktiraj administratora na \"\n\"%1. Tvoj URL za skraćivanje: %2\"\n\n#: themes/default/templates/api.html.ep:119 themes/default/templates/api.html.ep:146 themes/default/templates/api.html.ep:17 themes/default/templates/api.html.ep:33 themes/default/templates/api.html.ep:49 themes/default/templates/api.html.ep:91\nmsgid \"Parameters:\"\nmsgstr \"Parametri:\"\n\n#: themes/default/templates/login.html.ep:12\nmsgid \"Password\"\nmsgstr \"Lozinka\"\n\n#: lib/Lstu/Controller/Authent.pm:35 themes/default/templates/api.html.ep:26\nmsgid \"Please, check your credentials: unable to authenticate.\"\nmsgstr \"Provjeri svoje podatke autentifikacije: autentifikacija je neuspjela.\"\n\n#: themes/default/templates/stats.html.ep:118\nmsgid \"Previous\"\nmsgstr \"Prijašnja\"\n\n#: themes/default/templates/stats.html.ep:86\nmsgid \"QRCode\"\nmsgstr \"QR kod\"\n\n#: themes/default/templates/api.html.ep:104 themes/default/templates/api.html.ep:131 themes/default/templates/api.html.ep:138 themes/default/templates/api.html.ep:154 themes/default/templates/api.html.ep:27 themes/default/templates/api.html.ep:40 themes/default/templates/api.html.ep:62\nmsgid \"Response for HTML format\"\nmsgstr \"Odgovor za HTML format\"\n\n#: themes/default/templates/api.html.ep:103\nmsgid \"Response for JSON format\"\nmsgstr \"Odgovor za JSON format\"\n\n#: themes/default/templates/api.html.ep:110 themes/default/templates/api.html.ep:125 themes/default/templates/api.html.ep:150 themes/default/templates/api.html.ep:23 themes/default/templates/api.html.ep:37 themes/default/templates/api.html.ep:55 themes/default/templates/api.html.ep:67 themes/default/templates/api.html.ep:76 themes/default/templates/api.html.ep:98\nmsgid \"Response:\"\nmsgstr \"Odgovor:\"\n\n#: themes/default/templates/stats.html.ep:57 themes/default/templates/stats.html.ep:75\nmsgid \"Shortened URL\"\nmsgstr \"Skraćeni URL\"\n\n#: themes/default/templates/api.html.ep:135 themes/default/templates/api.html.ep:32\nmsgid \"Should always be successful\"\nmsgstr \"Trebalo bi uvijek uspjeti\"\n\n#: themes/default/templates/layouts/default.html.ep:63 themes/default/templates/login.html.ep:16 themes/default/templates/logout.html.ep:5\nmsgid \"Signin\"\nmsgstr \"Registracija\"\n\n#: lib/Lstu/Controller/URL.pm:53 themes/default/templates/api.html.ep:8\nmsgid \"Sorry, the API is disabled.\"\nmsgstr \"\"\n\n#: lib/Lstu/Controller/Stats.pm:45\nmsgid \"Sorry, unable to parse the provided file\"\nmsgstr \"Žao nam je, obrada zadane datoteke nije uspjela\"\n\n#: themes/default/templates/layouts/default.html.ep:60 themes/default/templates/layouts/default.html.ep:66 themes/default/templates/stats.html.ep:9\nmsgid \"Statistics\"\nmsgstr \"Statistika\"\n\n#. ($url->host)\n#: lib/Lstu/Plugin/Helpers.pm:172\nmsgid \"The URL host or one of its redirection(s) (%1) is blacklisted at Spamhaus. I refuse to shorten it.\"\nmsgstr \"\"\n\"URL host ili jedno od njegovih preusmjeravanja (%1) je na popisu nepoželjnih \"\n\"u Spamhausu. Odbijam ga skratiti.\"\n\n#. ($url)\n#: lib/Lstu/Plugin/Helpers.pm:178\nmsgid \"The URL or one of its redirection(s) (%1) is blacklisted in Google Safe Browsing database. I refuse to shorten it.\"\nmsgstr \"\"\n\"URL ili jedno od njegovih preusmjeravanja (%1) nalazi se na popisu \"\n\"nepoželjnih u bazi podataka Googleovog sigurnog pregledavanja. Odbijam ga \"\n\"skratiti.\"\n\n#. ($c->config('max_redir')\n#: lib/Lstu/Plugin/Helpers.pm:194\nmsgid \"The URL redirects %1 times or most. It's most likely a dangerous URL (spam, phishing, etc.). I refuse to shorten it.\"\nmsgstr \"\"\n\"URL preusmjerava barem %1 puta. Najvjerojatnije se radi o opasnom URL-u (\"\n\"neželjena pošta, krađa podataka itd.). Odbijam ga skratiti.\"\n\n#. ($url->host)\n#: lib/Lstu/Plugin/Helpers.pm:164\nmsgid \"The URL you want to shorten comes from a domain (%1) that is blacklisted on this server (usually because of spammers that use this domain).\"\nmsgstr \"\"\n\"URL koji želiš skratiti dolazi s domene (%1) koja je na popisu nepoželjnih \"\n\"na ovom poslužitelju (obično zbog pošiljatelja neželjene pošte koji koriste \"\n\"ovu domenu).\"\n\n#. ($c->url_for('/')\n#: lib/Lstu/Controller/Admin.pm:131 lib/Lstu/Controller/Stats.pm:200 lib/Lstu/Controller/URL.pm:260\nmsgid \"The shortened URL %1 doesn't exist.\"\nmsgstr \"Skraćeni URL %1 ne postoji.\"\n\n#. ($c->url_for('/')\n#: lib/Lstu/Controller/URL.pm:258\nmsgid \"The shortened URL %1 no longer exists.\"\nmsgstr \"Skraćeni URL %1 više ne postoji.\"\n\n#. ($url)\n#: lib/Lstu/Controller/URL.pm:77\nmsgid \"The shortened text can't be \\\"a\\\", \\\"api\\\", \\\"d\\\", \\\"cookie\\\", \\\"stats\\\", \\\"fullstats\\\", \\\"login\\\" or \\\"logout\\\" or end with \\\".json\\\". Your URL to shorten: %1\"\nmsgstr \"\"\n\"Skraćeni tekst ne može biti „a”, „api”, „d”, „cookie”, „stats”, „fullstats”, \"\n\"„login” ili „logout” niti završiti s „.json”. Tvoj URL za skraćivanje: %1\"\n\n#: themes/default/templates/api.html.ep:9\nmsgid \"This page is informational only.\"\nmsgstr \"\"\n\n#: themes/default/templates/api.html.ep:121\nmsgid \"To do an admin login, set it to the password defined in the settings (\\\"adminpwd\\\" or \\\"hashed_adminpwd\\\")\"\nmsgstr \"\"\n\"Za administratorsku prijavu, postavi je na lozinku definiranu u postavkama \"\n\"(„adminpwd” ili „hashed_adminpwd”)\"\n\n#: themes/default/templates/api.html.ep:122\nmsgid \"To do an admin logout, set it to \\\"logout\\\".\"\nmsgstr \"Za administratorsku odjavu postavi je na „logout” (odjava).\"\n\n#: lib/Lstu/Controller/Admin.pm:29\nmsgid \"Too many bad passwords. You're banned.\"\nmsgstr \"Previše neispravnih lozinki. Isključen/a si.\"\n\n#: themes/default/templates/api.html.ep:103 themes/default/templates/api.html.ep:112 themes/default/templates/stats.html.ep:52 themes/default/templates/stats.html.ep:72\nmsgid \"URL\"\nmsgstr \"URL\"\n\n#: themes/default/templates/api.html.ep:51 themes/default/templates/index.html.ep:5 themes/default/templates/index.html.ep:6\nmsgid \"URL to shorten\"\nmsgstr \"URL za skraćivanje\"\n\n#. ($penalty/3600)\n#: lib/Lstu/Controller/URL.pm:41\nmsgid \"You asked to shorten too many URLs too quickly. You're banned for %1 hour(s).\"\nmsgstr \"\"\n\"Prebrzo si zatražio/la skraćivanje previše URL-ova. Isključen/a si za %1 h.\"\n\n#: lib/Lstu/Controller/Admin.pm:52 lib/Lstu/Controller/Authent.pm:26 themes/default/templates/api.html.ep:129 themes/default/templates/api.html.ep:25\nmsgid \"You have been successfully logged in.\"\nmsgstr \"Uspješno si prijavljan/a.\"\n\n#: lib/Lstu/Controller/Admin.pm:73 lib/Lstu/Controller/Authent.pm:65 themes/default/templates/api.html.ep:137 themes/default/templates/api.html.ep:39 themes/default/templates/logout.html.ep:3\nmsgid \"You have been successfully logged out.\"\nmsgstr \"Uspješno si odjevljen/a.\"\n\n#: themes/default/templates/api.html.ep:145\nmsgid \"You must be logged in as admin (\\\"adminpwd\\\" or \\\"hashed_adminpwd\\\" setting) to use it.\"\nmsgstr \"\"\n\"Za korištnje moraš biti prijavljen kao administrator (postavka „adminpwd” \"\n\"ili „hashed_adminpwd”).\"\n\n#: themes/default/templates/api.html.ep:47 themes/default/templates/api.html.ep:85\nmsgid \"You must be logged in to use it.\"\nmsgstr \"Za korištenje se moraš prijaviti.\"\n\n#: themes/default/templates/api.html.ep:138\nmsgid \"You will be redirected to Lstu statistics page\"\nmsgstr \"Preusmjerit ćemo te na Lstu stranicu statistike\"\n\n#: themes/default/templates/api.html.ep:154\nmsgid \"You will be redirected to Lstu statistics page with a message in case of failure\"\nmsgstr \"\"\n\"Preusmjerit ćemo te na Lstu stranicu statistike s porukom u slučaju neuspjeha\"\n\n#: themes/default/templates/api.html.ep:40\nmsgid \"You will be redirected to Lstu successfully logged out interface\"\nmsgstr \"Preusmjerit ćemo te na uspješno odjavljeno Lstu sučelje\"\n\n#: themes/default/templates/api.html.ep:27\nmsgid \"You will be redirected to the Lstu classic interface where you will be able to shorten URLs\"\nmsgstr \"\"\n\"Preusmjerit ćemo te na klasično Lstu sučelje gdje ćeš moći skratiti URL-ove\"\n\n#: themes/default/templates/api.html.ep:62\nmsgid \"You will be redirected to the Lstu classic interface with a message giving the shortened URL\"\nmsgstr \"\"\n\"Preusmjerit ćemo te na klasično Lstu sučelje s porukom o skraćenim URL-om\"\n\n#: themes/default/templates/api.html.ep:70\nmsgid \"You will be redirected to the targeted URL or to the Lstu interface with a message giving the failure reason\"\nmsgstr \"\"\n\"Preusmjerit ćemo te na ciljani URL ili na klasično Lstu sučelje s porukom \"\n\"razloga neuspjeha\"\n\n#: themes/default/templates/api.html.ep:131\nmsgid \"You will have the statistics page with the admin stats if you're succesfully logged in, or your stats and a failure message otherwise\"\nmsgstr \"\"\n\"Dobit ćeš stranicu statistike sa statistikom administratora ako si uspješno \"\n\"prijavljen/a. U suprotnom ćeš dobiti svoju statistiku i poruku o neuspjehu\"\n\n#: lib/Lstu/Controller/Admin.pm:142\nmsgid \"You're not authenticated as the admin\"\nmsgstr \"Nisi autentificiran/a kao administrator\"\n\n#: themes/default/templates/api.html.ep:19\nmsgid \"Your login\"\nmsgstr \"Tvoja prijava\"\n\n#: themes/default/templates/api.html.ep:20\nmsgid \"Your password\"\nmsgstr \"Tvoja lozinka\"\n\n#: themes/default/templates/api.html.ep:103 themes/default/templates/api.html.ep:112\nmsgid \"integer, how many unique visits of the shortened URL\"\nmsgstr \"cijeli broj, broj jedinstvenih posjeta skraćenog URL-a\"\n\n#: themes/default/templates/api.html.ep:19 themes/default/templates/api.html.ep:20 themes/default/templates/api.html.ep:51\nmsgid \"mandatory\"\nmsgstr \"obavezno\"\n\n#: themes/default/templates/api.html.ep:121 themes/default/templates/api.html.ep:122 themes/default/templates/api.html.ep:123 themes/default/templates/api.html.ep:148 themes/default/templates/api.html.ep:21 themes/default/templates/api.html.ep:35 themes/default/templates/api.html.ep:52 themes/default/templates/api.html.ep:53 themes/default/templates/api.html.ep:94 themes/default/templates/api.html.ep:96\nmsgid \"optional\"\nmsgstr \"opcionalno\"\n\n#: themes/default/templates/api.html.ep:100 themes/default/templates/api.html.ep:107 themes/default/templates/api.html.ep:143 themes/default/templates/api.html.ep:65 themes/default/templates/api.html.ep:74\nmsgid \"shortened_url\"\nmsgstr \"skraćeni_url\"\n"
  },
  {
    "path": "themes/default/lib/Lstu/I18N/lstu.pot",
    "content": "# SOME DESCRIPTIVE TITLE.\n# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER\n# This file is distributed under the same license as the PACKAGE package.\n# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.\n#\n#, fuzzy\nmsgid \"\"\nmsgstr \"\"\n\"Project-Id-Version: PACKAGE VERSION\\n\"\n\"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\\n\"\n\"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\\n\"\n\"Last-Translator: FULL NAME <EMAIL@ADDRESS>\\n\"\n\"Language-Team: LANGUAGE <LL@li.org>\\n\"\n\"MIME-Version: 1.0\\n\"\n\"Content-Type: text/plain; charset=CHARSET\\n\"\n\"Content-Transfer-Encoding: 8bit\\n\"\n\n#. ($url)\n#: lib/Lstu/Controller/URL.pm:136\nmsgid \"%1 is not a valid URL.\"\nmsgstr \"\"\n\n#: themes/default/templates/api.html.ep:104\nmsgid \"A page with a table containing the same informations that the JSON response\"\nmsgstr \"\"\n\n#: themes/default/templates/layouts/default.html.ep:56\nmsgid \"About\"\nmsgstr \"\"\n\n#: themes/default/templates/stats.html.ep:18 themes/default/templates/stats.html.ep:19\nmsgid \"Admin password\"\nmsgstr \"\"\n\n#: lib/Lstu/Controller/Admin.pm:87 themes/default/templates/api.html.ep:130\nmsgid \"Bad password\"\nmsgstr \"\"\n\n#: themes/default/templates/index.html.ep:22\nmsgid \"Copy to clipboard\"\nmsgstr \"\"\n\n#: themes/default/templates/stats.html.ep:62 themes/default/templates/stats.html.ep:78\nmsgid \"Counter\"\nmsgstr \"\"\n\n#: themes/default/templates/stats.html.ep:67 themes/default/templates/stats.html.ep:81\nmsgid \"Created\"\nmsgstr \"\"\n\n#: themes/default/templates/api.html.ep:52 themes/default/templates/index.html.ep:10 themes/default/templates/index.html.ep:9\nmsgid \"Custom shortened text\"\nmsgstr \"\"\n\n#: themes/default/templates/stats.html.ep:88\nmsgid \"Delete\"\nmsgstr \"\"\n\n#: themes/default/templates/stats.html.ep:41\nmsgid \"Export your URLs\"\nmsgstr \"\"\n\n#: themes/default/templates/api.html.ep:113 themes/default/templates/api.html.ep:153 themes/default/templates/api.html.ep:61 themes/default/templates/api.html.ep:79\nmsgid \"Failure reason\"\nmsgstr \"\"\n\n#: lib/Lstu/Controller/Stats.pm:43\nmsgid \"File imported\"\nmsgstr \"\"\n\n#: themes/default/templates/api.html.ep:109\nmsgid \"Get the details (visit counter, creation date, etc.) of a shortened URL.\"\nmsgstr \"\"\n\n#: themes/default/templates/index.html.ep:13 themes/default/templates/stats.html.ep:22\nmsgid \"Go!\"\nmsgstr \"\"\n\n#: themes/default/templates/partial/lstu.js.ep:30\nmsgid \"Hit Enter, then Ctrl+C to copy the short link\"\nmsgstr \"\"\n\n#: themes/default/templates/stats.html.ep:125\nmsgid \"Home\"\nmsgstr \"\"\n\n#: themes/default/templates/api.html.ep:134\nmsgid \"If \\\"action\\\" is defined to \\\"logout\\\":\"\nmsgstr \"\"\n\n#: themes/default/templates/api.html.ep:127\nmsgid \"If \\\"adminpwd\\\" is defined:\"\nmsgstr \"\"\n\n#: themes/default/templates/api.html.ep:123 themes/default/templates/api.html.ep:148 themes/default/templates/api.html.ep:21 themes/default/templates/api.html.ep:35 themes/default/templates/api.html.ep:53 themes/default/templates/api.html.ep:96\nmsgid \"If equal to \\\"json\\\", response will be in JSON format, HTML format otherwise\"\nmsgstr \"\"\n\n#. (config('page_offset')\n#: themes/default/templates/api.html.ep:89\nmsgid \"If you are logged in as admin (\\\"adminpwd\\\" or \\\"hashed_adminpwd\\\" setting), it will give you statistics for all URLs, sorted by the most visited first, paginated with pages containing %1 records.\"\nmsgstr \"\"\n\n#: themes/default/templates/api.html.ep:94\nmsgid \"If you are logged in as admin, you can provide a \\\"page\\\" parameter\"\nmsgstr \"\"\n\n#: themes/default/templates/stats.html.ep:37 themes/default/templates/stats.html.ep:40\nmsgid \"Import URLs\"\nmsgstr \"\"\n\n#: themes/default/templates/api.html.ep:87\nmsgid \"It will use Lstu's cookies to know which shortened URL it will return statistics for.\"\nmsgstr \"\"\n\n#: themes/default/templates/api.html.ep:113 themes/default/templates/api.html.ep:130 themes/default/templates/api.html.ep:153 themes/default/templates/api.html.ep:26 themes/default/templates/api.html.ep:61 themes/default/templates/api.html.ep:79\nmsgid \"JSON: failure\"\nmsgstr \"\"\n\n#: themes/default/templates/api.html.ep:112 themes/default/templates/api.html.ep:129 themes/default/templates/api.html.ep:137 themes/default/templates/api.html.ep:152 themes/default/templates/api.html.ep:25 themes/default/templates/api.html.ep:39 themes/default/templates/api.html.ep:60 themes/default/templates/api.html.ep:78\nmsgid \"JSON: success\"\nmsgstr \"\"\n\n#: themes/default/templates/layouts/default.html.ep:55\nmsgid \"License:\"\nmsgstr \"\"\n\n#: themes/default/templates/login.html.ep:8\nmsgid \"Login\"\nmsgstr \"\"\n\n#: themes/default/templates/layouts/default.html.ep:61\nmsgid \"Logout\"\nmsgstr \"\"\n\n#: themes/default/templates/stats.html.ep:15\nmsgid \"Logout from admin stats\"\nmsgstr \"\"\n\n#: themes/default/templates/stats.html.ep:120\nmsgid \"Next\"\nmsgstr \"\"\n\n#. ($c->config('contact')\n#: lib/Lstu/Controller/URL.pm:130\nmsgid \"No shortened URL available. Please retry or contact the administrator at %1. Your URL to shorten: %2\"\nmsgstr \"\"\n\n#: themes/default/templates/api.html.ep:119 themes/default/templates/api.html.ep:146 themes/default/templates/api.html.ep:17 themes/default/templates/api.html.ep:33 themes/default/templates/api.html.ep:49 themes/default/templates/api.html.ep:91\nmsgid \"Parameters:\"\nmsgstr \"\"\n\n#: themes/default/templates/login.html.ep:12\nmsgid \"Password\"\nmsgstr \"\"\n\n#: lib/Lstu/Controller/Authent.pm:35 themes/default/templates/api.html.ep:26\nmsgid \"Please, check your credentials: unable to authenticate.\"\nmsgstr \"\"\n\n#: themes/default/templates/stats.html.ep:118\nmsgid \"Previous\"\nmsgstr \"\"\n\n#: themes/default/templates/stats.html.ep:86\nmsgid \"QRCode\"\nmsgstr \"\"\n\n#: themes/default/templates/api.html.ep:104 themes/default/templates/api.html.ep:131 themes/default/templates/api.html.ep:138 themes/default/templates/api.html.ep:154 themes/default/templates/api.html.ep:27 themes/default/templates/api.html.ep:40 themes/default/templates/api.html.ep:62\nmsgid \"Response for HTML format\"\nmsgstr \"\"\n\n#: themes/default/templates/api.html.ep:103\nmsgid \"Response for JSON format\"\nmsgstr \"\"\n\n#: themes/default/templates/api.html.ep:110 themes/default/templates/api.html.ep:125 themes/default/templates/api.html.ep:150 themes/default/templates/api.html.ep:23 themes/default/templates/api.html.ep:37 themes/default/templates/api.html.ep:55 themes/default/templates/api.html.ep:67 themes/default/templates/api.html.ep:76 themes/default/templates/api.html.ep:98\nmsgid \"Response:\"\nmsgstr \"\"\n\n#: themes/default/templates/stats.html.ep:57 themes/default/templates/stats.html.ep:75\nmsgid \"Shortened URL\"\nmsgstr \"\"\n\n#: themes/default/templates/api.html.ep:135 themes/default/templates/api.html.ep:32\nmsgid \"Should always be successful\"\nmsgstr \"\"\n\n#: themes/default/templates/layouts/default.html.ep:63 themes/default/templates/login.html.ep:16 themes/default/templates/logout.html.ep:5\nmsgid \"Signin\"\nmsgstr \"\"\n\n#: lib/Lstu/Controller/URL.pm:53 themes/default/templates/api.html.ep:8\nmsgid \"Sorry, the API is disabled.\"\nmsgstr \"\"\n\n#: lib/Lstu/Controller/Stats.pm:45\nmsgid \"Sorry, unable to parse the provided file\"\nmsgstr \"\"\n\n#: themes/default/templates/layouts/default.html.ep:60 themes/default/templates/layouts/default.html.ep:66 themes/default/templates/stats.html.ep:9\nmsgid \"Statistics\"\nmsgstr \"\"\n\n#. ($url->host)\n#: lib/Lstu/Plugin/Helpers.pm:172\nmsgid \"The URL host or one of its redirection(s) (%1) is blacklisted at Spamhaus. I refuse to shorten it.\"\nmsgstr \"\"\n\n#. ($url)\n#: lib/Lstu/Plugin/Helpers.pm:178\nmsgid \"The URL or one of its redirection(s) (%1) is blacklisted in Google Safe Browsing database. I refuse to shorten it.\"\nmsgstr \"\"\n\n#. ($c->config('max_redir')\n#: lib/Lstu/Plugin/Helpers.pm:194\nmsgid \"The URL redirects %1 times or most. It's most likely a dangerous URL (spam, phishing, etc.). I refuse to shorten it.\"\nmsgstr \"\"\n\n#. ($url->host)\n#: lib/Lstu/Plugin/Helpers.pm:164\nmsgid \"The URL you want to shorten comes from a domain (%1) that is blacklisted on this server (usually because of spammers that use this domain).\"\nmsgstr \"\"\n\n#. ($c->url_for('/')\n#: lib/Lstu/Controller/Admin.pm:131 lib/Lstu/Controller/Stats.pm:200 lib/Lstu/Controller/URL.pm:260\nmsgid \"The shortened URL %1 doesn't exist.\"\nmsgstr \"\"\n\n#. ($c->url_for('/')\n#: lib/Lstu/Controller/URL.pm:258\nmsgid \"The shortened URL %1 no longer exists.\"\nmsgstr \"\"\n\n#. ($url)\n#: lib/Lstu/Controller/URL.pm:77\nmsgid \"The shortened text can't be \\\"a\\\", \\\"api\\\", \\\"d\\\", \\\"cookie\\\", \\\"stats\\\", \\\"fullstats\\\", \\\"login\\\" or \\\"logout\\\" or end with \\\".json\\\". Your URL to shorten: %1\"\nmsgstr \"\"\n\n#: themes/default/templates/api.html.ep:9\nmsgid \"This page is informational only.\"\nmsgstr \"\"\n\n#: themes/default/templates/api.html.ep:121\nmsgid \"To do an admin login, set it to the password defined in the settings (\\\"adminpwd\\\" or \\\"hashed_adminpwd\\\")\"\nmsgstr \"\"\n\n#: themes/default/templates/api.html.ep:122\nmsgid \"To do an admin logout, set it to \\\"logout\\\".\"\nmsgstr \"\"\n\n#: lib/Lstu/Controller/Admin.pm:29\nmsgid \"Too many bad passwords. You're banned.\"\nmsgstr \"\"\n\n#: themes/default/templates/api.html.ep:103 themes/default/templates/api.html.ep:112 themes/default/templates/stats.html.ep:52 themes/default/templates/stats.html.ep:72\nmsgid \"URL\"\nmsgstr \"\"\n\n#: themes/default/templates/api.html.ep:51 themes/default/templates/index.html.ep:5 themes/default/templates/index.html.ep:6\nmsgid \"URL to shorten\"\nmsgstr \"\"\n\n#. ($penalty/3600)\n#: lib/Lstu/Controller/URL.pm:41\nmsgid \"You asked to shorten too many URLs too quickly. You're banned for %1 hour(s).\"\nmsgstr \"\"\n\n#: lib/Lstu/Controller/Admin.pm:52 lib/Lstu/Controller/Authent.pm:26 themes/default/templates/api.html.ep:129 themes/default/templates/api.html.ep:25\nmsgid \"You have been successfully logged in.\"\nmsgstr \"\"\n\n#: lib/Lstu/Controller/Admin.pm:73 lib/Lstu/Controller/Authent.pm:65 themes/default/templates/api.html.ep:137 themes/default/templates/api.html.ep:39 themes/default/templates/logout.html.ep:3\nmsgid \"You have been successfully logged out.\"\nmsgstr \"\"\n\n#: themes/default/templates/api.html.ep:145\nmsgid \"You must be logged in as admin (\\\"adminpwd\\\" or \\\"hashed_adminpwd\\\" setting) to use it.\"\nmsgstr \"\"\n\n#: themes/default/templates/api.html.ep:47 themes/default/templates/api.html.ep:85\nmsgid \"You must be logged in to use it.\"\nmsgstr \"\"\n\n#: themes/default/templates/api.html.ep:138\nmsgid \"You will be redirected to Lstu statistics page\"\nmsgstr \"\"\n\n#: themes/default/templates/api.html.ep:154\nmsgid \"You will be redirected to Lstu statistics page with a message in case of failure\"\nmsgstr \"\"\n\n#: themes/default/templates/api.html.ep:40\nmsgid \"You will be redirected to Lstu successfully logged out interface\"\nmsgstr \"\"\n\n#: themes/default/templates/api.html.ep:27\nmsgid \"You will be redirected to the Lstu classic interface where you will be able to shorten URLs\"\nmsgstr \"\"\n\n#: themes/default/templates/api.html.ep:62\nmsgid \"You will be redirected to the Lstu classic interface with a message giving the shortened URL\"\nmsgstr \"\"\n\n#: themes/default/templates/api.html.ep:70\nmsgid \"You will be redirected to the targeted URL or to the Lstu interface with a message giving the failure reason\"\nmsgstr \"\"\n\n#: themes/default/templates/api.html.ep:131\nmsgid \"You will have the statistics page with the admin stats if you're succesfully logged in, or your stats and a failure message otherwise\"\nmsgstr \"\"\n\n#: lib/Lstu/Controller/Admin.pm:142\nmsgid \"You're not authenticated as the admin\"\nmsgstr \"\"\n\n#: themes/default/templates/api.html.ep:19\nmsgid \"Your login\"\nmsgstr \"\"\n\n#: themes/default/templates/api.html.ep:20\nmsgid \"Your password\"\nmsgstr \"\"\n\n#: themes/default/templates/api.html.ep:103 themes/default/templates/api.html.ep:112\nmsgid \"integer, how many unique visits of the shortened URL\"\nmsgstr \"\"\n\n#: themes/default/templates/api.html.ep:19 themes/default/templates/api.html.ep:20 themes/default/templates/api.html.ep:51\nmsgid \"mandatory\"\nmsgstr \"\"\n\n#: themes/default/templates/api.html.ep:121 themes/default/templates/api.html.ep:122 themes/default/templates/api.html.ep:123 themes/default/templates/api.html.ep:148 themes/default/templates/api.html.ep:21 themes/default/templates/api.html.ep:35 themes/default/templates/api.html.ep:52 themes/default/templates/api.html.ep:53 themes/default/templates/api.html.ep:94 themes/default/templates/api.html.ep:96\nmsgid \"optional\"\nmsgstr \"\"\n\n#: themes/default/templates/api.html.ep:100 themes/default/templates/api.html.ep:107 themes/default/templates/api.html.ep:143 themes/default/templates/api.html.ep:65 themes/default/templates/api.html.ep:74\nmsgid \"shortened_url\"\nmsgstr \"\"\n"
  },
  {
    "path": "themes/default/lib/Lstu/I18N/oc.po",
    "content": "# Lstu\n# Copyright (C) 2013 Luc Didry\n# This file is distributed under the same license as the Lstu package.\n# \n# Translators:\n# Lo Quentin\n# Luc Didry <luc@didry.org>, 2015\n# Cédric Valmary (totenoc.eu) <cvalmary@yahoo.fr>, 2016.\n# Luc Didry <luc@framasoft.org>, 2018. #zanata\n# Quentí, 2018. #zanata\nmsgid \"\"\nmsgstr \"\"\n\"Project-Id-Version: PACKAGE VERSION\\n\"\n\"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\\n\"\n\"PO-Revision-Date: 2021-04-28 09:40+0000\\n\"\n\"Last-Translator: Quentin PAGÈS <quentinantonin@free.fr>\\n\"\n\"Language-Team: Occitan <https://weblate.framasoft.org/projects/lstu/\"\n\"development/oc/>\\n\"\n\"Language: oc\\n\"\n\"MIME-Version: 1.0\\n\"\n\"Content-Type: text/plain; charset=UTF-8\\n\"\n\"Content-Transfer-Encoding: 8bit\\n\"\n\"Plural-Forms: nplurals=2; plural=n > 1;\\n\"\n\"X-Generator: Weblate 4.6\\n\"\n\"X-POOTLE-MTIME: 1441357092.000000\\n\"\n\"X-Poedit-SourceCharset: UTF-8\\n\"\n\n#. ($url)\n#: lib/Lstu/Controller/URL.pm:118\nmsgid \"%1 is not a valid URL.\"\nmsgstr \"%1 es pas una URL valida.\"\n\n#: themes/default/templates/api.html.ep:96\nmsgid \"\"\n\"A page with a table containing the same informations that the JSON response\"\nmsgstr \"\"\n\"Una pagina amb un tablèu que conten las meteissas informacions que lo \"\n\"messatge JSON\"\n\n#: themes/default/templates/layouts/default.html.ep:38\nmsgid \"About\"\nmsgstr \"A prepaus\"\n\n#: themes/default/templates/stats.html.ep:13 themes/default/templates/stats.html.ep:14\nmsgid \"Admin password\"\nmsgstr \"Senhal administrator\"\n\n#: lib/Lstu/Controller/Admin.pm:87 themes/default/templates/api.html.ep:122\nmsgid \"Bad password\"\nmsgstr \"Senhal incorrècte\"\n\n#: themes/default/templates/index.html.ep:21\nmsgid \"Copy to clipboard\"\nmsgstr \"Copiar al quichapapièrs\"\n\n#: themes/default/templates/stats.html.ep:46\nmsgid \"Counter\"\nmsgstr \"Comptador\"\n\n#: themes/default/templates/stats.html.ep:47\nmsgid \"Created\"\nmsgstr \"Creat lo\"\n\n#: themes/default/templates/api.html.ep:44 themes/default/templates/index.html.ep:10 themes/default/templates/index.html.ep:9\nmsgid \"Custom shortened text\"\nmsgstr \"Tèxte de l’acorchi personalizat\"\n\n#: themes/default/templates/stats.html.ep:52\nmsgid \"Delete\"\nmsgstr \"Suprimir\"\n\n#: themes/default/templates/stats.html.ep:36\nmsgid \"Export your URLs\"\nmsgstr \"Exportar vòstras URL\"\n\n#: themes/default/templates/api.html.ep:105 themes/default/templates/api.html.ep:145 themes/default/templates/api.html.ep:53 themes/default/templates/api.html.ep:71\nmsgid \"Failure reason\"\nmsgstr \"Rason del fracàs\"\n\n#: lib/Lstu/Controller/Stats.pm:43\nmsgid \"File imported\"\nmsgstr \"Fichièr importat\"\n\n#: themes/default/templates/api.html.ep:101\nmsgid \"\"\n\"Get the details (visit counter, creation date, etc.) of a shortened URL.\"\nmsgstr \"\"\n\"Obténer los detalhs (comptador de visitas, data de creacion, etc.) d’una URL \"\n\"acorchida.\"\n\n#: themes/default/templates/index.html.ep:12 themes/default/templates/stats.html.ep:17\nmsgid \"Go!\"\nmsgstr \"Zo !\"\n\n#: themes/default/templates/partial/lstu.js.ep:30\nmsgid \"Hit Enter, then Ctrl+C to copy the short link\"\nmsgstr \"Picatz sus Entrada puèi fasètz Ctrl+C per copiar lo ligam\"\n\n#: themes/default/templates/stats.html.ep:89\nmsgid \"Home\"\nmsgstr \"Acuèlh\"\n\n#: themes/default/templates/api.html.ep:126\nmsgid \"If \\\"action\\\" is defined to \\\"logout\\\":\"\nmsgstr \"Se \\\"action\\\" es definit coma \\\"logout\\\" :\"\n\n#: themes/default/templates/api.html.ep:119\nmsgid \"If \\\"adminpwd\\\" is defined:\"\nmsgstr \"Se \\\"adminpwd\\\" es definit :\"\n\n#: themes/default/templates/api.html.ep:115 themes/default/templates/api.html.ep:13 themes/default/templates/api.html.ep:140 themes/default/templates/api.html.ep:27 themes/default/templates/api.html.ep:45 themes/default/templates/api.html.ep:88\nmsgid \"\"\n\"If equal to \\\"json\\\", response will be in JSON format, HTML format otherwise\"\nmsgstr \"\"\n\"Se es egal a \\\"json\\\", la responsa serà al format JSON, autrament aquò serà \"\n\"una responsa en HTML\"\n\n#. (config('page_offset')\n#: themes/default/templates/api.html.ep:81\nmsgid \"\"\n\"If you are logged in as admin (\\\"adminpwd\\\" or \\\"hashed_adminpwd\\\" setting), \"\n\"it will give you statistics for all URLs, sorted by the most visited first, \"\n\"paginated with pages containing %1 records.\"\nmsgstr \"\"\n\"Se sètz connectat·ada coma admin (\\\"adminpwd\\\" o \\\"hashed_adminpwd\\\" \"\n\"paramètre) aquò donarà totas las estatisticas per totas las URL, triadas per \"\n\"nombre de visitas en primièr las mai visitas, amb una paginacion amb %1 \"\n\"enregistraments per pagina.\"\n\n#: themes/default/templates/api.html.ep:86\nmsgid \"If you are logged in as admin, you can provide a \\\"page\\\" parameter\"\nmsgstr \"Se sètz connectat·ada coma admin, podètz fornir un paramètre \\\"page\\\"\"\n\n#: themes/default/templates/stats.html.ep:32 themes/default/templates/stats.html.ep:35\nmsgid \"Import URLs\"\nmsgstr \"Importar vòstras URL\"\n\n#: themes/default/templates/api.html.ep:79\nmsgid \"\"\n\"It will use Lstu's cookies to know which shortened URL it will return \"\n\"statistics for.\"\nmsgstr \"\"\n\"Aquò utilizarà los cookies de Lstu per saber quinas estatisticas tornar.\"\n\n#: themes/default/templates/api.html.ep:105 themes/default/templates/api.html.ep:122 themes/default/templates/api.html.ep:145 themes/default/templates/api.html.ep:18 themes/default/templates/api.html.ep:53 themes/default/templates/api.html.ep:71\nmsgid \"JSON: failure\"\nmsgstr \"JSON : fracàs\"\n\n#: themes/default/templates/api.html.ep:104 themes/default/templates/api.html.ep:121 themes/default/templates/api.html.ep:129 themes/default/templates/api.html.ep:144 themes/default/templates/api.html.ep:17 themes/default/templates/api.html.ep:31 themes/default/templates/api.html.ep:52 themes/default/templates/api.html.ep:70\nmsgid \"JSON: success\"\nmsgstr \"JSON : succès\"\n\n#: themes/default/templates/layouts/default.html.ep:37\nmsgid \"License:\"\nmsgstr \"Licéncia :\"\n\n#: themes/default/templates/login.html.ep:8\nmsgid \"Login\"\nmsgstr \"Connexion\"\n\n#: themes/default/templates/layouts/default.html.ep:43\nmsgid \"Logout\"\nmsgstr \"Desconnexion\"\n\n#: themes/default/templates/stats.html.ep:10\nmsgid \"Logout from admin stats\"\nmsgstr \"Desconnexion de las estatisticas admin\"\n\n#: themes/default/templates/stats.html.ep:84\nmsgid \"Next\"\nmsgstr \"Seguent\"\n\n#. ($c->config('contact')\n#: lib/Lstu/Controller/URL.pm:112\nmsgid \"\"\n\"No shortened URL available. Please retry or contact the administrator at %1. \"\n\"Your URL to shorten: %2\"\nmsgstr \"\"\n\"I a pas mai d’URL acorchadas disponiblas. Mercés de tornar ensajar o de \"\n\"contactar l’administrator sus %1. Recòrd de l’URL per acorchar : %2\"\n\n#: themes/default/templates/api.html.ep:111 themes/default/templates/api.html.ep:138 themes/default/templates/api.html.ep:25 themes/default/templates/api.html.ep:41 themes/default/templates/api.html.ep:83 themes/default/templates/api.html.ep:9\nmsgid \"Parameters:\"\nmsgstr \"Paramètres :\"\n\n#: themes/default/templates/login.html.ep:12\nmsgid \"Password\"\nmsgstr \"Senhal\"\n\n#: lib/Lstu/Controller/Authent.pm:35 themes/default/templates/api.html.ep:18\nmsgid \"Please, check your credentials: unable to authenticate.\"\nmsgstr \"\"\n\"Mercés de verificar vòstres identificants : fracàs de l’autentificacion.\"\n\n#: themes/default/templates/stats.html.ep:82\nmsgid \"Previous\"\nmsgstr \"Precedent\"\n\n#: themes/default/templates/stats.html.ep:50\nmsgid \"QRCode\"\nmsgstr \"QRCode\"\n\n#: themes/default/templates/api.html.ep:123 themes/default/templates/api.html.ep:130 themes/default/templates/api.html.ep:146 themes/default/templates/api.html.ep:19 themes/default/templates/api.html.ep:32 themes/default/templates/api.html.ep:54 themes/default/templates/api.html.ep:96\nmsgid \"Response for HTML format\"\nmsgstr \"Responsa pel format HTML\"\n\n#: themes/default/templates/api.html.ep:95\nmsgid \"Response for JSON format\"\nmsgstr \"Responsa pel format JSON\"\n\n#: themes/default/templates/api.html.ep:102 themes/default/templates/api.html.ep:117 themes/default/templates/api.html.ep:142 themes/default/templates/api.html.ep:15 themes/default/templates/api.html.ep:29 themes/default/templates/api.html.ep:47 themes/default/templates/api.html.ep:59 themes/default/templates/api.html.ep:68 themes/default/templates/api.html.ep:90\nmsgid \"Response:\"\nmsgstr \"Responsa :\"\n\n#: themes/default/templates/stats.html.ep:45\nmsgid \"Shortened URL\"\nmsgstr \"URL acorchada\"\n\n#: themes/default/templates/api.html.ep:127 themes/default/templates/api.html.ep:24\nmsgid \"Should always be successful\"\nmsgstr \"Deu totjorn tornar una capitada\"\n\n#: themes/default/templates/layouts/default.html.ep:45 themes/default/templates/login.html.ep:16 themes/default/templates/logout.html.ep:5\nmsgid \"Signin\"\nmsgstr \"Connexion\"\n\n#: lib/Lstu/Controller/Stats.pm:45\nmsgid \"Sorry, unable to parse the provided file\"\nmsgstr \"O planhèm èra pas possible de percórrer lo fichièr provesit\"\n\n#: themes/default/templates/layouts/default.html.ep:42 themes/default/templates/layouts/default.html.ep:48 themes/default/templates/stats.html.ep:4\nmsgid \"Statistics\"\nmsgstr \"Estatisticas\"\n\n#. ($url->host)\n#: lib/Lstu/Plugin/Helpers.pm:172\nmsgid \"\"\n\"The URL host or one of its redirection(s) (%1) is blacklisted at Spamhaus. I \"\n\"refuse to shorten it.\"\nmsgstr \"\"\n\"L’òste de l’URL o d’una de sas redireccions (%1) es considerat coma nociu \"\n\"per Spamhaus. Refusi de l’acorchar.\"\n\n#. ($url)\n#: lib/Lstu/Plugin/Helpers.pm:178\nmsgid \"\"\n\"The URL or one of its redirection(s) (%1) is blacklisted in Google Safe \"\n\"Browsing database. I refuse to shorten it.\"\nmsgstr \"\"\n\"L’URL o una de sas redireccions (%1) es considerat coma nociva per Google \"\n\"Safe Browsing. Refusi de l’acorchar.\"\n\n#. ($c->config('max_redir')\n#: lib/Lstu/Plugin/Helpers.pm:194\nmsgid \"\"\n\"The URL redirects %1 times or most. It's most likely a dangerous URL (spam, \"\n\"phishing, etc.). I refuse to shorten it.\"\nmsgstr \"\"\n\"L’URL endralha %1 còps o mai cap a un a autre site. Pòt èsser una URL \"\n\"dangerossa (porrièl, pesca electronica, etc). Refusi de l’acorchar.\"\n\n#. ($url->host)\n#: lib/Lstu/Plugin/Helpers.pm:164\nmsgid \"\"\n\"The URL you want to shorten comes from a domain (%1) that is blacklisted on \"\n\"this server (usually because of spammers that use this domain).\"\nmsgstr \"\"\n\"L’UR que volètz acorchar ven d’un domeni (%1) qu’es lista negra en aqueste \"\n\"servidor (sovent a causa de spammers qu’utilizan aqueste domeni).\"\n\n#. ($c->url_for('/')\n#: lib/Lstu/Controller/Admin.pm:131 lib/Lstu/Controller/Stats.pm:184 lib/Lstu/Controller/URL.pm:226\nmsgid \"The shortened URL %1 doesn't exist.\"\nmsgstr \"L’URL acorchada %1 existís pas.\"\n\n#. ($url)\n#: lib/Lstu/Controller/URL.pm:59\nmsgid \"\"\n\"The shortened text can't be \\\"a\\\", \\\"api\\\", \\\"d\\\", \\\"cookie\\\", \\\"stats\\\", \"\n\"\\\"fullstats\\\", \\\"login\\\" or \\\"logout\\\" or end with \\\".json\\\". Your URL to \"\n\"shorten: %1\"\nmsgstr \"\"\n\"Lo tèxte de l’acorchi deu pas èsser \\\"a\\\", \\\"api\\\", \\\"d\\\", \\\"cookie\\\", \"\n\"\\\"stats\\\", \\\"fullstats\\\", \\\"login\\\" o \\\"logout\\\" o acabar per \\\".json\\\". \"\n\"Recòrd de l’URL per acorchar : %1\"\n\n#: themes/default/templates/api.html.ep:113\nmsgid \"\"\n\"To do an admin login, set it to the password defined in the settings \"\n\"(\\\"adminpwd\\\" or \\\"hashed_adminpwd\\\")\"\nmsgstr \"\"\n\"Per vos connectar coma admin, botatz lo senhal definit dins los paramètres \"\n\"(\\\"adminpwd\\\" or \\\"hashed_adminpwd\\\")\"\n\n#: themes/default/templates/api.html.ep:114\nmsgid \"To do an admin logout, set it to \\\"logout\\\".\"\nmsgstr \"\"\n\"Per vos desconnectar de l’administracion, definissètz aqueste paramètre coma \"\n\"\\\"logout\\\".\"\n\n#: lib/Lstu/Controller/Admin.pm:29\nmsgid \"Too many bad passwords. You're banned.\"\nmsgstr \"Tròp de marrits senhals. Sètz bandit·ida.\"\n\n#: themes/default/templates/api.html.ep:104 themes/default/templates/api.html.ep:95 themes/default/templates/stats.html.ep:44\nmsgid \"URL\"\nmsgstr \"URL\"\n\n#: themes/default/templates/api.html.ep:43 themes/default/templates/index.html.ep:5 themes/default/templates/index.html.ep:6\nmsgid \"URL to shorten\"\nmsgstr \"URL per acorchar\"\n\n#. ($penalty/3600)\n#: lib/Lstu/Controller/URL.pm:35\nmsgid \"\"\n\"You asked to shorten too many URLs too quickly. You're banned for %1 hour(s).\"\n\"\"\nmsgstr \"\"\n\"Avètz demandat d’acorchar tròp d’URL en pauc de temps. Sètz bandit per %1 \"\n\"ora(s).\"\n\n#: lib/Lstu/Controller/Admin.pm:52 lib/Lstu/Controller/Authent.pm:26 themes/default/templates/api.html.ep:121 themes/default/templates/api.html.ep:17\nmsgid \"You have been successfully logged in.\"\nmsgstr \"Sètz ben estat·ada connectat·ada.\"\n\n#: lib/Lstu/Controller/Admin.pm:73 lib/Lstu/Controller/Authent.pm:65 themes/default/templates/api.html.ep:129 themes/default/templates/api.html.ep:31 themes/default/templates/logout.html.ep:3\nmsgid \"You have been successfully logged out.\"\nmsgstr \"Sètz ben estat·ada desconnectat·ada.\"\n\n#: themes/default/templates/api.html.ep:137\nmsgid \"\"\n\"You must be logged in as admin (\\\"adminpwd\\\" or \\\"hashed_adminpwd\\\" setting) \"\n\"to use it.\"\nmsgstr \"\"\n\"Vos cal èsser connectat·ada coma admin (\\\"adminpwd\\\" o \\\"hashed_adminpwd\\\" \"\n\"paramètres) per utilizar aquò.\"\n\n#: themes/default/templates/api.html.ep:39 themes/default/templates/api.html.ep:77\nmsgid \"You must be logged in to use it.\"\nmsgstr \"Vos cal èsser connectat·ada per utilizar aquò.\"\n\n#: themes/default/templates/api.html.ep:130\nmsgid \"You will be redirected to Lstu statistics page\"\nmsgstr \"Seretz dirigit·ida cap a la pagina de las estatisticas de Lstu\"\n\n#: themes/default/templates/api.html.ep:146\nmsgid \"\"\n\"You will be redirected to Lstu statistics page with a message in case of \"\n\"failure\"\nmsgstr \"\"\n\"Seretz dirigit·ida cap a la pagina de las estatisticas de Lstu amb un \"\n\"messatge se i a agut un fracàs\"\n\n#: themes/default/templates/api.html.ep:32\nmsgid \"You will be redirected to Lstu successfully logged out interface\"\nmsgstr \"Seretz dirigit·ida cap a l’interfàcia de Lstu per la desconnexion\"\n\n#: themes/default/templates/api.html.ep:19\nmsgid \"\"\n\"You will be redirected to the Lstu classic interface where you will be able \"\n\"to shorten URLs\"\nmsgstr \"\"\n\"Seretz dirigit·ida cap a l’interfàcia classica de Lstu ont poiretz acorchir \"\n\"d’URLs\"\n\n#: themes/default/templates/api.html.ep:54\nmsgid \"\"\n\"You will be redirected to the Lstu classic interface with a message giving \"\n\"the shortened URL\"\nmsgstr \"\"\n\"Seretz dirigit·ida cap a l’interfàcia classica de Lstu amb un message donant \"\n\"l’URL acorchida\"\n\n#: themes/default/templates/api.html.ep:62\nmsgid \"\"\n\"You will be redirected to the targeted URL or to the Lstu interface with a \"\n\"message giving the failure reason\"\nmsgstr \"\"\n\"Seretz dirigit·ida cap a l’URL finala o la pagina d’acuèlh de Lstu amb un \"\n\"messatge qu’indica la rason del fracàs\"\n\n#: themes/default/templates/api.html.ep:123\nmsgid \"\"\n\"You will have the statistics page with the admin stats if you're succesfully \"\n\"logged in, or your stats and a failure message otherwise\"\nmsgstr \"\"\n\"Auretz la pagina d’estatisticas amb las statisticas admin se sètz ben \"\n\"connectat·ada, autrament vòstres estatisticas amb un messatge de fracàs\"\n\n#: lib/Lstu/Controller/Admin.pm:142\nmsgid \"You're not authenticated as the admin\"\nmsgstr \"Sètz pas connectat·ada coma admin\"\n\n#: themes/default/templates/api.html.ep:11\nmsgid \"Your login\"\nmsgstr \"Vòstre identificant\"\n\n#: themes/default/templates/api.html.ep:12\nmsgid \"Your password\"\nmsgstr \"Vòstre senhal\"\n\n#: themes/default/templates/api.html.ep:104 themes/default/templates/api.html.ep:95\nmsgid \"integer, how many unique visits of the shortened URL\"\nmsgstr \"entièr, quantas visitas unicas per l’URL acorchida\"\n\n#: themes/default/templates/api.html.ep:11 themes/default/templates/api.html.ep:12 themes/default/templates/api.html.ep:43\nmsgid \"mandatory\"\nmsgstr \"obligatòri\"\n\n#: themes/default/templates/api.html.ep:113 themes/default/templates/api.html.ep:114 themes/default/templates/api.html.ep:115 themes/default/templates/api.html.ep:13 themes/default/templates/api.html.ep:140 themes/default/templates/api.html.ep:27 themes/default/templates/api.html.ep:44 themes/default/templates/api.html.ep:45 themes/default/templates/api.html.ep:86 themes/default/templates/api.html.ep:88\nmsgid \"optional\"\nmsgstr \"facultatiu\"\n\n#: themes/default/templates/api.html.ep:135 themes/default/templates/api.html.ep:57 themes/default/templates/api.html.ep:66 themes/default/templates/api.html.ep:92 themes/default/templates/api.html.ep:99\nmsgid \"shortened_url\"\nmsgstr \"url_acorchida\"\n\n#. ($c->url_for('/')\n#: lib/Lstu/Controller/URL.pm:240\nmsgid \"The shortened URL %1 no longer exists.\"\nmsgstr \"L’URL acorchida %1 existís pas pus.\"\n"
  },
  {
    "path": "themes/default/lib/Lstu/I18N/pt_BR.po",
    "content": "# SOME DESCRIPTIVE TITLE.\n# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER\n# This file is distributed under the same license as the PACKAGE package.\n# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.\n#\nmsgid \"\"\nmsgstr \"\"\n\"Project-Id-Version: PACKAGE VERSION\\n\"\n\"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\\n\"\n\"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\\n\"\n\"Last-Translator: Automatically generated\\n\"\n\"Language-Team: none\\n\"\n\"Language: pt_BR\\n\"\n\"MIME-Version: 1.0\\n\"\n\"Content-Type: text/plain; charset=UTF-8\\n\"\n\"Content-Transfer-Encoding: 8bit\\n\"\n\n#. ($url)\n#: lib/Lstu/Controller/URL.pm:136\nmsgid \"%1 is not a valid URL.\"\nmsgstr \"\"\n\n#: themes/default/templates/api.html.ep:104\nmsgid \"A page with a table containing the same informations that the JSON response\"\nmsgstr \"\"\n\n#: themes/default/templates/layouts/default.html.ep:56\nmsgid \"About\"\nmsgstr \"\"\n\n#: themes/default/templates/stats.html.ep:18 themes/default/templates/stats.html.ep:19\nmsgid \"Admin password\"\nmsgstr \"\"\n\n#: lib/Lstu/Controller/Admin.pm:87 themes/default/templates/api.html.ep:130\nmsgid \"Bad password\"\nmsgstr \"\"\n\n#: themes/default/templates/layouts/default.html.ep:68\nmsgid \"Browser extensions\"\nmsgstr \"\"\n\n#: themes/default/templates/index.html.ep:22\nmsgid \"Copy to clipboard\"\nmsgstr \"\"\n\n#: themes/default/templates/stats.html.ep:62 themes/default/templates/stats.html.ep:78\nmsgid \"Counter\"\nmsgstr \"\"\n\n#: themes/default/templates/stats.html.ep:67 themes/default/templates/stats.html.ep:81\nmsgid \"Created\"\nmsgstr \"\"\n\n#: themes/default/templates/api.html.ep:52 themes/default/templates/index.html.ep:10 themes/default/templates/index.html.ep:9\nmsgid \"Custom shortened text\"\nmsgstr \"\"\n\n#: themes/default/templates/stats.html.ep:88\nmsgid \"Delete\"\nmsgstr \"\"\n\n#: themes/default/templates/stats.html.ep:41\nmsgid \"Export your URLs\"\nmsgstr \"\"\n\n#: themes/default/templates/api.html.ep:113 themes/default/templates/api.html.ep:153 themes/default/templates/api.html.ep:61 themes/default/templates/api.html.ep:79\nmsgid \"Failure reason\"\nmsgstr \"\"\n\n#: lib/Lstu/Controller/Stats.pm:43\nmsgid \"File imported\"\nmsgstr \"\"\n\n#: themes/default/templates/api.html.ep:109\nmsgid \"Get the details (visit counter, creation date, etc.) of a shortened URL.\"\nmsgstr \"\"\n\n#: themes/default/templates/index.html.ep:13 themes/default/templates/stats.html.ep:22\nmsgid \"Go!\"\nmsgstr \"\"\n\n#: themes/default/templates/partial/lstu.js.ep:30\nmsgid \"Hit Enter, then Ctrl+C to copy the short link\"\nmsgstr \"\"\n\n#: themes/default/templates/stats.html.ep:125\nmsgid \"Home\"\nmsgstr \"\"\n\n#: themes/default/templates/api.html.ep:134\nmsgid \"If \\\"action\\\" is defined to \\\"logout\\\":\"\nmsgstr \"\"\n\n#: themes/default/templates/api.html.ep:127\nmsgid \"If \\\"adminpwd\\\" is defined:\"\nmsgstr \"\"\n\n#: themes/default/templates/api.html.ep:123 themes/default/templates/api.html.ep:148 themes/default/templates/api.html.ep:21 themes/default/templates/api.html.ep:35 themes/default/templates/api.html.ep:53 themes/default/templates/api.html.ep:96\nmsgid \"If equal to \\\"json\\\", response will be in JSON format, HTML format otherwise\"\nmsgstr \"\"\n\n#. (config('page_offset')\n#: themes/default/templates/api.html.ep:89\nmsgid \"If you are logged in as admin (\\\"adminpwd\\\" or \\\"hashed_adminpwd\\\" setting), it will give you statistics for all URLs, sorted by the most visited first, paginated with pages containing %1 records.\"\nmsgstr \"\"\n\n#: themes/default/templates/api.html.ep:94\nmsgid \"If you are logged in as admin, you can provide a \\\"page\\\" parameter\"\nmsgstr \"\"\n\n#: themes/default/templates/stats.html.ep:37 themes/default/templates/stats.html.ep:40\nmsgid \"Import URLs\"\nmsgstr \"\"\n\n#: themes/default/templates/api.html.ep:87\nmsgid \"It will use Lstu's cookies to know which shortened URL it will return statistics for.\"\nmsgstr \"\"\n\n#: themes/default/templates/api.html.ep:113 themes/default/templates/api.html.ep:130 themes/default/templates/api.html.ep:153 themes/default/templates/api.html.ep:26 themes/default/templates/api.html.ep:61 themes/default/templates/api.html.ep:79\nmsgid \"JSON: failure\"\nmsgstr \"\"\n\n#: themes/default/templates/api.html.ep:112 themes/default/templates/api.html.ep:129 themes/default/templates/api.html.ep:137 themes/default/templates/api.html.ep:152 themes/default/templates/api.html.ep:25 themes/default/templates/api.html.ep:39 themes/default/templates/api.html.ep:60 themes/default/templates/api.html.ep:78\nmsgid \"JSON: success\"\nmsgstr \"\"\n\n#: themes/default/templates/layouts/default.html.ep:55\nmsgid \"License:\"\nmsgstr \"\"\n\n#: themes/default/templates/login.html.ep:8\nmsgid \"Login\"\nmsgstr \"\"\n\n#: themes/default/templates/layouts/default.html.ep:61\nmsgid \"Logout\"\nmsgstr \"\"\n\n#: themes/default/templates/stats.html.ep:15\nmsgid \"Logout from admin stats\"\nmsgstr \"\"\n\n#: themes/default/templates/stats.html.ep:120\nmsgid \"Next\"\nmsgstr \"\"\n\n#. ($c->config('contact')\n#: lib/Lstu/Controller/URL.pm:130\nmsgid \"No shortened URL available. Please retry or contact the administrator at %1. Your URL to shorten: %2\"\nmsgstr \"\"\n\n#: themes/default/templates/api.html.ep:119 themes/default/templates/api.html.ep:146 themes/default/templates/api.html.ep:17 themes/default/templates/api.html.ep:33 themes/default/templates/api.html.ep:49 themes/default/templates/api.html.ep:91\nmsgid \"Parameters:\"\nmsgstr \"\"\n\n#: themes/default/templates/login.html.ep:12\nmsgid \"Password\"\nmsgstr \"\"\n\n#: lib/Lstu/Controller/Authent.pm:35 themes/default/templates/api.html.ep:26\nmsgid \"Please, check your credentials: unable to authenticate.\"\nmsgstr \"\"\n\n#: themes/default/templates/stats.html.ep:118\nmsgid \"Previous\"\nmsgstr \"\"\n\n#: themes/default/templates/stats.html.ep:86\nmsgid \"QRCode\"\nmsgstr \"\"\n\n#: themes/default/templates/api.html.ep:104 themes/default/templates/api.html.ep:131 themes/default/templates/api.html.ep:138 themes/default/templates/api.html.ep:154 themes/default/templates/api.html.ep:27 themes/default/templates/api.html.ep:40 themes/default/templates/api.html.ep:62\nmsgid \"Response for HTML format\"\nmsgstr \"\"\n\n#: themes/default/templates/api.html.ep:103\nmsgid \"Response for JSON format\"\nmsgstr \"\"\n\n#: themes/default/templates/api.html.ep:110 themes/default/templates/api.html.ep:125 themes/default/templates/api.html.ep:150 themes/default/templates/api.html.ep:23 themes/default/templates/api.html.ep:37 themes/default/templates/api.html.ep:55 themes/default/templates/api.html.ep:67 themes/default/templates/api.html.ep:76 themes/default/templates/api.html.ep:98\nmsgid \"Response:\"\nmsgstr \"\"\n\n#: themes/default/templates/stats.html.ep:57 themes/default/templates/stats.html.ep:75\nmsgid \"Shortened URL\"\nmsgstr \"\"\n\n#: themes/default/templates/api.html.ep:135 themes/default/templates/api.html.ep:32\nmsgid \"Should always be successful\"\nmsgstr \"\"\n\n#: themes/default/templates/layouts/default.html.ep:63 themes/default/templates/login.html.ep:16 themes/default/templates/logout.html.ep:5\nmsgid \"Signin\"\nmsgstr \"\"\n\n#: lib/Lstu/Controller/URL.pm:53 themes/default/templates/api.html.ep:8\nmsgid \"Sorry, the API is disabled.\"\nmsgstr \"\"\n\n#: lib/Lstu/Controller/Stats.pm:45\nmsgid \"Sorry, unable to parse the provided file\"\nmsgstr \"\"\n\n#: themes/default/templates/layouts/default.html.ep:60 themes/default/templates/layouts/default.html.ep:66 themes/default/templates/stats.html.ep:9\nmsgid \"Statistics\"\nmsgstr \"\"\n\n#. ($url->host)\n#: lib/Lstu/Plugin/Helpers.pm:172\nmsgid \"The URL host or one of its redirection(s) (%1) is blacklisted at Spamhaus. I refuse to shorten it.\"\nmsgstr \"\"\n\n#. ($url)\n#: lib/Lstu/Plugin/Helpers.pm:178\nmsgid \"The URL or one of its redirection(s) (%1) is blacklisted in Google Safe Browsing database. I refuse to shorten it.\"\nmsgstr \"\"\n\n#. ($c->config('max_redir')\n#: lib/Lstu/Plugin/Helpers.pm:194\nmsgid \"The URL redirects %1 times or most. It's most likely a dangerous URL (spam, phishing, etc.). I refuse to shorten it.\"\nmsgstr \"\"\n\n#. ($url->host)\n#: lib/Lstu/Plugin/Helpers.pm:164\nmsgid \"The URL you want to shorten comes from a domain (%1) that is blacklisted on this server (usually because of spammers that use this domain).\"\nmsgstr \"\"\n\n#. ($c->url_for('/')\n#: lib/Lstu/Controller/Admin.pm:131 lib/Lstu/Controller/Stats.pm:200 lib/Lstu/Controller/URL.pm:260\nmsgid \"The shortened URL %1 doesn't exist.\"\nmsgstr \"\"\n\n#. ($c->url_for('/')\n#: lib/Lstu/Controller/URL.pm:258\nmsgid \"The shortened URL %1 no longer exists.\"\nmsgstr \"\"\n\n#. ($url)\n#: lib/Lstu/Controller/URL.pm:77\nmsgid \"The shortened text can't be \\\"a\\\", \\\"api\\\", \\\"d\\\", \\\"cookie\\\", \\\"stats\\\", \\\"fullstats\\\", \\\"login\\\" or \\\"logout\\\" or end with \\\".json\\\". Your URL to shorten: %1\"\nmsgstr \"\"\n\n#: themes/default/templates/api.html.ep:9\nmsgid \"This page is informational only.\"\nmsgstr \"\"\n\n#: themes/default/templates/api.html.ep:121\nmsgid \"To do an admin login, set it to the password defined in the settings (\\\"adminpwd\\\" or \\\"hashed_adminpwd\\\")\"\nmsgstr \"\"\n\n#: themes/default/templates/api.html.ep:122\nmsgid \"To do an admin logout, set it to \\\"logout\\\".\"\nmsgstr \"\"\n\n#: lib/Lstu/Controller/Admin.pm:29\nmsgid \"Too many bad passwords. You're banned.\"\nmsgstr \"\"\n\n#: themes/default/templates/api.html.ep:103 themes/default/templates/api.html.ep:112 themes/default/templates/stats.html.ep:52 themes/default/templates/stats.html.ep:72\nmsgid \"URL\"\nmsgstr \"\"\n\n#: themes/default/templates/api.html.ep:51 themes/default/templates/index.html.ep:5 themes/default/templates/index.html.ep:6\nmsgid \"URL to shorten\"\nmsgstr \"\"\n\n#. ($penalty/3600)\n#: lib/Lstu/Controller/URL.pm:41\nmsgid \"You asked to shorten too many URLs too quickly. You're banned for %1 hour(s).\"\nmsgstr \"\"\n\n#: lib/Lstu/Controller/Admin.pm:52 lib/Lstu/Controller/Authent.pm:26 themes/default/templates/api.html.ep:129 themes/default/templates/api.html.ep:25\nmsgid \"You have been successfully logged in.\"\nmsgstr \"\"\n\n#: lib/Lstu/Controller/Admin.pm:73 lib/Lstu/Controller/Authent.pm:65 themes/default/templates/api.html.ep:137 themes/default/templates/api.html.ep:39 themes/default/templates/logout.html.ep:3\nmsgid \"You have been successfully logged out.\"\nmsgstr \"\"\n\n#: themes/default/templates/api.html.ep:145\nmsgid \"You must be logged in as admin (\\\"adminpwd\\\" or \\\"hashed_adminpwd\\\" setting) to use it.\"\nmsgstr \"\"\n\n#: themes/default/templates/api.html.ep:47 themes/default/templates/api.html.ep:85\nmsgid \"You must be logged in to use it.\"\nmsgstr \"\"\n\n#: themes/default/templates/api.html.ep:138\nmsgid \"You will be redirected to Lstu statistics page\"\nmsgstr \"\"\n\n#: themes/default/templates/api.html.ep:154\nmsgid \"You will be redirected to Lstu statistics page with a message in case of failure\"\nmsgstr \"\"\n\n#: themes/default/templates/api.html.ep:40\nmsgid \"You will be redirected to Lstu successfully logged out interface\"\nmsgstr \"\"\n\n#: themes/default/templates/api.html.ep:27\nmsgid \"You will be redirected to the Lstu classic interface where you will be able to shorten URLs\"\nmsgstr \"\"\n\n#: themes/default/templates/api.html.ep:62\nmsgid \"You will be redirected to the Lstu classic interface with a message giving the shortened URL\"\nmsgstr \"\"\n\n#: themes/default/templates/api.html.ep:70\nmsgid \"You will be redirected to the targeted URL or to the Lstu interface with a message giving the failure reason\"\nmsgstr \"\"\n\n#: themes/default/templates/api.html.ep:131\nmsgid \"You will have the statistics page with the admin stats if you're succesfully logged in, or your stats and a failure message otherwise\"\nmsgstr \"\"\n\n#: lib/Lstu/Controller/Admin.pm:142\nmsgid \"You're not authenticated as the admin\"\nmsgstr \"\"\n\n#: themes/default/templates/api.html.ep:19\nmsgid \"Your login\"\nmsgstr \"\"\n\n#: themes/default/templates/api.html.ep:20\nmsgid \"Your password\"\nmsgstr \"\"\n\n#: themes/default/templates/api.html.ep:103 themes/default/templates/api.html.ep:112\nmsgid \"integer, how many unique visits of the shortened URL\"\nmsgstr \"\"\n\n#: themes/default/templates/api.html.ep:19 themes/default/templates/api.html.ep:20 themes/default/templates/api.html.ep:51\nmsgid \"mandatory\"\nmsgstr \"\"\n\n#: themes/default/templates/api.html.ep:121 themes/default/templates/api.html.ep:122 themes/default/templates/api.html.ep:123 themes/default/templates/api.html.ep:148 themes/default/templates/api.html.ep:21 themes/default/templates/api.html.ep:35 themes/default/templates/api.html.ep:52 themes/default/templates/api.html.ep:53 themes/default/templates/api.html.ep:94 themes/default/templates/api.html.ep:96\nmsgid \"optional\"\nmsgstr \"\"\n\n#: themes/default/templates/api.html.ep:100 themes/default/templates/api.html.ep:107 themes/default/templates/api.html.ep:143 themes/default/templates/api.html.ep:65 themes/default/templates/api.html.ep:74\nmsgid \"shortened_url\"\nmsgstr \"\"\n"
  },
  {
    "path": "themes/default/lib/Lstu/I18N/sv.po",
    "content": "# SOME DESCRIPTIVE TITLE.\n# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER\n# This file is distributed under the same license as the PACKAGE package.\n# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.\n#\nmsgid \"\"\nmsgstr \"\"\n\"Project-Id-Version: PACKAGE VERSION\\n\"\n\"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\\n\"\n\"PO-Revision-Date: 2020-01-03 20:14+0000\\n\"\n\"Last-Translator: Filip Bengtsson <filip@libreradio.org>\\n\"\n\"Language-Team: Swedish <https://weblate.framasoft.org/projects/lstu/\"\n\"development/sv/>\\n\"\n\"Language: sv\\n\"\n\"MIME-Version: 1.0\\n\"\n\"Content-Type: text/plain; charset=UTF-8\\n\"\n\"Content-Transfer-Encoding: 8bit\\n\"\n\"Plural-Forms: nplurals=2; plural=n != 1;\\n\"\n\"X-Generator: Weblate 3.9.1\\n\"\n\n#. ($url)\n#: lib/Lstu/Controller/URL.pm:118\nmsgid \"%1 is not a valid URL.\"\nmsgstr \"%1 är inte en giltig länk.\"\n\n#: themes/default/templates/api.html.ep:96\nmsgid \"A page with a table containing the same informations that the JSON response\"\nmsgstr \"En sida med en tabell innehållande samma information som JSON-responsen\"\n\n#: themes/default/templates/layouts/default.html.ep:54\nmsgid \"About\"\nmsgstr \"Om\"\n\n#: themes/default/templates/stats.html.ep:13 themes/default/templates/stats.html.ep:14\nmsgid \"Admin password\"\nmsgstr \"Administratörslösenord\"\n\n#: lib/Lstu/Controller/Admin.pm:87 themes/default/templates/api.html.ep:122\nmsgid \"Bad password\"\nmsgstr \"Ogiltigt lösenord\"\n\n#: themes/default/templates/index.html.ep:21\nmsgid \"Copy to clipboard\"\nmsgstr \"Kopiera till urklipp\"\n\n#: themes/default/templates/stats.html.ep:46\nmsgid \"Counter\"\nmsgstr \"Räknare\"\n\n#: themes/default/templates/stats.html.ep:47\nmsgid \"Created\"\nmsgstr \"Skapad\"\n\n#: themes/default/templates/api.html.ep:44 themes/default/templates/index.html.ep:10 themes/default/templates/index.html.ep:9\nmsgid \"Custom shortened text\"\nmsgstr \"Anpassad förkortad text\"\n\n#: themes/default/templates/stats.html.ep:52\nmsgid \"Delete\"\nmsgstr \"Radera\"\n\n#: themes/default/templates/stats.html.ep:36\nmsgid \"Export your URLs\"\nmsgstr \"Exportera dina länkar\"\n\n#: themes/default/templates/api.html.ep:105 themes/default/templates/api.html.ep:145 themes/default/templates/api.html.ep:53 themes/default/templates/api.html.ep:71\nmsgid \"Failure reason\"\nmsgstr \"Orsak för haveri\"\n\n#: lib/Lstu/Controller/Stats.pm:43\nmsgid \"File imported\"\nmsgstr \"Filen har importerats\"\n\n#: themes/default/templates/api.html.ep:101\nmsgid \"Get the details (visit counter, creation date, etc.) of a shortened URL.\"\nmsgstr \"\"\n\"Visa information (som besöksräknare och datum för skapande) för en förkortad \"\n\"länk.\"\n\n#: themes/default/templates/index.html.ep:12 themes/default/templates/stats.html.ep:17\nmsgid \"Go!\"\nmsgstr \"Kör!\"\n\n#: themes/default/templates/partial/lstu.js.ep:30\nmsgid \"Hit Enter, then Ctrl+C to copy the short link\"\nmsgstr \"Tryck Enter och sedan Crtl+C för att kopiera den nerkortade länken\"\n\n#: themes/default/templates/stats.html.ep:89\nmsgid \"Home\"\nmsgstr \"Hem\"\n\n#: themes/default/templates/api.html.ep:126\nmsgid \"If \\\"action\\\" is defined to \\\"logout\\\":\"\nmsgstr \"Om ”action” har satts till ”logout”:\"\n\n#: themes/default/templates/api.html.ep:119\nmsgid \"If \\\"adminpwd\\\" is defined:\"\nmsgstr \"Om ”adminpwd” har definierats:\"\n\n#: themes/default/templates/api.html.ep:115 themes/default/templates/api.html.ep:13 themes/default/templates/api.html.ep:140 themes/default/templates/api.html.ep:27 themes/default/templates/api.html.ep:45 themes/default/templates/api.html.ep:88\nmsgid \"If equal to \\\"json\\\", response will be in JSON format, HTML format otherwise\"\nmsgstr \"\"\n\"Om det är lika med ”json” kommer svaret ges i JSON-format, i annat fall som \"\n\"HTML\"\n\n#. (config('page_offset')\n#: themes/default/templates/api.html.ep:81\nmsgid \"If you are logged in as admin (\\\"adminpwd\\\" or \\\"hashed_adminpwd\\\" setting), it will give you statistics for all URLs, sorted by the most visited first, paginated with pages containing %1 records.\"\nmsgstr \"\"\n\"Om du är inloggad som administratör (inställningen ”adminpwd” eller \"\n\"”hashed_adminpwd”) kommer du få statistiken för alla länkar, sorterade efter \"\n\"antal besökare i fallande ordning och %1 poster per sida.\"\n\n#: themes/default/templates/api.html.ep:86\nmsgid \"If you are logged in as admin, you can provide a \\\"page\\\" parameter\"\nmsgstr \"Om du är inloggad som administratör kan du ange parametern ”sida”\"\n\n#: themes/default/templates/stats.html.ep:32 themes/default/templates/stats.html.ep:35\nmsgid \"Import URLs\"\nmsgstr \"Importera länkar\"\n\n#: themes/default/templates/api.html.ep:79\nmsgid \"It will use Lstu's cookies to know which shortened URL it will return statistics for.\"\nmsgstr \"\"\n\"Detta kommer använda LSTUs kakor för att avgöra vilken förkortad länks \"\n\"statistik som ska skickas.\"\n\n#: themes/default/templates/api.html.ep:105 themes/default/templates/api.html.ep:122 themes/default/templates/api.html.ep:145 themes/default/templates/api.html.ep:18 themes/default/templates/api.html.ep:53 themes/default/templates/api.html.ep:71\nmsgid \"JSON: failure\"\nmsgstr \"JSON: misslyckades\"\n\n#: themes/default/templates/api.html.ep:104 themes/default/templates/api.html.ep:121 themes/default/templates/api.html.ep:129 themes/default/templates/api.html.ep:144 themes/default/templates/api.html.ep:17 themes/default/templates/api.html.ep:31 themes/default/templates/api.html.ep:52 themes/default/templates/api.html.ep:70\nmsgid \"JSON: success\"\nmsgstr \"JSON: lyckades\"\n\n#: themes/default/templates/layouts/default.html.ep:53\nmsgid \"License:\"\nmsgstr \"Licens:\"\n\n#: themes/default/templates/login.html.ep:8\nmsgid \"Login\"\nmsgstr \"Logga in\"\n\n#: themes/default/templates/layouts/default.html.ep:59\nmsgid \"Logout\"\nmsgstr \"Logga ut\"\n\n#: themes/default/templates/stats.html.ep:10\nmsgid \"Logout from admin stats\"\nmsgstr \"Logga ut från administrationsstatistiken\"\n\n#: themes/default/templates/stats.html.ep:84\nmsgid \"Next\"\nmsgstr \"Nästa\"\n\n#. ($c->config('contact')\n#: lib/Lstu/Controller/URL.pm:112\nmsgid \"No shortened URL available. Please retry or contact the administrator at %1. Your URL to shorten: %2\"\nmsgstr \"\"\n\"Ingen förkortad länk tillgänglig. Försök kontakta administratören på %1. Din \"\n\"länk som skulle kortas: %2\"\n\n#: themes/default/templates/api.html.ep:111 themes/default/templates/api.html.ep:138 themes/default/templates/api.html.ep:25 themes/default/templates/api.html.ep:41 themes/default/templates/api.html.ep:83 themes/default/templates/api.html.ep:9\nmsgid \"Parameters:\"\nmsgstr \"Parameterar:\"\n\n#: themes/default/templates/login.html.ep:12\nmsgid \"Password\"\nmsgstr \"Lösenord\"\n\n#: lib/Lstu/Controller/Authent.pm:35 themes/default/templates/api.html.ep:18\nmsgid \"Please, check your credentials: unable to authenticate.\"\nmsgstr \"Kontrollera gärna dina uppgifter: kunde inte bekräfta identitet.\"\n\n#: themes/default/templates/stats.html.ep:82\nmsgid \"Previous\"\nmsgstr \"Föregående\"\n\n#: themes/default/templates/stats.html.ep:50\nmsgid \"QRCode\"\nmsgstr \"QR-kod\"\n\n#: themes/default/templates/api.html.ep:123 themes/default/templates/api.html.ep:130 themes/default/templates/api.html.ep:146 themes/default/templates/api.html.ep:19 themes/default/templates/api.html.ep:32 themes/default/templates/api.html.ep:54 themes/default/templates/api.html.ep:96\nmsgid \"Response for HTML format\"\nmsgstr \"Svar för HTML-format\"\n\n#: themes/default/templates/api.html.ep:95\nmsgid \"Response for JSON format\"\nmsgstr \"Svar för JSON-format\"\n\n#: themes/default/templates/api.html.ep:102 themes/default/templates/api.html.ep:117 themes/default/templates/api.html.ep:142 themes/default/templates/api.html.ep:15 themes/default/templates/api.html.ep:29 themes/default/templates/api.html.ep:47 themes/default/templates/api.html.ep:59 themes/default/templates/api.html.ep:68 themes/default/templates/api.html.ep:90\nmsgid \"Response:\"\nmsgstr \"Svar:\"\n\n#: themes/default/templates/stats.html.ep:45\nmsgid \"Shortened URL\"\nmsgstr \"Förkortad länk\"\n\n#: themes/default/templates/api.html.ep:127 themes/default/templates/api.html.ep:24\nmsgid \"Should always be successful\"\nmsgstr \"Borde alltid lyckas\"\n\n#: themes/default/templates/layouts/default.html.ep:61 themes/default/templates/login.html.ep:16 themes/default/templates/logout.html.ep:5\nmsgid \"Signin\"\nmsgstr \"Logga in\"\n\n#: lib/Lstu/Controller/Stats.pm:45\nmsgid \"Sorry, unable to parse the provided file\"\nmsgstr \"Kunde tyvärr inte tolka filen\"\n\n#: themes/default/templates/layouts/default.html.ep:58 themes/default/templates/layouts/default.html.ep:64 themes/default/templates/stats.html.ep:4\nmsgid \"Statistics\"\nmsgstr \"Statistik\"\n\n#. ($url->host)\n#: lib/Lstu/Plugin/Helpers.pm:172\nmsgid \"The URL host or one of its redirection(s) (%1) is blacklisted at Spamhaus. I refuse to shorten it.\"\nmsgstr \"\"\n\"Länkens värd eller en av dess omdirigeringar (%1) har svartlistats hos \"\n\"Spamhaus. Jag vägrar förkorta den.\"\n\n#. ($url)\n#: lib/Lstu/Plugin/Helpers.pm:178\nmsgid \"The URL or one of its redirection(s) (%1) is blacklisted in Google Safe Browsing database. I refuse to shorten it.\"\nmsgstr \"\"\n\"Länkens värd eller en av dess omdirigeringar (%1) har svartlistats hos \"\n\"Google Safe Browsing. Jag vägrar förkorta den.\"\n\n#. ($c->config('max_redir')\n#: lib/Lstu/Plugin/Helpers.pm:194\nmsgid \"The URL redirects %1 times or most. It's most likely a dangerous URL (spam, phishing, etc.). I refuse to shorten it.\"\nmsgstr \"\"\n\"Länken omdirigerar minst %1 gånger. Det är troligen en osäker länk (till \"\n\"exempel spam eller phishing). Jag vägrar förkorta den.\"\n\n#. ($url->host)\n#: lib/Lstu/Plugin/Helpers.pm:164\nmsgid \"The URL you want to shorten comes from a domain (%1) that is blacklisted on this server (usually because of spammers that use this domain).\"\nmsgstr \"\"\n\"Länken du vill förkorta kommer från en domän (%1) har på den här servern (\"\n\"troligen på grund av att spammare använder den här domänen). Jag vägrar \"\n\"förkorta den.\"\n\n#. ($c->url_for('/')\n#: lib/Lstu/Controller/Admin.pm:131 lib/Lstu/Controller/Stats.pm:184 lib/Lstu/Controller/URL.pm:229\nmsgid \"The shortened URL %1 doesn't exist.\"\nmsgstr \"Den förkortade länken %1 finns inte.\"\n\n#. ($url)\n#: lib/Lstu/Controller/URL.pm:59\nmsgid \"The shortened text can't be \\\"a\\\", \\\"api\\\", \\\"d\\\", \\\"cookie\\\", \\\"stats\\\", \\\"fullstats\\\", \\\"login\\\" or \\\"logout\\\" or end with \\\".json\\\". Your URL to shorten: %1\"\nmsgstr \"\"\n\"Den nerkortade texten får inte vara ”a”, ”api”, ”cookie”, ”d”, ”stats”, \"\n\"”fullstats”, ”login”, ”logout” eller sluta med ”.json”. Din länk att \"\n\"förkorta: %1\"\n\n#: themes/default/templates/api.html.ep:113\nmsgid \"To do an admin login, set it to the password defined in the settings (\\\"adminpwd\\\" or \\\"hashed_adminpwd\\\")\"\nmsgstr \"\"\n\"För att logga in som administratör, ändra det till lösenordet som anges i \"\n\"inställningen ”adminpwd” eller ”hashed_adminpwd”\"\n\n#: themes/default/templates/api.html.ep:114\nmsgid \"To do an admin logout, set it to \\\"logout\\\".\"\nmsgstr \"För att logga ut som administratör, ändra det till ”logout”.\"\n\n#: lib/Lstu/Controller/Admin.pm:29\nmsgid \"Too many bad passwords. You're banned.\"\nmsgstr \"För många ogiltiga lösenord. Du har blockerats.\"\n\n#: themes/default/templates/api.html.ep:104 themes/default/templates/api.html.ep:95 themes/default/templates/stats.html.ep:44\nmsgid \"URL\"\nmsgstr \"Länk\"\n\n#: themes/default/templates/api.html.ep:43 themes/default/templates/index.html.ep:5 themes/default/templates/index.html.ep:6\nmsgid \"URL to shorten\"\nmsgstr \"Länk att förkorta\"\n\n#. ($penalty/3600)\n#: lib/Lstu/Controller/URL.pm:35\nmsgid \"You asked to shorten too many URLs too quickly. You're banned for %1 hour(s).\"\nmsgstr \"\"\n\"Nu har du bett om för många länkförkortningar under för kort tid. Du har \"\n\"blockerats i %1 timmar.\"\n\n#: lib/Lstu/Controller/Admin.pm:52 lib/Lstu/Controller/Authent.pm:26 themes/default/templates/api.html.ep:121 themes/default/templates/api.html.ep:17\nmsgid \"You have been successfully logged in.\"\nmsgstr \"Du har loggats in.\"\n\n#: lib/Lstu/Controller/Admin.pm:73 lib/Lstu/Controller/Authent.pm:65 themes/default/templates/api.html.ep:129 themes/default/templates/api.html.ep:31 themes/default/templates/logout.html.ep:3\nmsgid \"You have been successfully logged out.\"\nmsgstr \"Du har loggats ut.\"\n\n#: themes/default/templates/api.html.ep:137\nmsgid \"You must be logged in as admin (\\\"adminpwd\\\" or \\\"hashed_adminpwd\\\" setting) to use it.\"\nmsgstr \"\"\n\"Du måste vara inloggad som administratör (inställningen ”adminpwd” eller \"\n\"”hashed_adminpwd”) för att använda den.\"\n\n#: themes/default/templates/api.html.ep:39 themes/default/templates/api.html.ep:77\nmsgid \"You must be logged in to use it.\"\nmsgstr \"Du måste vara inloggad för att använda den.\"\n\n#: themes/default/templates/api.html.ep:130\nmsgid \"You will be redirected to Lstu statistics page\"\nmsgstr \"Du kommer skickas vidare till sidan med statistik för LSTU\"\n\n#: themes/default/templates/api.html.ep:146\nmsgid \"You will be redirected to Lstu statistics page with a message in case of failure\"\nmsgstr \"\"\n\"Du kommer skickas vidare till sidan med statistik för LSTU med ett \"\n\"meddelande om det inte lyckas\"\n\n#: themes/default/templates/api.html.ep:32\nmsgid \"You will be redirected to Lstu successfully logged out interface\"\nmsgstr \"Du kommer skickas vidare till sidan för lyckad utloggning från LSTU\"\n\n#: themes/default/templates/api.html.ep:19\nmsgid \"You will be redirected to the Lstu classic interface where you will be able to shorten URLs\"\nmsgstr \"\"\n\"Du kommer skickas vidare till LSTUs klassiska gränssnitt där du kan förkorta \"\n\"länkar\"\n\n#: themes/default/templates/api.html.ep:54\nmsgid \"You will be redirected to the Lstu classic interface with a message giving the shortened URL\"\nmsgstr \"\"\n\"Du kommer skickas vidare till LSTUs klassiska gränssnitt med ett meddelande \"\n\"innehållande den förkortade länken\"\n\n#: themes/default/templates/api.html.ep:62\nmsgid \"You will be redirected to the targeted URL or to the Lstu interface with a message giving the failure reason\"\nmsgstr \"\"\n\"Du kommer skickas vidare till mållänken eller en LTSU-sida med en förklaring \"\n\"av vad som gått snett\"\n\n#: themes/default/templates/api.html.ep:123\nmsgid \"You will have the statistics page with the admin stats if you're succesfully logged in, or your stats and a failure message otherwise\"\nmsgstr \"\"\n\"Du kommer få statistiksidan med administrationsstatistiken om du har loggats \"\n\"in, och annars statistiken och ett felmeddelande\"\n\n#: lib/Lstu/Controller/Admin.pm:142\nmsgid \"You're not authenticated as the admin\"\nmsgstr \"Du är inte inloggad som administratör\"\n\n#: themes/default/templates/api.html.ep:11\nmsgid \"Your login\"\nmsgstr \"Dina inloggningsuppgifter\"\n\n#: themes/default/templates/api.html.ep:12\nmsgid \"Your password\"\nmsgstr \"Ditt lösenord\"\n\n#: themes/default/templates/api.html.ep:104 themes/default/templates/api.html.ep:95\nmsgid \"integer, how many unique visits of the shortened URL\"\nmsgstr \"heltal, hur många enskilda besökare den förkortade länken har haft\"\n\n#: themes/default/templates/api.html.ep:11 themes/default/templates/api.html.ep:12 themes/default/templates/api.html.ep:43\nmsgid \"mandatory\"\nmsgstr \"obligatoriskt\"\n\n#: themes/default/templates/api.html.ep:113 themes/default/templates/api.html.ep:114 themes/default/templates/api.html.ep:115 themes/default/templates/api.html.ep:13 themes/default/templates/api.html.ep:140 themes/default/templates/api.html.ep:27 themes/default/templates/api.html.ep:44 themes/default/templates/api.html.ep:45 themes/default/templates/api.html.ep:86 themes/default/templates/api.html.ep:88\nmsgid \"optional\"\nmsgstr \"frivilligt\"\n\n#: themes/default/templates/api.html.ep:135 themes/default/templates/api.html.ep:57 themes/default/templates/api.html.ep:66 themes/default/templates/api.html.ep:92 themes/default/templates/api.html.ep:99\nmsgid \"shortened_url\"\nmsgstr \"forkortad_lank\"\n"
  },
  {
    "path": "themes/default/lib/Lstu/I18N.pm",
    "content": "package Lstu::I18N;\n\nuse base 'Locale::Maketext';\nuse File::Basename qw/dirname/;\nuse Locale::Maketext::Lexicon {\n    _auto => 1,\n    _decode => 1,\n    _style  => 'gettext',\n    '*' => [Gettext => dirname(__FILE__) . '/I18N/*.po']\n};\n\n1;\n"
  },
  {
    "path": "themes/default/public/browserconfig.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<browserconfig>\n    <msapplication>\n        <tile>\n            <square70x70logo src=\"/img/mstile-lstu70.png\"/>\n            <square150x150logo src=\"/img/mstile-lstu150.png\"/>\n            <square310x310logo src=\"/img/mstile-lstu310.png\"/>\n            <wide310x150logo src=\"/img/mstile-lstu150w.png\"/>\n            <TileColor>#ffc40d</TileColor>\n        </tile>\n    </msapplication>\n</browserconfig>\n"
  },
  {
    "path": "themes/default/public/css/animation.css",
    "content": "/*\n   Animation example, for spinners\n*/\n.animate-spin {\n  -moz-animation: spin 2s infinite linear;\n  -o-animation: spin 2s infinite linear;\n  -webkit-animation: spin 2s infinite linear;\n  animation: spin 2s infinite linear;\n  display: inline-block;\n}\n@-moz-keyframes spin {\n  0% {\n    -moz-transform: rotate(0deg);\n    -o-transform: rotate(0deg);\n    -webkit-transform: rotate(0deg);\n    transform: rotate(0deg);\n  }\n\n  100% {\n    -moz-transform: rotate(359deg);\n    -o-transform: rotate(359deg);\n    -webkit-transform: rotate(359deg);\n    transform: rotate(359deg);\n  }\n}\n@-webkit-keyframes spin {\n  0% {\n    -moz-transform: rotate(0deg);\n    -o-transform: rotate(0deg);\n    -webkit-transform: rotate(0deg);\n    transform: rotate(0deg);\n  }\n\n  100% {\n    -moz-transform: rotate(359deg);\n    -o-transform: rotate(359deg);\n    -webkit-transform: rotate(359deg);\n    transform: rotate(359deg);\n  }\n}\n@-o-keyframes spin {\n  0% {\n    -moz-transform: rotate(0deg);\n    -o-transform: rotate(0deg);\n    -webkit-transform: rotate(0deg);\n    transform: rotate(0deg);\n  }\n\n  100% {\n    -moz-transform: rotate(359deg);\n    -o-transform: rotate(359deg);\n    -webkit-transform: rotate(359deg);\n    transform: rotate(359deg);\n  }\n}\n@-ms-keyframes spin {\n  0% {\n    -moz-transform: rotate(0deg);\n    -o-transform: rotate(0deg);\n    -webkit-transform: rotate(0deg);\n    transform: rotate(0deg);\n  }\n\n  100% {\n    -moz-transform: rotate(359deg);\n    -o-transform: rotate(359deg);\n    -webkit-transform: rotate(359deg);\n    transform: rotate(359deg);\n  }\n}\n@keyframes spin {\n  0% {\n    -moz-transform: rotate(0deg);\n    -o-transform: rotate(0deg);\n    -webkit-transform: rotate(0deg);\n    transform: rotate(0deg);\n  }\n\n  100% {\n    -moz-transform: rotate(359deg);\n    -o-transform: rotate(359deg);\n    -webkit-transform: rotate(359deg);\n    transform: rotate(359deg);\n  }\n}\n"
  },
  {
    "path": "themes/default/public/css/bootstrap-lstu.min.css",
    "content": "/*!\n * Bootstrap v3.3.4 (http://getbootstrap.com)\n * Copyright 2011-2015 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n */\n/*!\n * Generated using the Bootstrap Customizer (http://getbootstrap.com/customize/?id=8d56756b325f9f22f4eb)\n * Config saved to config.json and https://gist.github.com/8d56756b325f9f22f4eb\n */\n/*! normalize.css v3.0.2 | MIT License | git.io/normalize */\nhtml{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}h1{font-size:2em;margin:.67em 0}mark{background:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box;height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input[type=checkbox],input[type=radio]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}legend{border:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-collapse:collapse;border-spacing:0}legend,td,th{padding:0}\n/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */\n@media print{*,:after,:before{background:0 0!important;color:#000!important;-webkit-box-shadow:none!important;box-shadow:none!important;text-shadow:none!important}a,a:visited{text-decoration:underline}a[href]:after{content:\" (\" attr(href) \")\"}abbr[title]:after{content:\" (\" attr(title) \")\"}a[href^=\"#\"]:after,a[href^=\"javascript:\"]:after{content:\"\"}blockquote,pre{border:1px solid #999}thead{display:table-header-group}blockquote,img,pre,tr{page-break-inside:avoid}img{max-width:100%!important}h2,h3,p{orphans:3;widows:3}h2,h3{page-break-after:avoid}select{background:#fff!important}.navbar{display:none}.btn>.caret,.dropup>.btn>.caret{border-top-color:#000!important}.label{border:1px solid #000}.table{border-collapse:collapse!important}.table td,.table th{background-color:#fff!important}.table-bordered td,.table-bordered th{border:1px solid #ddd!important}}*,:after,:before,input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:10px;-webkit-tap-highlight-color:transparent}body{font-family:\"Helvetica Neue\",Helvetica,Arial,sans-serif;font-size:14px;line-height:1.42857143;color:#333;background-color:#fff;padding-top:40px;padding-bottom:40px}button,input,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}a{color:#337ab7;text-decoration:none}a:focus,a:hover{color:#23527c;text-decoration:underline}a:focus,input[type=checkbox]:focus,input[type=file]:focus,input[type=radio]:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}figure{margin:0}img{vertical-align:middle}.img-responsive{display:block;max-width:100%;height:auto}.img-rounded{border-radius:6px}.img-thumbnail{padding:4px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out;display:inline-block;max-width:100%;height:auto}.img-circle{border-radius:50%}hr{margin-top:20px;margin-bottom:20px;border:0;border-top:1px solid #eee}.sr-only{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}[role=button]{cursor:pointer}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{font-family:inherit;font-weight:500;line-height:1.1;color:inherit}.h1 .small,.h1 small,.h2 .small,.h2 small,.h3 .small,.h3 small,.h4 .small,.h4 small,.h5 .small,.h5 small,.h6 .small,.h6 small,h1 .small,h1 small,h2 .small,h2 small,h3 .small,h3 small,h4 .small,h4 small,h5 .small,h5 small,h6 .small,h6 small{font-weight:400;line-height:1;color:#777}.h1,.h2,.h3,h1,h2,h3{margin-top:20px;margin-bottom:10px}.h1 .small,.h1 small,.h2 .small,.h2 small,.h3 .small,.h3 small,h1 .small,h1 small,h2 .small,h2 small,h3 .small,h3 small{font-size:65%}.h4,.h5,.h6,dl,h4,h5,h6,ol,ul{margin-top:10px;margin-bottom:10px}.h4 .small,.h4 small,.h5 .small,.h5 small,.h6 .small,.h6 small,h4 .small,h4 small,h5 .small,h5 small,h6 .small,h6 small{font-size:75%}.h1,h1{font-size:36px}.h2,h2{font-size:30px}.h3,h3{font-size:24px}.h4,h4{font-size:18px}.h5,h5{font-size:14px}.h6,h6{font-size:12px}p{margin:0 0 10px}.lead{margin-bottom:20px;font-size:16px;font-weight:300;line-height:1.4}@media (min-width:768px){.lead{font-size:21px}}.small,small{font-size:85%}.mark,mark{background-color:#fcf8e3;padding:.2em}.text-left,th{text-align:left}.text-right{text-align:right}.text-center{text-align:center}.text-justify{text-align:justify}.text-nowrap{white-space:nowrap}.text-lowercase{text-transform:lowercase}.text-uppercase{text-transform:uppercase}.text-capitalize{text-transform:capitalize}.text-muted{color:#777}.text-primary{color:#337ab7}a.text-primary:hover{color:#286090}.text-success{color:#3c763d}a.text-success:hover{color:#2b542c}.text-info{color:#31708f}a.text-info:hover{color:#245269}.text-warning{color:#8a6d3b}a.text-warning:hover{color:#66512c}.text-danger{color:#a94442}a.text-danger:hover{color:#843534}.bg-primary{color:#fff;background-color:#337ab7}a.bg-primary:hover{background-color:#286090}.bg-success{background-color:#dff0d8}a.bg-success:hover{background-color:#c1e2b3}.bg-info{background-color:#d9edf7}a.bg-info:hover{background-color:#afd9ee}.bg-warning{background-color:#fcf8e3}a.bg-warning:hover{background-color:#f7ecb5}.bg-danger{background-color:#f2dede}a.bg-danger:hover{background-color:#e4b9b9}.page-header{padding-bottom:9px;margin:40px 0 20px;border-bottom:1px solid #eee}dl,ol,ul{margin-top:0}.alert>p,.alert>ul,ol ol,ol ul,ul ol,ul ul{margin-bottom:0}.list-inline,.list-unstyled{padding-left:0;list-style:none}.list-inline{margin-left:-5px}.list-inline>li{display:inline-block;padding-left:5px;padding-right:5px}dl{margin-bottom:20px}dd,dt{line-height:1.42857143}dt{font-weight:700}dd{margin-left:0}@media (min-width:768px){.dl-horizontal dt{float:left;width:160px;clear:left;text-align:right;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}}abbr[data-original-title],abbr[title]{cursor:help;border-bottom:1px dotted #777}.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:10px 20px;margin:0 0 20px;font-size:17.5px;border-left:5px solid #eee}blockquote ol:last-child,blockquote p:last-child,blockquote ul:last-child{margin-bottom:0}blockquote .small,blockquote footer,blockquote small{display:block;font-size:80%;line-height:1.42857143;color:#777}blockquote .small:before,blockquote footer:before,blockquote small:before{content:'\\2014 \\00A0'}.blockquote-reverse,blockquote.pull-right{padding-right:15px;padding-left:0;border-right:5px solid #eee;border-left:0;text-align:right}.blockquote-reverse .small:before,.blockquote-reverse footer:before,.blockquote-reverse small:before,blockquote.pull-right .small:before,blockquote.pull-right footer:before,blockquote.pull-right small:before{content:''}.blockquote-reverse .small:after,.blockquote-reverse footer:after,.blockquote-reverse small:after,blockquote.pull-right .small:after,blockquote.pull-right footer:after,blockquote.pull-right small:after{content:'\\00A0 \\2014'}address{margin-bottom:20px;font-style:normal;line-height:1.42857143}@media (min-width:768px){.container{width:750px}}@media (min-width:992px){.container{width:970px}}@media (min-width:1200px){.container{width:1170px}}.container-fluid{margin-right:auto;margin-left:auto;padding-left:15px;padding-right:15px}.row{margin-left:-15px;margin-right:-15px}.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{position:relative;min-height:1px;padding-left:15px;padding-right:15px}.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{float:left}.col-xs-12{width:100%}.col-xs-11{width:91.66666667%}.col-xs-10{width:83.33333333%}.col-xs-9{width:75%}.col-xs-8{width:66.66666667%}.col-xs-7{width:58.33333333%}.col-xs-6{width:50%}.col-xs-5{width:41.66666667%}.col-xs-4{width:33.33333333%}.col-xs-3{width:25%}.col-xs-2{width:16.66666667%}.col-xs-1{width:8.33333333%}.col-xs-pull-12{right:100%}.col-xs-pull-11{right:91.66666667%}.col-xs-pull-10{right:83.33333333%}.col-xs-pull-9{right:75%}.col-xs-pull-8{right:66.66666667%}.col-xs-pull-7{right:58.33333333%}.col-xs-pull-6{right:50%}.col-xs-pull-5{right:41.66666667%}.col-xs-pull-4{right:33.33333333%}.col-xs-pull-3{right:25%}.col-xs-pull-2{right:16.66666667%}.col-xs-pull-1{right:8.33333333%}.col-xs-pull-0{right:auto}.col-xs-push-12{left:100%}.col-xs-push-11{left:91.66666667%}.col-xs-push-10{left:83.33333333%}.col-xs-push-9{left:75%}.col-xs-push-8{left:66.66666667%}.col-xs-push-7{left:58.33333333%}.col-xs-push-6{left:50%}.col-xs-push-5{left:41.66666667%}.col-xs-push-4{left:33.33333333%}.col-xs-push-3{left:25%}.col-xs-push-2{left:16.66666667%}.col-xs-push-1{left:8.33333333%}.col-xs-push-0{left:auto}.col-xs-offset-12{margin-left:100%}.col-xs-offset-11{margin-left:91.66666667%}.col-xs-offset-10{margin-left:83.33333333%}.col-xs-offset-9{margin-left:75%}.col-xs-offset-8{margin-left:66.66666667%}.col-xs-offset-7{margin-left:58.33333333%}.col-xs-offset-6{margin-left:50%}.col-xs-offset-5{margin-left:41.66666667%}.col-xs-offset-4{margin-left:33.33333333%}.col-xs-offset-3{margin-left:25%}.col-xs-offset-2{margin-left:16.66666667%}.col-xs-offset-1{margin-left:8.33333333%}.col-xs-offset-0{margin-left:0}@media (min-width:768px){.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9{float:left}.col-sm-12{width:100%}.col-sm-11{width:91.66666667%}.col-sm-10{width:83.33333333%}.col-sm-9{width:75%}.col-sm-8{width:66.66666667%}.col-sm-7{width:58.33333333%}.col-sm-6{width:50%}.col-sm-5{width:41.66666667%}.col-sm-4{width:33.33333333%}.col-sm-3{width:25%}.col-sm-2{width:16.66666667%}.col-sm-1{width:8.33333333%}.col-sm-pull-12{right:100%}.col-sm-pull-11{right:91.66666667%}.col-sm-pull-10{right:83.33333333%}.col-sm-pull-9{right:75%}.col-sm-pull-8{right:66.66666667%}.col-sm-pull-7{right:58.33333333%}.col-sm-pull-6{right:50%}.col-sm-pull-5{right:41.66666667%}.col-sm-pull-4{right:33.33333333%}.col-sm-pull-3{right:25%}.col-sm-pull-2{right:16.66666667%}.col-sm-pull-1{right:8.33333333%}.col-sm-pull-0{right:auto}.col-sm-push-12{left:100%}.col-sm-push-11{left:91.66666667%}.col-sm-push-10{left:83.33333333%}.col-sm-push-9{left:75%}.col-sm-push-8{left:66.66666667%}.col-sm-push-7{left:58.33333333%}.col-sm-push-6{left:50%}.col-sm-push-5{left:41.66666667%}.col-sm-push-4{left:33.33333333%}.col-sm-push-3{left:25%}.col-sm-push-2{left:16.66666667%}.col-sm-push-1{left:8.33333333%}.col-sm-push-0{left:auto}.col-sm-offset-12{margin-left:100%}.col-sm-offset-11{margin-left:91.66666667%}.col-sm-offset-10{margin-left:83.33333333%}.col-sm-offset-9{margin-left:75%}.col-sm-offset-8{margin-left:66.66666667%}.col-sm-offset-7{margin-left:58.33333333%}.col-sm-offset-6{margin-left:50%}.col-sm-offset-5{margin-left:41.66666667%}.col-sm-offset-4{margin-left:33.33333333%}.col-sm-offset-3{margin-left:25%}.col-sm-offset-2{margin-left:16.66666667%}.col-sm-offset-1{margin-left:8.33333333%}.col-sm-offset-0{margin-left:0}}@media (min-width:992px){.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9{float:left}.col-md-12{width:100%}.col-md-11{width:91.66666667%}.col-md-10{width:83.33333333%}.col-md-9{width:75%}.col-md-8{width:66.66666667%}.col-md-7{width:58.33333333%}.col-md-6{width:50%}.col-md-5{width:41.66666667%}.col-md-4{width:33.33333333%}.col-md-3{width:25%}.col-md-2{width:16.66666667%}.col-md-1{width:8.33333333%}.col-md-pull-12{right:100%}.col-md-pull-11{right:91.66666667%}.col-md-pull-10{right:83.33333333%}.col-md-pull-9{right:75%}.col-md-pull-8{right:66.66666667%}.col-md-pull-7{right:58.33333333%}.col-md-pull-6{right:50%}.col-md-pull-5{right:41.66666667%}.col-md-pull-4{right:33.33333333%}.col-md-pull-3{right:25%}.col-md-pull-2{right:16.66666667%}.col-md-pull-1{right:8.33333333%}.col-md-pull-0{right:auto}.col-md-push-12{left:100%}.col-md-push-11{left:91.66666667%}.col-md-push-10{left:83.33333333%}.col-md-push-9{left:75%}.col-md-push-8{left:66.66666667%}.col-md-push-7{left:58.33333333%}.col-md-push-6{left:50%}.col-md-push-5{left:41.66666667%}.col-md-push-4{left:33.33333333%}.col-md-push-3{left:25%}.col-md-push-2{left:16.66666667%}.col-md-push-1{left:8.33333333%}.col-md-push-0{left:auto}.col-md-offset-12{margin-left:100%}.col-md-offset-11{margin-left:91.66666667%}.col-md-offset-10{margin-left:83.33333333%}.col-md-offset-9{margin-left:75%}.col-md-offset-8{margin-left:66.66666667%}.col-md-offset-7{margin-left:58.33333333%}.col-md-offset-6{margin-left:50%}.col-md-offset-5{margin-left:41.66666667%}.col-md-offset-4{margin-left:33.33333333%}.col-md-offset-3{margin-left:25%}.col-md-offset-2{margin-left:16.66666667%}.col-md-offset-1{margin-left:8.33333333%}.col-md-offset-0{margin-left:0}}@media (min-width:1200px){.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9{float:left}.col-lg-12{width:100%}.col-lg-11{width:91.66666667%}.col-lg-10{width:83.33333333%}.col-lg-9{width:75%}.col-lg-8{width:66.66666667%}.col-lg-7{width:58.33333333%}.col-lg-6{width:50%}.col-lg-5{width:41.66666667%}.col-lg-4{width:33.33333333%}.col-lg-3{width:25%}.col-lg-2{width:16.66666667%}.col-lg-1{width:8.33333333%}.col-lg-pull-12{right:100%}.col-lg-pull-11{right:91.66666667%}.col-lg-pull-10{right:83.33333333%}.col-lg-pull-9{right:75%}.col-lg-pull-8{right:66.66666667%}.col-lg-pull-7{right:58.33333333%}.col-lg-pull-6{right:50%}.col-lg-pull-5{right:41.66666667%}.col-lg-pull-4{right:33.33333333%}.col-lg-pull-3{right:25%}.col-lg-pull-2{right:16.66666667%}.col-lg-pull-1{right:8.33333333%}.col-lg-pull-0{right:auto}.col-lg-push-12{left:100%}.col-lg-push-11{left:91.66666667%}.col-lg-push-10{left:83.33333333%}.col-lg-push-9{left:75%}.col-lg-push-8{left:66.66666667%}.col-lg-push-7{left:58.33333333%}.col-lg-push-6{left:50%}.col-lg-push-5{left:41.66666667%}.col-lg-push-4{left:33.33333333%}.col-lg-push-3{left:25%}.col-lg-push-2{left:16.66666667%}.col-lg-push-1{left:8.33333333%}.col-lg-push-0{left:auto}.col-lg-offset-12{margin-left:100%}.col-lg-offset-11{margin-left:91.66666667%}.col-lg-offset-10{margin-left:83.33333333%}.col-lg-offset-9{margin-left:75%}.col-lg-offset-8{margin-left:66.66666667%}.col-lg-offset-7{margin-left:58.33333333%}.col-lg-offset-6{margin-left:50%}.col-lg-offset-5{margin-left:41.66666667%}.col-lg-offset-4{margin-left:33.33333333%}.col-lg-offset-3{margin-left:25%}.col-lg-offset-2{margin-left:16.66666667%}.col-lg-offset-1{margin-left:8.33333333%}.col-lg-offset-0{margin-left:0}}table{background-color:transparent}caption{padding-top:8px;padding-bottom:8px;color:#777;text-align:left}.table{width:100%;max-width:100%;margin-bottom:20px}.table>thead>tr>th{padding:8px;line-height:1.42857143;border-top:1px solid #ddd}.table>tbody>tr>td,.table>tbody>tr>th,.table>tfoot>tr>td,.table>tfoot>tr>th,.table>thead>tr>td{padding:8px;line-height:1.42857143;vertical-align:top;border-top:1px solid #ddd}.table>thead>tr>th{vertical-align:bottom;border-bottom:2px solid #ddd}.table>caption+thead>tr:first-child>td,.table>caption+thead>tr:first-child>th,.table>colgroup+thead>tr:first-child>td,.table>colgroup+thead>tr:first-child>th,.table>thead:first-child>tr:first-child>td,.table>thead:first-child>tr:first-child>th{border-top:0}.table>tbody+tbody{border-top:2px solid #ddd}.table .table{background-color:#fff}.table-condensed>tbody>tr>td,.table-condensed>tbody>tr>th,.table-condensed>tfoot>tr>td,.table-condensed>tfoot>tr>th,.table-condensed>thead>tr>td,.table-condensed>thead>tr>th{padding:5px}.table-bordered,.table-bordered>tbody>tr>td,.table-bordered>tbody>tr>th,.table-bordered>tfoot>tr>td,.table-bordered>tfoot>tr>th,.table-bordered>thead>tr>td,.table-bordered>thead>tr>th{border:1px solid #ddd}.table-bordered>thead>tr>td,.table-bordered>thead>tr>th{border-bottom-width:2px}.table-striped>tbody>tr:nth-of-type(odd){background-color:#f9f9f9}.table-hover>tbody>tr:hover,.table>tbody>tr.active>td,.table>tbody>tr.active>th,.table>tbody>tr>td.active,.table>tbody>tr>th.active,.table>tfoot>tr.active>td,.table>tfoot>tr.active>th,.table>tfoot>tr>td.active,.table>tfoot>tr>th.active,.table>thead>tr.active>td,.table>thead>tr.active>th,.table>thead>tr>td.active,.table>thead>tr>th.active{background-color:#f5f5f5}table col[class*=col-]{position:static;float:none;display:table-column}table td[class*=col-],table th[class*=col-]{position:static;float:none;display:table-cell}.table-hover>tbody>tr.active:hover>td,.table-hover>tbody>tr.active:hover>th,.table-hover>tbody>tr:hover>.active,.table-hover>tbody>tr>td.active:hover,.table-hover>tbody>tr>th.active:hover{background-color:#e8e8e8}.table>tbody>tr.success>td,.table>tbody>tr.success>th,.table>tbody>tr>td.success,.table>tbody>tr>th.success,.table>tfoot>tr.success>td,.table>tfoot>tr.success>th,.table>tfoot>tr>td.success,.table>tfoot>tr>th.success,.table>thead>tr.success>td,.table>thead>tr.success>th,.table>thead>tr>td.success,.table>thead>tr>th.success{background-color:#dff0d8}.table-hover>tbody>tr.success:hover>td,.table-hover>tbody>tr.success:hover>th,.table-hover>tbody>tr:hover>.success,.table-hover>tbody>tr>td.success:hover,.table-hover>tbody>tr>th.success:hover{background-color:#d0e9c6}.table>tbody>tr.info>td,.table>tbody>tr.info>th,.table>tbody>tr>td.info,.table>tbody>tr>th.info,.table>tfoot>tr.info>td,.table>tfoot>tr.info>th,.table>tfoot>tr>td.info,.table>tfoot>tr>th.info,.table>thead>tr.info>td,.table>thead>tr.info>th,.table>thead>tr>td.info,.table>thead>tr>th.info{background-color:#d9edf7}.table-hover>tbody>tr.info:hover>td,.table-hover>tbody>tr.info:hover>th,.table-hover>tbody>tr:hover>.info,.table-hover>tbody>tr>td.info:hover,.table-hover>tbody>tr>th.info:hover{background-color:#c4e3f3}.table>tbody>tr.warning>td,.table>tbody>tr.warning>th,.table>tbody>tr>td.warning,.table>tbody>tr>th.warning,.table>tfoot>tr.warning>td,.table>tfoot>tr.warning>th,.table>tfoot>tr>td.warning,.table>tfoot>tr>th.warning,.table>thead>tr.warning>td,.table>thead>tr.warning>th,.table>thead>tr>td.warning,.table>thead>tr>th.warning{background-color:#fcf8e3}.table-hover>tbody>tr.warning:hover>td,.table-hover>tbody>tr.warning:hover>th,.table-hover>tbody>tr:hover>.warning,.table-hover>tbody>tr>td.warning:hover,.table-hover>tbody>tr>th.warning:hover{background-color:#faf2cc}.table>tbody>tr.danger>td,.table>tbody>tr.danger>th,.table>tbody>tr>td.danger,.table>tbody>tr>th.danger,.table>tfoot>tr.danger>td,.table>tfoot>tr.danger>th,.table>tfoot>tr>td.danger,.table>tfoot>tr>th.danger,.table>thead>tr.danger>td,.table>thead>tr.danger>th,.table>thead>tr>td.danger,.table>thead>tr>th.danger{background-color:#f2dede}.table-hover>tbody>tr.danger:hover>td,.table-hover>tbody>tr.danger:hover>th,.table-hover>tbody>tr:hover>.danger,.table-hover>tbody>tr>td.danger:hover,.table-hover>tbody>tr>th.danger:hover{background-color:#ebcccc}.table-responsive{overflow-x:auto;min-height:.01%}@media screen and (max-width:767px){.table-responsive{width:100%;margin-bottom:15px;overflow-y:hidden;-ms-overflow-style:-ms-autohiding-scrollbar;border:1px solid #ddd}.table-responsive>.table{margin-bottom:0}.table-responsive>.table>tbody>tr>td,.table-responsive>.table>tbody>tr>th,.table-responsive>.table>tfoot>tr>td,.table-responsive>.table>tfoot>tr>th,.table-responsive>.table>thead>tr>td,.table-responsive>.table>thead>tr>th{white-space:nowrap}.table-responsive>.table-bordered{border:0}.table-responsive>.table-bordered>tbody>tr>td:first-child,.table-responsive>.table-bordered>tbody>tr>th:first-child,.table-responsive>.table-bordered>tfoot>tr>td:first-child,.table-responsive>.table-bordered>tfoot>tr>th:first-child,.table-responsive>.table-bordered>thead>tr>td:first-child,.table-responsive>.table-bordered>thead>tr>th:first-child{border-left:0}.table-responsive>.table-bordered>tbody>tr>td:last-child,.table-responsive>.table-bordered>tbody>tr>th:last-child,.table-responsive>.table-bordered>tfoot>tr>td:last-child,.table-responsive>.table-bordered>tfoot>tr>th:last-child,.table-responsive>.table-bordered>thead>tr>td:last-child,.table-responsive>.table-bordered>thead>tr>th:last-child{border-right:0}.table-responsive>.table-bordered>tbody>tr:last-child>td,.table-responsive>.table-bordered>tbody>tr:last-child>th,.table-responsive>.table-bordered>tfoot>tr:last-child>td,.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}}fieldset,legend{padding:0;border:0}fieldset{margin:0;min-width:0}legend{width:100%;margin-bottom:20px;font-size:21px;line-height:inherit;color:#333;border-bottom:1px solid #e5e5e5}label{display:inline-block;max-width:100%;margin-bottom:5px;font-weight:700}input[type=checkbox],input[type=radio]{margin:4px 0 0;margin-top:1px \\9;line-height:normal}input[type=file],legend{display:block}input[type=range]{display:block;width:100%}select[multiple],select[multiple].input-sm,select[size],textarea.form-control,textarea.input-sm{height:auto}.form-control,output{display:block;font-size:14px;line-height:1.42857143;color:#555}output{padding-top:7px}.form-control{width:100%;height:34px;padding:6px 12px;background-color:#fff;background-image:none;border:1px solid #ccc;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075);-webkit-transition:border-color ease-in-out .15s,-webkit-box-shadow ease-in-out .15s;-o-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s}.form-control:focus{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6);box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6)}.form-control::-moz-placeholder{color:#999;opacity:1}.form-control:-ms-input-placeholder{color:#999}.form-control::-webkit-input-placeholder{color:#999}.form-control[disabled],.form-control[readonly],fieldset[disabled] .form-control{background-color:#eee;opacity:1}.form-control[disabled],fieldset[disabled] .form-control{cursor:not-allowed}input[type=search]{-webkit-appearance:none}@media screen and (-webkit-min-device-pixel-ratio:0){input[type=date],input[type=datetime-local],input[type=month],input[type=time]{line-height:34px}.input-group-sm input[type=date],.input-group-sm input[type=datetime-local],.input-group-sm input[type=month],.input-group-sm input[type=time],input[type=date].input-sm,input[type=datetime-local].input-sm,input[type=month].input-sm,input[type=time].input-sm{line-height:30px}.input-group-lg input[type=date],.input-group-lg input[type=datetime-local],.input-group-lg input[type=month],.input-group-lg input[type=time],input[type=date].input-lg,input[type=datetime-local].input-lg,input[type=month].input-lg,input[type=time].input-lg{line-height:46px}}.form-group{margin-bottom:15px}.checkbox,.radio{position:relative;display:block;margin-top:10px;margin-bottom:10px}.checkbox label,.checkbox-inline,.radio label,.radio-inline{padding-left:20px;margin-bottom:0;font-weight:400;cursor:pointer}.checkbox label,.radio label{min-height:20px}.checkbox input[type=checkbox],.checkbox-inline input[type=checkbox],.radio input[type=radio],.radio-inline input[type=radio]{position:absolute;margin-left:-20px;margin-top:4px \\9}.checkbox+.checkbox,.radio+.radio{margin-top:-5px}.checkbox-inline,.radio-inline{position:relative;display:inline-block;vertical-align:middle}.checkbox-inline+.checkbox-inline,.radio-inline+.radio-inline{margin-top:0;margin-left:10px}.checkbox-inline.disabled,.checkbox.disabled label,.radio-inline.disabled,.radio.disabled label,fieldset[disabled] .checkbox label,fieldset[disabled] .checkbox-inline,fieldset[disabled] .radio label,fieldset[disabled] .radio-inline,fieldset[disabled] input[type=checkbox],fieldset[disabled] input[type=radio],input[type=checkbox].disabled,input[type=checkbox][disabled],input[type=radio].disabled,input[type=radio][disabled]{cursor:not-allowed}.form-control-static{padding-top:7px;padding-bottom:7px;margin-bottom:0;min-height:34px}.form-control-static.input-lg,.form-control-static.input-sm{padding-left:0;padding-right:0}.form-group-sm .form-control,.input-sm{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.form-group-sm .form-control,select.input-sm{height:30px;line-height:30px}select[multiple].form-group-sm .form-control,select[multiple].input-lg,textarea.form-group-sm .form-control,textarea.input-lg{height:auto}.form-group-sm .form-control-static{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;min-height:32px}.form-group-lg .form-control,.input-lg{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.form-group-lg .form-control,select.input-lg{height:46px;line-height:46px}select[multiple].form-group-lg .form-control,textarea.form-group-lg .form-control{height:auto}.form-group-lg .form-control-static{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;min-height:38px}.has-feedback{position:relative}.has-feedback .form-control{padding-right:42.5px}.form-control-feedback{position:absolute;top:0;right:0;z-index:2;display:block;width:34px;height:34px;line-height:34px;text-align:center;pointer-events:none}.input-lg+.form-control-feedback{width:46px;height:46px;line-height:46px}.input-sm+.form-control-feedback{width:30px;height:30px;line-height:30px}.has-success .checkbox,.has-success .checkbox-inline,.has-success .control-label,.has-success .help-block,.has-success .radio,.has-success .radio-inline,.has-success.checkbox label,.has-success.checkbox-inline label,.has-success.radio label,.has-success.radio-inline label{color:#3c763d}.has-success .form-control{border-color:#3c763d;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-success .form-control:focus{border-color:#2b542c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168}.has-success .input-group-addon{color:#3c763d;border-color:#3c763d;background-color:#dff0d8}.has-success .form-control-feedback{color:#3c763d}.has-warning .checkbox,.has-warning .checkbox-inline,.has-warning .control-label,.has-warning .help-block,.has-warning .radio,.has-warning .radio-inline,.has-warning.checkbox label,.has-warning.checkbox-inline label,.has-warning.radio label,.has-warning.radio-inline label{color:#8a6d3b}.has-warning .form-control{border-color:#8a6d3b;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-warning .form-control:focus{border-color:#66512c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b}.has-warning .input-group-addon{color:#8a6d3b;border-color:#8a6d3b;background-color:#fcf8e3}.has-warning .form-control-feedback{color:#8a6d3b}.has-error .checkbox,.has-error .checkbox-inline,.has-error .control-label,.has-error .help-block,.has-error .radio,.has-error .radio-inline,.has-error.checkbox label,.has-error.checkbox-inline label,.has-error.radio label,.has-error.radio-inline label{color:#a94442}.has-error .form-control{border-color:#a94442;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-error .form-control:focus{border-color:#843534;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483}.has-error .input-group-addon{color:#a94442;border-color:#a94442;background-color:#f2dede}.has-error .form-control-feedback{color:#a94442}.has-feedback label~.form-control-feedback{top:25px}.has-feedback label.sr-only~.form-control-feedback{top:0}.help-block{display:block;margin-top:5px;margin-bottom:10px;color:#737373}@media (min-width:768px){.form-inline .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-static{display:inline-block}.form-inline .input-group{display:inline-table;vertical-align:middle}.form-inline .input-group .form-control,.form-inline .input-group .input-group-addon,.form-inline .input-group .input-group-btn{width:auto}.form-inline .input-group>.form-control{width:100%}.form-inline .control-label{margin-bottom:0;vertical-align:middle}.form-inline .checkbox,.form-inline .radio{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.form-inline .checkbox label,.form-inline .radio label{padding-left:0}.form-inline .checkbox input[type=checkbox],.form-inline .radio input[type=radio]{position:relative;margin-left:0}.form-inline .has-feedback .form-control-feedback{top:0}}.form-horizontal .checkbox,.form-horizontal .checkbox-inline,.form-horizontal .radio,.form-horizontal .radio-inline{margin-top:0;margin-bottom:0;padding-top:7px}.form-horizontal .checkbox,.form-horizontal .radio{min-height:27px}.form-horizontal .form-group{margin-left:-15px;margin-right:-15px}@media (min-width:768px){.form-horizontal .control-label{text-align:right;margin-bottom:0;padding-top:7px}}.form-horizontal .has-feedback .form-control-feedback{right:15px}@media (min-width:768px){.form-horizontal .form-group-lg .control-label{padding-top:14.333333px}.form-horizontal .form-group-sm .control-label{padding-top:6px}}.btn{display:inline-block;margin-bottom:0;font-weight:400;text-align:center;vertical-align:middle;-ms-touch-action:manipulation;touch-action:manipulation;cursor:pointer;background-image:none;border:1px solid transparent;white-space:nowrap;padding:6px 12px;font-size:14px;line-height:1.42857143;border-radius:4px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.btn.active.focus,.btn.active:focus,.btn.focus,.btn:active.focus,.btn:active:focus,.btn:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn.focus,.btn:focus,.btn:hover{color:#333;text-decoration:none}.btn.active,.btn:active{outline:0;background-image:none;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn.disabled,.btn[disabled],fieldset[disabled] .btn{cursor:not-allowed;pointer-events:none;opacity:.65;filter:alpha(opacity=65);-webkit-box-shadow:none;box-shadow:none}.btn-default{color:#333;background-color:#fff;border-color:#ccc}.btn-default.active,.btn-default.focus,.btn-default:active,.btn-default:focus,.btn-default:hover,.open>.dropdown-toggle.btn-default{color:#333;background-color:#e6e6e6;border-color:#adadad}.btn-default.active,.btn-default:active,.open>.dropdown-toggle.btn-default{background-image:none}.btn-default.disabled,.btn-default.disabled.active,.btn-default.disabled.focus,.btn-default.disabled:active,.btn-default.disabled:focus,.btn-default.disabled:hover,.btn-default[disabled],.btn-default[disabled].active,.btn-default[disabled].focus,.btn-default[disabled]:active,.btn-default[disabled]:focus,.btn-default[disabled]:hover,fieldset[disabled] .btn-default,fieldset[disabled] .btn-default.active,fieldset[disabled] .btn-default.focus,fieldset[disabled] .btn-default:active,fieldset[disabled] .btn-default:focus,fieldset[disabled] .btn-default:hover{background-color:#fff;border-color:#ccc}.btn-default .badge{color:#fff;background-color:#333}.btn-primary{color:#fff;background-color:#337ab7;border-color:#2e6da4}.btn-primary.active,.btn-primary.focus,.btn-primary:active,.btn-primary:focus,.btn-primary:hover,.open>.dropdown-toggle.btn-primary{color:#fff;background-color:#286090;border-color:#204d74}.btn-primary.active,.btn-primary:active,.open>.dropdown-toggle.btn-primary{background-image:none}.btn-primary.disabled,.btn-primary.disabled.active,.btn-primary.disabled.focus,.btn-primary.disabled:active,.btn-primary.disabled:focus,.btn-primary.disabled:hover,.btn-primary[disabled],.btn-primary[disabled].active,.btn-primary[disabled].focus,.btn-primary[disabled]:active,.btn-primary[disabled]:focus,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary,fieldset[disabled] .btn-primary.active,fieldset[disabled] .btn-primary.focus,fieldset[disabled] .btn-primary:active,fieldset[disabled] .btn-primary:focus,fieldset[disabled] .btn-primary:hover{background-color:#337ab7;border-color:#2e6da4}.btn-primary .badge{color:#337ab7;background-color:#fff}.btn-success{color:#fff;background-color:#5cb85c;border-color:#4cae4c}.btn-success.active,.btn-success.focus,.btn-success:active,.btn-success:focus,.btn-success:hover,.open>.dropdown-toggle.btn-success{color:#fff;background-color:#449d44;border-color:#398439}.btn-success.active,.btn-success:active,.open>.dropdown-toggle.btn-success{background-image:none}.btn-success.disabled,.btn-success.disabled.active,.btn-success.disabled.focus,.btn-success.disabled:active,.btn-success.disabled:focus,.btn-success.disabled:hover,.btn-success[disabled],.btn-success[disabled].active,.btn-success[disabled].focus,.btn-success[disabled]:active,.btn-success[disabled]:focus,.btn-success[disabled]:hover,fieldset[disabled] .btn-success,fieldset[disabled] .btn-success.active,fieldset[disabled] .btn-success.focus,fieldset[disabled] .btn-success:active,fieldset[disabled] .btn-success:focus,fieldset[disabled] .btn-success:hover{background-color:#5cb85c;border-color:#4cae4c}.btn-success .badge{color:#5cb85c;background-color:#fff}.btn-info{color:#fff;background-color:#5bc0de;border-color:#46b8da}.btn-info.active,.btn-info.focus,.btn-info:active,.btn-info:focus,.btn-info:hover,.open>.dropdown-toggle.btn-info{color:#fff;background-color:#31b0d5;border-color:#269abc}.btn-info.active,.btn-info:active,.open>.dropdown-toggle.btn-info{background-image:none}.btn-info.disabled,.btn-info.disabled.active,.btn-info.disabled.focus,.btn-info.disabled:active,.btn-info.disabled:focus,.btn-info.disabled:hover,.btn-info[disabled],.btn-info[disabled].active,.btn-info[disabled].focus,.btn-info[disabled]:active,.btn-info[disabled]:focus,.btn-info[disabled]:hover,fieldset[disabled] .btn-info,fieldset[disabled] .btn-info.active,fieldset[disabled] .btn-info.focus,fieldset[disabled] .btn-info:active,fieldset[disabled] .btn-info:focus,fieldset[disabled] .btn-info:hover{background-color:#5bc0de;border-color:#46b8da}.btn-info .badge{color:#5bc0de;background-color:#fff}.btn-warning{color:#fff;background-color:#f0ad4e;border-color:#eea236}.btn-warning.active,.btn-warning.focus,.btn-warning:active,.btn-warning:focus,.btn-warning:hover,.open>.dropdown-toggle.btn-warning{color:#fff;background-color:#ec971f;border-color:#d58512}.btn-warning.active,.btn-warning:active,.open>.dropdown-toggle.btn-warning{background-image:none}.btn-warning.disabled,.btn-warning.disabled.active,.btn-warning.disabled.focus,.btn-warning.disabled:active,.btn-warning.disabled:focus,.btn-warning.disabled:hover,.btn-warning[disabled],.btn-warning[disabled].active,.btn-warning[disabled].focus,.btn-warning[disabled]:active,.btn-warning[disabled]:focus,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning,fieldset[disabled] .btn-warning.active,fieldset[disabled] .btn-warning.focus,fieldset[disabled] .btn-warning:active,fieldset[disabled] .btn-warning:focus,fieldset[disabled] .btn-warning:hover{background-color:#f0ad4e;border-color:#eea236}.btn-warning .badge{color:#f0ad4e;background-color:#fff}.btn-danger{color:#fff;background-color:#d9534f;border-color:#d43f3a}.btn-danger.active,.btn-danger.focus,.btn-danger:active,.btn-danger:focus,.btn-danger:hover,.open>.dropdown-toggle.btn-danger{color:#fff;background-color:#c9302c;border-color:#ac2925}.btn-danger.active,.btn-danger:active,.open>.dropdown-toggle.btn-danger{background-image:none}.btn-danger.disabled,.btn-danger.disabled.active,.btn-danger.disabled.focus,.btn-danger.disabled:active,.btn-danger.disabled:focus,.btn-danger.disabled:hover,.btn-danger[disabled],.btn-danger[disabled].active,.btn-danger[disabled].focus,.btn-danger[disabled]:active,.btn-danger[disabled]:focus,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger,fieldset[disabled] .btn-danger.active,fieldset[disabled] .btn-danger.focus,fieldset[disabled] .btn-danger:active,fieldset[disabled] .btn-danger:focus,fieldset[disabled] .btn-danger:hover{background-color:#d9534f;border-color:#d43f3a}.btn-danger .badge{color:#d9534f;background-color:#fff}.btn-link{color:#337ab7;font-weight:400;border-radius:0}.btn-link,.btn-link.active,.btn-link:active,.btn-link[disabled],fieldset[disabled] .btn-link{background-color:transparent;-webkit-box-shadow:none;box-shadow:none}.btn-link,.btn-link:active,.btn-link:focus,.btn-link:hover{border-color:transparent}.btn-link:focus,.btn-link:hover{color:#23527c;text-decoration:underline;background-color:transparent}.btn-link[disabled]:focus,.btn-link[disabled]:hover,fieldset[disabled] .btn-link:focus,fieldset[disabled] .btn-link:hover{color:#777;text-decoration:none}.btn-lg{padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}.btn-sm,.btn-xs{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.btn-xs{padding:1px 5px}.btn-block{display:block;width:100%}.alert>p+p,.btn-block+.btn-block{margin-top:5px}input[type=button].btn-block,input[type=reset].btn-block,input[type=submit].btn-block{width:100%}.pagination{display:inline-block;padding-left:0;margin:20px 0;border-radius:4px}.pager li,.pagination>li{display:inline}.pagination>li>a,.pagination>li>span{position:relative;float:left;padding:6px 12px;line-height:1.42857143;text-decoration:none;color:#337ab7;background-color:#fff;border:1px solid #ddd;margin-left:-1px}.pagination>li:first-child>a,.pagination>li:first-child>span{margin-left:0;border-bottom-left-radius:4px;border-top-left-radius:4px}.pagination>li:last-child>a,.pagination>li:last-child>span{border-bottom-right-radius:4px;border-top-right-radius:4px}.pagination>li>a:focus,.pagination>li>a:hover,.pagination>li>span:focus,.pagination>li>span:hover{color:#23527c;background-color:#eee;border-color:#ddd}.pagination>.active>a,.pagination>.active>a:focus,.pagination>.active>a:hover,.pagination>.active>span,.pagination>.active>span:focus,.pagination>.active>span:hover{z-index:2;color:#fff;background-color:#337ab7;border-color:#337ab7;cursor:default}.pagination>.disabled>a,.pagination>.disabled>a:focus,.pagination>.disabled>a:hover,.pagination>.disabled>span,.pagination>.disabled>span:focus,.pagination>.disabled>span:hover{color:#777;background-color:#fff;border-color:#ddd;cursor:not-allowed}.pagination-lg>li>a,.pagination-lg>li>span{padding:10px 16px;font-size:18px}.pagination-lg>li:first-child>a,.pagination-lg>li:first-child>span{border-bottom-left-radius:6px;border-top-left-radius:6px}.pagination-lg>li:last-child>a,.pagination-lg>li:last-child>span{border-bottom-right-radius:6px;border-top-right-radius:6px}.pagination-sm>li>a,.pagination-sm>li>span{padding:5px 10px;font-size:12px}.pagination-sm>li:first-child>a,.pagination-sm>li:first-child>span{border-bottom-left-radius:3px;border-top-left-radius:3px}.pagination-sm>li:last-child>a,.pagination-sm>li:last-child>span{border-bottom-right-radius:3px;border-top-right-radius:3px}.pager{padding-left:0;margin:20px 0;list-style:none;text-align:center}.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;border-radius:15px}.pager li>a:focus,.pager li>a:hover{text-decoration:none;background-color:#eee}.pager .next>a,.pager .next>span{float:right}.pager .previous>a,.pager .previous>span{float:left}.pager .disabled>a,.pager .disabled>a:focus,.pager .disabled>a:hover,.pager .disabled>span{color:#777;background-color:#fff;cursor:not-allowed}.alert{padding:15px;margin-bottom:20px;border:1px solid transparent;border-radius:4px}.alert h4{margin-top:0;color:inherit}.alert .alert-link{font-weight:700}.alert-dismissable,.alert-dismissible{padding-right:35px}.alert-dismissable .close,.alert-dismissible .close{position:relative;top:-2px;right:-21px;color:inherit}.alert-success{background-color:#dff0d8;border-color:#d6e9c6;color:#3c763d}.alert-success hr{border-top-color:#c9e2b3}.alert-success .alert-link{color:#2b542c}.alert-info{background-color:#d9edf7;border-color:#bce8f1;color:#31708f}.alert-info hr{border-top-color:#a6e1ec}.alert-info .alert-link{color:#245269}.alert-warning{background-color:#fcf8e3;border-color:#faebcc;color:#8a6d3b}.alert-warning hr{border-top-color:#f7e1b5}.alert-warning .alert-link{color:#66512c}.alert-danger{background-color:#f2dede;border-color:#ebccd1;color:#a94442}.alert-danger hr{border-top-color:#e4b9c0}.alert-danger .alert-link{color:#843534}.clearfix:after,.clearfix:before,.container-fluid:after,.container-fluid:before,.container:after,.container:before,.dl-horizontal dd:after,.dl-horizontal dd:before,.form-horizontal .form-group:after,.form-horizontal .form-group:before,.pager:after,.pager:before,.row:after,.row:before{content:\" \";display:table}.clearfix:after,.container-fluid:after,.container:after,.dl-horizontal dd:after,.form-horizontal .form-group:after,.pager:after,.row:after{clear:both}.center-block{display:block;margin-left:auto;margin-right:auto}.pull-right{float:right!important}.pull-left{float:left!important}.hide{display:none!important}.show{display:block!important}.invisible{visibility:hidden}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.hidden{display:none!important}.affix{position:fixed}@-ms-viewport{width:device-width}.visible-lg,.visible-lg-block,.visible-lg-inline,.visible-lg-inline-block,.visible-md,.visible-md-block,.visible-md-inline,.visible-md-inline-block,.visible-sm,.visible-sm-block,.visible-sm-inline,.visible-sm-inline-block,.visible-xs,.visible-xs-block,.visible-xs-inline,.visible-xs-inline-block{display:none!important}@media (max-width:767px){.visible-xs,.visible-xs-block{display:block!important}table.visible-xs{display:table}tr.visible-xs{display:table-row!important}td.visible-xs,th.visible-xs{display:table-cell!important}.visible-xs-inline{display:inline!important}.visible-xs-inline-block{display:inline-block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm,.visible-sm-block{display:block!important}table.visible-sm{display:table}tr.visible-sm{display:table-row!important}td.visible-sm,th.visible-sm{display:table-cell!important}.visible-sm-inline{display:inline!important}.visible-sm-inline-block{display:inline-block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md,.visible-md-block{display:block!important}table.visible-md{display:table}tr.visible-md{display:table-row!important}td.visible-md,th.visible-md{display:table-cell!important}.visible-md-inline{display:inline!important}.visible-md-inline-block{display:inline-block!important}}@media (min-width:1200px){.visible-lg,.visible-lg-block{display:block!important}table.visible-lg{display:table}tr.visible-lg{display:table-row!important}td.visible-lg,th.visible-lg{display:table-cell!important}.visible-lg-inline{display:inline!important}.visible-lg-inline-block{display:inline-block!important}}@media (max-width:767px){.hidden-xs{display:none!important}}@media (min-width:768px) and (max-width:991px){.hidden-sm{display:none!important}}@media (min-width:992px) and (max-width:1199px){.hidden-md{display:none!important}}@media (min-width:1200px){.hidden-lg{display:none!important}}.visible-print{display:none!important}@media print{.visible-print{display:block!important}table.visible-print{display:table}tr.visible-print{display:table-row!important}td.visible-print,th.visible-print{display:table-cell!important}}.visible-print-block{display:none!important}@media print{.visible-print-block{display:block!important}}.visible-print-inline{display:none!important}@media print{.visible-print-inline{display:inline!important}}.visible-print-inline-block{display:none!important}@media print{.visible-print-inline-block{display:inline-block!important}.hidden-print{display:none!important}}.container{padding:15px;margin:0 auto}@font-face{font-family:'Henny_Penny';font-style:normal;font-weight:400;src:local('Henny Penny'),local('HennyPenny-Regular'),url(../font/hennypenny.woff2) format('woff2')}@font-face{font-family:'Oswald';font-style:bold;font-weight:400;src:local('Oswald'),url(../font/Oswald-Bold.ttf)}@font-face{font-family:'OpenSans';font-style:normal;font-weight:200;src:local('OpenSans'),url(../font/OpenSans-Regular.ttf)}.hennypenny,.oswald{font-family:'Oswald';font-size:42px}.hennypenny{font-family:'Henny_Penny',cursive}.opensans{font-family:'OpenSans';font-size:25px}.link_nocol,.link_nocol:hover{color:#000;text-decoration:none}dd>strong{padding-left:15px}.logo{height:auto!important;padding-right:20px}.logo-img{height:200px;width:100%}.allons-y{border-style:none;background:linear-gradient(to right,rgba(255,255,255,.3) 0%,rgba(255,255,255,.5) 100%,transparent 25px) no-repeat,#b24b04;background-repeat:no-repeat,no-repeat;border-radius:5px;box-shadow:2px 2px 1px 1px rgba(0,0,0,.3);padding:8px;margin-right:9px;color:#fff;font-family:'OpenSans';font-size:14px;background-size:0 100%,100% 100%;transition:background-size .3s}.allons-y:hover{background-size:101% 100%}.allons-y:active{box-shadow:none;transform:translate(2px,2px);transition:all .1s}@font-face{font-family:'fontelico';src:url(../font/fontelico.eot?21941692);src:url(../font/fontelico.eot?21941692#iefix) format('embedded-opentype'),url(../font/fontelico.woff2?21941692) format('woff2'),url(../font/fontelico.woff?21941692) format('woff'),url(../font/fontelico.ttf?21941692) format('truetype'),url(../font/fontelico.svg?21941692#fontelico) format('svg');font-weight:400;font-style:normal}[class*=\" icon-\"]:before,[class^=icon-]:before{font-family:\"fontelico\";font-style:normal;font-weight:400;speak:none;display:inline-block;text-decoration:inherit;width:1em;margin-right:.2em;text-align:center;font-variant:normal;text-transform:none;line-height:1em;margin-left:.2em;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.icon-clipboard:before{content:'\\e800'}.icon-trash:before{content:'\\e804'}\n"
  },
  {
    "path": "themes/default/public/css/bootstrap.min.css",
    "content": "/*!\n * Bootstrap v3.3.4 (http://getbootstrap.com)\n * Copyright 2011-2015 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n */\n\n/*!\n * Generated using the Bootstrap Customizer (http://getbootstrap.com/customize/?id=8d56756b325f9f22f4eb)\n * Config saved to config.json and https://gist.github.com/8d56756b325f9f22f4eb\n *//*! normalize.css v3.0.2 | MIT License | git.io/normalize */html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:bold}dfn{font-style:italic}h1{font-size:2em;margin:0.67em 0}mark{background:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-0.5em}sub{bottom:-0.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box;height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace, monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button{overflow:visible}button,select{text-transform:none}button,html input[type=\"button\"],input[type=\"reset\"],input[type=\"submit\"]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input[type=\"checkbox\"],input[type=\"radio\"]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0}input[type=\"number\"]::-webkit-inner-spin-button,input[type=\"number\"]::-webkit-outer-spin-button{height:auto}input[type=\"search\"]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}input[type=\"search\"]::-webkit-search-cancel-button,input[type=\"search\"]::-webkit-search-decoration{-webkit-appearance:none}fieldset{border:1px solid #c0c0c0;margin:0 2px;padding:0.35em 0.625em 0.75em}legend{border:0;padding:0}textarea{overflow:auto}optgroup{font-weight:bold}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */@media print{*,*:before,*:after{background:transparent !important;color:#000 !important;-webkit-box-shadow:none !important;box-shadow:none !important;text-shadow:none !important}a,a:visited{text-decoration:underline}a[href]:after{content:\" (\" attr(href) \")\"}abbr[title]:after{content:\" (\" attr(title) \")\"}a[href^=\"#\"]:after,a[href^=\"javascript:\"]:after{content:\"\"}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}p,h2,h3{orphans:3;widows:3}h2,h3{page-break-after:avoid}select{background:#fff !important}.navbar{display:none}.btn>.caret,.dropup>.btn>.caret{border-top-color:#000 !important}.label{border:1px solid #000}.table{border-collapse:collapse !important}.table td,.table th{background-color:#fff !important}.table-bordered th,.table-bordered td{border:1px solid #ddd !important}}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}*:before,*:after{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:10px;-webkit-tap-highlight-color:rgba(0,0,0,0)}body{font-family:\"Helvetica Neue\",Helvetica,Arial,sans-serif;font-size:14px;line-height:1.42857143;color:#333;background-color:#fff}input,button,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}a{color:#337ab7;text-decoration:none}a:hover,a:focus{color:#23527c;text-decoration:underline}a:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}figure{margin:0}img{vertical-align:middle}.img-responsive{display:block;max-width:100%;height:auto}.img-rounded{border-radius:6px}.img-thumbnail{padding:4px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out;display:inline-block;max-width:100%;height:auto}.img-circle{border-radius:50%}hr{margin-top:20px;margin-bottom:20px;border:0;border-top:1px solid #eee}.sr-only{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0, 0, 0, 0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}[role=\"button\"]{cursor:pointer}h1,h2,h3,h4,h5,h6,.h1,.h2,.h3,.h4,.h5,.h6{font-family:inherit;font-weight:500;line-height:1.1;color:inherit}h1 small,h2 small,h3 small,h4 small,h5 small,h6 small,.h1 small,.h2 small,.h3 small,.h4 small,.h5 small,.h6 small,h1 .small,h2 .small,h3 .small,h4 .small,h5 .small,h6 .small,.h1 .small,.h2 .small,.h3 .small,.h4 .small,.h5 .small,.h6 .small{font-weight:normal;line-height:1;color:#777}h1,.h1,h2,.h2,h3,.h3{margin-top:20px;margin-bottom:10px}h1 small,.h1 small,h2 small,.h2 small,h3 small,.h3 small,h1 .small,.h1 .small,h2 .small,.h2 .small,h3 .small,.h3 .small{font-size:65%}h4,.h4,h5,.h5,h6,.h6{margin-top:10px;margin-bottom:10px}h4 small,.h4 small,h5 small,.h5 small,h6 small,.h6 small,h4 .small,.h4 .small,h5 .small,.h5 .small,h6 .small,.h6 .small{font-size:75%}h1,.h1{font-size:36px}h2,.h2{font-size:30px}h3,.h3{font-size:24px}h4,.h4{font-size:18px}h5,.h5{font-size:14px}h6,.h6{font-size:12px}p{margin:0 0 10px}.lead{margin-bottom:20px;font-size:16px;font-weight:300;line-height:1.4}@media (min-width:768px){.lead{font-size:21px}}small,.small{font-size:85%}mark,.mark{background-color:#fcf8e3;padding:.2em}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}.text-justify{text-align:justify}.text-nowrap{white-space:nowrap}.text-lowercase{text-transform:lowercase}.text-uppercase{text-transform:uppercase}.text-capitalize{text-transform:capitalize}.text-muted{color:#777}.text-primary{color:#337ab7}a.text-primary:hover{color:#286090}.text-success{color:#3c763d}a.text-success:hover{color:#2b542c}.text-info{color:#31708f}a.text-info:hover{color:#245269}.text-warning{color:#8a6d3b}a.text-warning:hover{color:#66512c}.text-danger{color:#a94442}a.text-danger:hover{color:#843534}.bg-primary{color:#fff;background-color:#337ab7}a.bg-primary:hover{background-color:#286090}.bg-success{background-color:#dff0d8}a.bg-success:hover{background-color:#c1e2b3}.bg-info{background-color:#d9edf7}a.bg-info:hover{background-color:#afd9ee}.bg-warning{background-color:#fcf8e3}a.bg-warning:hover{background-color:#f7ecb5}.bg-danger{background-color:#f2dede}a.bg-danger:hover{background-color:#e4b9b9}.page-header{padding-bottom:9px;margin:40px 0 20px;border-bottom:1px solid #eee}ul,ol{margin-top:0;margin-bottom:10px}ul ul,ol ul,ul ol,ol ol{margin-bottom:0}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;list-style:none;margin-left:-5px}.list-inline>li{display:inline-block;padding-left:5px;padding-right:5px}dl{margin-top:0;margin-bottom:20px}dt,dd{line-height:1.42857143}dt{font-weight:bold}dd{margin-left:0}@media (min-width:768px){.dl-horizontal dt{float:left;width:160px;clear:left;text-align:right;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}}abbr[title],abbr[data-original-title]{cursor:help;border-bottom:1px dotted #777}.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:10px 20px;margin:0 0 20px;font-size:17.5px;border-left:5px solid #eee}blockquote p:last-child,blockquote ul:last-child,blockquote ol:last-child{margin-bottom:0}blockquote footer,blockquote small,blockquote .small{display:block;font-size:80%;line-height:1.42857143;color:#777}blockquote footer:before,blockquote small:before,blockquote .small:before{content:'\\2014 \\00A0'}.blockquote-reverse,blockquote.pull-right{padding-right:15px;padding-left:0;border-right:5px solid #eee;border-left:0;text-align:right}.blockquote-reverse footer:before,blockquote.pull-right footer:before,.blockquote-reverse small:before,blockquote.pull-right small:before,.blockquote-reverse .small:before,blockquote.pull-right .small:before{content:''}.blockquote-reverse footer:after,blockquote.pull-right footer:after,.blockquote-reverse small:after,blockquote.pull-right small:after,.blockquote-reverse .small:after,blockquote.pull-right .small:after{content:'\\00A0 \\2014'}address{margin-bottom:20px;font-style:normal;line-height:1.42857143}.container{margin-right:auto;margin-left:auto;padding-left:15px;padding-right:15px}@media (min-width:768px){.container{width:750px}}@media (min-width:992px){.container{width:970px}}@media (min-width:1200px){.container{width:1170px}}.container-fluid{margin-right:auto;margin-left:auto;padding-left:15px;padding-right:15px}.row{margin-left:-15px;margin-right:-15px}.col-xs-1, .col-sm-1, .col-md-1, .col-lg-1, .col-xs-2, .col-sm-2, .col-md-2, .col-lg-2, .col-xs-3, .col-sm-3, .col-md-3, .col-lg-3, .col-xs-4, .col-sm-4, .col-md-4, .col-lg-4, .col-xs-5, .col-sm-5, .col-md-5, .col-lg-5, .col-xs-6, .col-sm-6, .col-md-6, .col-lg-6, .col-xs-7, .col-sm-7, .col-md-7, .col-lg-7, .col-xs-8, .col-sm-8, .col-md-8, .col-lg-8, .col-xs-9, .col-sm-9, .col-md-9, .col-lg-9, .col-xs-10, .col-sm-10, .col-md-10, .col-lg-10, .col-xs-11, .col-sm-11, .col-md-11, .col-lg-11, .col-xs-12, .col-sm-12, .col-md-12, .col-lg-12{position:relative;min-height:1px;padding-left:15px;padding-right:15px}.col-xs-1, .col-xs-2, .col-xs-3, .col-xs-4, .col-xs-5, .col-xs-6, .col-xs-7, .col-xs-8, .col-xs-9, .col-xs-10, .col-xs-11, .col-xs-12{float:left}.col-xs-12{width:100%}.col-xs-11{width:91.66666667%}.col-xs-10{width:83.33333333%}.col-xs-9{width:75%}.col-xs-8{width:66.66666667%}.col-xs-7{width:58.33333333%}.col-xs-6{width:50%}.col-xs-5{width:41.66666667%}.col-xs-4{width:33.33333333%}.col-xs-3{width:25%}.col-xs-2{width:16.66666667%}.col-xs-1{width:8.33333333%}.col-xs-pull-12{right:100%}.col-xs-pull-11{right:91.66666667%}.col-xs-pull-10{right:83.33333333%}.col-xs-pull-9{right:75%}.col-xs-pull-8{right:66.66666667%}.col-xs-pull-7{right:58.33333333%}.col-xs-pull-6{right:50%}.col-xs-pull-5{right:41.66666667%}.col-xs-pull-4{right:33.33333333%}.col-xs-pull-3{right:25%}.col-xs-pull-2{right:16.66666667%}.col-xs-pull-1{right:8.33333333%}.col-xs-pull-0{right:auto}.col-xs-push-12{left:100%}.col-xs-push-11{left:91.66666667%}.col-xs-push-10{left:83.33333333%}.col-xs-push-9{left:75%}.col-xs-push-8{left:66.66666667%}.col-xs-push-7{left:58.33333333%}.col-xs-push-6{left:50%}.col-xs-push-5{left:41.66666667%}.col-xs-push-4{left:33.33333333%}.col-xs-push-3{left:25%}.col-xs-push-2{left:16.66666667%}.col-xs-push-1{left:8.33333333%}.col-xs-push-0{left:auto}.col-xs-offset-12{margin-left:100%}.col-xs-offset-11{margin-left:91.66666667%}.col-xs-offset-10{margin-left:83.33333333%}.col-xs-offset-9{margin-left:75%}.col-xs-offset-8{margin-left:66.66666667%}.col-xs-offset-7{margin-left:58.33333333%}.col-xs-offset-6{margin-left:50%}.col-xs-offset-5{margin-left:41.66666667%}.col-xs-offset-4{margin-left:33.33333333%}.col-xs-offset-3{margin-left:25%}.col-xs-offset-2{margin-left:16.66666667%}.col-xs-offset-1{margin-left:8.33333333%}.col-xs-offset-0{margin-left:0}@media (min-width:768px){.col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12{float:left}.col-sm-12{width:100%}.col-sm-11{width:91.66666667%}.col-sm-10{width:83.33333333%}.col-sm-9{width:75%}.col-sm-8{width:66.66666667%}.col-sm-7{width:58.33333333%}.col-sm-6{width:50%}.col-sm-5{width:41.66666667%}.col-sm-4{width:33.33333333%}.col-sm-3{width:25%}.col-sm-2{width:16.66666667%}.col-sm-1{width:8.33333333%}.col-sm-pull-12{right:100%}.col-sm-pull-11{right:91.66666667%}.col-sm-pull-10{right:83.33333333%}.col-sm-pull-9{right:75%}.col-sm-pull-8{right:66.66666667%}.col-sm-pull-7{right:58.33333333%}.col-sm-pull-6{right:50%}.col-sm-pull-5{right:41.66666667%}.col-sm-pull-4{right:33.33333333%}.col-sm-pull-3{right:25%}.col-sm-pull-2{right:16.66666667%}.col-sm-pull-1{right:8.33333333%}.col-sm-pull-0{right:auto}.col-sm-push-12{left:100%}.col-sm-push-11{left:91.66666667%}.col-sm-push-10{left:83.33333333%}.col-sm-push-9{left:75%}.col-sm-push-8{left:66.66666667%}.col-sm-push-7{left:58.33333333%}.col-sm-push-6{left:50%}.col-sm-push-5{left:41.66666667%}.col-sm-push-4{left:33.33333333%}.col-sm-push-3{left:25%}.col-sm-push-2{left:16.66666667%}.col-sm-push-1{left:8.33333333%}.col-sm-push-0{left:auto}.col-sm-offset-12{margin-left:100%}.col-sm-offset-11{margin-left:91.66666667%}.col-sm-offset-10{margin-left:83.33333333%}.col-sm-offset-9{margin-left:75%}.col-sm-offset-8{margin-left:66.66666667%}.col-sm-offset-7{margin-left:58.33333333%}.col-sm-offset-6{margin-left:50%}.col-sm-offset-5{margin-left:41.66666667%}.col-sm-offset-4{margin-left:33.33333333%}.col-sm-offset-3{margin-left:25%}.col-sm-offset-2{margin-left:16.66666667%}.col-sm-offset-1{margin-left:8.33333333%}.col-sm-offset-0{margin-left:0}}@media (min-width:992px){.col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12{float:left}.col-md-12{width:100%}.col-md-11{width:91.66666667%}.col-md-10{width:83.33333333%}.col-md-9{width:75%}.col-md-8{width:66.66666667%}.col-md-7{width:58.33333333%}.col-md-6{width:50%}.col-md-5{width:41.66666667%}.col-md-4{width:33.33333333%}.col-md-3{width:25%}.col-md-2{width:16.66666667%}.col-md-1{width:8.33333333%}.col-md-pull-12{right:100%}.col-md-pull-11{right:91.66666667%}.col-md-pull-10{right:83.33333333%}.col-md-pull-9{right:75%}.col-md-pull-8{right:66.66666667%}.col-md-pull-7{right:58.33333333%}.col-md-pull-6{right:50%}.col-md-pull-5{right:41.66666667%}.col-md-pull-4{right:33.33333333%}.col-md-pull-3{right:25%}.col-md-pull-2{right:16.66666667%}.col-md-pull-1{right:8.33333333%}.col-md-pull-0{right:auto}.col-md-push-12{left:100%}.col-md-push-11{left:91.66666667%}.col-md-push-10{left:83.33333333%}.col-md-push-9{left:75%}.col-md-push-8{left:66.66666667%}.col-md-push-7{left:58.33333333%}.col-md-push-6{left:50%}.col-md-push-5{left:41.66666667%}.col-md-push-4{left:33.33333333%}.col-md-push-3{left:25%}.col-md-push-2{left:16.66666667%}.col-md-push-1{left:8.33333333%}.col-md-push-0{left:auto}.col-md-offset-12{margin-left:100%}.col-md-offset-11{margin-left:91.66666667%}.col-md-offset-10{margin-left:83.33333333%}.col-md-offset-9{margin-left:75%}.col-md-offset-8{margin-left:66.66666667%}.col-md-offset-7{margin-left:58.33333333%}.col-md-offset-6{margin-left:50%}.col-md-offset-5{margin-left:41.66666667%}.col-md-offset-4{margin-left:33.33333333%}.col-md-offset-3{margin-left:25%}.col-md-offset-2{margin-left:16.66666667%}.col-md-offset-1{margin-left:8.33333333%}.col-md-offset-0{margin-left:0}}@media (min-width:1200px){.col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12{float:left}.col-lg-12{width:100%}.col-lg-11{width:91.66666667%}.col-lg-10{width:83.33333333%}.col-lg-9{width:75%}.col-lg-8{width:66.66666667%}.col-lg-7{width:58.33333333%}.col-lg-6{width:50%}.col-lg-5{width:41.66666667%}.col-lg-4{width:33.33333333%}.col-lg-3{width:25%}.col-lg-2{width:16.66666667%}.col-lg-1{width:8.33333333%}.col-lg-pull-12{right:100%}.col-lg-pull-11{right:91.66666667%}.col-lg-pull-10{right:83.33333333%}.col-lg-pull-9{right:75%}.col-lg-pull-8{right:66.66666667%}.col-lg-pull-7{right:58.33333333%}.col-lg-pull-6{right:50%}.col-lg-pull-5{right:41.66666667%}.col-lg-pull-4{right:33.33333333%}.col-lg-pull-3{right:25%}.col-lg-pull-2{right:16.66666667%}.col-lg-pull-1{right:8.33333333%}.col-lg-pull-0{right:auto}.col-lg-push-12{left:100%}.col-lg-push-11{left:91.66666667%}.col-lg-push-10{left:83.33333333%}.col-lg-push-9{left:75%}.col-lg-push-8{left:66.66666667%}.col-lg-push-7{left:58.33333333%}.col-lg-push-6{left:50%}.col-lg-push-5{left:41.66666667%}.col-lg-push-4{left:33.33333333%}.col-lg-push-3{left:25%}.col-lg-push-2{left:16.66666667%}.col-lg-push-1{left:8.33333333%}.col-lg-push-0{left:auto}.col-lg-offset-12{margin-left:100%}.col-lg-offset-11{margin-left:91.66666667%}.col-lg-offset-10{margin-left:83.33333333%}.col-lg-offset-9{margin-left:75%}.col-lg-offset-8{margin-left:66.66666667%}.col-lg-offset-7{margin-left:58.33333333%}.col-lg-offset-6{margin-left:50%}.col-lg-offset-5{margin-left:41.66666667%}.col-lg-offset-4{margin-left:33.33333333%}.col-lg-offset-3{margin-left:25%}.col-lg-offset-2{margin-left:16.66666667%}.col-lg-offset-1{margin-left:8.33333333%}.col-lg-offset-0{margin-left:0}}table{background-color:transparent}caption{padding-top:8px;padding-bottom:8px;color:#777;text-align:left}th{text-align:left}.table{width:100%;max-width:100%;margin-bottom:20px}.table>thead>tr>th,.table>tbody>tr>th,.table>tfoot>tr>th,.table>thead>tr>td,.table>tbody>tr>td,.table>tfoot>tr>td{padding:8px;line-height:1.42857143;vertical-align:top;border-top:1px solid #ddd}.table>thead>tr>th{vertical-align:bottom;border-bottom:2px solid #ddd}.table>caption+thead>tr:first-child>th,.table>colgroup+thead>tr:first-child>th,.table>thead:first-child>tr:first-child>th,.table>caption+thead>tr:first-child>td,.table>colgroup+thead>tr:first-child>td,.table>thead:first-child>tr:first-child>td{border-top:0}.table>tbody+tbody{border-top:2px solid #ddd}.table .table{background-color:#fff}.table-condensed>thead>tr>th,.table-condensed>tbody>tr>th,.table-condensed>tfoot>tr>th,.table-condensed>thead>tr>td,.table-condensed>tbody>tr>td,.table-condensed>tfoot>tr>td{padding:5px}.table-bordered{border:1px solid #ddd}.table-bordered>thead>tr>th,.table-bordered>tbody>tr>th,.table-bordered>tfoot>tr>th,.table-bordered>thead>tr>td,.table-bordered>tbody>tr>td,.table-bordered>tfoot>tr>td{border:1px solid #ddd}.table-bordered>thead>tr>th,.table-bordered>thead>tr>td{border-bottom-width:2px}.table-striped>tbody>tr:nth-of-type(odd){background-color:#f9f9f9}.table-hover>tbody>tr:hover{background-color:#f5f5f5}table col[class*=\"col-\"]{position:static;float:none;display:table-column}table td[class*=\"col-\"],table th[class*=\"col-\"]{position:static;float:none;display:table-cell}.table>thead>tr>td.active,.table>tbody>tr>td.active,.table>tfoot>tr>td.active,.table>thead>tr>th.active,.table>tbody>tr>th.active,.table>tfoot>tr>th.active,.table>thead>tr.active>td,.table>tbody>tr.active>td,.table>tfoot>tr.active>td,.table>thead>tr.active>th,.table>tbody>tr.active>th,.table>tfoot>tr.active>th{background-color:#f5f5f5}.table-hover>tbody>tr>td.active:hover,.table-hover>tbody>tr>th.active:hover,.table-hover>tbody>tr.active:hover>td,.table-hover>tbody>tr:hover>.active,.table-hover>tbody>tr.active:hover>th{background-color:#e8e8e8}.table>thead>tr>td.success,.table>tbody>tr>td.success,.table>tfoot>tr>td.success,.table>thead>tr>th.success,.table>tbody>tr>th.success,.table>tfoot>tr>th.success,.table>thead>tr.success>td,.table>tbody>tr.success>td,.table>tfoot>tr.success>td,.table>thead>tr.success>th,.table>tbody>tr.success>th,.table>tfoot>tr.success>th{background-color:#dff0d8}.table-hover>tbody>tr>td.success:hover,.table-hover>tbody>tr>th.success:hover,.table-hover>tbody>tr.success:hover>td,.table-hover>tbody>tr:hover>.success,.table-hover>tbody>tr.success:hover>th{background-color:#d0e9c6}.table>thead>tr>td.info,.table>tbody>tr>td.info,.table>tfoot>tr>td.info,.table>thead>tr>th.info,.table>tbody>tr>th.info,.table>tfoot>tr>th.info,.table>thead>tr.info>td,.table>tbody>tr.info>td,.table>tfoot>tr.info>td,.table>thead>tr.info>th,.table>tbody>tr.info>th,.table>tfoot>tr.info>th{background-color:#d9edf7}.table-hover>tbody>tr>td.info:hover,.table-hover>tbody>tr>th.info:hover,.table-hover>tbody>tr.info:hover>td,.table-hover>tbody>tr:hover>.info,.table-hover>tbody>tr.info:hover>th{background-color:#c4e3f3}.table>thead>tr>td.warning,.table>tbody>tr>td.warning,.table>tfoot>tr>td.warning,.table>thead>tr>th.warning,.table>tbody>tr>th.warning,.table>tfoot>tr>th.warning,.table>thead>tr.warning>td,.table>tbody>tr.warning>td,.table>tfoot>tr.warning>td,.table>thead>tr.warning>th,.table>tbody>tr.warning>th,.table>tfoot>tr.warning>th{background-color:#fcf8e3}.table-hover>tbody>tr>td.warning:hover,.table-hover>tbody>tr>th.warning:hover,.table-hover>tbody>tr.warning:hover>td,.table-hover>tbody>tr:hover>.warning,.table-hover>tbody>tr.warning:hover>th{background-color:#faf2cc}.table>thead>tr>td.danger,.table>tbody>tr>td.danger,.table>tfoot>tr>td.danger,.table>thead>tr>th.danger,.table>tbody>tr>th.danger,.table>tfoot>tr>th.danger,.table>thead>tr.danger>td,.table>tbody>tr.danger>td,.table>tfoot>tr.danger>td,.table>thead>tr.danger>th,.table>tbody>tr.danger>th,.table>tfoot>tr.danger>th{background-color:#f2dede}.table-hover>tbody>tr>td.danger:hover,.table-hover>tbody>tr>th.danger:hover,.table-hover>tbody>tr.danger:hover>td,.table-hover>tbody>tr:hover>.danger,.table-hover>tbody>tr.danger:hover>th{background-color:#ebcccc}.table-responsive{overflow-x:auto;min-height:0.01%}@media screen and (max-width:767px){.table-responsive{width:100%;margin-bottom:15px;overflow-y:hidden;-ms-overflow-style:-ms-autohiding-scrollbar;border:1px solid #ddd}.table-responsive>.table{margin-bottom:0}.table-responsive>.table>thead>tr>th,.table-responsive>.table>tbody>tr>th,.table-responsive>.table>tfoot>tr>th,.table-responsive>.table>thead>tr>td,.table-responsive>.table>tbody>tr>td,.table-responsive>.table>tfoot>tr>td{white-space:nowrap}.table-responsive>.table-bordered{border:0}.table-responsive>.table-bordered>thead>tr>th:first-child,.table-responsive>.table-bordered>tbody>tr>th:first-child,.table-responsive>.table-bordered>tfoot>tr>th:first-child,.table-responsive>.table-bordered>thead>tr>td:first-child,.table-responsive>.table-bordered>tbody>tr>td:first-child,.table-responsive>.table-bordered>tfoot>tr>td:first-child{border-left:0}.table-responsive>.table-bordered>thead>tr>th:last-child,.table-responsive>.table-bordered>tbody>tr>th:last-child,.table-responsive>.table-bordered>tfoot>tr>th:last-child,.table-responsive>.table-bordered>thead>tr>td:last-child,.table-responsive>.table-bordered>tbody>tr>td:last-child,.table-responsive>.table-bordered>tfoot>tr>td:last-child{border-right:0}.table-responsive>.table-bordered>tbody>tr:last-child>th,.table-responsive>.table-bordered>tfoot>tr:last-child>th,.table-responsive>.table-bordered>tbody>tr:last-child>td,.table-responsive>.table-bordered>tfoot>tr:last-child>td{border-bottom:0}}fieldset{padding:0;margin:0;border:0;min-width:0}legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:inherit;color:#333;border:0;border-bottom:1px solid #e5e5e5}label{display:inline-block;max-width:100%;margin-bottom:5px;font-weight:bold}input[type=\"search\"]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type=\"radio\"],input[type=\"checkbox\"]{margin:4px 0 0;margin-top:1px \\9;line-height:normal}input[type=\"file\"]{display:block}input[type=\"range\"]{display:block;width:100%}select[multiple],select[size]{height:auto}input[type=\"file\"]:focus,input[type=\"radio\"]:focus,input[type=\"checkbox\"]:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}output{display:block;padding-top:7px;font-size:14px;line-height:1.42857143;color:#555}.form-control{display:block;width:100%;height:34px;padding:6px 12px;font-size:14px;line-height:1.42857143;color:#555;background-color:#fff;background-image:none;border:1px solid #ccc;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-webkit-transition:border-color ease-in-out .15s, -webkit-box-shadow ease-in-out .15s;-o-transition:border-color ease-in-out .15s, box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s, box-shadow ease-in-out .15s}.form-control:focus{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6);box-shadow:inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6)}.form-control::-moz-placeholder{color:#999;opacity:1}.form-control:-ms-input-placeholder{color:#999}.form-control::-webkit-input-placeholder{color:#999}.form-control[disabled],.form-control[readonly],fieldset[disabled] .form-control{background-color:#eee;opacity:1}.form-control[disabled],fieldset[disabled] .form-control{cursor:not-allowed}textarea.form-control{height:auto}input[type=\"search\"]{-webkit-appearance:none}@media screen and (-webkit-min-device-pixel-ratio:0){input[type=\"date\"],input[type=\"time\"],input[type=\"datetime-local\"],input[type=\"month\"]{line-height:34px}input[type=\"date\"].input-sm,input[type=\"time\"].input-sm,input[type=\"datetime-local\"].input-sm,input[type=\"month\"].input-sm,.input-group-sm input[type=\"date\"],.input-group-sm input[type=\"time\"],.input-group-sm input[type=\"datetime-local\"],.input-group-sm input[type=\"month\"]{line-height:30px}input[type=\"date\"].input-lg,input[type=\"time\"].input-lg,input[type=\"datetime-local\"].input-lg,input[type=\"month\"].input-lg,.input-group-lg input[type=\"date\"],.input-group-lg input[type=\"time\"],.input-group-lg input[type=\"datetime-local\"],.input-group-lg input[type=\"month\"]{line-height:46px}}.form-group{margin-bottom:15px}.radio,.checkbox{position:relative;display:block;margin-top:10px;margin-bottom:10px}.radio label,.checkbox label{min-height:20px;padding-left:20px;margin-bottom:0;font-weight:normal;cursor:pointer}.radio input[type=\"radio\"],.radio-inline input[type=\"radio\"],.checkbox input[type=\"checkbox\"],.checkbox-inline input[type=\"checkbox\"]{position:absolute;margin-left:-20px;margin-top:4px \\9}.radio+.radio,.checkbox+.checkbox{margin-top:-5px}.radio-inline,.checkbox-inline{position:relative;display:inline-block;padding-left:20px;margin-bottom:0;vertical-align:middle;font-weight:normal;cursor:pointer}.radio-inline+.radio-inline,.checkbox-inline+.checkbox-inline{margin-top:0;margin-left:10px}input[type=\"radio\"][disabled],input[type=\"checkbox\"][disabled],input[type=\"radio\"].disabled,input[type=\"checkbox\"].disabled,fieldset[disabled] input[type=\"radio\"],fieldset[disabled] input[type=\"checkbox\"]{cursor:not-allowed}.radio-inline.disabled,.checkbox-inline.disabled,fieldset[disabled] .radio-inline,fieldset[disabled] .checkbox-inline{cursor:not-allowed}.radio.disabled label,.checkbox.disabled label,fieldset[disabled] .radio label,fieldset[disabled] .checkbox label{cursor:not-allowed}.form-control-static{padding-top:7px;padding-bottom:7px;margin-bottom:0;min-height:34px}.form-control-static.input-lg,.form-control-static.input-sm{padding-left:0;padding-right:0}.input-sm{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-sm{height:30px;line-height:30px}textarea.input-sm,select[multiple].input-sm{height:auto}.form-group-sm .form-control{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.form-group-sm .form-control{height:30px;line-height:30px}textarea.form-group-sm .form-control,select[multiple].form-group-sm .form-control{height:auto}.form-group-sm .form-control-static{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;min-height:32px}.input-lg{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.input-lg{height:46px;line-height:46px}textarea.input-lg,select[multiple].input-lg{height:auto}.form-group-lg .form-control{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.form-group-lg .form-control{height:46px;line-height:46px}textarea.form-group-lg .form-control,select[multiple].form-group-lg .form-control{height:auto}.form-group-lg .form-control-static{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;min-height:38px}.has-feedback{position:relative}.has-feedback .form-control{padding-right:42.5px}.form-control-feedback{position:absolute;top:0;right:0;z-index:2;display:block;width:34px;height:34px;line-height:34px;text-align:center;pointer-events:none}.input-lg+.form-control-feedback{width:46px;height:46px;line-height:46px}.input-sm+.form-control-feedback{width:30px;height:30px;line-height:30px}.has-success .help-block,.has-success .control-label,.has-success .radio,.has-success .checkbox,.has-success .radio-inline,.has-success .checkbox-inline,.has-success.radio label,.has-success.checkbox label,.has-success.radio-inline label,.has-success.checkbox-inline label{color:#3c763d}.has-success .form-control{border-color:#3c763d;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.has-success .form-control:focus{border-color:#2b542c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #67b168;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #67b168}.has-success .input-group-addon{color:#3c763d;border-color:#3c763d;background-color:#dff0d8}.has-success .form-control-feedback{color:#3c763d}.has-warning .help-block,.has-warning .control-label,.has-warning .radio,.has-warning .checkbox,.has-warning .radio-inline,.has-warning .checkbox-inline,.has-warning.radio label,.has-warning.checkbox label,.has-warning.radio-inline label,.has-warning.checkbox-inline label{color:#8a6d3b}.has-warning .form-control{border-color:#8a6d3b;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.has-warning .form-control:focus{border-color:#66512c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #c0a16b;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #c0a16b}.has-warning .input-group-addon{color:#8a6d3b;border-color:#8a6d3b;background-color:#fcf8e3}.has-warning .form-control-feedback{color:#8a6d3b}.has-error .help-block,.has-error .control-label,.has-error .radio,.has-error .checkbox,.has-error .radio-inline,.has-error .checkbox-inline,.has-error.radio label,.has-error.checkbox label,.has-error.radio-inline label,.has-error.checkbox-inline label{color:#a94442}.has-error .form-control{border-color:#a94442;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.has-error .form-control:focus{border-color:#843534;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #ce8483;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #ce8483}.has-error .input-group-addon{color:#a94442;border-color:#a94442;background-color:#f2dede}.has-error .form-control-feedback{color:#a94442}.has-feedback label~.form-control-feedback{top:25px}.has-feedback label.sr-only~.form-control-feedback{top:0}.help-block{display:block;margin-top:5px;margin-bottom:10px;color:#737373}@media (min-width:768px){.form-inline .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-static{display:inline-block}.form-inline .input-group{display:inline-table;vertical-align:middle}.form-inline .input-group .input-group-addon,.form-inline .input-group .input-group-btn,.form-inline .input-group .form-control{width:auto}.form-inline .input-group>.form-control{width:100%}.form-inline .control-label{margin-bottom:0;vertical-align:middle}.form-inline .radio,.form-inline .checkbox{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.form-inline .radio label,.form-inline .checkbox label{padding-left:0}.form-inline .radio input[type=\"radio\"],.form-inline .checkbox input[type=\"checkbox\"]{position:relative;margin-left:0}.form-inline .has-feedback .form-control-feedback{top:0}}.form-horizontal .radio,.form-horizontal .checkbox,.form-horizontal .radio-inline,.form-horizontal .checkbox-inline{margin-top:0;margin-bottom:0;padding-top:7px}.form-horizontal .radio,.form-horizontal .checkbox{min-height:27px}.form-horizontal .form-group{margin-left:-15px;margin-right:-15px}@media (min-width:768px){.form-horizontal .control-label{text-align:right;margin-bottom:0;padding-top:7px}}.form-horizontal .has-feedback .form-control-feedback{right:15px}@media (min-width:768px){.form-horizontal .form-group-lg .control-label{padding-top:14.333333px}}@media (min-width:768px){.form-horizontal .form-group-sm .control-label{padding-top:6px}}.btn{display:inline-block;margin-bottom:0;font-weight:normal;text-align:center;vertical-align:middle;-ms-touch-action:manipulation;touch-action:manipulation;cursor:pointer;background-image:none;border:1px solid transparent;white-space:nowrap;padding:6px 12px;font-size:14px;line-height:1.42857143;border-radius:4px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.btn:focus,.btn:active:focus,.btn.active:focus,.btn.focus,.btn:active.focus,.btn.active.focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn:hover,.btn:focus,.btn.focus{color:#333;text-decoration:none}.btn:active,.btn.active{outline:0;background-image:none;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,0.125);box-shadow:inset 0 3px 5px rgba(0,0,0,0.125)}.btn.disabled,.btn[disabled],fieldset[disabled] .btn{cursor:not-allowed;pointer-events:none;opacity:.65;filter:alpha(opacity=65);-webkit-box-shadow:none;box-shadow:none}.btn-default{color:#333;background-color:#fff;border-color:#ccc}.btn-default:hover,.btn-default:focus,.btn-default.focus,.btn-default:active,.btn-default.active,.open>.dropdown-toggle.btn-default{color:#333;background-color:#e6e6e6;border-color:#adadad}.btn-default:active,.btn-default.active,.open>.dropdown-toggle.btn-default{background-image:none}.btn-default.disabled,.btn-default[disabled],fieldset[disabled] .btn-default,.btn-default.disabled:hover,.btn-default[disabled]:hover,fieldset[disabled] .btn-default:hover,.btn-default.disabled:focus,.btn-default[disabled]:focus,fieldset[disabled] .btn-default:focus,.btn-default.disabled.focus,.btn-default[disabled].focus,fieldset[disabled] .btn-default.focus,.btn-default.disabled:active,.btn-default[disabled]:active,fieldset[disabled] .btn-default:active,.btn-default.disabled.active,.btn-default[disabled].active,fieldset[disabled] .btn-default.active{background-color:#fff;border-color:#ccc}.btn-default .badge{color:#fff;background-color:#333}.btn-primary{color:#fff;background-color:#337ab7;border-color:#2e6da4}.btn-primary:hover,.btn-primary:focus,.btn-primary.focus,.btn-primary:active,.btn-primary.active,.open>.dropdown-toggle.btn-primary{color:#fff;background-color:#286090;border-color:#204d74}.btn-primary:active,.btn-primary.active,.open>.dropdown-toggle.btn-primary{background-image:none}.btn-primary.disabled,.btn-primary[disabled],fieldset[disabled] .btn-primary,.btn-primary.disabled:hover,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary:hover,.btn-primary.disabled:focus,.btn-primary[disabled]:focus,fieldset[disabled] .btn-primary:focus,.btn-primary.disabled.focus,.btn-primary[disabled].focus,fieldset[disabled] .btn-primary.focus,.btn-primary.disabled:active,.btn-primary[disabled]:active,fieldset[disabled] .btn-primary:active,.btn-primary.disabled.active,.btn-primary[disabled].active,fieldset[disabled] .btn-primary.active{background-color:#337ab7;border-color:#2e6da4}.btn-primary .badge{color:#337ab7;background-color:#fff}.btn-success{color:#fff;background-color:#5cb85c;border-color:#4cae4c}.btn-success:hover,.btn-success:focus,.btn-success.focus,.btn-success:active,.btn-success.active,.open>.dropdown-toggle.btn-success{color:#fff;background-color:#449d44;border-color:#398439}.btn-success:active,.btn-success.active,.open>.dropdown-toggle.btn-success{background-image:none}.btn-success.disabled,.btn-success[disabled],fieldset[disabled] .btn-success,.btn-success.disabled:hover,.btn-success[disabled]:hover,fieldset[disabled] .btn-success:hover,.btn-success.disabled:focus,.btn-success[disabled]:focus,fieldset[disabled] .btn-success:focus,.btn-success.disabled.focus,.btn-success[disabled].focus,fieldset[disabled] .btn-success.focus,.btn-success.disabled:active,.btn-success[disabled]:active,fieldset[disabled] .btn-success:active,.btn-success.disabled.active,.btn-success[disabled].active,fieldset[disabled] .btn-success.active{background-color:#5cb85c;border-color:#4cae4c}.btn-success .badge{color:#5cb85c;background-color:#fff}.btn-info{color:#fff;background-color:#5bc0de;border-color:#46b8da}.btn-info:hover,.btn-info:focus,.btn-info.focus,.btn-info:active,.btn-info.active,.open>.dropdown-toggle.btn-info{color:#fff;background-color:#31b0d5;border-color:#269abc}.btn-info:active,.btn-info.active,.open>.dropdown-toggle.btn-info{background-image:none}.btn-info.disabled,.btn-info[disabled],fieldset[disabled] .btn-info,.btn-info.disabled:hover,.btn-info[disabled]:hover,fieldset[disabled] .btn-info:hover,.btn-info.disabled:focus,.btn-info[disabled]:focus,fieldset[disabled] .btn-info:focus,.btn-info.disabled.focus,.btn-info[disabled].focus,fieldset[disabled] .btn-info.focus,.btn-info.disabled:active,.btn-info[disabled]:active,fieldset[disabled] .btn-info:active,.btn-info.disabled.active,.btn-info[disabled].active,fieldset[disabled] .btn-info.active{background-color:#5bc0de;border-color:#46b8da}.btn-info .badge{color:#5bc0de;background-color:#fff}.btn-warning{color:#fff;background-color:#f0ad4e;border-color:#eea236}.btn-warning:hover,.btn-warning:focus,.btn-warning.focus,.btn-warning:active,.btn-warning.active,.open>.dropdown-toggle.btn-warning{color:#fff;background-color:#ec971f;border-color:#d58512}.btn-warning:active,.btn-warning.active,.open>.dropdown-toggle.btn-warning{background-image:none}.btn-warning.disabled,.btn-warning[disabled],fieldset[disabled] .btn-warning,.btn-warning.disabled:hover,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning:hover,.btn-warning.disabled:focus,.btn-warning[disabled]:focus,fieldset[disabled] .btn-warning:focus,.btn-warning.disabled.focus,.btn-warning[disabled].focus,fieldset[disabled] .btn-warning.focus,.btn-warning.disabled:active,.btn-warning[disabled]:active,fieldset[disabled] .btn-warning:active,.btn-warning.disabled.active,.btn-warning[disabled].active,fieldset[disabled] .btn-warning.active{background-color:#f0ad4e;border-color:#eea236}.btn-warning .badge{color:#f0ad4e;background-color:#fff}.btn-danger{color:#fff;background-color:#d9534f;border-color:#d43f3a}.btn-danger:hover,.btn-danger:focus,.btn-danger.focus,.btn-danger:active,.btn-danger.active,.open>.dropdown-toggle.btn-danger{color:#fff;background-color:#c9302c;border-color:#ac2925}.btn-danger:active,.btn-danger.active,.open>.dropdown-toggle.btn-danger{background-image:none}.btn-danger.disabled,.btn-danger[disabled],fieldset[disabled] .btn-danger,.btn-danger.disabled:hover,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger:hover,.btn-danger.disabled:focus,.btn-danger[disabled]:focus,fieldset[disabled] .btn-danger:focus,.btn-danger.disabled.focus,.btn-danger[disabled].focus,fieldset[disabled] .btn-danger.focus,.btn-danger.disabled:active,.btn-danger[disabled]:active,fieldset[disabled] .btn-danger:active,.btn-danger.disabled.active,.btn-danger[disabled].active,fieldset[disabled] .btn-danger.active{background-color:#d9534f;border-color:#d43f3a}.btn-danger .badge{color:#d9534f;background-color:#fff}.btn-link{color:#337ab7;font-weight:normal;border-radius:0}.btn-link,.btn-link:active,.btn-link.active,.btn-link[disabled],fieldset[disabled] .btn-link{background-color:transparent;-webkit-box-shadow:none;box-shadow:none}.btn-link,.btn-link:hover,.btn-link:focus,.btn-link:active{border-color:transparent}.btn-link:hover,.btn-link:focus{color:#23527c;text-decoration:underline;background-color:transparent}.btn-link[disabled]:hover,fieldset[disabled] .btn-link:hover,.btn-link[disabled]:focus,fieldset[disabled] .btn-link:focus{color:#777;text-decoration:none}.btn-lg{padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}.btn-sm{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.btn-xs{padding:1px 5px;font-size:12px;line-height:1.5;border-radius:3px}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:5px}input[type=\"submit\"].btn-block,input[type=\"reset\"].btn-block,input[type=\"button\"].btn-block{width:100%}.pagination{display:inline-block;padding-left:0;margin:20px 0;border-radius:4px}.pagination>li{display:inline}.pagination>li>a,.pagination>li>span{position:relative;float:left;padding:6px 12px;line-height:1.42857143;text-decoration:none;color:#337ab7;background-color:#fff;border:1px solid #ddd;margin-left:-1px}.pagination>li:first-child>a,.pagination>li:first-child>span{margin-left:0;border-bottom-left-radius:4px;border-top-left-radius:4px}.pagination>li:last-child>a,.pagination>li:last-child>span{border-bottom-right-radius:4px;border-top-right-radius:4px}.pagination>li>a:hover,.pagination>li>span:hover,.pagination>li>a:focus,.pagination>li>span:focus{color:#23527c;background-color:#eee;border-color:#ddd}.pagination>.active>a,.pagination>.active>span,.pagination>.active>a:hover,.pagination>.active>span:hover,.pagination>.active>a:focus,.pagination>.active>span:focus{z-index:2;color:#fff;background-color:#337ab7;border-color:#337ab7;cursor:default}.pagination>.disabled>span,.pagination>.disabled>span:hover,.pagination>.disabled>span:focus,.pagination>.disabled>a,.pagination>.disabled>a:hover,.pagination>.disabled>a:focus{color:#777;background-color:#fff;border-color:#ddd;cursor:not-allowed}.pagination-lg>li>a,.pagination-lg>li>span{padding:10px 16px;font-size:18px}.pagination-lg>li:first-child>a,.pagination-lg>li:first-child>span{border-bottom-left-radius:6px;border-top-left-radius:6px}.pagination-lg>li:last-child>a,.pagination-lg>li:last-child>span{border-bottom-right-radius:6px;border-top-right-radius:6px}.pagination-sm>li>a,.pagination-sm>li>span{padding:5px 10px;font-size:12px}.pagination-sm>li:first-child>a,.pagination-sm>li:first-child>span{border-bottom-left-radius:3px;border-top-left-radius:3px}.pagination-sm>li:last-child>a,.pagination-sm>li:last-child>span{border-bottom-right-radius:3px;border-top-right-radius:3px}.pager{padding-left:0;margin:20px 0;list-style:none;text-align:center}.pager li{display:inline}.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;border-radius:15px}.pager li>a:hover,.pager li>a:focus{text-decoration:none;background-color:#eee}.pager .next>a,.pager .next>span{float:right}.pager .previous>a,.pager .previous>span{float:left}.pager .disabled>a,.pager .disabled>a:hover,.pager .disabled>a:focus,.pager .disabled>span{color:#777;background-color:#fff;cursor:not-allowed}.alert{padding:15px;margin-bottom:20px;border:1px solid transparent;border-radius:4px}.alert h4{margin-top:0;color:inherit}.alert .alert-link{font-weight:bold}.alert>p,.alert>ul{margin-bottom:0}.alert>p+p{margin-top:5px}.alert-dismissable,.alert-dismissible{padding-right:35px}.alert-dismissable .close,.alert-dismissible .close{position:relative;top:-2px;right:-21px;color:inherit}.alert-success{background-color:#dff0d8;border-color:#d6e9c6;color:#3c763d}.alert-success hr{border-top-color:#c9e2b3}.alert-success .alert-link{color:#2b542c}.alert-info{background-color:#d9edf7;border-color:#bce8f1;color:#31708f}.alert-info hr{border-top-color:#a6e1ec}.alert-info .alert-link{color:#245269}.alert-warning{background-color:#fcf8e3;border-color:#faebcc;color:#8a6d3b}.alert-warning hr{border-top-color:#f7e1b5}.alert-warning .alert-link{color:#66512c}.alert-danger{background-color:#f2dede;border-color:#ebccd1;color:#a94442}.alert-danger hr{border-top-color:#e4b9c0}.alert-danger .alert-link{color:#843534}.clearfix:before,.clearfix:after,.dl-horizontal dd:before,.dl-horizontal dd:after,.container:before,.container:after,.container-fluid:before,.container-fluid:after,.row:before,.row:after,.form-horizontal .form-group:before,.form-horizontal .form-group:after,.pager:before,.pager:after{content:\" \";display:table}.clearfix:after,.dl-horizontal dd:after,.container:after,.container-fluid:after,.row:after,.form-horizontal .form-group:after,.pager:after{clear:both}.center-block{display:block;margin-left:auto;margin-right:auto}.pull-right{float:right !important}.pull-left{float:left !important}.hide{display:none !important}.show{display:block !important}.invisible{visibility:hidden}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.hidden{display:none !important}.affix{position:fixed}@-ms-viewport{width:device-width}.visible-xs,.visible-sm,.visible-md,.visible-lg{display:none !important}.visible-xs-block,.visible-xs-inline,.visible-xs-inline-block,.visible-sm-block,.visible-sm-inline,.visible-sm-inline-block,.visible-md-block,.visible-md-inline,.visible-md-inline-block,.visible-lg-block,.visible-lg-inline,.visible-lg-inline-block{display:none !important}@media (max-width:767px){.visible-xs{display:block !important}table.visible-xs{display:table}tr.visible-xs{display:table-row !important}th.visible-xs,td.visible-xs{display:table-cell !important}}@media (max-width:767px){.visible-xs-block{display:block !important}}@media (max-width:767px){.visible-xs-inline{display:inline !important}}@media (max-width:767px){.visible-xs-inline-block{display:inline-block !important}}@media (min-width:768px) and (max-width:991px){.visible-sm{display:block !important}table.visible-sm{display:table}tr.visible-sm{display:table-row !important}th.visible-sm,td.visible-sm{display:table-cell !important}}@media (min-width:768px) and (max-width:991px){.visible-sm-block{display:block !important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline{display:inline !important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline-block{display:inline-block !important}}@media (min-width:992px) and (max-width:1199px){.visible-md{display:block !important}table.visible-md{display:table}tr.visible-md{display:table-row !important}th.visible-md,td.visible-md{display:table-cell !important}}@media (min-width:992px) and (max-width:1199px){.visible-md-block{display:block !important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline{display:inline !important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline-block{display:inline-block !important}}@media (min-width:1200px){.visible-lg{display:block !important}table.visible-lg{display:table}tr.visible-lg{display:table-row !important}th.visible-lg,td.visible-lg{display:table-cell !important}}@media (min-width:1200px){.visible-lg-block{display:block !important}}@media (min-width:1200px){.visible-lg-inline{display:inline !important}}@media (min-width:1200px){.visible-lg-inline-block{display:inline-block !important}}@media (max-width:767px){.hidden-xs{display:none !important}}@media (min-width:768px) and (max-width:991px){.hidden-sm{display:none !important}}@media (min-width:992px) and (max-width:1199px){.hidden-md{display:none !important}}@media (min-width:1200px){.hidden-lg{display:none !important}}.visible-print{display:none !important}@media print{.visible-print{display:block !important}table.visible-print{display:table}tr.visible-print{display:table-row !important}th.visible-print,td.visible-print{display:table-cell !important}}.visible-print-block{display:none !important}@media print{.visible-print-block{display:block !important}}.visible-print-inline{display:none !important}@media print{.visible-print-inline{display:inline !important}}.visible-print-inline-block{display:none !important}@media print{.visible-print-inline-block{display:inline-block !important}}@media print{.hidden-print{display:none !important}}"
  },
  {
    "path": "themes/default/public/css/fontelico-codes.css",
    "content": "\n.icon-clipboard:before { content: '\\e800'; } /* '' */\n.icon-trash:before { content: '\\e804'; } /* '' */"
  },
  {
    "path": "themes/default/public/css/fontelico-embedded.css",
    "content": "@font-face {\n  font-family: 'fontelico';\n  src: url('../font/fontelico.eot?87465342');\n  src: url('../font/fontelico.eot?87465342#iefix') format('embedded-opentype'),\n       url('../font/fontelico.svg?87465342#fontelico') format('svg');\n  font-weight: normal;\n  font-style: normal;\n}\n@font-face {\n  font-family: 'fontelico';\n  src: url('data:application/octet-stream;base64,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') format('woff'),\n       url('data:application/octet-stream;base64,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') format('truetype');\n}\n/* Chrome hack: SVG is rendered more smooth in Windozze. 100% magic, uncomment if you need it. */\n/* Note, that will break hinting! In other OS-es font will be not as sharp as it could be */\n/*\n@media screen and (-webkit-min-device-pixel-ratio:0) {\n  @font-face {\n    font-family: 'fontelico';\n    src: url('../font/fontelico.svg?87465342#fontelico') format('svg');\n  }\n}\n*/\n \n [class^=\"icon-\"]:before, [class*=\" icon-\"]:before {\n  font-family: \"fontelico\";\n  font-style: normal;\n  font-weight: normal;\n  speak: none;\n \n  display: inline-block;\n  text-decoration: inherit;\n  width: 1em;\n  margin-right: .2em;\n  text-align: center;\n  /* opacity: .8; */\n \n  /* For safety - reset parent styles, that can break glyph codes*/\n  font-variant: normal;\n  text-transform: none;\n     \n  /* fix buttons height, for twitter bootstrap */\n  line-height: 1em;\n \n  /* Animation center compensation - margins should be symmetric */\n  /* remove if not needed */\n  margin-left: .2em;\n \n  /* you can be more comfortable with increased icons size */\n  /* font-size: 120%; */\n \n  /* Uncomment for 3D effect */\n  /* text-shadow: 1px 1px 1px rgba(127, 127, 127, 0.3); */\n}\n.icon-clipboard:before { content: '\\e800'; } /* '' */\n.icon-trash:before { content: '\\e804'; } /* '' */"
  },
  {
    "path": "themes/default/public/css/fontelico-ie7-codes.css",
    "content": "\n.icon-clipboard { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe800;&nbsp;'); }\n.icon-trash { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe804;&nbsp;'); }"
  },
  {
    "path": "themes/default/public/css/fontelico-ie7.css",
    "content": "[class^=\"icon-\"], [class*=\" icon-\"] {\n  font-family: 'fontelico';\n  font-style: normal;\n  font-weight: normal;\n \n  /* fix buttons height */\n  line-height: 1em;\n \n  /* you can be more comfortable with increased icons size */\n  /* font-size: 120%; */\n}\n \n.icon-clipboard { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe800;&nbsp;'); }\n.icon-trash { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe804;&nbsp;'); }"
  },
  {
    "path": "themes/default/public/css/fontelico.css",
    "content": "@font-face {\n  font-family: 'fontelico';\n  src: url('../font/fontelico.eot?21941692');\n  src: url('../font/fontelico.eot?21941692#iefix') format('embedded-opentype'),\n       url('../font/fontelico.woff2?21941692') format('woff2'),\n       url('../font/fontelico.woff?21941692') format('woff'),\n       url('../font/fontelico.ttf?21941692') format('truetype'),\n       url('../font/fontelico.svg?21941692#fontelico') format('svg');\n  font-weight: normal;\n  font-style: normal;\n}\n/* Chrome hack: SVG is rendered more smooth in Windozze. 100% magic, uncomment if you need it. */\n/* Note, that will break hinting! In other OS-es font will be not as sharp as it could be */\n/*\n@media screen and (-webkit-min-device-pixel-ratio:0) {\n  @font-face {\n    font-family: 'fontelico';\n    src: url('../font/fontelico.svg?21941692#fontelico') format('svg');\n  }\n}\n*/\n \n [class^=\"icon-\"]:before, [class*=\" icon-\"]:before {\n  font-family: \"fontelico\";\n  font-style: normal;\n  font-weight: normal;\n  speak: none;\n \n  display: inline-block;\n  text-decoration: inherit;\n  width: 1em;\n  margin-right: .2em;\n  text-align: center;\n  /* opacity: .8; */\n \n  /* For safety - reset parent styles, that can break glyph codes*/\n  font-variant: normal;\n  text-transform: none;\n \n  /* fix buttons height, for twitter bootstrap */\n  line-height: 1em;\n \n  /* Animation center compensation - margins should be symmetric */\n  /* remove if not needed */\n  margin-left: .2em;\n \n  /* you can be more comfortable with increased icons size */\n  /* font-size: 120%; */\n \n  /* Font smoothing. That was taken from TWBS */\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n \n  /* Uncomment for 3D effect */\n  /* text-shadow: 1px 1px 1px rgba(127, 127, 127, 0.3); */\n}\n \n.icon-clipboard:before { content: '\\e800'; } /* '' */\n.icon-trash:before { content: '\\e804'; } /* '' */"
  },
  {
    "path": "themes/default/public/css/fontelico.min.css",
    "content": "@font-face{font-family:fontelico;src:url(data:application/vnd.ms-fontobject;base64,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sgEAPistsFUssgEBPistsFYssgAAQCstsFcssgABQCstsFgssgEAQCstsFkssgEBQCstsFossgAAQystsFsssgABQystsFwssgEAQystsF0ssgEBQystsF4ssgAAPystsF8ssgABPystsGAssgEAPystsGEssgEBPystsGIssDcrLrErARQrLbBjLLA3K7A7Ky2wZCywNyuwPCstsGUssAAWsDcrsD0rLbBmLLA4Ky6xKwEUKy2wZyywOCuwOystsGgssDgrsDwrLbBpLLA4K7A9Ky2waiywOSsusSsBFCstsGsssDkrsDsrLbBsLLA5K7A8Ky2wbSywOSuwPSstsG4ssDorLrErARQrLbBvLLA6K7A7Ky2wcCywOiuwPCstsHEssDorsD0rLbByLLMJBAIDRVghGyMhWUIrsAhlsAMkUHiwARUwLQBLuADIUlixAQGOWbABuQgACABjcLEABUKyAAEAKrEABUKzCgIBCCqxAAVCsw4AAQgqsQAGQroCwAABAAkqsQAHQroAQAABAAkqsQMARLEkAYhRWLBAiFixA2REsSYBiFFYugiAAAEEQIhjVFixAwBEWVlZWbMMAgEMKrgB/4WwBI2xAgBEAAA=);src:url(data:application/vnd.ms-fontobject;base64,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sgEAPistsFUssgEBPistsFYssgAAQCstsFcssgABQCstsFgssgEAQCstsFkssgEBQCstsFossgAAQystsFsssgABQystsFwssgEAQystsF0ssgEBQystsF4ssgAAPystsF8ssgABPystsGAssgEAPystsGEssgEBPystsGIssDcrLrErARQrLbBjLLA3K7A7Ky2wZCywNyuwPCstsGUssAAWsDcrsD0rLbBmLLA4Ky6xKwEUKy2wZyywOCuwOystsGgssDgrsDwrLbBpLLA4K7A9Ky2waiywOSsusSsBFCstsGsssDkrsDsrLbBsLLA5K7A8Ky2wbSywOSuwPSstsG4ssDorLrErARQrLbBvLLA6K7A7Ky2wcCywOiuwPCstsHEssDorsD0rLbByLLMJBAIDRVghGyMhWUIrsAhlsAMkUHiwARUwLQBLuADIUlixAQGOWbABuQgACABjcLEABUKyAAEAKrEABUKzCgIBCCqxAAVCsw4AAQgqsQAGQroCwAABAAkqsQAHQroAQAABAAkqsQMARLEkAYhRWLBAiFixA2REsSYBiFFYugiAAAEEQIhjVFixAwBEWVlZWbMMAgEMKrgB/4WwBI2xAgBEAAA=) format('embedded-opentype'),url(data:application/font-woff2;base64,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) format('woff2'),url(data:application/x-font-woff;base64,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) format('woff'),url(data:application/x-font-ttf;base64,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) format('truetype'),url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/Pgo8IURPQ1RZUEUgc3ZnIFBVQkxJQyAiLS8vVzNDLy9EVEQgU1ZHIDEuMS8vRU4iICJodHRwOi8vd3d3LnczLm9yZy9HcmFwaGljcy9TVkcvMS4xL0RURC9zdmcxMS5kdGQiPgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxtZXRhZGF0YT5Db3B5cmlnaHQgKEMpIDIwMTYgYnkgb3JpZ2luYWwgYXV0aG9ycyBAIGZvbnRlbGxvLmNvbTwvbWV0YWRhdGE+CjxkZWZzPgo8Zm9udCBpZD0iZm9udGVsaWNvIiBob3Jpei1hZHYteD0iMTAwMCIgPgo8Zm9udC1mYWNlIGZvbnQtZmFtaWx5PSJmb250ZWxpY28iIGZvbnQtd2VpZ2h0PSI0MDAiIGZvbnQtc3RyZXRjaD0ibm9ybWFsIiB1bml0cy1wZXItZW09IjEwMDAiIGFzY2VudD0iODUwIiBkZXNjZW50PSItMTUwIiAvPgo8bWlzc2luZy1nbHlwaCBob3Jpei1hZHYteD0iMTAwMCIgLz4KPGdseXBoIGdseXBoLW5hbWU9ImNsaXBib2FyZCIgdW5pY29kZT0iJiN4ZTgwMDsiIGQ9Ik0wLTE1MGwwIDkwNCAyMjUgMCAwLTY0LTE2MSAwIDAtNzc0IDU3OSAwIDAgNzc0LTE2MSAwIDAgNjQgMjI1IDAgMC05MDQtNzA3IDB6IG0xMjkgMTI5bDAgMzEgMzEgMCAwLTMxLTMxIDB6IG0wIDEyMWwwIDMxIDMxIDAgMC0zMS0zMSAweiBtMCAxMjFsMCAzMSAzMSAwIDAtMzEtMzEgMHogbTAgMTIxbDAgMzIgMzEgMCAwLTMyLTMxIDB6IG0wIDEyMWwwIDMyIDMxIDAgMC0zMi0zMSAweiBtMCA5NmwwIDk0IDEyOSAwIDAgOTdxMCA0MSAyNyA3MXQ2OSAyOSA2OS0zMCAyOC03MHEwLTU2LTItOTdsMTI5IDAgMC05NC00NDkgMHogbTk2LTU4MmwwIDMzIDM1MyAwIDAtMzMtMzUzIDB6IG0wIDEyMWwwIDMzIDM1MyAwIDAtMzMtMzUzIDB6IG0wIDEyMWwwIDMzIDM1MyAwIDAtMzMtMzUzIDB6IG0wIDEyMWwwIDM0IDM1MyAwIDAtMzQtMzUzIDB6IG0wIDEyMWwwIDM0IDM1MyAwIDAtMzQtMzUzIDB6IG05NyAyNjBxMC0xNCA5LTIydDIzLTkgMjIgOSA5IDIyLTkgMjQtMjIgOS0yMy05LTktMjR6IiBob3Jpei1hZHYteD0iNzA3IiAvPgoKPGdseXBoIGdseXBoLW5hbWU9InRyYXNoIiB1bmljb2RlPSImI3hlODA0OyIgZD0iTTI4NiA0Mzl2LTMyMXEwLTgtNS0xM3QtMTMtNWgtMzZxLTggMC0xMyA1dC01IDEzdjMyMXEwIDggNSAxM3QxMyA1aDM2cTggMCAxMy01dDUtMTN6IG0xNDMgMHYtMzIxcTAtOC01LTEzdC0xMy01aC0zNnEtOCAwLTEzIDV0LTUgMTN2MzIxcTAgOCA1IDEzdDEzIDVoMzZxOCAwIDEzLTV0NS0xM3ogbTE0MiAwdi0zMjFxMC04LTUtMTN0LTEyLTVoLTM2cS04IDAtMTMgNXQtNSAxM3YzMjFxMCA4IDUgMTN0MTMgNWgzNnE3IDAgMTItNXQ1LTEzeiBtNzItNDA0djUyOWgtNTAwdi01MjlxMC0xMiA0LTIydDgtMTUgNi01aDQ2NHEyIDAgNiA1dDggMTUgNCAyMnogbS0zNzUgNjAxaDI1MGwtMjcgNjVxLTQgNS05IDZoLTE3N3EtNi0xLTEwLTZ6IG01MTgtMTh2LTM2cTAtOC01LTEzdC0xMy01aC01NHYtNTI5cTAtNDYtMjYtODB0LTYzLTM0aC00NjRxLTM3IDAtNjMgMzN0LTI3IDc5djUzMWgtNTNxLTggMC0xMyA1dC01IDEzdjM2cTAgOCA1IDEzdDEzIDVoMTcybDM5IDkzcTkgMjEgMzEgMzV0NDQgMTVoMTc4cTIzIDAgNDQtMTV0MzAtMzVsMzktOTNoMTczcTggMCAxMy01dDUtMTN6IiBob3Jpei1hZHYteD0iNzg1LjciIC8+CjwvZm9udD4KPC9kZWZzPgo8L3N2Zz4=) format('svg');font-weight:400;font-style:normal}[class*=\" icon-\"]:before,[class^=icon-]:before{font-family:fontelico;font-style:normal;font-weight:400;speak:none;display:inline-block;text-decoration:inherit;width:1em;margin-right:.2em;text-align:center;font-variant:normal;text-transform:none;line-height:1em;margin-left:.2em;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.icon-clipboard:before{content:'\\e800'}.icon-trash:before{content:'\\e804'}\n"
  },
  {
    "path": "themes/default/public/css/lstu.css",
    "content": "body {\n    padding-top: 40px;\n    padding-bottom: 40px;\n}\n\n.container {\n    padding: 15px;\n    margin: 0 auto;\n}\n\n@font-face {\n    font-family: 'Henny_Penny';\n    font-style: normal;\n    font-weight: 400;\n    src: local('Henny Penny'), local('HennyPenny-Regular'), url('../font/hennypenny.woff2') format('woff2');\n}\n\n@font-face {\n    font-family: 'Oswald';\n    font-style: bold;\n    font-weight: 400;\n    src: local('Oswald'), url('../font/Oswald-Bold.ttf')\n}\n\n@font-face {\n    font-family: 'OpenSans';\n    font-style: normal;\n    font-weight: 200;\n    src: local('OpenSans'), url('../font/OpenSans-Regular.ttf')\n}\n\n.oswald {\n    font-family: 'Oswald';\n    font-size: 42px;\n}\n\n.hennypenny {\n    font-family: 'Henny_Penny', cursive;\n    font-size: 42px;\n}\n\n.opensans {\n    font-family: 'OpenSans';\n    font-size: 25px;\n}\n.link_nocol, .link_nocol:hover {\n    color: #000;\n    text-decoration: none;\n}\ndd > strong {\n    padding-left: 15px;\n}\n\n.logo {\n    height: auto!important;\n    padding-right: 20px;\n}\n\n.logo-img {\n    height: 200px;\n    width: 100%;\n}\n\n.allons-y {\n    border-style: none;\n    background: linear-gradient(to right, rgba(255, 255, 255, 0.3) 0%, rgba(255,255,255, 0.5) 100%, transparent 25px) no-repeat, #B24B04;\n    background-repeat: no-repeat, no-repeat;\n    border-radius: 5px;\n    box-shadow: 2px 2px 1px 1px rgba(0,0,0,0.3);\n    padding: 8px;\n    margin-right: 9px;\n    color: white;\n    font-family: 'OpenSans';\n    font-size: 14px;\n    background-size: 0 100%, 100% 100%;\n    transition: background-size 0.3s; \n}\n\n.allons-y:hover {\n    background-size: 101% 100%;\n}\n.allons-y:active {\n    box-shadow: none; transform: translate(2px, 2px); transition: all 0.1s;\n}\n"
  },
  {
    "path": "themes/default/public/font/licenses/Apache License.txt",
    "content": "Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License."
  },
  {
    "path": "themes/default/public/font/licenses/SIL Open Font License.txt",
    "content": "Copyright (c) 2012, Vernon Adams (vern@newtypography.co.uk),\nwith Reserved Font Name Oswald\n\nThis Font Software is licensed under the SIL Open Font License, Version 1.1.\nThis license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL\n\n-----------------------------------------------------------\nSIL OPEN FONT LICENSE Version 1.1 - 26 February 2007\n-----------------------------------------------------------\n\nPREAMBLE\nThe goals of the Open Font License (OFL) are to stimulate worldwide development of collaborative font projects, to support the font creation efforts of academic and linguistic communities, and to provide a free and open framework in which fonts may be shared and improved in partnership with others.\n\nThe OFL allows the licensed fonts to be used, studied, modified and redistributed freely as long as they are not sold by themselves. The fonts, including any derivative works, can be bundled, embedded, redistributed and/or sold with any software provided that any reserved names are not used by derivative works. The fonts and derivatives, however, cannot be released under any other type of license. The requirement for fonts to remain under this license does not apply to any document created using the fonts or their derivatives.\n\nDEFINITIONS\n\"Font Software\" refers to the set of files released by the Copyright Holder(s) under this license and clearly marked as such. This may include source files, build scripts and documentation.\n\n\"Reserved Font Name\" refers to any names specified as such after the copyright statement(s).\n\n\"Original Version\" refers to the collection of Font Software components as distributed by the Copyright Holder(s).\n\n\"Modified Version\" refers to any derivative made by adding to, deleting, or substituting -- in part or in whole -- any of the components of the Original Version, by changing formats or by porting the Font Software to a new environment.\n\n\"Author\" refers to any designer, engineer, programmer, technical writer or other person who contributed to the Font Software.\n\nPERMISSION & CONDITIONS\nPermission is hereby granted, free of charge, to any person obtaining a copy of the Font Software, to use, study, copy, merge, embed, modify, redistribute, and sell modified and unmodified copies of the Font Software, subject to the following conditions:\n\n1) Neither the Font Software nor any of its individual components, in Original or Modified Versions, may be sold by itself.\n\n2) Original or Modified Versions of the Font Software may be bundled, redistributed and/or sold with any software, provided that each copy contains the above copyright notice and this license. These can be included either as stand-alone text files, human-readable headers or in the appropriate machine-readable metadata fields within text or binary files as long as those fields can be easily viewed by the user.\n\n3) No Modified Version of the Font Software may use the Reserved Font Name(s) unless explicit written permission is granted by the corresponding Copyright Holder. This restriction only applies to the primary font name as presented to the users.\n\n4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font Software shall not be used to promote, endorse or advertise any Modified Version, except to acknowledge the contribution(s) of the Copyright Holder(s) and the Author(s) or with their explicit written permission.\n\n5) The Font Software, modified or unmodified, in part or in whole, must be distributed entirely under this license, and must not be distributed under any other license. The requirement for fonts to remain under this license does not apply to any document created using the Font Software.\n\nTERMINATION\nThis license becomes null and void if any of the above conditions are not met.\n\nDISCLAIMER\nTHE FONT SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE."
  },
  {
    "path": "themes/default/public/fontello.json",
    "content": "{\n  \"name\": \"fontelico\",\n  \"css_prefix_text\": \"icon-\",\n  \"css_use_suffix\": false,\n  \"hinting\": true,\n  \"units_per_em\": 1000,\n  \"ascent\": 850,\n  \"glyphs\": [\n    {\n      \"uid\": \"c9bef3dc67fea47e94c4a5030ea64dad\",\n      \"css\": \"clipboard\",\n      \"code\": 59392,\n      \"src\": \"elusive\"\n    },\n    {\n      \"uid\": \"f48ae54adfb27d8ada53d0fd9e34ee10\",\n      \"css\": \"trash\",\n      \"code\": 59396,\n      \"src\": \"fontawesome\"\n    }\n  ]\n}"
  },
  {
    "path": "themes/default/public/manifest.json",
    "content": "{\n    \"name\": \"Let's Shorten That Url\",\n    \"short_name\": \"lstu\",\n    \"icons\": [\n        {\n            \"src\": \"/img/lstu36.png\",\n            \"sizes\": \"36x36\",\n            \"type\": \"image/png\"\n        },\n        {\n            \"src\": \"/img/lstu48.png\",\n            \"sizes\": \"48x48\",\n            \"type\": \"image/png\"\n        },\n        {\n            \"src\": \"/img/lstu72.png\",\n            \"sizes\": \"72x72\",\n            \"type\": \"image/png\"\n        },\n        {\n            \"src\": \"/img/lstu96.png\",\n            \"sizes\": \"96x96\",\n            \"type\": \"image/png\"\n        },\n        {\n            \"src\": \"/img/lstu144.png\",\n            \"sizes\": \"144x144\",\n            \"type\": \"image/png\"\n        },\n        {\n            \"src\": \"/img/lstu192.png\",\n            \"sizes\": \"192x192\",\n            \"type\": \"image/png\"\n        }\n    ],\n    \"theme_color\": \"#ffffff\",\n    \"background_color\": \"#ffffff\",\n    \"display\": \"standalone\"\n}\n"
  },
  {
    "path": "themes/default/templates/api.html.ep",
    "content": "% # vim:set sw=4 ts=4 sts=4 ft=html.epl expandtab:\n% title 'Lstu API';\n% use Mojo::JSON qw(to_json);\n<h2>Lstu API</h2>\n% if ($self->config('disable_api')) {\n<p>\n    <strong>\n        %= l('Sorry, the API is disabled.')\n        %= l('This page is informational only.')\n    </strong>\n</p>\n% }\n<dl>\n% if (defined $self->config('ldap') || defined $self->config('htpasswd')) {\n    <dt>POST <%= url_for('login')->to_abs %></dt>\n    <dd>\n        <strong><%= l('Parameters:') %></strong>\n        <ul>\n            <li><strong>login</strong> <em><%= l('mandatory') %></em><br><%= l('Your login') %></li>\n            <li><strong>password</strong> <em><%= l('mandatory') %></em><br><%= l('Your password') %></li>\n            <li><strong>_format</strong> <em><%= l('optional') %></em><br><%= l('If equal to \"json\", response will be in JSON format, HTML format otherwise') %></li>\n        </ul>\n        <strong><%= l('Response:') %></strong>\n        <ul>\n            <li><strong><%= l('JSON: success') %></strong><br><code>{\"msg\":\"<%= l('You have been successfully logged in.')%>\",\"success\":true}</code></li>\n            <li><strong><%= l('JSON: failure') %></strong><br><code>{\"msg\":\"<%= l('Please, check your credentials: unable to authenticate.') %>\",\"success\":false}</code></li>\n            <li><strong><%= l('Response for HTML format') %></strong><br><%= l('You will be redirected to the Lstu classic interface where you will be able to shorten URLs') %></li>\n        </ul>\n    </dd>\n    <dt>GET <%= url_for('logout')->to_abs %></dt>\n    <dd>\n        <p><%= l('Should always be successful') %></p>\n        <strong><%= l('Parameters:') %></strong>\n        <ul>\n            <li><strong>_format</strong> <em><%= l('optional') %></em><br><%= l('If equal to \"json\", response will be in JSON format, HTML format otherwise') %></li>\n        </ul>\n        <strong><%= l('Response:') %></strong>\n        <ul>\n            <li><strong><%= l('JSON: success') %></strong><br><code>{\"msg\":\"<%= l('You have been successfully logged out.')%>\",\"success\":true}</code></li>\n            <li><strong><%= l('Response for HTML format') %></strong><br><%= l('You will be redirected to Lstu successfully logged out interface') %></li>\n        </ul>\n    </dd>\n% }\n    <dt>POST <%= url_for('add')->to_abs %></dt>\n    <dd>\n% if (defined $self->config('ldap') || defined $self->config('htpasswd')) {\n        <p><%= l('You must be logged in to use it.') %></p>\n% }\n        <strong><%= l('Parameters:') %></strong>\n        <ul>\n            <li><strong>lsturl</strong> <em><%= l('mandatory') %></em><br><%= l('URL to shorten') %></li>\n            <li><strong>lsturl-custom</strong> <em><%= l('optional') %></em><br><%= l('Custom shortened text')%></li>\n            <li><strong>_format</strong> <em><%= l('optional') %></em><br><%= l('If equal to \"json\", response will be in JSON format, HTML format otherwise') %></li>\n        </ul>\n        <strong><%= l('Response:') %></strong>\n        <ul>\n            % my $u = prefix().url_for('short', short => 'XzQBd6eFa');\n            % $u =~ s#//#/#g;\n            % $u = to_json $u;\n            <li><strong><%= l('JSON: success') %></strong><br><code>{\"url\":\"https:\\/\\/fiat-tux.fr\",\"short\":<%= $u %>,\"success\":true}</code></li>\n            <li><strong><%= l('JSON: failure') %></strong><br><code>{\"msg\":\"<%= l('Failure reason') %>\",\"success\":false}</code></li>\n            <li><strong><%= l('Response for HTML format') %></strong><br><%= l('You will be redirected to the Lstu classic interface with a message giving the shortened URL') %></li>\n        </ul>\n    </dd>\n    <dt>GET <%= url_for('short', short => l('shortened_url'))->to_abs %></dt>\n    <dd>\n        <strong><%= l('Response:') %></strong>\n        <ul>\n            <li>\n                <%= l('You will be redirected to the targeted URL or to the Lstu interface with a message giving the failure reason') %>\n            </li>\n        </ul>\n    </dd>\n    <dt>GET <%= url_for('short', short => l('shortened_url'))->to_abs %>?_format=json</dt>\n    <dd>\n        <strong><%= l('Response:') %></strong>\n        <ul>\n            <li><strong><%= l('JSON: success') %></strong><br><code>{\"url\":\"https:\\/\\/fiat-tux.fr\",\"success\":true}</code></li>\n            <li><strong><%= l('JSON: failure') %></strong><br><code>{\"msg\":\"<%= l('Failure reason') %>\",\"success\":false}</code></li>\n        </li>\n    </dd>\n    <dt>GET <%= url_for('stats')->to_abs %></dt>\n    <dd>\n    % if (defined $self->config('ldap') || defined $self->config('htpasswd')) {\n        <p><%= l('You must be logged in to use it.') %></p>\n    % }\n        <p><%= l('It will use Lstu\\'s cookies to know which shortened URL it will return statistics for.') %></p>\n    % if (defined(config('adminpwd')) || defined(config('hashed_adminpwd'))) {\n        <p><%= l('If you are logged in as admin (\"adminpwd\" or \"hashed_adminpwd\" setting), it will give you statistics for all URLs, sorted by the most visited first, paginated with pages containing %1 records.', config('page_offset')) %></p>\n    % }\n        <strong><%= l('Parameters:') %></strong>\n        <ul>\n    % if (defined(config('adminpwd')) || defined(config('hashed_adminpwd'))) {\n            <li><strong>page</strong> <em><%= l('optional') %></em><br><%= l('If you are logged in as admin, you can provide a \"page\" parameter') %>\n    % }\n            <li><strong>_format</strong> <em><%= l('optional') %></em><br><%= l('If equal to \"json\", response will be in JSON format, HTML format otherwise') %></li>\n        </ul>\n        <strong><%= l('Response:') %></strong><br>\n        <ul>\n            % $u = prefix().url_for('short', short => l('shortened_url'));\n            % $u =~ s#//#/#g;\n            % $u = to_json $u;\n            <li><strong><%= l('Response for JSON format') %></strong><br><code>[{\"short\":<%= $u %>,\"url\":\"<%= l('URL') %>\",\"counter\":<%= l('integer, how many unique visits of the shortened URL') %>}]</code></li>\n            <li><strong><%= l('Response for HTML format') %></strong><br><%= l('A page with a table containing the same informations that the JSON response') %></li>\n        </ul>\n    </dd>\n    <dt>GET <%= url_for('stats/'.l('shortened_url'))->to_abs %></dt>\n    <dd>\n        <p><%= l('Get the details (visit counter, creation date, etc.) of a shortened URL.') %></p>\n        <strong><%= l('Response:') %></strong>\n        <ul>\n            <li><strong><%= l('JSON: success') %></strong><br><code>{\"url\":\"https:\\/\\/fiat-tux.fr\",\"short\":<%= $u %>,\"success\":true,\"counter\":<%= l('integer, how many unique visits of the shortened URL') %>,\"created_at\":1519296674,\"short\":\"<%= l('URL') %>\",\"timestamp\":1519296680}</code></li>\n            <li><strong><%= l('JSON: failure') %></strong><br><code>{\"msg\":\"<%= l('Failure reason') %>\",\"success\":false}</code></li>\n        </ul>\n    </dd>\n% if (defined(config('adminpwd')) || defined(config('hashed_adminpwd'))) {\n    <dt>POST <%= url_for('stats')->to_abs %></dt>\n    <dd>\n        <strong><%= l('Parameters:') %></strong>\n        <ul>\n            <li><strong>adminpwd</strong></li> <em><%= l('optional') %></em><br><%= l('To do an admin login, set it to the password defined in the settings (\"adminpwd\" or \"hashed_adminpwd\")') %></li>\n            <li><strong>action</strong></li> <em><%= l('optional') %></em><br><%= l('To do an admin logout, set it to \"logout\".') %></li>\n            <li><strong>_format</strong> <em><%= l('optional') %></em><br><%= l('If equal to \"json\", response will be in JSON format, HTML format otherwise') %></li>\n        </ul>\n        <strong><%= l('Response:') %></strong>\n        <ul>\n            <li><%= l('If \"adminpwd\" is defined:') %>\n                <ul>\n                    <li><strong><%= l('JSON: success') %></strong><br><code>{\"msg\":\"<%= l('You have been successfully logged in.')%>\",\"success\":true}</code></li>\n                    <li><strong><%= l('JSON: failure') %></strong><br><code>{\"msg\":\"<%= l('Bad password') %>\",\"success\":false}</code></li>\n                    <li><strong><%= l('Response for HTML format') %></strong><br><%= l('You will have the statistics page with the admin stats if you\\'re succesfully logged in, or your stats and a failure message otherwise') %></li>\n                </ul>\n            </li>\n            <li><%= l('If \"action\" is defined to \"logout\":') %><br>\n                <%= l('Should always be successful') %></p>\n                <ul>\n                    <li><strong><%= l('JSON: success') %></strong><br><code>{\"msg\":\"<%= l('You have been successfully logged out.')%>\",\"success\":true}</code></li>\n                    <li><strong><%= l('Response for HTML format') %></strong><br><%= l('You will be redirected to Lstu statistics page') %></li>\n                </ul>\n            </li>\n        </ul>\n    </dd>\n    <dt>GET <%= url_for('delete', short => l('shortened_url'))->to_abs %></dt>\n    <dd>\n        <p><%= l('You must be logged in as admin (\"adminpwd\" or \"hashed_adminpwd\" setting) to use it.') %></p>\n        <strong><%= l('Parameters:') %></strong>\n        <ul>\n            <li><strong>_format</strong> <em><%= l('optional') %></em><br><%= l('If equal to \"json\", response will be in JSON format, HTML format otherwise') %></li>\n        </ul>\n        <strong><%= l('Response:') %></strong>\n        <ul>\n            <li><strong><%= l('JSON: success') %></strong><br><code>{\"url\":\"https:\\/\\/fiat-tux.fr\",\"short\":<%= $u %>,\"success\":true}</code></li>\n            <li><strong><%= l('JSON: failure') %></strong><br><code>{\"msg\":\"<%= l('Failure reason') %>\",\"success\":false}</code></li>\n            <li><strong><%= l('Response for HTML format') %></strong><br><%= l('You will be redirected to Lstu statistics page with a message in case of failure') %></li>\n        </ul>\n    </dd>\n% }\n</dl>\n"
  },
  {
    "path": "themes/default/templates/index.html.ep",
    "content": "% # vim:set sw=4 ts=4 sts=4 ft=html.epl expandtab:\n% title 'Lstu';\n<form class=\"form\" method=\"POST\" action=\"<%== url_for 'add' %>\">\n    <div class=\"form-group\">\n        <label class=\"sr-only\" for=\"lsturl\"><%= l('URL to shorten') %></label>\n        <input type=\"url\" name=\"lsturl\" id=\"lsturl\" class=\"form-control\" placeholder=\"<%= l('URL to shorten') %>\" required>\n    </div>\n    <div class=\"form-group\">\n        <label class=\"sr-only\" for=\"lsturl-custom\"><%= l('Custom shortened text') %></label>\n        <input type=\"text\" name=\"lsturl-custom\" id=\"lsturl-custom\" class=\"form-control\" placeholder=\"<%= l('Custom shortened text') %>\">\n    </div>\n    %= csrf_field\n    <%= submit_button l('Go!'), class => 'allons-y' %>\n</form>\n\n% if (defined(stash('short')) && defined(stash('url'))) {\n    <h3 class=\"alert alert-success form-inline\">\n        <img alt=\"QRCode\" src=\"data:image/png;base64,<%= stash('qrcode') %>\">\n        <div class=\"form-group\">\n            <label><%= link_to stash('url') => begin %><%= stash('url') %><%= end %></a></label>\n            <br> =&gt; <input id=\"input-short\" value=\"<%== stash('short') %>\" class=\"form-control\" size=\"<%= length(stash('short')) %>\">\n            <span id=\"js\" class=\"hidden\"><a href=\"#\" id=\"clipboard\" class=\"btn btn-default\" title=\"<%= l('Copy to clipboard') %>\" data-short=\"<%== stash('short') %>\"><span class=\"icon icon-clipboard\"></span></a><span>\n        </div>\n    </h3>\n% }\n% if (defined(flash('msg'))) {\n    <h3 class=\"alert alert-danger\"><%= flash('msg') %></h3>\n% }\n% if (defined(stash('msg'))) {\n    <h3 class=\"alert alert-danger\"><%= stash('msg') %></h3>\n% }\n"
  },
  {
    "path": "themes/default/templates/layouts/default.html.ep",
    "content": "% # vim:set sw=4 ts=4 sts=4 ft=html.epl expandtab:\n% my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime();\n% $year += 1900;\n% my $lang = $self->languages;\n%    $lang =~ s/-(.*)/_\\U$1/;\n<!DOCTYPE html>\n<html lang=\"<%= $lang %>\">\n    <head>\n        <title><%= title %></title>\n        <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n        <meta charset=\"utf-8\" />\n        <meta name=\"mobile-web-app-capable\" content=\"yes\">\n        <meta name=\"apple-mobile-web-app-capable\" content=\"yes\">\n        <meta name=\"apple-mobile-web-app-status-bar-style\" content=\"black\">\n        <link rel=\"manifest\" href=\"<%= url_for('/manifest.json') %>\">\n        <link rel=\"shortcut icon\" href=\"<%= url_for('/favicon.ico') %>\">\n        <link rel=\"mask-icon\" href=\"<%= url_for('/img/lstu-small.svg') %>\" color=\"#9b4dca\">\n        <link rel=\"icon\" type=\"image/png\" href=\"<%= url_for('/img/favicon.png') %>\">\n        <link rel=\"icon\" sizes=\"16x16\" href=\"<%= url_for('/img/lstu16.png') %>\">\n        <link rel=\"icon\" sizes=\"32x32\" href=\"<%= url_for('/img/lstu32.png') %>\">\n        <link rel=\"icon\" sizes=\"128x128\" href=\"<%= url_for('/img/lstu128.png') %>\">\n        <link rel=\"icon\" sizes=\"192x192\" href=\"<%= url_for('/img/lstu192.png') %>\">\n        <link rel=\"apple-touch-icon\" href=\"<%= url_for('/img/lstu60.png') %>\">\n        <link rel=\"apple-touch-icon\" sizes=\"76x76\" href=\"<%= url_for('/img/lstu76.png') %>\">\n        <link rel=\"apple-touch-icon\" sizes=\"120x120\" href=\"<%= url_for('/img/lstu120.png') %>\">\n        <link rel=\"apple-touch-icon\" sizes=\"128x128\" href=\"<%= url_for('/img/lstu128.png') %>\">\n        <link rel=\"apple-touch-icon\" sizes=\"152x152\" href=\"<%= url_for('/img/lstu152.png') %>\">\n        <link rel=\"apple-touch-icon\" sizes=\"180x180\" href=\"<%= url_for('/img/lstu180.png') %>\">\n        <link rel=\"apple-touch-icon-precomposed\" sizes=\"120x120\" href=\"<%= url_for('/img/lstu120p.png') %>\">\n        <meta name=\"msapplication-TileColor\" content=\"#ffc40d\">\n        <meta name=\"msapplication-TileImage\" content=\"<%= url_for('/img/mstile-lstu144.png') %>\">\n        <meta name=\"msapplication-config\" content=\"<%= url_for('/browserconfig.xml') %>\">\n    % if ($self->app->mode eq 'production') {\n        %= stylesheet '/css/bootstrap-lstu.min.css'\n    % } else {\n        %= stylesheet '/css/bootstrap.min.css'\n        %= stylesheet '/css/lstu.css'\n        %= stylesheet '/css/fontelico.css'\n    % }\n    </head>\n    <body>\n        <div class=\"container\">\n            <h1 class=\"oswald hidden-sm hidden-md hidden-lg\">\n                <a href=\"<%= url_for('/') %>\">\n                    Let's Shorten That URL\n                </a>\n            </h1>\n            <div class=\"hidden-xs logo\">\n                <%= link_to url_for('/') => (class => 'link_nocol') => begin %>\n                    <img class=\"logo-img\" src=\"<%= url_for('/img/logo+type.svg') %>\" alt=\"lstu logo\" width=\"auto\" height=\"200\">\n                <% end %>\n            </div>\n            <p>\n                <small>&copy; 2013 — <%= $year %> <%= link_to 'Luc Didry' => 'https://fiat-tux.fr' %> —\n                    <%= l('License:') %> <%= link_to 'WTFPL' => 'http://www.wtfpl.net/' %> —\n                    <%= link_to l('About') => 'https://framagit.org/fiat-tux/hat-softwares/lstu/blob/master/README.md' %> —\n                    <%= link_to 'API' => url_for('api') %> —\n            % if (defined(config('ldap')) || defined(config('htpasswd'))) {\n                % if (is_user_authenticated()) {\n                    <%= link_to l('Statistics') => url_for('stats') %> —\n                    <%= link_to l('Logout') => url_for('/logout')%>\n                % } else {\n                    <%= link_to l('Signin') => url_for('/login') %>\n                % }\n            % } else {\n                    <%= link_to l('Statistics') => url_for('stats') %>\n            % }\n                </small>\n            </p>\n            <%= content %>\n        </div>\n% if (defined(stash('short')) && defined(stash('url'))) {\n        %= javascript url_for('lstu.js')\n% }\n    </body>\n</html>\n"
  },
  {
    "path": "themes/default/templates/login.html.ep",
    "content": "% # vim:set sw=4 ts=4 sts=4 ft=html.epl expandtab:\n% title 'Lstu login';\n% if (defined stash('msg')) {\n    <%= stash('msg') %>\n% }\n<form method=\"post\" action=\"<%= url_for('login') %>\"  class=\"form-inline\">\n    <div class=\"form-group\">\n        <label for=\"login\"><%= l('Login') %></label>\n        <input id=\"login\" type=\"text\" class=\"validate\" name=\"login\">\n    </div>\n    <div class=\"form-group\">\n        <label for=\"password\"><%= l('Password') %></label>\n        <input id=\"password\" type=\"password\" class=\"validate\" name=\"password\">\n    </div>\n    <button class=\"btn btn-default\" type=\"submit\" name=\"action\">\n        <%= l('Signin') %>\n    </button>\n</form>\n"
  },
  {
    "path": "themes/default/templates/logout.html.ep",
    "content": "% # vim:set sw=4 ts=4 sts=4 ft=html.epl expandtab:\n% title 'Lstu logout';\n<h4><%= l('You have been successfully logged out.') %></h4>\n<p>\n    <a href=\"<%= url_for('login') %>\" class=\"btn btn-default\"><%= l('Signin') %></a>\n</p\n"
  },
  {
    "path": "themes/default/templates/partial/lstu.js.ep",
    "content": "// vim:set sw=4 ts=4 sts=4 ft=javascript expandtab:\nvar j = document.getElementById('js');\nj.classList.remove('hidden');\n// Code from http://stackoverflow.com/questions/400212/how-do-i-copy-to-the-clipboard-in-javascript\nfunction copyTextToClipboard(text) {\n    var textArea              = document.createElement(\"textarea\");\n    textArea.style.position   = 'fixed';\n    textArea.style.top        = 0;\n    textArea.style.left       = 0;\n    textArea.style.width      = '2em';\n    textArea.style.height     = '2em';\n    textArea.style.padding    = 0;\n    textArea.style.border     = 'none';\n    textArea.style.outline    = 'none';\n    textArea.style.boxShadow  = 'none';\n    textArea.style.background = 'transparent';\n    textArea.value            = text;\n\n    document.body.appendChild(textArea);\n    textArea.select();\n\n    try {\n      var successful = document.execCommand('copy');\n      var msg = successful ? 'successful' : 'unsuccessful';\n      console.log('Copying text command was ' + msg);\n    } catch (err) {\n      var myInput = document.getElementById('input-short');\n      myInput.focus();\n      myInput.setSelectionRange(0, 9999);\n      alert('<%= l('Hit Enter, then Ctrl+C to copy the short link') %>');\n    }\n\n    document.body.removeChild(textArea);\n}\n\nvar copyBtn = document.getElementById('clipboard');\n\ncopyBtn.addEventListener('click', function(event) {\n    event.preventDefault();\n    copyTextToClipboard(this.getAttribute('data-short'));\n});\n\n\n"
  },
  {
    "path": "themes/default/templates/stats.html.ep",
    "content": "% # vim:set sw=4 ts=4 sts=4 ft=html.epl expandtab:\n% title 'Lstu stats';\n% use Mojo::Date;\n% my $order = $self->param('order') // 'counter';\n% my $dir   = $self->param('dir') // '-desc';\n% my $arrow = ($dir eq '-desc') ? '↓' : '↑';\n% my $adir  = sprintf('&dir=%s', ($dir eq '-desc') ? '-asc' : '-desc');\n% $dir      = sprintf('&dir=%s', $dir);\n<h2><%= l('Statistics') %></h2>\n% if (defined(config('adminpwd')) || defined(config('hashed_adminpwd'))) {\n%     if (!flash('banned')) {\n<form class=\"form\" method=\"POST\" action=\"<%== url_for 'stats' %>\">\n%         if (defined(stash('admin'))) {\n    <input type=\"hidden\" value=\"logout\" name=\"action\">\n    <%= submit_button l('Logout from admin stats'), class => 'btn btn-default btn-primary' %>\n%         } else {\n    <div class=\"form-group\">\n        <label class=\"sr-only\" for=\"adminpwd\"><%= l('Admin password') %></label>\n        <input type=\"password\" name=\"adminpwd\" id=\"adminpwd\" class=\"form-control\" placeholder=\"<%= l('Admin password') %>\" required>\n    </div>\n    <input type=\"hidden\" value=\"0\" name=\"page\">\n    <%= submit_button l('Go!'), class => 'btn btn-default btn-primary' %>\n%         }\n</form>\n%     }\n%     if (defined(flash('msg'))) {\n    <h3 class=\"alert alert-danger\"><%= flash('msg') %></h3>\n%     }\n<br>\n% }\n\n% if (defined(flash('success_msg'))) {\n    <h3 class=\"alert alert-success\"><%= flash('success_msg') %></h3>\n% }\n<form class=\"form\" method=\"POST\" action=\"<%== url_for 'import_cookie' %>\" enctype=\"multipart/form-data\">\n    <div class=\"form-group\">\n        <label for=\"file\"><%= l('Import URLs') %></label>\n        <input type=\"file\" name=\"file\" id=\"file\" required>\n    </div>\n    <%= submit_button l('Import URLs'), class => 'btn btn-default btn-primary' %>\n    <a href=\"<%= url_for 'export_cookie' %>\" class=\"btn btn-default\"><%= l('Export your URLs') %></a>\n</form>\n\n<br>\n\n<table class=\"table table-striped\">\n    <tr>\n        <th>#</th>\n% if ((defined(config('adminpwd')) || defined(config('hashed_adminpwd'))) && defined(stash('admin'))) {\n        <th>\n            <a href=\"<%= url_for('stats') %>?order=url<%= ($order eq 'url') ? $adir : $dir %>\">\n                <%= l('URL') %><%= $arrow if ($order eq 'url') %>\n            </a>\n        </th>\n        <th>\n            <a href=\"<%= url_for('stats') %>?order=short<%= ($order eq 'short') ? $adir : $dir %>\">\n                <%= l('Shortened URL') %><%= $arrow if ($order eq 'short') %>\n            </a>\n        </th>\n        <th>\n            <a href=\"<%= url_for('stats') %>?order=counter<%= ($order eq 'counter') ? $adir : $dir %>\">\n                <%= l('Counter') %><%= $arrow if ($order eq 'counter') %>\n            </a>\n        </th>\n        <th>\n            <a href=\"<%= url_for('stats') %>?order=created_by<%= ($order eq 'created_by') ? $adir : $dir %>\">\n                <%= l('Created') %><%= $arrow if ($order eq 'created_by') %>\n            </a>\n        </th>\n% } else {\n        <th>\n            <%= l('URL') %>\n        </th>\n        <th>\n            <%= l('Shortened URL') %>\n        </th>\n        <th>\n            <%= l('Counter') %>\n        </th>\n        <th>\n            <%= l('Created') %>\n        </th>\n% }\n% if (defined(config('adminpwd')) || defined(config('hashed_adminpwd'))) {\n%     unless (defined(stash('admin'))) {\n        <th><%= l('QRCode') %></th>\n%     } else {\n        <th><%= l('Delete') %></th>\n%     }\n% }\n    </tr>\n% my $i = 1;\n% if (defined(stash('page')) && stash('page') >= 0) {\n%     $i = 1 + config('page_offset') * stash('page');\n% }\n% my $j = $i;\n% for my $url (@{$urls}) {\n    <tr>\n        <td><%= $i++ %></td>\n        <td><%= link_to $url->{url} => $url->{url} %></td>\n        <td><%= link_to $prefix.$url->{short} => $prefix.$url->{short} %></td>\n        <td><%= $url->{counter} %></td>\n        <td><%= Mojo::Date->new($url->{timestamp})->to_string %></td>\n% if (defined(config('adminpwd')) || defined(config('hashed_adminpwd'))) {\n%     unless (defined(stash('admin'))) {\n        <td><img class=\"qrcode-stat\" alt=\"QRCode\" src=\"data:image/png;base64,<%= $url->{qrcode} %>\"></td>\n%     } else {\n        <td><a href=\"<%= url_for('delete', {short => $url->{short}}) %>\"><span class=\"icon icon-trash\"></span></a></td>\n%     }\n% }\n    </tr>\n% }\n</table>\n% if (defined(config('adminpwd')) || defined(config('hashed_adminpwd'))) {\n%     if (defined(stash('admin'))) {\n<nav>\n  <ul class=\"pager\">\n    <li class=\"previous<%= (stash('first')) ? ' disabled' : '' %>\"><%= link_to url_for->query(page => (stash('first')) ? 0 : stash('page') - 1) => begin %><span aria-hidden=\"true\">&larr;</span> <%= l('Previous') %><% end %></li>\n    <li class=\"center\"><%= $j.'-'.--$i.'/'.stash('total') %></li>\n    <li class=\"next<%= (stash('last')) ? ' disabled' : '' %>\"><%= link_to url_for->query(page => (stash('last')) ? stash('page') : stash('page') + 1) => begin %><%= l('Next') %> <span aria-hidden=\"true\">&rarr;</span><% end %></li>\n  </ul>\n</nav>\n%     }\n% }\n%= link_to l('Home') => '/'\n"
  },
  {
    "path": "themes/milligram/Makefile",
    "content": "POT=lib/Lstu/I18N/milligram.pot\nSEDOPTS=-e \"s@SOME DESCRIPTIVE TITLE@Lstu language file@\" \\\n\t\t-e \"s@YEAR THE PACKAGE'S COPYRIGHT HOLDER@2015 Luc Didry@\" \\\n\t\t-e \"s@CHARSET@utf8@\" \\\n\t\t-e \"s@the PACKAGE package@the Lstu package@\" \\\n\t\t-e '/^\\#\\. (/{N;/\\n\\#\\. (/{N;/\\n.*\\.\\.\\/default\\//{s/\\#\\..*\\n.*\\#\\./\\#. (/g}}}' \\\n\t\t-e '/^\\#\\. (/{N;/\\n.*\\.\\.\\/default\\//{s/\\n/ /}}'\nSEDOPTS2=-e '/^\\#.*\\.\\.\\/default\\//,+3d'\nXGETTEXT=carton exec ../../local/bin/xgettext.pl\nCARTON=carton exec\n\nlocales:\n\t\t$(XGETTEXT) -D templates -D ../default/templates -o $(POT) 2>/dev/null\n\t\tsed $(SEDOPTS) -i $(POT)\n\t\tsed $(SEDOPTS2) -i $(POT)\n"
  },
  {
    "path": "themes/milligram/lib/Lstu/I18N/en.po",
    "content": "# Lstu language file.\n# Copyright (C) 2013 Luc Didry\n# This file is distributed under the same license as the Lstu package.\n# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.\n#\n#, fuzzy\nmsgid \"\"\nmsgstr \"\"\n\"Project-Id-Version: Lstu\\n\"\n\"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\\n\"\n\"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\\n\"\n\"Last-Translator: Luc Didry <luc@didry.org>\\n\"\n\"Language-Team: English (http://www.transifex.com/projects/p/lstu/language/en/)\\n\"\n\"MIME-Version: 1.0\\n\"\n\"Content-Type: text/plain; charset=utf8\\n\"\n\"Content-Transfer-Encoding: 8bit\\n\"\n\"Language: en\\n\"\n\n"
  },
  {
    "path": "themes/milligram/lib/Lstu/I18N/fr.po",
    "content": "# Lstu language file.\n# Copyright (C) 2013 Luc Didry\n# This file is distributed under the same license as the Lstu package.\n# Luc Didry <luc@didry.org>, 2015\n#\n#, fuzzy\nmsgid \"\"\nmsgstr \"\"\n\"Project-Id-Version: Lstu\\n\"\n\"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\\n\"\n\"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\\n\"\n\"Last-Translator: Luc <luc@fiat-tux.fr>\\n\"\n\"Language-Team: French (http://www.transifex.com/projects/p/lstu/language/fr/)\"\n\"MIME-Version: 1.0\\n\"\n\"Content-Type: text/plain; charset=utf8\\n\"\n\"Content-Transfer-Encoding: 8bit\\n\"\n\n"
  },
  {
    "path": "themes/milligram/lib/Lstu/I18N/milligram.pot",
    "content": "# Lstu language file.\n# Copyright (C) 2015 Luc Didry\n# This file is distributed under the same license as the Lstu package.\n# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.\n#\n#, fuzzy\nmsgid \"\"\nmsgstr \"\"\n\"Project-Id-Version: PACKAGE VERSION\\n\"\n\"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\\n\"\n\"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\\n\"\n\"Last-Translator: FULL NAME <EMAIL@ADDRESS>\\n\"\n\"Language-Team: LANGUAGE <LL@li.org>\\n\"\n\"MIME-Version: 1.0\\n\"\n\"Content-Type: text/plain; charset=utf8\\n\"\n\"Content-Transfer-Encoding: 8bit\\n\"\n\n#: templates/index.html.ep:14\nmsgid \"The shortened URL\"\nmsgstr \"\"\n\n"
  },
  {
    "path": "themes/milligram/lib/Lstu/I18N/oc.po",
    "content": "# Lstu language file.\n# Copyright (C) 2013 Luc Didry\n# This file is distributed under the same license as the Lstu package.\n# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.\n#\n#, fuzzy\nmsgid \"\"\nmsgstr \"\"\n\"Project-Id-Version: PACKAGE VERSION\\n\"\n\"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\\n\"\n\"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\\n\"\n\"Last-Translator: FULL NAME <EMAIL@ADDRESS>\\n\"\n\"Language-Team: LANGUAGE <LL@li.org>\\n\"\n\"MIME-Version: 1.0\\n\"\n\"Content-Type: text/plain; charset=utf8\\n\"\n\"Content-Transfer-Encoding: 8bit\\n\"\n\n"
  },
  {
    "path": "themes/milligram/lib/Lstu/I18N.pm",
    "content": "# vim:set sw=4 ts=4 sts=4 ft=perl expandtab:\npackage Lstu::I18N;\n\nuse base 'Locale::Maketext';\nuse File::Basename qw/dirname/;\nuse Locale::Maketext::Lexicon {\n    _auto => 1,\n    _decode => 1,\n    _style  => 'gettext',\n    '*' => [\n        Gettext => dirname(__FILE__) . '/I18N/*.po',\n        Gettext => $app_dir . 'themes/default/lib/Lstu/I18N/*.po',\n    ]\n};\n\nuse vars qw($app_dir);\nBEGIN {\n    use Cwd;\n    my $app_dir = getcwd;\n}\n\n1;\n"
  },
  {
    "path": "themes/milligram/public/css/lstu.css",
    "content": "@font-face {\n    font-family: 'Henny_Penny';\n    font-style: normal;\n    font-weight: 400;\n    src: local('Henny Penny'), local('HennyPenny-Regular'), url('../font/hennypenny.woff2') format('woff2');\n}\n@font-face {\n    font-family: 'Oswald';\n    font-style: bold;\n    font-weight: 400;\n    src: local('Oswald'), url('../font/Oswald-Bold.ttf')\n}\n\n@font-face {\n    font-family: 'OpenSans';\n    font-style: normal;\n    font-weight: 200;\n    src: local('OpenSans'), url('../font/OpenSans-Regular.ttf')\n}\n\nbody {\n    padding-top: 40px;\n    padding-bottom: 40px;\n}\n.container {\n    padding: 15px;\n    margin: 0 auto;\n}\n.oswald {\n    font-family: 'Oswald';\n    font-size: 42px;\n}\n.hennypenny {\n    font-family: 'Henny_Penny', cursive;\n    font-size: 42px;\n}\n.link_nocol, .link_nocol:hover {\n    color: #000;\n    text-decoration: none;\n}\n.result {\n    border-color: #d6e9c6;\n    padding: 15px;\n    margin-bottom: 20px;\n    border: 1px solid;\n    border-radius: 4px;\n}\n.result a.button {\n    padding: 0;\n}\nul.pager {\n    list-style: none outside;\n    text-align: center;\n}\nul.pager li {\n    display: inline;\n}\n.disabled {\n    display: none !important;\n}\n@media (max-width: 767px) {\n    .hidden-xs {\n        display: none !important;\n    }\n}\n.qrcode-result {\n    float: right;\n}\ndd > strong {\n    padding-left: 15px;\n}\n.allons-y {\n    border-style: none;\n    background: linear-gradient(to right, rgba(255, 255, 255, 0.3) 0%, rgba(255,255,255, 0.5) 100%, transparent 25px) no-repeat, #9B4DCA;\n    background-repeat: no-repeat, no-repeat;\n    border-radius: 5px;\n    box-shadow: 2px 2px 1px 1px rgba(0,0,0,0.3);\n    padding: 8px;\n    margin-right: 9px;\n    color: white;\n    font-family: 'OpenSans';\n    font-size: 14px;\n    background-size: 0 100%, 100% 100%;\n    transition: background-size 0.3s; \n}\n\n.allons-y:hover {\n    background-size: 101% 100%;\n    background-color: #9B4DCA !important;\n}\n.allons-y:active {\n    box-shadow: none; transform: translate(2px, 2px); transition: all 0.1s;\n}\n@media (max-width:767px) {\n    .hidden-xs{\n        display:none !important\n    }\n}\n@media (min-width:768px) and (max-width:991px) {\n    .hidden-sm{\n        display:none !important\n    }\n}\n@media (min-width:992px) and (max-width:1199px) {\n    .hidden-md{\n        display:none !important\n    }\n}\n@media (min-width:1200px) {\n    .hidden-lg{display:none !important\n    }\n}\n"
  },
  {
    "path": "themes/milligram/public/css/lstu.min.css",
    "content": "@font-face{font-family:Henny_Penny;font-style:normal;font-weight:400;src:local('Henny Penny'),local('HennyPenny-Regular'),url(../font/hennypenny.woff2) format('woff2')}body{padding-top:40px;padding-bottom:40px}.container{padding:15px;margin:0 auto}.hennypenny{font-family:Henny_Penny,cursive;font-size:42px}.link_nocol,.link_nocol:hover{color:#000;text-decoration:none}.result{border-color:#d6e9c6;padding:15px;margin-bottom:20px;border:1px solid;border-radius:4px}.result a.button{padding:0}ul.pager{list-style:none outside;text-align:center}ul.pager li{display:inline}.disabled{display:none!important}@media (max-width:767px){.hidden-xs{display:none!important}}.qrcode-result{float:right}\n"
  },
  {
    "path": "themes/milligram/public/css/milli-lstu.min.css",
    "content": "/*!\n * Milligram v1.2.0\n * http://milligram.github.io\n *\n * Copyright (c) 2016 CJ Patoilo\n * Licensed under the MIT license\n*/\nhtml{box-sizing:border-box;font-size:62.5%}body{color:#606c76;font-family:'Roboto','Helvetica Neue','Helvetica','Arial',sans-serif;font-size:1.6em;font-weight:300;letter-spacing:.01em;line-height:1.6;padding-top:40px;padding-bottom:40px}*,:after,:before{box-sizing:inherit}blockquote{border-left:.3rem solid #d1d1d1;margin-left:0;margin-right:0;padding:1rem 1.5rem}blockquote :last-child{margin-bottom:0}.button,button,input[type=button],input[type=reset],input[type=submit]{background-color:#9b4dca;border:.1rem solid #9b4dca;border-radius:.4rem;color:#fff;cursor:pointer;display:inline-block;font-size:1.1rem;font-weight:700;height:3.8rem;letter-spacing:.1rem;line-height:3.8rem;padding:0 3rem;text-align:center;text-decoration:none;text-transform:uppercase;white-space:nowrap}.button:focus,.button:hover,button:focus,button:hover,input[type=button]:focus,input[type=button]:hover,input[type=reset]:focus,input[type=reset]:hover,input[type=submit]:focus,input[type=submit]:hover{background-color:#606c76;border-color:#606c76;color:#fff;outline:0}.button[disabled],button[disabled],input[type=button][disabled],input[type=reset][disabled],input[type=submit][disabled]{cursor:default;opacity:.5}.button[disabled]:focus,.button[disabled]:hover,button[disabled]:focus,button[disabled]:hover,input[type=button][disabled]:focus,input[type=button][disabled]:hover,input[type=reset][disabled]:focus,input[type=reset][disabled]:hover,input[type=submit][disabled]:focus,input[type=submit][disabled]:hover{background-color:#9b4dca;border-color:#9b4dca}.button.button-outline,button.button-outline,input[type=button].button-outline,input[type=reset].button-outline,input[type=submit].button-outline{background-color:transparent;color:#9b4dca}.button.button-outline:focus,.button.button-outline:hover,button.button-outline:focus,button.button-outline:hover,input[type=button].button-outline:focus,input[type=button].button-outline:hover,input[type=reset].button-outline:focus,input[type=reset].button-outline:hover,input[type=submit].button-outline:focus,input[type=submit].button-outline:hover{background-color:transparent;border-color:#606c76;color:#606c76}.button.button-outline[disabled]:focus,.button.button-outline[disabled]:hover,button.button-outline[disabled]:focus,button.button-outline[disabled]:hover,input[type=button].button-outline[disabled]:focus,input[type=button].button-outline[disabled]:hover,input[type=reset].button-outline[disabled]:focus,input[type=reset].button-outline[disabled]:hover,input[type=submit].button-outline[disabled]:focus,input[type=submit].button-outline[disabled]:hover{border-color:inherit;color:#9b4dca}.button.button-clear,button.button-clear,input[type=button].button-clear,input[type=reset].button-clear,input[type=submit].button-clear{background-color:transparent;border-color:transparent;color:#9b4dca}.button.button-clear:focus,.button.button-clear:hover,button.button-clear:focus,button.button-clear:hover,input[type=button].button-clear:focus,input[type=button].button-clear:hover,input[type=reset].button-clear:focus,input[type=reset].button-clear:hover,input[type=submit].button-clear:focus,input[type=submit].button-clear:hover{background-color:transparent;border-color:transparent;color:#606c76}.button.button-clear[disabled]:focus,.button.button-clear[disabled]:hover,button.button-clear[disabled]:focus,button.button-clear[disabled]:hover,input[type=button].button-clear[disabled]:focus,input[type=button].button-clear[disabled]:hover,input[type=reset].button-clear[disabled]:focus,input[type=reset].button-clear[disabled]:hover,input[type=submit].button-clear[disabled]:focus,input[type=submit].button-clear[disabled]:hover{color:#9b4dca}code,pre{background:#f4f5f6}code{border-radius:.4rem;font-size:86%;margin:0 .2rem;padding:.2rem .5rem;white-space:nowrap}pre{border-left:.3rem solid #9b4dca}pre>code{border-radius:0;display:block;padding:1rem 1.5rem;white-space:pre}hr{border:0;border-top:.1rem solid #f4f5f6;margin:3rem 0}input[type=email],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=url],select,textarea{-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:transparent;border:.1rem solid #d1d1d1;border-radius:.4rem;box-shadow:none;box-sizing:inherit;height:3.8rem;padding:.6rem 1rem;width:100%}input[type=email]:focus,input[type=number]:focus,input[type=password]:focus,input[type=search]:focus,input[type=tel]:focus,input[type=text]:focus,input[type=url]:focus,select:focus,textarea:focus{border-color:#9b4dca;outline:0}select{background:url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" height=\"14\" viewBox=\"0 0 29 14\" width=\"29\"><path fill=\"#d1d1d1\" d=\"M9.37727 3.625l5.08154 6.93523L19.54036 3.625\"/></svg>') center right no-repeat;padding-right:3rem}select:focus{background-image:url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" height=\"14\" viewBox=\"0 0 29 14\" width=\"29\"><path fill=\"#9b4dca\" d=\"M9.37727 3.625l5.08154 6.93523L19.54036 3.625\"/></svg>')}textarea{min-height:6.5rem}label,legend{display:block;font-size:1.6rem;font-weight:700;margin-bottom:.5rem}fieldset{border-width:0;padding:0}input[type=checkbox],input[type=radio],ul.pager li{display:inline}.label-inline{display:inline-block;font-weight:400;margin-left:.5rem}.container{max-width:112rem;padding:0 2rem;position:relative;width:100%}.row{display:flex;flex-direction:column;width:100%}.result a.button,.row,.row.row-no-padding,.row.row-no-padding>.column{padding:0}.row.row-wrap{flex-wrap:wrap}.row.row-top{align-items:flex-start}.row.row-bottom{align-items:flex-end}.row.row-center{align-items:center}.row.row-stretch{align-items:stretch}.row.row-baseline{align-items:baseline}.row .column{display:block;flex:1;margin-left:0;max-width:100%;width:100%}.row .column.column-offset-10{margin-left:10%}.row .column.column-offset-20{margin-left:20%}.row .column.column-offset-25{margin-left:25%}.row .column.column-offset-33,.row .column.column-offset-34{margin-left:33.3333%}.row .column.column-offset-50{margin-left:50%}.row .column.column-offset-66,.row .column.column-offset-67{margin-left:66.6666%}.row .column.column-offset-75{margin-left:75%}.row .column.column-offset-80{margin-left:80%}.row .column.column-offset-90{margin-left:90%}.row .column.column-10{flex:0 0 10%;max-width:10%}.row .column.column-20{flex:0 0 20%;max-width:20%}.row .column.column-25{flex:0 0 25%;max-width:25%}.row .column.column-33,.row .column.column-34{flex:0 0 33.3333%;max-width:33.3333%}.row .column.column-40{flex:0 0 40%;max-width:40%}.row .column.column-50{flex:0 0 50%;max-width:50%}.row .column.column-60{flex:0 0 60%;max-width:60%}.row .column.column-66,.row .column.column-67{flex:0 0 66.6666%;max-width:66.6666%}.row .column.column-75{flex:0 0 75%;max-width:75%}.row .column.column-80{flex:0 0 80%;max-width:80%}.row .column.column-90{flex:0 0 90%;max-width:90%}.row .column .column-top{align-self:flex-start}.row .column .column-bottom{align-self:flex-end}.row .column .column-center{-ms-grid-row-align:center;align-self:center}@media (min-width:40rem){.row{flex-direction:row;margin-left:-1rem;width:calc(100% + 2rem)}.row .column{margin-bottom:inherit;padding:0 1rem}}a{color:#9b4dca;text-decoration:none}a:focus,a:hover{color:#606c76}dl{list-style:none}dl,ol,ul{margin-top:0;padding-left:0}dl dl,dl ol,dl ul,ol dl,ol ol,ol ul,ul dl,ul ol,ul ul{font-size:90%;margin:1.5rem 0 1.5rem 3rem}ol{list-style:decimal inside}ul{list-style:circle inside}.button,button,dd,dt,li{margin-bottom:1rem}fieldset,input,select,textarea{margin-bottom:1.5rem}blockquote,dl,figure,form,ol,p,pre,table,ul{margin-bottom:2.5rem}table{width:100%}td,th{border-bottom:.1rem solid #e1e1e1;padding:1.2rem 1.5rem;text-align:left}td:first-child,th:first-child{padding-left:0}td:last-child,th:last-child{padding-right:0}p{margin-top:0}h1,h2,h3,h6{letter-spacing:-.1rem}h1,h2,h3,h4,h5,h6{font-weight:300;margin-bottom:2rem;margin-top:0}h1{font-size:4rem;line-height:1.2}h2{font-size:3.6rem;line-height:1.25}h3{font-size:3rem;line-height:1.3}h4{font-size:2.4rem;letter-spacing:-.08rem;line-height:1.35}h5{font-size:1.8rem;letter-spacing:-.05rem;line-height:1.5}h6{font-size:1.6rem;letter-spacing:0;line-height:1.4}@media (min-width:40rem){h1{font-size:5rem}h2{font-size:4.2rem}h3{font-size:3.6rem}h4{font-size:3rem}h5{font-size:2.4rem}h6{font-size:1.5rem}}img{max-width:100%}.clearfix:after{clear:both;content:' ';display:table}.float-left{float:left}.float-right{float:right}@font-face{font-family:'Henny_Penny';font-style:normal;font-weight:400;src:local('Henny Penny'),local('HennyPenny-Regular'),url(../font/hennypenny.woff2) format('woff2')}@font-face{font-family:'Oswald';font-style:bold;font-weight:400;src:local('Oswald'),url(../font/Oswald-Bold.ttf)}@font-face{font-family:'OpenSans';font-style:normal;font-weight:200;src:local('OpenSans'),url(../font/OpenSans-Regular.ttf)}.container{padding:15px;margin:0 auto}.hennypenny,.oswald{font-family:'Oswald';font-size:42px}.hennypenny{font-family:'Henny_Penny',cursive}.link_nocol,.link_nocol:hover{color:#000;text-decoration:none}.result{padding:15px;margin-bottom:20px;border:1px solid;border-radius:4px}ul.pager{list-style:none outside;text-align:center}.disabled{display:none!important}@media (max-width:767px){.hidden-xs{display:none!important}}.qrcode-result{float:right}dd>strong{padding-left:15px}.allons-y{border-style:none;background:linear-gradient(to right,rgba(255,255,255,.3) 0%,rgba(255,255,255,.5) 100%,transparent 25px) no-repeat,#9b4dca;background-repeat:no-repeat,no-repeat;border-radius:5px;box-shadow:2px 2px 1px 1px rgba(0,0,0,.3);padding:8px;margin-right:9px;color:#fff;font-family:'OpenSans';font-size:14px;background-size:0 100%,100% 100%;transition:background-size .3s}.allons-y:hover{background-size:101% 100%;background-color:#9b4dca!important}.allons-y:active{box-shadow:none;transform:translate(2px,2px);transition:all .1s}@media (max-width:767px){.hidden-xs{display:none!important}}@media (min-width:768px) and (max-width:991px){.hidden-sm{display:none!important}}@media (min-width:992px) and (max-width:1199px){.hidden-md{display:none!important}}@media (min-width:1200px){.hidden-lg{display:none!important}}@font-face{font-family:'fontelico';src:url(../font/fontelico.eot?21941692);src:url(../font/fontelico.eot?21941692#iefix) format('embedded-opentype'),url(../font/fontelico.woff2?21941692) format('woff2'),url(../font/fontelico.woff?21941692) format('woff'),url(../font/fontelico.ttf?21941692) format('truetype'),url(../font/fontelico.svg?21941692#fontelico) format('svg');font-weight:400;font-style:normal}[class*=\" icon-\"]:before,[class^=icon-]:before{font-family:\"fontelico\";font-style:normal;font-weight:400;speak:none;display:inline-block;text-decoration:inherit;width:1em;margin-right:.2em;text-align:center;font-variant:normal;text-transform:none;line-height:1em;margin-left:.2em;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.icon-clipboard:before{content:'\\e800'}.icon-trash:before{content:'\\e804'}\n"
  },
  {
    "path": "themes/milligram/public/css/milligram.min.css",
    "content": "/*!\n * Milligram v1.2.0\n * http://milligram.github.io\n *\n * Copyright (c) 2016 CJ Patoilo\n * Licensed under the MIT license\n*/\n\nhtml{box-sizing:border-box;font-size:62.5%}body{color:#606c76;font-family:'Roboto', 'Helvetica Neue', 'Helvetica', 'Arial', sans-serif;font-size:1.6em;font-weight:300;letter-spacing:.01em;line-height:1.6}*,*:after,*:before{box-sizing:inherit}blockquote{border-left:0.3rem solid #d1d1d1;margin-left:0;margin-right:0;padding:1rem 1.5rem}blockquote *:last-child{margin-bottom:0}.button,button,input[type='button'],input[type='reset'],input[type='submit']{background-color:#9b4dca;border:0.1rem solid #9b4dca;border-radius:.4rem;color:#fff;cursor:pointer;display:inline-block;font-size:1.1rem;font-weight:700;height:3.8rem;letter-spacing:.1rem;line-height:3.8rem;padding:0 3.0rem;text-align:center;text-decoration:none;text-transform:uppercase;white-space:nowrap}.button:focus,.button:hover,button:focus,button:hover,input[type='button']:focus,input[type='button']:hover,input[type='reset']:focus,input[type='reset']:hover,input[type='submit']:focus,input[type='submit']:hover{background-color:#606c76;border-color:#606c76;color:#fff;outline:0}.button[disabled],button[disabled],input[type='button'][disabled],input[type='reset'][disabled],input[type='submit'][disabled]{cursor:default;opacity:.5}.button[disabled]:focus,.button[disabled]:hover,button[disabled]:focus,button[disabled]:hover,input[type='button'][disabled]:focus,input[type='button'][disabled]:hover,input[type='reset'][disabled]:focus,input[type='reset'][disabled]:hover,input[type='submit'][disabled]:focus,input[type='submit'][disabled]:hover{background-color:#9b4dca;border-color:#9b4dca}.button.button-outline,button.button-outline,input[type='button'].button-outline,input[type='reset'].button-outline,input[type='submit'].button-outline{background-color:transparent;color:#9b4dca}.button.button-outline:focus,.button.button-outline:hover,button.button-outline:focus,button.button-outline:hover,input[type='button'].button-outline:focus,input[type='button'].button-outline:hover,input[type='reset'].button-outline:focus,input[type='reset'].button-outline:hover,input[type='submit'].button-outline:focus,input[type='submit'].button-outline:hover{background-color:transparent;border-color:#606c76;color:#606c76}.button.button-outline[disabled]:focus,.button.button-outline[disabled]:hover,button.button-outline[disabled]:focus,button.button-outline[disabled]:hover,input[type='button'].button-outline[disabled]:focus,input[type='button'].button-outline[disabled]:hover,input[type='reset'].button-outline[disabled]:focus,input[type='reset'].button-outline[disabled]:hover,input[type='submit'].button-outline[disabled]:focus,input[type='submit'].button-outline[disabled]:hover{border-color:inherit;color:#9b4dca}.button.button-clear,button.button-clear,input[type='button'].button-clear,input[type='reset'].button-clear,input[type='submit'].button-clear{background-color:transparent;border-color:transparent;color:#9b4dca}.button.button-clear:focus,.button.button-clear:hover,button.button-clear:focus,button.button-clear:hover,input[type='button'].button-clear:focus,input[type='button'].button-clear:hover,input[type='reset'].button-clear:focus,input[type='reset'].button-clear:hover,input[type='submit'].button-clear:focus,input[type='submit'].button-clear:hover{background-color:transparent;border-color:transparent;color:#606c76}.button.button-clear[disabled]:focus,.button.button-clear[disabled]:hover,button.button-clear[disabled]:focus,button.button-clear[disabled]:hover,input[type='button'].button-clear[disabled]:focus,input[type='button'].button-clear[disabled]:hover,input[type='reset'].button-clear[disabled]:focus,input[type='reset'].button-clear[disabled]:hover,input[type='submit'].button-clear[disabled]:focus,input[type='submit'].button-clear[disabled]:hover{color:#9b4dca}code{background:#f4f5f6;border-radius:.4rem;font-size:86%;margin:0 .2rem;padding:.2rem .5rem;white-space:nowrap}pre{background:#f4f5f6;border-left:0.3rem solid #9b4dca}pre>code{border-radius:0;display:block;padding:1rem 1.5rem;white-space:pre}hr{border:0;border-top:0.1rem solid #f4f5f6;margin:3.0rem 0}input[type='email'],input[type='number'],input[type='password'],input[type='search'],input[type='tel'],input[type='text'],input[type='url'],textarea,select{-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:transparent;border:0.1rem solid #d1d1d1;border-radius:.4rem;box-shadow:none;box-sizing:inherit;height:3.8rem;padding:.6rem 1.0rem;width:100%}input[type='email']:focus,input[type='number']:focus,input[type='password']:focus,input[type='search']:focus,input[type='tel']:focus,input[type='text']:focus,input[type='url']:focus,textarea:focus,select:focus{border-color:#9b4dca;outline:0}select{background:url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" height=\"14\" viewBox=\"0 0 29 14\" width=\"29\"><path fill=\"#d1d1d1\" d=\"M9.37727 3.625l5.08154 6.93523L19.54036 3.625\"/></svg>') center right no-repeat;padding-right:3.0rem}select:focus{background-image:url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" height=\"14\" viewBox=\"0 0 29 14\" width=\"29\"><path fill=\"#9b4dca\" d=\"M9.37727 3.625l5.08154 6.93523L19.54036 3.625\"/></svg>')}textarea{min-height:6.5rem}label,legend{display:block;font-size:1.6rem;font-weight:700;margin-bottom:.5rem}fieldset{border-width:0;padding:0}input[type='checkbox'],input[type='radio']{display:inline}.label-inline{display:inline-block;font-weight:normal;margin-left:.5rem}.container{margin:0 auto;max-width:112.0rem;padding:0 2.0rem;position:relative;width:100%}.row{display:flex;flex-direction:column;padding:0;width:100%}.row.row-no-padding{padding:0}.row.row-no-padding>.column{padding:0}.row.row-wrap{flex-wrap:wrap}.row.row-top{align-items:flex-start}.row.row-bottom{align-items:flex-end}.row.row-center{align-items:center}.row.row-stretch{align-items:stretch}.row.row-baseline{align-items:baseline}.row .column{display:block;flex:1;margin-left:0;max-width:100%;width:100%}.row .column.column-offset-10{margin-left:10%}.row .column.column-offset-20{margin-left:20%}.row .column.column-offset-25{margin-left:25%}.row .column.column-offset-33,.row .column.column-offset-34{margin-left:33.3333%}.row .column.column-offset-50{margin-left:50%}.row .column.column-offset-66,.row .column.column-offset-67{margin-left:66.6666%}.row .column.column-offset-75{margin-left:75%}.row .column.column-offset-80{margin-left:80%}.row .column.column-offset-90{margin-left:90%}.row .column.column-10{flex:0 0 10%;max-width:10%}.row .column.column-20{flex:0 0 20%;max-width:20%}.row .column.column-25{flex:0 0 25%;max-width:25%}.row .column.column-33,.row .column.column-34{flex:0 0 33.3333%;max-width:33.3333%}.row .column.column-40{flex:0 0 40%;max-width:40%}.row .column.column-50{flex:0 0 50%;max-width:50%}.row .column.column-60{flex:0 0 60%;max-width:60%}.row .column.column-66,.row .column.column-67{flex:0 0 66.6666%;max-width:66.6666%}.row .column.column-75{flex:0 0 75%;max-width:75%}.row .column.column-80{flex:0 0 80%;max-width:80%}.row .column.column-90{flex:0 0 90%;max-width:90%}.row .column .column-top{align-self:flex-start}.row .column .column-bottom{align-self:flex-end}.row .column .column-center{-ms-grid-row-align:center;align-self:center}@media (min-width: 40rem){.row{flex-direction:row;margin-left:-1.0rem;width:calc(100% + 2.0rem)}.row .column{margin-bottom:inherit;padding:0 1.0rem}}a{color:#9b4dca;text-decoration:none}a:focus,a:hover{color:#606c76}dl,ol,ul{list-style:none;margin-top:0;padding-left:0}dl dl,dl ol,dl ul,ol dl,ol ol,ol ul,ul dl,ul ol,ul ul{font-size:90%;margin:1.5rem 0 1.5rem 3.0rem}ol{list-style:decimal inside}ul{list-style:circle inside}.button,button,dd,dt,li{margin-bottom:1.0rem}fieldset,input,select,textarea{margin-bottom:1.5rem}blockquote,dl,figure,form,ol,p,pre,table,ul{margin-bottom:2.5rem}table{width:100%}td,th{border-bottom:0.1rem solid #e1e1e1;padding:1.2rem 1.5rem;text-align:left}td:first-child,th:first-child{padding-left:0}td:last-child,th:last-child{padding-right:0}p{margin-top:0}h1,h2,h3,h4,h5,h6{font-weight:300;letter-spacing:-.1rem;margin-bottom:2.0rem;margin-top:0}h1{font-size:4.0rem;line-height:1.2}h2{font-size:3.6rem;line-height:1.25}h3{font-size:3.0rem;line-height:1.3}h4{font-size:2.4rem;letter-spacing:-.08rem;line-height:1.35}h5{font-size:1.8rem;letter-spacing:-.05rem;line-height:1.5}h6{font-size:1.6rem;letter-spacing:0;line-height:1.4}@media (min-width: 40rem){h1{font-size:5.0rem}h2{font-size:4.2rem}h3{font-size:3.6rem}h4{font-size:3.0rem}h5{font-size:2.4rem}h6{font-size:1.5rem}}img{max-width:100%}.clearfix:after{clear:both;content:' ';display:table}.float-left{float:left}.float-right{float:right}\n\n/*# sourceMappingURL=milligram.min.css.map */"
  },
  {
    "path": "themes/milligram/public/css/milligram.min.css.map",
    "content": "{\"version\":3,\"sources\":[\"milligram.min.css\"],\"names\":[],\"mappings\":\"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\",\"file\":\"milligram.min.css\",\"sourcesContent\":[\"html{box-sizing:border-box;font-size:62.5%}body{color:#606c76;font-family:'Roboto', 'Helvetica Neue', 'Helvetica', 'Arial', sans-serif;font-size:1.6em;font-weight:300;letter-spacing:.01em;line-height:1.6}*,*:after,*:before{box-sizing:inherit}blockquote{border-left:0.3rem solid #d1d1d1;margin-left:0;margin-right:0;padding:1rem 1.5rem}blockquote *:last-child{margin-bottom:0}.button,button,input[type='button'],input[type='reset'],input[type='submit']{background-color:#9b4dca;border:0.1rem solid #9b4dca;border-radius:.4rem;color:#fff;cursor:pointer;display:inline-block;font-size:1.1rem;font-weight:700;height:3.8rem;letter-spacing:.1rem;line-height:3.8rem;padding:0 3.0rem;text-align:center;text-decoration:none;text-transform:uppercase;white-space:nowrap}.button:focus,.button:hover,button:focus,button:hover,input[type='button']:focus,input[type='button']:hover,input[type='reset']:focus,input[type='reset']:hover,input[type='submit']:focus,input[type='submit']:hover{background-color:#606c76;border-color:#606c76;color:#fff;outline:0}.button[disabled],button[disabled],input[type='button'][disabled],input[type='reset'][disabled],input[type='submit'][disabled]{cursor:default;opacity:.5}.button[disabled]:focus,.button[disabled]:hover,button[disabled]:focus,button[disabled]:hover,input[type='button'][disabled]:focus,input[type='button'][disabled]:hover,input[type='reset'][disabled]:focus,input[type='reset'][disabled]:hover,input[type='submit'][disabled]:focus,input[type='submit'][disabled]:hover{background-color:#9b4dca;border-color:#9b4dca}.button.button-outline,button.button-outline,input[type='button'].button-outline,input[type='reset'].button-outline,input[type='submit'].button-outline{background-color:transparent;color:#9b4dca}.button.button-outline:focus,.button.button-outline:hover,button.button-outline:focus,button.button-outline:hover,input[type='button'].button-outline:focus,input[type='button'].button-outline:hover,input[type='reset'].button-outline:focus,input[type='reset'].button-outline:hover,input[type='submit'].button-outline:focus,input[type='submit'].button-outline:hover{background-color:transparent;border-color:#606c76;color:#606c76}.button.button-outline[disabled]:focus,.button.button-outline[disabled]:hover,button.button-outline[disabled]:focus,button.button-outline[disabled]:hover,input[type='button'].button-outline[disabled]:focus,input[type='button'].button-outline[disabled]:hover,input[type='reset'].button-outline[disabled]:focus,input[type='reset'].button-outline[disabled]:hover,input[type='submit'].button-outline[disabled]:focus,input[type='submit'].button-outline[disabled]:hover{border-color:inherit;color:#9b4dca}.button.button-clear,button.button-clear,input[type='button'].button-clear,input[type='reset'].button-clear,input[type='submit'].button-clear{background-color:transparent;border-color:transparent;color:#9b4dca}.button.button-clear:focus,.button.button-clear:hover,button.button-clear:focus,button.button-clear:hover,input[type='button'].button-clear:focus,input[type='button'].button-clear:hover,input[type='reset'].button-clear:focus,input[type='reset'].button-clear:hover,input[type='submit'].button-clear:focus,input[type='submit'].button-clear:hover{background-color:transparent;border-color:transparent;color:#606c76}.button.button-clear[disabled]:focus,.button.button-clear[disabled]:hover,button.button-clear[disabled]:focus,button.button-clear[disabled]:hover,input[type='button'].button-clear[disabled]:focus,input[type='button'].button-clear[disabled]:hover,input[type='reset'].button-clear[disabled]:focus,input[type='reset'].button-clear[disabled]:hover,input[type='submit'].button-clear[disabled]:focus,input[type='submit'].button-clear[disabled]:hover{color:#9b4dca}code{background:#f4f5f6;border-radius:.4rem;font-size:86%;margin:0 .2rem;padding:.2rem .5rem;white-space:nowrap}pre{background:#f4f5f6;border-left:0.3rem solid #9b4dca}pre>code{border-radius:0;display:block;padding:1rem 1.5rem;white-space:pre}hr{border:0;border-top:0.1rem solid #f4f5f6;margin:3.0rem 0}input[type='email'],input[type='number'],input[type='password'],input[type='search'],input[type='tel'],input[type='text'],input[type='url'],textarea,select{appearance:none;background-color:transparent;border:0.1rem solid #d1d1d1;border-radius:.4rem;box-shadow:none;box-sizing:inherit;height:3.8rem;padding:.6rem 1.0rem;width:100%}input[type='email']:focus,input[type='number']:focus,input[type='password']:focus,input[type='search']:focus,input[type='tel']:focus,input[type='text']:focus,input[type='url']:focus,textarea:focus,select:focus{border-color:#9b4dca;outline:0}select{background:url('data:image/svg+xml;utf8,<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" height=\\\"14\\\" viewBox=\\\"0 0 29 14\\\" width=\\\"29\\\"><path fill=\\\"#d1d1d1\\\" d=\\\"M9.37727 3.625l5.08154 6.93523L19.54036 3.625\\\"/></svg>') center right no-repeat;padding-right:3.0rem}select:focus{background-image:url('data:image/svg+xml;utf8,<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" height=\\\"14\\\" viewBox=\\\"0 0 29 14\\\" width=\\\"29\\\"><path fill=\\\"#9b4dca\\\" d=\\\"M9.37727 3.625l5.08154 6.93523L19.54036 3.625\\\"/></svg>')}textarea{min-height:6.5rem}label,legend{display:block;font-size:1.6rem;font-weight:700;margin-bottom:.5rem}fieldset{border-width:0;padding:0}input[type='checkbox'],input[type='radio']{display:inline}.label-inline{display:inline-block;font-weight:normal;margin-left:.5rem}.container{margin:0 auto;max-width:112.0rem;padding:0 2.0rem;position:relative;width:100%}.row{display:flex;flex-direction:column;padding:0;width:100%}.row.row-no-padding{padding:0}.row.row-no-padding>.column{padding:0}.row.row-wrap{flex-wrap:wrap}.row.row-top{align-items:flex-start}.row.row-bottom{align-items:flex-end}.row.row-center{align-items:center}.row.row-stretch{align-items:stretch}.row.row-baseline{align-items:baseline}.row .column{display:block;flex:1;margin-left:0;max-width:100%;width:100%}.row .column.column-offset-10{margin-left:10%}.row .column.column-offset-20{margin-left:20%}.row .column.column-offset-25{margin-left:25%}.row .column.column-offset-33,.row .column.column-offset-34{margin-left:33.3333%}.row .column.column-offset-50{margin-left:50%}.row .column.column-offset-66,.row .column.column-offset-67{margin-left:66.6666%}.row .column.column-offset-75{margin-left:75%}.row .column.column-offset-80{margin-left:80%}.row .column.column-offset-90{margin-left:90%}.row .column.column-10{flex:0 0 10%;max-width:10%}.row .column.column-20{flex:0 0 20%;max-width:20%}.row .column.column-25{flex:0 0 25%;max-width:25%}.row .column.column-33,.row .column.column-34{flex:0 0 33.3333%;max-width:33.3333%}.row .column.column-40{flex:0 0 40%;max-width:40%}.row .column.column-50{flex:0 0 50%;max-width:50%}.row .column.column-60{flex:0 0 60%;max-width:60%}.row .column.column-66,.row .column.column-67{flex:0 0 66.6666%;max-width:66.6666%}.row .column.column-75{flex:0 0 75%;max-width:75%}.row .column.column-80{flex:0 0 80%;max-width:80%}.row .column.column-90{flex:0 0 90%;max-width:90%}.row .column .column-top{align-self:flex-start}.row .column .column-bottom{align-self:flex-end}.row .column .column-center{align-self:center}@media (min-width: 40rem){.row{flex-direction:row;margin-left:-1.0rem;width:calc(100% + 2.0rem)}.row .column{margin-bottom:inherit;padding:0 1.0rem}}a{color:#9b4dca;text-decoration:none}a:focus,a:hover{color:#606c76}dl,ol,ul{list-style:none;margin-top:0;padding-left:0}dl dl,dl ol,dl ul,ol dl,ol ol,ol ul,ul dl,ul ol,ul ul{font-size:90%;margin:1.5rem 0 1.5rem 3.0rem}ol{list-style:decimal inside}ul{list-style:circle inside}.button,button,dd,dt,li{margin-bottom:1.0rem}fieldset,input,select,textarea{margin-bottom:1.5rem}blockquote,dl,figure,form,ol,p,pre,table,ul{margin-bottom:2.5rem}table{width:100%}td,th{border-bottom:0.1rem solid #e1e1e1;padding:1.2rem 1.5rem;text-align:left}td:first-child,th:first-child{padding-left:0}td:last-child,th:last-child{padding-right:0}p{margin-top:0}h1,h2,h3,h4,h5,h6{font-weight:300;letter-spacing:-.1rem;margin-bottom:2.0rem;margin-top:0}h1{font-size:4.0rem;line-height:1.2}h2{font-size:3.6rem;line-height:1.25}h3{font-size:3.0rem;line-height:1.3}h4{font-size:2.4rem;letter-spacing:-.08rem;line-height:1.35}h5{font-size:1.8rem;letter-spacing:-.05rem;line-height:1.5}h6{font-size:1.6rem;letter-spacing:0;line-height:1.4}@media (min-width: 40rem){h1{font-size:5.0rem}h2{font-size:4.2rem}h3{font-size:3.6rem}h4{font-size:3.0rem}h5{font-size:2.4rem}h6{font-size:1.5rem}}img{max-width:100%}.clearfix:after{clear:both;content:' ';display:table}.float-left{float:left}.float-right{float:right}\\n\"]}"
  },
  {
    "path": "themes/milligram/templates/index.html.ep",
    "content": "% # vim:set sw=4 ts=4 sts=4 ft=html.epl expandtab:\n% title 'Lstu';\n<form class=\"form\" method=\"POST\" action=\"<%== url_for 'add' %>\">\n    <fieldset aria-labelledby=\"lsturl\">\n        <label class=\"sr-only\" for=\"lsturl\"><%= l('URL to shorten') %></label>\n        <input type=\"url\" name=\"lsturl\" id=\"lsturl\" class=\"form-control\" placeholder=\"<%= l('URL to shorten') %>\" required>\n        <label class=\"sr-only\" for=\"lsturl-custom\"><%= l('Custom shortened text') %></label>\n        <input type=\"text\" name=\"lsturl-custom\" id=\"lsturl-custom\" class=\"form-control\" placeholder=\"<%= l('Custom shortened text') %>\">\n        <%= submit_button l('Go!'), class => 'button allons-y' %>\n    </fieldset>\n</form>\n\n% if (defined(stash('short')) && defined(stash('url'))) {\n    <fieldset class=\"result\" aria-label=\"<%= l('The shortened URL') %>\">\n        <img class=\"qrcode-result\" alt=\"QRCode\" src=\"data:image/png;base64,<%= stash('qrcode') %>\">\n        <label><%= link_to stash('url') => begin %><h4><%= stash('url') %></h4><%= end %></label>\n        ⟹ <input id=\"input-short\" value=\"<%== stash('short') %>\" class=\"form-control\" size=\"<%= length(stash('short')) %>\">\n        <span id=\"js\" class=\"hidden\"><a href=\"#\" id=\"clipboard\" class=\"button button-clear\" title=\"<%= l('Copy to clipboard') %>\" data-short=\"<%== stash('short') %>\"><h5><span class=\"icon icon-clipboard\"></span></h5></a><span>\n    </fieldset>\n% }\n% if (defined(flash('msg'))) {\n    <h3 class=\"alert alert-danger\"><%= flash('msg') %></h3>\n% }\n% if (defined(stash('msg'))) {\n    <h3 class=\"alert alert-danger\"><%= stash('msg') %></h3>\n% }\n"
  },
  {
    "path": "themes/milligram/templates/layouts/default.html.ep",
    "content": "% # vim:set sw=4 ts=4 sts=4 ft=html.epl expandtab:\n% my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime();\n% $year += 1900;\n% my $lang = $self->languages;\n%    $lang =~ s/-(.*)/_\\U$1/;\n<!DOCTYPE html>\n<html lang=\"<%= $lang %>\">\n    <head>\n        <title><%= title %></title>\n        <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n        <meta charset=\"utf-8\" />\n        <meta name=\"mobile-web-app-capable\" content=\"yes\">\n        <meta name=\"apple-mobile-web-app-capable\" content=\"yes\">\n        <meta name=\"apple-mobile-web-app-status-bar-style\" content=\"black\">\n        <link rel=\"manifest\" href=\"<%= url_for('/manifest.json') %>\">\n        <link rel=\"shortcut icon\" href=\"<%= url_for('/favicon.ico') %>\">\n        <link rel=\"mask-icon\" href=\"<%= url_for('/img/lstu-small.svg') %>\" color=\"#9b4dca\">\n        <link rel=\"icon\" type=\"image/png\" href=\"<%= url_for('/img/favicon.png') %>\">\n        <link rel=\"icon\" sizes=\"16x16\" href=\"<%= url_for('/img/lstu16.png') %>\">\n        <link rel=\"icon\" sizes=\"32x32\" href=\"<%= url_for('/img/lstu32.png') %>\">\n        <link rel=\"icon\" sizes=\"128x128\" href=\"<%= url_for('/img/lstu128.png') %>\">\n        <link rel=\"icon\" sizes=\"192x192\" href=\"<%= url_for('/img/lstu192.png') %>\">\n        <link rel=\"apple-touch-icon\" href=\"<%= url_for('/img/lstu60.png') %>\">\n        <link rel=\"apple-touch-icon\" sizes=\"76x76\" href=\"<%= url_for('/img/lstu76.png') %>\">\n        <link rel=\"apple-touch-icon\" sizes=\"120x120\" href=\"<%= url_for('/img/lstu120.png') %>\">\n        <link rel=\"apple-touch-icon\" sizes=\"152x152\" href=\"<%= url_for('/img/lstu152.png') %>\">\n        <link rel=\"apple-touch-icon\" sizes=\"128x128\" href=\"<%= url_for('/img/lstu128.png') %>\">\n        <link rel=\"apple-touch-icon\" sizes=\"152x152\" href=\"<%= url_for('/img/lstu152.png') %>\">\n        <link rel=\"apple-touch-icon\" sizes=\"180x180\" href=\"<%= url_for('/img/lstu180.png') %>\">\n        <link rel=\"apple-touch-icon-precomposed\" sizes=\"120x120\" href=\"<%= url_for('/img/lstu120p.png') %>\">\n        <meta name=\"msapplication-TileColor\" content=\"#ffc40d\">\n        <meta name=\"msapplication-TileImage\" content=\"<%= url_for('/img/mstile-lstu144.png') %>\">\n        <meta name=\"msapplication-config\" content=\"<%= url_for('/browserconfig.xml') %>\">\n    </head>\n    <body>\n        <div class=\"container\">\n            <h1 class=\"oswald hidden-sm hidden-md hidden-lg\">\n                <a href=\"<%= url_for('/') %>\">\n                    Let's Shorten That URL\n                </a>\n            </h1>\n            <div class=\"hidden-xs logo\">\n                <%= link_to url_for('/') => (class => 'link_nocol') => begin %>\n                    <img class=\"logo-img\" src=\"<%= url_for('/img/logo+type.svg') %>\" alt=\"lstu logo\" width=\"auto\" height=\"200\">\n                <% end %>\n            </div>\n            <p>\n                <small>&copy; 2013 — <%= $year %> <%= link_to 'Luc Didry' => 'https://fiat-tux.fr' %> —\n                    <%= l('License:') %> <%= link_to 'WTFPL' => 'http://www.wtfpl.net/' %> —\n                    <%= link_to l('About') => 'https://framagit.org/fiat-tux/hat-softwares/lstu/blob/master/README.md' %> —\n                    <%= link_to 'API' => url_for('api') %> —\n            % if (defined(config('ldap')) || defined(config('htpasswd'))) {\n                % if (is_user_authenticated()) {\n                    <%= link_to l('Statistics') => url_for('stats') %> —\n                    <%= link_to l('Logout') => url_for('/logout')%>\n                % } else {\n                    <%= link_to l('Signin') => url_for('/login') %>\n                % }\n            % } else {\n                    <%= link_to l('Statistics') => url_for('stats') %>\n            % }\n                </small>\n            </p>\n            <%= content %>\n        </div>\n    % if ($self->app->mode eq 'production') {\n        %= stylesheet '/css/milli-lstu.min.css'\n    % } else {\n        %= stylesheet '/css/milligram.min.css'\n        %= stylesheet '/css/lstu.css'\n        %= stylesheet '/css/fontelico.css'\n    % }\n% if (defined(stash('short')) && defined(stash('url'))) {\n        %= javascript url_for('lstu.js')\n% }\n    </body>\n</html>\n"
  },
  {
    "path": "themes/milligram/templates/stats.html.ep",
    "content": "% # vim:set sw=4 ts=4 sts=4 ft=html.epl expandtab:\n% title 'Lstu stats';\n% use Mojo::Date;\n<h2><%= l('Statistics') %></h2>\n% if (defined(config('adminpwd')) || defined(config('hashed_adminpwd'))) {\n%     if (!flash('banned')) {\n<form class=\"form\" method=\"POST\" action=\"<%== url_for 'stats' %>\">\n    <fieldset>\n%         if (defined(stash('admin'))) {\n        <input type=\"hidden\" value=\"logout\" name=\"action\">\n        <%= submit_button l('Logout from admin stats'), class => 'button' %>\n%         } else {\n        <label class=\"sr-only\" for=\"adminpwd\"><%= l('Admin password') %></label>\n        <input type=\"password\" name=\"adminpwd\" id=\"adminpwd\" class=\"form-control\" placeholder=\"<%= l('Admin password') %>\" required>\n        <input type=\"hidden\" value=\"0\" name=\"page\">\n        <%= submit_button l('Go!'), class => 'button' %>\n%         }\n    </fieldset>\n</form>\n%     }\n%     if (defined(flash('msg'))) {\n    <h3 class=\"alert alert-danger\"><%= flash('msg') %></h3>\n%     }\n% }\n\n% if (defined(flash('success_msg'))) {\n    <h3 class=\"alert alert-success\"><%= flash('success_msg') %></h3>\n% }\n<form class=\"form\" method=\"POST\" action=\"<%== url_for 'import_cookie' %>\" enctype=\"multipart/form-data\">\n    <fieldset>\n        <label for=\"file\"><%= l('Import URLs') %></label>\n        <input type=\"file\" name=\"file\" id=\"file\" required>\n    </fieldset>\n    <%= submit_button l('Import URLs'), class => 'button' %>\n    <a href=\"<%= url_for 'export_cookie' %>\" class=\"button button-outline\"><%= l('Export your URLs') %></a>\n</form>\n\n<table class=\"table table-striped\">\n    <tr>\n        <th>#</th>\n        <th><%= l('URL') %></th>\n        <th><%= l('Shortened URL') %></th>\n        <th><%= l('Counter') %></th>\n        <th><%= l('Created') %></th>\n% if (defined(config('adminpwd')) || defined(config('hashed_adminpwd'))) {\n%     unless (defined(stash('admin'))) {\n        <th><%= l('QRCode') %></th>\n%     } else {\n        <th><%= l('Delete') %></th>\n%     }\n% }\n    </tr>\n% my $i = 1;\n% if (defined(stash('page')) && stash('page') >= 0) {\n%     $i = 1 + config('page_offset') * stash('page');\n% }\n% my $j = $i;\n% for my $url (@{$urls}) {\n    <tr>\n        <td><%= $i++ %></td>\n        <td><%= link_to $url->{url} => $url->{url} %></td>\n        <td><%= link_to $prefix.$url->{short} => $prefix.$url->{short} %></td>\n        <td><%= $url->{counter} %></td>\n        <td><%= Mojo::Date->new($url->{timestamp})->to_string %></td>\n% if (defined(config('adminpwd')) || defined(config('hashed_adminpwd'))) {\n%     unless (defined(stash('admin'))) {\n        <td><img class=\"qrcode-stat\" alt=\"QRCode\" src=\"data:image/png;base64,<%= $url->{qrcode} %>\"></td>\n%     } else {\n        <td><a href=\"<%= url_for('delete', {short => $url->{short}}) %>\"><h5><span class=\"icon icon-trash\"></span></h5></a></td>\n%     }\n% }\n    </tr>\n% }\n</table>\n% if (defined(config('adminpwd')) || defined(config('hashed_adminpwd'))) {\n%     if (defined(stash('admin'))) {\n<nav>\n  <ul class=\"pager\">\n    <li class=\"previous<%= (stash('first')) ? ' disabled' : '' %>\"><%= link_to url_for->query(page => (stash('first')) ? 0 : stash('page') - 1) => begin %><span aria-hidden=\"true\">&larr;</span> <%= l('Previous') %><% end %></li>\n    <li class=\"center\"><%= $j.'-'.--$i.'/'.stash('total') %></li>\n    <li class=\"next<%= (stash('last')) ? ' disabled' : '' %>\"><%= link_to url_for->query(page => (stash('last')) ? stash('page') : stash('page') + 1) => begin %><%= l('Next') %> <span aria-hidden=\"true\">&rarr;</span><% end %></li>\n  </ul>\n</nav>\n%     }\n% }\n%= link_to l('Home') => '/' => (class => 'button')\n"
  },
  {
    "path": "utilities/bootstrap.json",
    "content": "{\n  \"vars\": {\n    \"@gray-base\": \"#000\",\n    \"@gray-darker\": \"lighten(@gray-base, 13.5%)\",\n    \"@gray-dark\": \"lighten(@gray-base, 20%)\",\n    \"@gray\": \"lighten(@gray-base, 33.5%)\",\n    \"@gray-light\": \"lighten(@gray-base, 46.7%)\",\n    \"@gray-lighter\": \"lighten(@gray-base, 93.5%)\",\n    \"@brand-primary\": \"darken(#428bca, 6.5%)\",\n    \"@brand-success\": \"#5cb85c\",\n    \"@brand-info\": \"#5bc0de\",\n    \"@brand-warning\": \"#f0ad4e\",\n    \"@brand-danger\": \"#d9534f\",\n    \"@body-bg\": \"#fff\",\n    \"@text-color\": \"@gray-dark\",\n    \"@link-color\": \"@brand-primary\",\n    \"@link-hover-color\": \"darken(@link-color, 15%)\",\n    \"@link-hover-decoration\": \"underline\",\n    \"@font-family-sans-serif\": \"\\\"Helvetica Neue\\\", Helvetica, Arial, sans-serif\",\n    \"@font-family-serif\": \"Georgia, \\\"Times New Roman\\\", Times, serif\",\n    \"@font-family-monospace\": \"Menlo, Monaco, Consolas, \\\"Courier New\\\", monospace\",\n    \"@font-family-base\": \"@font-family-sans-serif\",\n    \"@font-size-base\": \"14px\",\n    \"@font-size-large\": \"ceil((@font-size-base * 1.25))\",\n    \"@font-size-small\": \"ceil((@font-size-base * 0.85))\",\n    \"@font-size-h1\": \"floor((@font-size-base * 2.6))\",\n    \"@font-size-h2\": \"floor((@font-size-base * 2.15))\",\n    \"@font-size-h3\": \"ceil((@font-size-base * 1.7))\",\n    \"@font-size-h4\": \"ceil((@font-size-base * 1.25))\",\n    \"@font-size-h5\": \"@font-size-base\",\n    \"@font-size-h6\": \"ceil((@font-size-base * 0.85))\",\n    \"@line-height-base\": \"1.428571429\",\n    \"@line-height-computed\": \"floor((@font-size-base * @line-height-base))\",\n    \"@headings-font-family\": \"inherit\",\n    \"@headings-font-weight\": \"500\",\n    \"@headings-line-height\": \"1.1\",\n    \"@headings-color\": \"inherit\",\n    \"@icon-font-path\": \"\\\"../fonts/\\\"\",\n    \"@icon-font-name\": \"\\\"glyphicons-halflings-regular\\\"\",\n    \"@icon-font-svg-id\": \"\\\"glyphicons_halflingsregular\\\"\",\n    \"@padding-base-vertical\": \"6px\",\n    \"@padding-base-horizontal\": \"12px\",\n    \"@padding-large-vertical\": \"10px\",\n    \"@padding-large-horizontal\": \"16px\",\n    \"@padding-small-vertical\": \"5px\",\n    \"@padding-small-horizontal\": \"10px\",\n    \"@padding-xs-vertical\": \"1px\",\n    \"@padding-xs-horizontal\": \"5px\",\n    \"@line-height-large\": \"1.3333333\",\n    \"@line-height-small\": \"1.5\",\n    \"@border-radius-base\": \"4px\",\n    \"@border-radius-large\": \"6px\",\n    \"@border-radius-small\": \"3px\",\n    \"@component-active-color\": \"#fff\",\n    \"@component-active-bg\": \"@brand-primary\",\n    \"@caret-width-base\": \"4px\",\n    \"@caret-width-large\": \"5px\",\n    \"@table-cell-padding\": \"8px\",\n    \"@table-condensed-cell-padding\": \"5px\",\n    \"@table-bg\": \"transparent\",\n    \"@table-bg-accent\": \"#f9f9f9\",\n    \"@table-bg-hover\": \"#f5f5f5\",\n    \"@table-bg-active\": \"@table-bg-hover\",\n    \"@table-border-color\": \"#ddd\",\n    \"@btn-font-weight\": \"normal\",\n    \"@btn-default-color\": \"#333\",\n    \"@btn-default-bg\": \"#fff\",\n    \"@btn-default-border\": \"#ccc\",\n    \"@btn-primary-color\": \"#fff\",\n    \"@btn-primary-bg\": \"@brand-primary\",\n    \"@btn-primary-border\": \"darken(@btn-primary-bg, 5%)\",\n    \"@btn-success-color\": \"#fff\",\n    \"@btn-success-bg\": \"@brand-success\",\n    \"@btn-success-border\": \"darken(@btn-success-bg, 5%)\",\n    \"@btn-info-color\": \"#fff\",\n    \"@btn-info-bg\": \"@brand-info\",\n    \"@btn-info-border\": \"darken(@btn-info-bg, 5%)\",\n    \"@btn-warning-color\": \"#fff\",\n    \"@btn-warning-bg\": \"@brand-warning\",\n    \"@btn-warning-border\": \"darken(@btn-warning-bg, 5%)\",\n    \"@btn-danger-color\": \"#fff\",\n    \"@btn-danger-bg\": \"@brand-danger\",\n    \"@btn-danger-border\": \"darken(@btn-danger-bg, 5%)\",\n    \"@btn-link-disabled-color\": \"@gray-light\",\n    \"@input-bg\": \"#fff\",\n    \"@input-bg-disabled\": \"@gray-lighter\",\n    \"@input-color\": \"@gray\",\n    \"@input-border\": \"#ccc\",\n    \"@input-border-radius\": \"@border-radius-base\",\n    \"@input-border-radius-large\": \"@border-radius-large\",\n    \"@input-border-radius-small\": \"@border-radius-small\",\n    \"@input-border-focus\": \"#66afe9\",\n    \"@input-color-placeholder\": \"#999\",\n    \"@input-height-base\": \"(@line-height-computed + (@padding-base-vertical * 2) + 2)\",\n    \"@input-height-large\": \"(ceil(@font-size-large * @line-height-large) + (@padding-large-vertical * 2) + 2)\",\n    \"@input-height-small\": \"(floor(@font-size-small * @line-height-small) + (@padding-small-vertical * 2) + 2)\",\n    \"@form-group-margin-bottom\": \"15px\",\n    \"@legend-color\": \"@gray-dark\",\n    \"@legend-border-color\": \"#e5e5e5\",\n    \"@input-group-addon-bg\": \"@gray-lighter\",\n    \"@input-group-addon-border-color\": \"@input-border\",\n    \"@cursor-disabled\": \"not-allowed\",\n    \"@dropdown-bg\": \"#fff\",\n    \"@dropdown-border\": \"rgba(0,0,0,.15)\",\n    \"@dropdown-fallback-border\": \"#ccc\",\n    \"@dropdown-divider-bg\": \"#e5e5e5\",\n    \"@dropdown-link-color\": \"@gray-dark\",\n    \"@dropdown-link-hover-color\": \"darken(@gray-dark, 5%)\",\n    \"@dropdown-link-hover-bg\": \"#f5f5f5\",\n    \"@dropdown-link-active-color\": \"@component-active-color\",\n    \"@dropdown-link-active-bg\": \"@component-active-bg\",\n    \"@dropdown-link-disabled-color\": \"@gray-light\",\n    \"@dropdown-header-color\": \"@gray-light\",\n    \"@dropdown-caret-color\": \"#000\",\n    \"@screen-xs\": \"480px\",\n    \"@screen-xs-min\": \"@screen-xs\",\n    \"@screen-phone\": \"@screen-xs-min\",\n    \"@screen-sm\": \"768px\",\n    \"@screen-sm-min\": \"@screen-sm\",\n    \"@screen-tablet\": \"@screen-sm-min\",\n    \"@screen-md\": \"992px\",\n    \"@screen-md-min\": \"@screen-md\",\n    \"@screen-desktop\": \"@screen-md-min\",\n    \"@screen-lg\": \"1200px\",\n    \"@screen-lg-min\": \"@screen-lg\",\n    \"@screen-lg-desktop\": \"@screen-lg-min\",\n    \"@screen-xs-max\": \"(@screen-sm-min - 1)\",\n    \"@screen-sm-max\": \"(@screen-md-min - 1)\",\n    \"@screen-md-max\": \"(@screen-lg-min - 1)\",\n    \"@grid-columns\": \"12\",\n    \"@grid-gutter-width\": \"30px\",\n    \"@grid-float-breakpoint\": \"@screen-sm-min\",\n    \"@grid-float-breakpoint-max\": \"(@grid-float-breakpoint - 1)\",\n    \"@container-tablet\": \"(720px + @grid-gutter-width)\",\n    \"@container-sm\": \"@container-tablet\",\n    \"@container-desktop\": \"(940px + @grid-gutter-width)\",\n    \"@container-md\": \"@container-desktop\",\n    \"@container-large-desktop\": \"(1140px + @grid-gutter-width)\",\n    \"@container-lg\": \"@container-large-desktop\",\n    \"@navbar-height\": \"50px\",\n    \"@navbar-margin-bottom\": \"@line-height-computed\",\n    \"@navbar-border-radius\": \"@border-radius-base\",\n    \"@navbar-padding-horizontal\": \"floor((@grid-gutter-width / 2))\",\n    \"@navbar-padding-vertical\": \"((@navbar-height - @line-height-computed) / 2)\",\n    \"@navbar-collapse-max-height\": \"340px\",\n    \"@navbar-default-color\": \"#777\",\n    \"@navbar-default-bg\": \"#f8f8f8\",\n    \"@navbar-default-border\": \"darken(@navbar-default-bg, 6.5%)\",\n    \"@navbar-default-link-color\": \"#777\",\n    \"@navbar-default-link-hover-color\": \"#333\",\n    \"@navbar-default-link-hover-bg\": \"transparent\",\n    \"@navbar-default-link-active-color\": \"#555\",\n    \"@navbar-default-link-active-bg\": \"darken(@navbar-default-bg, 6.5%)\",\n    \"@navbar-default-link-disabled-color\": \"#ccc\",\n    \"@navbar-default-link-disabled-bg\": \"transparent\",\n    \"@navbar-default-brand-color\": \"@navbar-default-link-color\",\n    \"@navbar-default-brand-hover-color\": \"darken(@navbar-default-brand-color, 10%)\",\n    \"@navbar-default-brand-hover-bg\": \"transparent\",\n    \"@navbar-default-toggle-hover-bg\": \"#ddd\",\n    \"@navbar-default-toggle-icon-bar-bg\": \"#888\",\n    \"@navbar-default-toggle-border-color\": \"#ddd\",\n    \"@navbar-inverse-color\": \"lighten(@gray-light, 15%)\",\n    \"@navbar-inverse-bg\": \"#222\",\n    \"@navbar-inverse-border\": \"darken(@navbar-inverse-bg, 10%)\",\n    \"@navbar-inverse-link-color\": \"lighten(@gray-light, 15%)\",\n    \"@navbar-inverse-link-hover-color\": \"#fff\",\n    \"@navbar-inverse-link-hover-bg\": \"transparent\",\n    \"@navbar-inverse-link-active-color\": \"@navbar-inverse-link-hover-color\",\n    \"@navbar-inverse-link-active-bg\": \"darken(@navbar-inverse-bg, 10%)\",\n    \"@navbar-inverse-link-disabled-color\": \"#444\",\n    \"@navbar-inverse-link-disabled-bg\": \"transparent\",\n    \"@navbar-inverse-brand-color\": \"@navbar-inverse-link-color\",\n    \"@navbar-inverse-brand-hover-color\": \"#fff\",\n    \"@navbar-inverse-brand-hover-bg\": \"transparent\",\n    \"@navbar-inverse-toggle-hover-bg\": \"#333\",\n    \"@navbar-inverse-toggle-icon-bar-bg\": \"#fff\",\n    \"@navbar-inverse-toggle-border-color\": \"#333\",\n    \"@nav-link-padding\": \"10px 15px\",\n    \"@nav-link-hover-bg\": \"@gray-lighter\",\n    \"@nav-disabled-link-color\": \"@gray-light\",\n    \"@nav-disabled-link-hover-color\": \"@gray-light\",\n    \"@nav-tabs-border-color\": \"#ddd\",\n    \"@nav-tabs-link-hover-border-color\": \"@gray-lighter\",\n    \"@nav-tabs-active-link-hover-bg\": \"@body-bg\",\n    \"@nav-tabs-active-link-hover-color\": \"@gray\",\n    \"@nav-tabs-active-link-hover-border-color\": \"#ddd\",\n    \"@nav-tabs-justified-link-border-color\": \"#ddd\",\n    \"@nav-tabs-justified-active-link-border-color\": \"@body-bg\",\n    \"@nav-pills-border-radius\": \"@border-radius-base\",\n    \"@nav-pills-active-link-hover-bg\": \"@component-active-bg\",\n    \"@nav-pills-active-link-hover-color\": \"@component-active-color\",\n    \"@pagination-color\": \"@link-color\",\n    \"@pagination-bg\": \"#fff\",\n    \"@pagination-border\": \"#ddd\",\n    \"@pagination-hover-color\": \"@link-hover-color\",\n    \"@pagination-hover-bg\": \"@gray-lighter\",\n    \"@pagination-hover-border\": \"#ddd\",\n    \"@pagination-active-color\": \"#fff\",\n    \"@pagination-active-bg\": \"@brand-primary\",\n    \"@pagination-active-border\": \"@brand-primary\",\n    \"@pagination-disabled-color\": \"@gray-light\",\n    \"@pagination-disabled-bg\": \"#fff\",\n    \"@pagination-disabled-border\": \"#ddd\",\n    \"@pager-bg\": \"@pagination-bg\",\n    \"@pager-border\": \"@pagination-border\",\n    \"@pager-border-radius\": \"15px\",\n    \"@pager-hover-bg\": \"@pagination-hover-bg\",\n    \"@pager-active-bg\": \"@pagination-active-bg\",\n    \"@pager-active-color\": \"@pagination-active-color\",\n    \"@pager-disabled-color\": \"@pagination-disabled-color\",\n    \"@jumbotron-padding\": \"30px\",\n    \"@jumbotron-color\": \"inherit\",\n    \"@jumbotron-bg\": \"@gray-lighter\",\n    \"@jumbotron-heading-color\": \"inherit\",\n    \"@jumbotron-font-size\": \"ceil((@font-size-base * 1.5))\",\n    \"@state-success-text\": \"#3c763d\",\n    \"@state-success-bg\": \"#dff0d8\",\n    \"@state-success-border\": \"darken(spin(@state-success-bg, -10), 5%)\",\n    \"@state-info-text\": \"#31708f\",\n    \"@state-info-bg\": \"#d9edf7\",\n    \"@state-info-border\": \"darken(spin(@state-info-bg, -10), 7%)\",\n    \"@state-warning-text\": \"#8a6d3b\",\n    \"@state-warning-bg\": \"#fcf8e3\",\n    \"@state-warning-border\": \"darken(spin(@state-warning-bg, -10), 5%)\",\n    \"@state-danger-text\": \"#a94442\",\n    \"@state-danger-bg\": \"#f2dede\",\n    \"@state-danger-border\": \"darken(spin(@state-danger-bg, -10), 5%)\",\n    \"@tooltip-max-width\": \"200px\",\n    \"@tooltip-color\": \"#fff\",\n    \"@tooltip-bg\": \"#000\",\n    \"@tooltip-opacity\": \".9\",\n    \"@tooltip-arrow-width\": \"5px\",\n    \"@tooltip-arrow-color\": \"@tooltip-bg\",\n    \"@popover-bg\": \"#fff\",\n    \"@popover-max-width\": \"276px\",\n    \"@popover-border-color\": \"rgba(0,0,0,.2)\",\n    \"@popover-fallback-border-color\": \"#ccc\",\n    \"@popover-title-bg\": \"darken(@popover-bg, 3%)\",\n    \"@popover-arrow-width\": \"10px\",\n    \"@popover-arrow-color\": \"@popover-bg\",\n    \"@popover-arrow-outer-width\": \"(@popover-arrow-width + 1)\",\n    \"@popover-arrow-outer-color\": \"fadein(@popover-border-color, 5%)\",\n    \"@popover-arrow-outer-fallback-color\": \"darken(@popover-fallback-border-color, 20%)\",\n    \"@label-default-bg\": \"@gray-light\",\n    \"@label-primary-bg\": \"@brand-primary\",\n    \"@label-success-bg\": \"@brand-success\",\n    \"@label-info-bg\": \"@brand-info\",\n    \"@label-warning-bg\": \"@brand-warning\",\n    \"@label-danger-bg\": \"@brand-danger\",\n    \"@label-color\": \"#fff\",\n    \"@label-link-hover-color\": \"#fff\",\n    \"@modal-inner-padding\": \"15px\",\n    \"@modal-title-padding\": \"15px\",\n    \"@modal-title-line-height\": \"@line-height-base\",\n    \"@modal-content-bg\": \"#fff\",\n    \"@modal-content-border-color\": \"rgba(0,0,0,.2)\",\n    \"@modal-content-fallback-border-color\": \"#999\",\n    \"@modal-backdrop-bg\": \"#000\",\n    \"@modal-backdrop-opacity\": \".5\",\n    \"@modal-header-border-color\": \"#e5e5e5\",\n    \"@modal-footer-border-color\": \"@modal-header-border-color\",\n    \"@modal-lg\": \"900px\",\n    \"@modal-md\": \"600px\",\n    \"@modal-sm\": \"300px\",\n    \"@alert-padding\": \"15px\",\n    \"@alert-border-radius\": \"@border-radius-base\",\n    \"@alert-link-font-weight\": \"bold\",\n    \"@alert-success-bg\": \"@state-success-bg\",\n    \"@alert-success-text\": \"@state-success-text\",\n    \"@alert-success-border\": \"@state-success-border\",\n    \"@alert-info-bg\": \"@state-info-bg\",\n    \"@alert-info-text\": \"@state-info-text\",\n    \"@alert-info-border\": \"@state-info-border\",\n    \"@alert-warning-bg\": \"@state-warning-bg\",\n    \"@alert-warning-text\": \"@state-warning-text\",\n    \"@alert-warning-border\": \"@state-warning-border\",\n    \"@alert-danger-bg\": \"@state-danger-bg\",\n    \"@alert-danger-text\": \"@state-danger-text\",\n    \"@alert-danger-border\": \"@state-danger-border\",\n    \"@progress-bg\": \"#f5f5f5\",\n    \"@progress-bar-color\": \"#fff\",\n    \"@progress-border-radius\": \"@border-radius-base\",\n    \"@progress-bar-bg\": \"@brand-primary\",\n    \"@progress-bar-success-bg\": \"@brand-success\",\n    \"@progress-bar-warning-bg\": \"@brand-warning\",\n    \"@progress-bar-danger-bg\": \"@brand-danger\",\n    \"@progress-bar-info-bg\": \"@brand-info\",\n    \"@list-group-bg\": \"#fff\",\n    \"@list-group-border\": \"#ddd\",\n    \"@list-group-border-radius\": \"@border-radius-base\",\n    \"@list-group-hover-bg\": \"#f5f5f5\",\n    \"@list-group-active-color\": \"@component-active-color\",\n    \"@list-group-active-bg\": \"@component-active-bg\",\n    \"@list-group-active-border\": \"@list-group-active-bg\",\n    \"@list-group-active-text-color\": \"lighten(@list-group-active-bg, 40%)\",\n    \"@list-group-disabled-color\": \"@gray-light\",\n    \"@list-group-disabled-bg\": \"@gray-lighter\",\n    \"@list-group-disabled-text-color\": \"@list-group-disabled-color\",\n    \"@list-group-link-color\": \"#555\",\n    \"@list-group-link-hover-color\": \"@list-group-link-color\",\n    \"@list-group-link-heading-color\": \"#333\",\n    \"@panel-bg\": \"#fff\",\n    \"@panel-body-padding\": \"15px\",\n    \"@panel-heading-padding\": \"10px 15px\",\n    \"@panel-footer-padding\": \"@panel-heading-padding\",\n    \"@panel-border-radius\": \"@border-radius-base\",\n    \"@panel-inner-border\": \"#ddd\",\n    \"@panel-footer-bg\": \"#f5f5f5\",\n    \"@panel-default-text\": \"@gray-dark\",\n    \"@panel-default-border\": \"#ddd\",\n    \"@panel-default-heading-bg\": \"#f5f5f5\",\n    \"@panel-primary-text\": \"#fff\",\n    \"@panel-primary-border\": \"@brand-primary\",\n    \"@panel-primary-heading-bg\": \"@brand-primary\",\n    \"@panel-success-text\": \"@state-success-text\",\n    \"@panel-success-border\": \"@state-success-border\",\n    \"@panel-success-heading-bg\": \"@state-success-bg\",\n    \"@panel-info-text\": \"@state-info-text\",\n    \"@panel-info-border\": \"@state-info-border\",\n    \"@panel-info-heading-bg\": \"@state-info-bg\",\n    \"@panel-warning-text\": \"@state-warning-text\",\n    \"@panel-warning-border\": \"@state-warning-border\",\n    \"@panel-warning-heading-bg\": \"@state-warning-bg\",\n    \"@panel-danger-text\": \"@state-danger-text\",\n    \"@panel-danger-border\": \"@state-danger-border\",\n    \"@panel-danger-heading-bg\": \"@state-danger-bg\",\n    \"@thumbnail-padding\": \"4px\",\n    \"@thumbnail-bg\": \"@body-bg\",\n    \"@thumbnail-border\": \"#ddd\",\n    \"@thumbnail-border-radius\": \"@border-radius-base\",\n    \"@thumbnail-caption-color\": \"@text-color\",\n    \"@thumbnail-caption-padding\": \"9px\",\n    \"@well-bg\": \"#f5f5f5\",\n    \"@well-border\": \"darken(@well-bg, 7%)\",\n    \"@badge-color\": \"#fff\",\n    \"@badge-link-hover-color\": \"#fff\",\n    \"@badge-bg\": \"@gray-light\",\n    \"@badge-active-color\": \"@link-color\",\n    \"@badge-active-bg\": \"#fff\",\n    \"@badge-font-weight\": \"bold\",\n    \"@badge-line-height\": \"1\",\n    \"@badge-border-radius\": \"10px\",\n    \"@breadcrumb-padding-vertical\": \"8px\",\n    \"@breadcrumb-padding-horizontal\": \"15px\",\n    \"@breadcrumb-bg\": \"#f5f5f5\",\n    \"@breadcrumb-color\": \"#ccc\",\n    \"@breadcrumb-active-color\": \"@gray-light\",\n    \"@breadcrumb-separator\": \"\\\"/\\\"\",\n    \"@carousel-text-shadow\": \"0 1px 2px rgba(0,0,0,.6)\",\n    \"@carousel-control-color\": \"#fff\",\n    \"@carousel-control-width\": \"15%\",\n    \"@carousel-control-opacity\": \".5\",\n    \"@carousel-control-font-size\": \"20px\",\n    \"@carousel-indicator-active-bg\": \"#fff\",\n    \"@carousel-indicator-border-color\": \"#fff\",\n    \"@carousel-caption-color\": \"#fff\",\n    \"@close-font-weight\": \"bold\",\n    \"@close-color\": \"#000\",\n    \"@close-text-shadow\": \"0 1px 0 #fff\",\n    \"@code-color\": \"#c7254e\",\n    \"@code-bg\": \"#f9f2f4\",\n    \"@kbd-color\": \"#fff\",\n    \"@kbd-bg\": \"#333\",\n    \"@pre-bg\": \"#f5f5f5\",\n    \"@pre-color\": \"@gray-dark\",\n    \"@pre-border-color\": \"#ccc\",\n    \"@pre-scrollable-max-height\": \"340px\",\n    \"@component-offset-horizontal\": \"180px\",\n    \"@text-muted\": \"@gray-light\",\n    \"@abbr-border-color\": \"@gray-light\",\n    \"@headings-small-color\": \"@gray-light\",\n    \"@blockquote-small-color\": \"@gray-light\",\n    \"@blockquote-font-size\": \"(@font-size-base * 1.25)\",\n    \"@blockquote-border-color\": \"@gray-lighter\",\n    \"@page-header-border-color\": \"@gray-lighter\",\n    \"@dl-horizontal-offset\": \"@component-offset-horizontal\",\n    \"@hr-border\": \"@gray-lighter\"\n  },\n  \"css\": [\n    \"print.less\",\n    \"type.less\",\n    \"grid.less\",\n    \"tables.less\",\n    \"forms.less\",\n    \"buttons.less\",\n    \"responsive-utilities.less\",\n    \"pagination.less\",\n    \"pager.less\",\n    \"alerts.less\"\n  ],\n  \"js\": [],\n  \"customizerUrl\": \"http://getbootstrap.com/customize/?id=8d56756b325f9f22f4eb\"\n}"
  },
  {
    "path": "utilities/lstu-minion@.service",
    "content": "[Unit]\nDescription=Shortened URLs service job queue\nDocumentation=https://framagit.org/fiat-tux/hat-softwares/lstu\n\n[Service]\nType=simple\nUser=www-data\nWorkingDirectory=/var/www/lstu/\nExecStart=/usr/local/bin/carton exec script/application minion worker\n\n[Install]\nWantedBy=multi-user.target\n"
  },
  {
    "path": "utilities/lstu.apache",
    "content": "<VirtualHost *:80>\n    ServerName http://lstu.example.org\n    ServerAdmin contact@lstu.example.org\n\n    ProxyRequests Off\n    ProxyPreserveHost On\n    ProxyPass / http://127.0.0.1:8080/\n    ProxyPassReverse / http://lstu.example.org/\n\n    LogLevel info\n    ErrorLog ${APACHE_LOG_DIR}/lstu.error.log\n    CustomLog ${APACHE_LOG_DIR}/lstu.access.log combined\n\n    # Local reverse proxy authorization override\n    # Most unix distribution deny proxy by default\n    <Proxy http://127.0.0.1:8080/*>;\n        # If apache 2.4:\n        Require all granted\n        # If apache 2.2:\n        #Order deny,allow\n        #Allow from all\n    </Proxy>\n</VirtualHost>\n"
  },
  {
    "path": "utilities/lstu.default",
    "content": "# LDIR is the path where you installed Lstu\n# It has to end with a final /\nLDIR=/var/www/lstu/\n\n# USER is the user who will launch Lstu\nUSER=www-data\n"
  },
  {
    "path": "utilities/lstu.init",
    "content": "#!/bin/sh\n# vim: set ts=4 sw=4 sts=4 tw=0:\n# vim: set expandtab:\n\n### BEGIN INIT INFO\n# Provides:          lstu\n# Required-Start:    $local_fs $remote_fs $network $syslog\n# Required-Stop:     $local_fs $remote_fs $network $syslog\n# Default-Start:     2 3 4 5\n# Default-Stop:      0 1 6\n# Short-Description: starts lstu with hypnotoad\n# Description:       starts lstu with hypnotoad\n### END INIT INFO\n\n\nPATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin\nDAEMON=script/lstu\nNAME=lstu\nDESC=lstu\n\nif [ -f \"/etc/default/lstu\" ]\nthen\n    . /etc/default/lstu\n    if [ -z $LDIR ]\n    then\n        echo \"LDIR variable is empty, please fill it in /etc/default/lstu\"\n        exit 0\n    fi\n    if [ -z $USER ]\n    then\n        echo \"USER variable is empty, please fill it in /etc/default/lstu\"\n        exit 0\n    fi\nelse\n    echo \"Missing /etc/default/lstu file\"\n    exit 0\nfi\n\nif [ ! -f \"$LDIR$DAEMON\" ]\nthen\n    echo \"Missing $LDIR$DAEMON file\"\n    exit 0\nfi\n\nset -e\n\n. /lib/lsb/init-functions\n\ndo_start()\n{\n    # Return\n    # 0 if daemon has been started\n    # 1 if daemon was already running\n    # 2 if daemon could not be started\n\n    cd $LDIR\n    su $USER -c \"carton exec hypnotoad $DAEMON >/dev/null 2>&1\"\n    return \"$?\"\n}\n\ndo_stop()\n{\n    # Return\n    # 0 if daemon has been stopped\n    # 1 if daemon was already stopped\n    # 2 if daemon could not be stopped\n    # other if a failure occurred\n\n    cd $LDIR\n    su $USER -c \"carton exec hypnotoad -s $DAEMON >/dev/null 2>&1\"\n    return \"$?\"\n}\n\ndo_status()\n{\n    cd $LDIR\n    if [ -f \"script/hypnotoad.pid\" ]\n    then\n        pgrep -lf $DAEMON >/dev/null 2>&1\n        if [ \"$?\" = \"0\" ]; then\n            log_progress_msg \"$NAME is running\"\n        else\n            log_failure_msg \"$NAME is NOT running but PID file exists\"\n        fi\n    else\n        log_failure_msg \"$NAME is NOT running\"\n    fi\n}\n\ncase \"$1\" in\n    start)\n        log_daemon_msg \"Starting $NAME\"\n        cd $LDIR\n        if [ -f \"script/hypnotoad.pid\" ]\n        then\n             pgrep -lf $DAEMON >/dev/null 2>&1\n             if [ \"$?\" = \"0\" ]\n             then\n                 log_progress_msg \"$NAME is already running. Unable to start.\"\n                 log_end_msg 1;\n             else\n                 do_start\n                 case \"$?\" in\n                     0|1)\n                         log_progress_msg \"done\"\n                         log_end_msg 0\n                         ;;\n                     2)\n                         log_failure_msg \"failed\"\n                         log_end_msg 1\n                         ;;\n                 esac\n             fi\n        else\n            do_start\n            case \"$?\" in\n                0|1)\n                    log_progress_msg \"done\"\n                    log_end_msg 0\n                    ;;\n                2)\n                    log_failure_msg \"failed\"\n                    log_end_msg 1\n                    ;;\n            esac\n        fi\n        ;;\n    stop)\n        log_daemon_msg \"Stopping $NAME\"\n        cd $LDIR\n        if [ -f \"script/hypnotoad.pid\" ]\n        then\n            pgrep -lf $DAEMON >/dev/null 2>&1\n            if [ \"$?\" = \"0\" ]; then\n                do_stop\n                case \"$?\" in\n                    0|1)\n                        log_progress_msg \"done\"\n                        log_end_msg 0\n                        ;;\n                    *)\n                        log_failure_msg \"failed\"\n                        log_end_msg 1\n                        ;;\n                esac\n            else\n                log_failure_msg \"$NAME is NOT running. Unable to stop\"\n                log_end_msg 1\n            fi\n        else\n            log_failure_msg \"$NAME is NOT running. Unable to stop\"\n            log_end_msg 1\n        fi\n        ;;\n    status)\n        log_daemon_msg \"Checking $NAME status\"\n        do_status\n        log_end_msg 0\n        ;;\n    reload)\n        log_daemon_msg \"Reloading $NAME\"\n        do_start\n        sleep 1\n        case \"$?\" in\n            0|1)\n                log_progress_msg \"done\"\n                log_end_msg 0\n                ;;\n            2)\n                log_failure_msg \"failed\"\n                log_end_msg 1\n                ;;\n        esac\n        ;;\n    restart)\n        log_daemon_msg \"Restarting $NAME\"\n        do_stop\n        sleep 6\n        do_start\n        case \"$?\" in\n            0|1)\n                log_progress_msg \"done\"\n                log_end_msg 0\n                ;;\n            2)\n                log_failure_msg \"failed\";\n                log_end_msg 1\n                ;;\n        esac\n        ;;\n    *)\n        echo \"Usage: $0 {start|stop|status|reload|restart}\" >&2\n        exit 3\n        ;;\nesac\n\nexit 0\n"
  },
  {
    "path": "utilities/lstu.nginx",
    "content": "upstream lstu {\n    server 127.0.0.1:8442;\n}\n\nserver {\n    listen 80; \n    listen [::]:80;\n\n    server_name lstu.example.org;\n\n    access_log  /var/log/nginx/lstu.access.log;\n    error_log   /var/log/nginx/lstu.error.log;\n\n    location / {\n        proxy_http_version 1.1;\n        proxy_set_header Host $host;\n        proxy_set_header X-Real-IP $remote_addr;\n        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n        proxy_set_header X-Remote-Port $remote_port;\n        proxy_set_header X-Forwarded-Proto $scheme;\n\n        proxy_pass http://lstu;\n        proxy_redirect http://lstu https://lstu.example.org;\n    }\n}\n"
  },
  {
    "path": "utilities/lstu.service",
    "content": "[Unit]\nDescription=Shortened URLs service\nDocumentation=https://framagit.org/fiat-tux/hat-softwares/lstu\nRequires=network.target\nAfter=network.target\n\n[Service]\nType=forking\nUser=www-data\nRemainAfterExit=yes\nWorkingDirectory=/var/www/lstu/\nPIDFile=/var/www/lstu/script/hypnotoad.pid\nExecStart=/usr/local/bin/carton exec hypnotoad script/lstu\nExecStop=/usr/local/bin/carton exec hypnotoad -s script/lstu\nExecReload=/usr/local/bin/carton exec hypnotoad script/lstu\n\n[Install]\nWantedBy=multi-user.target\n"
  },
  {
    "path": "utilities/lstu_upstart.conf",
    "content": "# -*- upstart -*-\ndescription \"lstu\"\nauthor \"Luc Didry <luc@didry.org>\"\n\nstart on (networking)\nstop on runlevel [!2345]\n\nscript\n  if [ -f \"/etc/default/lstu\" ]\n  then\n    . /etc/default/lstu\n    if [ -z $LDIR ]\n    then\n      echo \"LDIR variable is empty, please fill it in /etc/default/lstu\"\n      exit 0\n    fi\n    if [ -z $USER ]\n    then\n      echo \"USER variable is empty, please fill it in /etc/default/lstu\"\n      exit 0\n    fi\n  else\n    echo \"Missing /etc/default/lstu file\"\n    exit 0\n  fi\n  cd $LDIR\n  su $USER -c \"carton exec hypnotoad -f script/lstu\"\nend script\n"
  },
  {
    "path": "utilities/migrations/mysql.sql",
    "content": "-- 1 up\nCREATE TABLE IF NOT EXISTS lstu (\n    short varchar(255) PRIMARY KEY,\n    url text,\n    counter integer default 0,\n    timestamp integer\n);\nCREATE TABLE IF NOT EXISTS sessions (\n    token varchar(255) PRIMARY KEY,\n    until integer\n);\nCREATE TABLE IF NOT EXISTS ban (\n    ip varbinary(16) PRIMARY KEY,\n    until integer,\n    strike integer\n);\n-- 1 down\nDROP TABLE ban;\nDROP TABLE sessions;\nDROP TABLE lstu;\n-- 2 up\nALTER TABLE lstu ADD created_by text;\n-- 2 down\nALTER TABLE lstu DROP COLUMN created_by;\n-- 3 up\nALTER TABLE lstu ADD disabled integer DEFAULT 0;\n-- 3 down\nALTER TABLE lstu DROP COLUMN disabled;\n-- 4 up\nALTER TABLE ban MODIFY ip varbinary(39);\n-- 4 down\nALTER TABLE ban MODIFY ip varbinary(16);\n"
  },
  {
    "path": "utilities/migrations/postgresql.sql",
    "content": "-- 1 up\nCREATE TABLE IF NOT EXISTS lstu (\n    short text PRIMARY KEY,\n    url text,\n    counter integer default 0,\n    timestamp integer\n);\nCREATE TABLE IF NOT EXISTS sessions (\n    token text PRIMARY KEY,\n    until integer\n);\nCREATE TABLE IF NOT EXISTS ban (\n    ip text PRIMARY KEY,\n    until integer,\n    strike integer\n);\n-- 1 down\nDROP TABLE ban;\nDROP TABLE sessions;\nDROP TABLE lstu;\n-- 2 up\nCREATE INDEX IF NOT EXISTS empty_short_idx ON lstu (short) WHERE url IS NULL;\n-- 2 down\nDROP INDEX empty_short_idx;\n-- 3 up\nALTER TABLE lstu ADD COLUMN created_by text;\n-- 3 down\nALTER TABLE lstu DROP COLUMN created_by;\n-- 4 up\nALTER TABLE lstu ADD disabled integer default 0;\n-- 4 down\nALTER TABLE lstu DROP COLUMN disabled;\n"
  },
  {
    "path": "utilities/migrations/sqlite.sql",
    "content": "-- 1 up\nCREATE TABLE IF NOT EXISTS lstu (\n    short     TEXT PRIMARY KEY,\n    url       TEXT,\n    counter   INTEGER,\n    timestamp INTEGER\n);\nCREATE TABLE IF NOT EXISTS sessions (\n    token TEXT PRIMARY KEY,\n    until INTEGER\n);\nCREATE TABLE IF NOT EXISTS ban (\n    ip     TEXT PRIMARY KEY,\n    until  INTEGER,\n    strike INTEGER\n);\nCREATE INDEX IF NOT EXISTS empty_short_idx ON lstu (short) WHERE url IS NULL;\n-- 1 down\nDROP TABLE lstu;\nDROP TABLE sessions;\nDROP TABLE ban;\nDROP INDEX empty_short_idx;\n-- 2 up\nALTER TABLE lstu ADD COLUMN created_by TEXT;\n-- 2 down\nBEGIN TRANSACTION;\n    CREATE TABLE lstu_backup(\n        short     TEXT PRIMARY KEY,\n        url       TEXT,\n        counter   INTEGER,\n        timestamp INTEGER\n    );\n    INSERT INTO lstu_backup SELECT short, url, counter, timestamp FROM lstu;\n    DROP TABLE lstu;\n    ALTER TABLE lstu_backup RENAME TO lstu;\nCOMMIT;\n-- 3 up\nALTER TABLE lstu ADD COLUMN disabled INTEGER default 0;\n-- 3 down\nBEGIN TRANSACTION;\n    CREATE TABLE lstu_backup(\n        short      TEXT PRIMARY KEY,\n        url        TEXT,\n        counter    INTEGER,\n        timestamp  INTEGER,\n        created_by TEXT\n    );\n    INSERT INTO lstu_backup SELECT short, url, counter, timestamp, created_by FROM lstu;\n    DROP TABLE lstu;\n    ALTER TABLE lstu_backup RENAME TO lstu;\nCOMMIT;\n"
  },
  {
    "path": "utilities/read_conf.pl",
    "content": "#!/usr/bin/env perl\n\n# read_conf.pl - Outputs lstu's config value for given keypath\n\nuse strict;\nuse warnings;\n\nuse FindBin;\nuse Cwd qw(realpath);\nuse Config::FromHash;\n\nsub print_help {\n    print <<END;\n  Usage:\n      $0 [-h] KEYPATH [DEFAULT] -- reads the lstu.conf file and outputs value at KEYPATH, or prints DEFAULT value\n\n  where:\n      -h                   prints this help message and exit\n      KEYPATH              refers to the path in the hash, slash-separated (ie. mysqldb/host)\n      DEFAULT              if keypath is undefined, return this value (ie. localhost)\nEND\n    return;\n}\n\nif (defined $ARGV[0] and $ARGV[0] eq \"-h\") {\n    print_help();\n    exit 0;\n}\n \nif (not defined $ARGV[0]) {\n    print_help();\n    exit 1;\n}\n\nmy $filename = realpath(\"$FindBin::Bin/../lstu.conf\");\nif (! -r $filename) {\n    print STDERR \"Error: unable to read config file \\\"$filename\\\"\\n\";\n    exit 1;\n}\n\nmy $config = Config::FromHash->new(filename => $filename);\nmy $value = $config->get($ARGV[0]);\n\nif (defined $value) {\n    print $value;\n    exit 0;\n}\nif (not defined $value and defined $ARGV[1]) {\n    print $ARGV[1];\n    exit 0;\n}\nprint STDERR \"Error: keypath \\\"$ARGV[0]\\\" not found in config, and no default value provided.\\n\";\nexit 1;"
  }
]