[
  {
    "path": "README.md",
    "content": "<a href=\"https://codingwithmitch.com/courses/build-a-rest-api/\"><img class='header-img' src='https://codingwithmitch.s3.amazonaws.com/static/build-a-rest-api-with-the-django-rest-framework/images/Django_REST-framework_Setup.png' /></a>\n<a href=\"https://codingwithmitch.com/courses/build-a-rest-api/\"><h1>Build a REST API</h1></a>\n\n<p>In this course you'll learn to build a REST API for a website so other technologies can interact with it.</p>\n<p>This course is a continuation of the <a href=\"https://codingwithmitch.com/courses/building-a-website-django-python/\" target=\"_blank\">\"Building a website with Django (Python)\"</a> course. Which is a free course where I show you how to build a website like  <a href=\"https://open-api.xyz\" target=\"_blank\" rel=\"nofollow\">open-api.xyz</a>.</p>\n<p><strong>What you'll learn:</strong></p>\n<ul>\n<li>How to build and customize a Rest API</li>\n<li>User authentication via Django \"TokenAuthentication\"</li>\n<li>Generating Auth Tokens from a mobile app</li>\n<li>\nCRUD functionality on a live website:<br>\n<ol>\n<li>Create blog posts</li>\n<li>Retrieve blog posts</li>\n<li>Update blog posts</li>\n<li>Delete blog posts</li>\n</ol>\n</li>\n<li>Pagination (very important for mobile apps)</li>\n<li>Serialization of data</li>\n<li>JSON</li>\n</ul>\n\n"
  },
  {
    "path": "src/account/__init__.py",
    "content": ""
  },
  {
    "path": "src/account/admin.py",
    "content": "from django.contrib import admin\nfrom django.contrib.auth.admin import UserAdmin\nfrom account.models import Account\n\n\nclass AccountAdmin(UserAdmin):\n\tlist_display = ('pk', 'email','username','date_joined', 'last_login', 'is_admin','is_staff')\n\tsearch_fields = ('pk', 'email','username',)\n\treadonly_fields=('pk', 'date_joined', 'last_login')\n\n\tfilter_horizontal = ()\n\tlist_filter = ()\n\tfieldsets = ()\n\n\nadmin.site.register(Account, AccountAdmin)\n\n\n\n"
  },
  {
    "path": "src/account/api/__init__.py",
    "content": ""
  },
  {
    "path": "src/account/api/serializers.py",
    "content": "from rest_framework import serializers\n\nfrom account.models import Account\n\n\nclass RegistrationSerializer(serializers.ModelSerializer):\n\n\tpassword2 \t\t\t\t= serializers.CharField(style={'input_type': 'password'}, write_only=True)\n\n\tclass Meta:\n\t\tmodel = Account\n\t\tfields = ['email', 'username', 'password', 'password2']\n\t\textra_kwargs = {\n\t\t\t\t'password': {'write_only': True},\n\t\t}\t\n\n\n\tdef\tsave(self):\n\n\t\taccount = Account(\n\t\t\t\t\temail=self.validated_data['email'],\n\t\t\t\t\tusername=self.validated_data['username']\n\t\t\t\t)\n\t\tpassword = self.validated_data['password']\n\t\tpassword2 = self.validated_data['password2']\n\t\tif password != password2:\n\t\t\traise serializers.ValidationError({'password': 'Passwords must match.'})\n\t\taccount.set_password(password)\n\t\taccount.save()\n\t\treturn account\n\n\nclass AccountPropertiesSerializer(serializers.ModelSerializer):\n\n\tclass Meta:\n\t\tmodel = Account\n\t\tfields = ['pk', 'email', 'username', ]\n\n\n\n\nclass ChangePasswordSerializer(serializers.Serializer):\n\n\told_password \t\t\t\t= serializers.CharField(required=True)\n\tnew_password \t\t\t\t= serializers.CharField(required=True)\n\tconfirm_new_password \t\t= serializers.CharField(required=True)\n\n\n\n\n\n"
  },
  {
    "path": "src/account/api/urls.py",
    "content": "from django.urls import path\nfrom account.api.views import(\n\tregistration_view,\n\tObtainAuthTokenView,\n\taccount_properties_view,\n\tupdate_account_view,\n\tdoes_account_exist_view,\n\tChangePasswordView,\n)\nfrom rest_framework.authtoken.views import obtain_auth_token\n\napp_name = 'account'\n\nurlpatterns = [\n\tpath('check_if_account_exists/', does_account_exist_view, name=\"check_if_account_exists\"),\n\tpath('change_password/', ChangePasswordView.as_view(), name=\"change_password\"),\n\tpath('properties', account_properties_view, name=\"properties\"),\n\tpath('properties/update', update_account_view, name=\"update\"),\n \tpath('login', ObtainAuthTokenView.as_view(), name=\"login\"), \n\tpath('register', registration_view, name=\"register\"),\n\n]"
  },
  {
    "path": "src/account/api/views.py",
    "content": "from rest_framework import status\nfrom rest_framework.response import Response\nfrom rest_framework.decorators import api_view, permission_classes\nfrom rest_framework.permissions import IsAuthenticated\nfrom rest_framework.views import APIView\nfrom rest_framework.generics import UpdateAPIView\nfrom django.contrib.auth import authenticate\nfrom rest_framework.authentication import TokenAuthentication\nfrom rest_framework.decorators import api_view, authentication_classes, permission_classes\n\nfrom account.api.serializers import RegistrationSerializer, AccountPropertiesSerializer, ChangePasswordSerializer\nfrom account.models import Account\nfrom rest_framework.authtoken.models import Token\n\n# Register\n# Response: https://gist.github.com/mitchtabian/c13c41fa0f51b304d7638b7bac7cb694\n# Url: https://<your-domain>/api/account/register\n@api_view(['POST', ])\n@permission_classes([])\n@authentication_classes([])\ndef registration_view(request):\n\n\tif request.method == 'POST':\n\t\tdata = {}\n\t\temail = request.data.get('email', '0').lower()\n\t\tif validate_email(email) != None:\n\t\t\tdata['error_message'] = 'That email is already in use.'\n\t\t\tdata['response'] = 'Error'\n\t\t\treturn Response(data)\n\n\t\tusername = request.data.get('username', '0')\n\t\tif validate_username(username) != None:\n\t\t\tdata['error_message'] = 'That username is already in use.'\n\t\t\tdata['response'] = 'Error'\n\t\t\treturn Response(data)\n\n\t\tserializer = RegistrationSerializer(data=request.data)\n\t\t\n\t\tif serializer.is_valid():\n\t\t\taccount = serializer.save()\n\t\t\tdata['response'] = 'successfully registered new user.'\n\t\t\tdata['email'] = account.email\n\t\t\tdata['username'] = account.username\n\t\t\tdata['pk'] = account.pk\n\t\t\ttoken = Token.objects.get(user=account).key\n\t\t\tdata['token'] = token\n\t\telse:\n\t\t\tdata = serializer.errors\n\t\treturn Response(data)\n\ndef validate_email(email):\n\taccount = None\n\ttry:\n\t\taccount = Account.objects.get(email=email)\n\texcept Account.DoesNotExist:\n\t\treturn None\n\tif account != None:\n\t\treturn email\n\ndef validate_username(username):\n\taccount = None\n\ttry:\n\t\taccount = Account.objects.get(username=username)\n\texcept Account.DoesNotExist:\n\t\treturn None\n\tif account != None:\n\t\treturn username\n\n\n# Account properties\n# Response: https://gist.github.com/mitchtabian/4adaaaabc767df73c5001a44b4828ca5\n# Url: https://<your-domain>/api/account/\n# Headers: Authorization: Token <token>\n@api_view(['GET', ])\n@permission_classes((IsAuthenticated, ))\ndef account_properties_view(request):\n\n\ttry:\n\t\taccount = request.user\n\texcept Account.DoesNotExist:\n\t\treturn Response(status=status.HTTP_404_NOT_FOUND)\n\n\tif request.method == 'GET':\n\t\tserializer = AccountPropertiesSerializer(account)\n\t\treturn Response(serializer.data)\n\n\n# Account update properties\n# Response: https://gist.github.com/mitchtabian/72bb4c4811199b1d303eb2d71ec932b2\n# Url: https://<your-domain>/api/account/properties/update\n# Headers: Authorization: Token <token>\n@api_view(['PUT',])\n@permission_classes((IsAuthenticated, ))\ndef update_account_view(request):\n\n\ttry:\n\t\taccount = request.user\n\texcept Account.DoesNotExist:\n\t\treturn Response(status=status.HTTP_404_NOT_FOUND)\n\t\t\n\tif request.method == 'PUT':\n\t\tserializer = AccountPropertiesSerializer(account, data=request.data)\n\t\tdata = {}\n\t\tif serializer.is_valid():\n\t\t\tserializer.save()\n\t\t\tdata['response'] = 'Account update success'\n\t\t\treturn Response(data=data)\n\t\treturn Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)\n\n\n\n# LOGIN\n# Response: https://gist.github.com/mitchtabian/8e1bde81b3be342853ddfcc45ec0df8a\n# URL: http://127.0.0.1:8000/api/account/login\nclass ObtainAuthTokenView(APIView):\n\n\tauthentication_classes = []\n\tpermission_classes = []\n\n\tdef post(self, request):\n\t\tcontext = {}\n\n\t\temail = request.POST.get('username')\n\t\tpassword = request.POST.get('password')\n\t\taccount = authenticate(email=email, password=password)\n\t\tif account:\n\t\t\ttry:\n\t\t\t\ttoken = Token.objects.get(user=account)\n\t\t\texcept Token.DoesNotExist:\n\t\t\t\ttoken = Token.objects.create(user=account)\n\t\t\tcontext['response'] = 'Successfully authenticated.'\n\t\t\tcontext['pk'] = account.pk\n\t\t\tcontext['email'] = email.lower()\n\t\t\tcontext['token'] = token.key\n\t\telse:\n\t\t\tcontext['response'] = 'Error'\n\t\t\tcontext['error_message'] = 'Invalid credentials'\n\n\t\treturn Response(context)\n\n\n\n\n@api_view(['GET', ])\n@permission_classes([])\n@authentication_classes([])\ndef does_account_exist_view(request):\n\n\tif request.method == 'GET':\n\t\temail = request.GET['email'].lower()\n\t\tdata = {}\n\t\ttry:\n\t\t\taccount = Account.objects.get(email=email)\n\t\t\tdata['response'] = email\n\t\texcept Account.DoesNotExist:\n\t\t\tdata['response'] = \"Account does not exist\"\n\t\treturn Response(data)\n\n\n\nclass ChangePasswordView(UpdateAPIView):\n\n\tserializer_class = ChangePasswordSerializer\n\tmodel = Account\n\tpermission_classes = (IsAuthenticated,)\n\tauthentication_classes = (TokenAuthentication,)\n\n\tdef get_object(self, queryset=None):\n\t\tobj = self.request.user\n\t\treturn obj\n\n\tdef update(self, request, *args, **kwargs):\n\t\tself.object = self.get_object()\n\t\tserializer = self.get_serializer(data=request.data)\n\n\t\tif serializer.is_valid():\n\t\t\t# Check old password\n\t\t\tif not self.object.check_password(serializer.data.get(\"old_password\")):\n\t\t\t\treturn Response({\"old_password\": [\"Wrong password.\"]}, status=status.HTTP_400_BAD_REQUEST)\n\n\t\t\t# confirm the new passwords match\n\t\t\tnew_password = serializer.data.get(\"new_password\")\n\t\t\tconfirm_new_password = serializer.data.get(\"confirm_new_password\")\n\t\t\tif new_password != confirm_new_password:\n\t\t\t\treturn Response({\"new_password\": [\"New passwords must match\"]}, status=status.HTTP_400_BAD_REQUEST)\n\n\t\t\t# set_password also hashes the password that the user will get\n\t\t\tself.object.set_password(serializer.data.get(\"new_password\"))\n\t\t\tself.object.save()\n\t\t\treturn Response({\"response\":\"successfully changed password\"}, status=status.HTTP_200_OK)\n\n\t\treturn Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
  },
  {
    "path": "src/account/apps.py",
    "content": "from django.apps import AppConfig\n\n\nclass AccountConfig(AppConfig):\n    name = 'account'\n"
  },
  {
    "path": "src/account/backends.py",
    "content": "from django.contrib.auth import get_user_model\nfrom django.contrib.auth.backends import ModelBackend\n\n\nclass CaseInsensitiveModelBackend(ModelBackend):\n    def authenticate(self, request, username=None, password=None, **kwargs):\n        UserModel = get_user_model()\n        if username is None:\n            username = kwargs.get(UserModel.USERNAME_FIELD)\n        try:\n            case_insensitive_username_field = '{}__iexact'.format(UserModel.USERNAME_FIELD)\n            user = UserModel._default_manager.get(**{case_insensitive_username_field: username})\n        except UserModel.DoesNotExist:\n            # Run the default password hasher once to reduce the timing\n            # difference between an existing and a non-existing user (#20760).\n            UserModel().set_password(password)\n        else:\n            if user.check_password(password) and self.user_can_authenticate(user):\n                return user\n\n\n"
  },
  {
    "path": "src/account/forms.py",
    "content": "from django import forms\nfrom django.contrib.auth.forms import UserCreationForm\nfrom django.contrib.auth import authenticate\n\nfrom account.models import Account\n\n\nclass RegistrationForm(UserCreationForm):\n\temail = forms.EmailField(max_length=254, help_text='Required. Add a valid email address.')\n\n\tclass Meta:\n\t\tmodel = Account\n\t\tfields = ('email', 'username', 'password1', 'password2', )\n\n\tdef clean_email(self):\n\t\temail = self.cleaned_data['email'].lower()\n\t\ttry:\n\t\t\taccount = Account.objects.exclude(pk=self.instance.pk).get(email=email)\n\t\texcept Account.DoesNotExist:\n\t\t\treturn email\n\t\traise forms.ValidationError('Email \"%s\" is already in use.' % account)\n\n\tdef clean_username(self):\n\t\tusername = self.cleaned_data['username']\n\t\ttry:\n\t\t\taccount = Account.objects.exclude(pk=self.instance.pk).get(username=username)\n\t\texcept Account.DoesNotExist:\n\t\t\treturn username\n\t\traise forms.ValidationError('Username \"%s\" is already in use.' % username)\n\n\nclass AccountAuthenticationForm(forms.ModelForm):\n\n\tpassword = forms.CharField(label='Password', widget=forms.PasswordInput)\n\n\tclass Meta:\n\t\tmodel = Account\n\t\tfields = ('email', 'password')\n\n\tdef clean(self):\n\t\tif self.is_valid():\n\t\t\temail = self.cleaned_data['email']\n\t\t\tpassword = self.cleaned_data['password']\n\t\t\tif not authenticate(email=email, password=password):\n\t\t\t\traise forms.ValidationError(\"Invalid login\")\n\n\nclass AccountUpdateForm(forms.ModelForm):\n\n\tclass Meta:\n\t\tmodel = Account\n\t\tfields = ('email', 'username', )\n\n\tdef clean_email(self):\n\t\temail = self.cleaned_data['email'].lower()\n\t\ttry:\n\t\t\taccount = Account.objects.exclude(pk=self.instance.pk).get(email=email)\n\t\texcept Account.DoesNotExist:\n\t\t\treturn email\n\t\traise forms.ValidationError('Email \"%s\" is already in use.' % account)\n\n\tdef clean_username(self):\n\t\tusername = self.cleaned_data['username']\n\t\ttry:\n\t\t\taccount = Account.objects.exclude(pk=self.instance.pk).get(username=username)\n\t\texcept Account.DoesNotExist:\n\t\t\treturn username\n\t\traise forms.ValidationError('Username \"%s\" is already in use.' % username)\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
  },
  {
    "path": "src/account/migrations/0001_initial.py",
    "content": "# Generated by Django 2.2.2 on 2019-06-24 20:53\n\nfrom django.db import migrations, models\n\n\nclass Migration(migrations.Migration):\n\n    initial = True\n\n    dependencies = [\n    ]\n\n    operations = [\n        migrations.CreateModel(\n            name='Account',\n            fields=[\n                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),\n                ('password', models.CharField(max_length=128, verbose_name='password')),\n                ('email', models.EmailField(max_length=60, unique=True, verbose_name='email')),\n                ('username', models.CharField(max_length=30, unique=True)),\n                ('date_joined', models.DateTimeField(auto_now_add=True, verbose_name='date joined')),\n                ('last_login', models.DateTimeField(auto_now=True, verbose_name='last login')),\n                ('is_admin', models.BooleanField(default=False)),\n                ('is_active', models.BooleanField(default=True)),\n                ('is_staff', models.BooleanField(default=False)),\n                ('is_superuser', models.BooleanField(default=False)),\n            ],\n            options={\n                'abstract': False,\n            },\n        ),\n    ]\n"
  },
  {
    "path": "src/account/migrations/__init__.py",
    "content": ""
  },
  {
    "path": "src/account/models.py",
    "content": "from django.db import models\nfrom django.contrib.auth.models import AbstractBaseUser, BaseUserManager\n\nfrom django.conf import settings\nfrom django.db.models.signals import post_save\nfrom django.dispatch import receiver\nfrom rest_framework.authtoken.models import Token\n\n\nclass MyAccountManager(BaseUserManager):\n\tdef create_user(self, email, username, password=None):\n\t\tif not email:\n\t\t\traise ValueError('Users must have an email address')\n\t\tif not username:\n\t\t\traise ValueError('Users must have a username')\n\n\t\tuser = self.model(\n\t\t\temail=self.normalize_email(email),\n\t\t\tusername=username,\n\t\t)\n\n\t\tuser.set_password(password)\n\t\tuser.save(using=self._db)\n\t\treturn user\n\n\tdef create_superuser(self, email, username, password):\n\t\tuser = self.create_user(\n\t\t\temail=self.normalize_email(email),\n\t\t\tpassword=password,\n\t\t\tusername=username,\n\t\t)\n\t\tuser.is_admin = True\n\t\tuser.is_staff = True\n\t\tuser.is_superuser = True\n\t\tuser.save(using=self._db)\n\t\treturn user\n\n\nclass Account(AbstractBaseUser):\n\temail \t\t\t\t\t= models.EmailField(verbose_name=\"email\", max_length=60, unique=True)\n\tusername \t\t\t\t= models.CharField(max_length=30, unique=True)\n\tdate_joined\t\t\t\t= models.DateTimeField(verbose_name='date joined', auto_now_add=True)\n\tlast_login\t\t\t\t= models.DateTimeField(verbose_name='last login', auto_now=True)\n\tis_admin\t\t\t\t= models.BooleanField(default=False)\n\tis_active\t\t\t\t= models.BooleanField(default=True)\n\tis_staff\t\t\t\t= models.BooleanField(default=False)\n\tis_superuser\t\t\t= models.BooleanField(default=False)\n\n\n\tUSERNAME_FIELD = 'email'\n\tREQUIRED_FIELDS = ['username']\n\n\tobjects = MyAccountManager()\n\n\tdef __str__(self):\n\t\treturn self.email\n\n\t# For checking permissions. to keep it simple all admin have ALL permissons\n\tdef has_perm(self, perm, obj=None):\n\t\treturn self.is_admin\n\n\t# Does this user have permission to view this app? (ALWAYS YES FOR SIMPLICITY)\n\tdef has_module_perms(self, app_label):\n\t\treturn True\n\n\n@receiver(post_save, sender=settings.AUTH_USER_MODEL)\ndef create_auth_token(sender, instance=None, created=False, **kwargs):\n    if created:\n        Token.objects.create(user=instance)\n\n\n\n\n\n\n\n\n\n\n\n\n"
  },
  {
    "path": "src/account/templates/account/account.html",
    "content": "{% extends 'base.html' %}\n\n\n{% block content %}\n\n<style type=\"text/css\">\n  .form-signin {\n  width: 100%;\n  max-width: 330px;\n  padding: 15px;\n  margin: auto;\n  }\n\n  .form-signin .form-control {\n    position: relative;\n    box-sizing: border-box;\n    height: auto;\n    padding: 10px;\n    font-size: 16px;\n  }\n  .form-signin .form-control:focus {\n    z-index: 2;\n  }\n  .form-signin input[type=\"email\"] {\n    margin-bottom: 10px;\n    border-bottom-right-radius: 0;\n    border-bottom-left-radius: 0;\n  }\n  .form-signin input[type=\"username\"] {\n    margin-bottom: 10px;\n    border-top-left-radius: 0;\n    border-top-right-radius: 0;\n  }\n  .h3{\n    text-align: center;\n  }\n  .blog-posts{\n    max-width: 500px;\n    width:100%;\n    margin: auto;\n  }\n</style>\n\n\n<form class=\"form-signin\" method=\"post\">{% csrf_token %}\n\n  <h1 class=\"h3 mb-3 font-weight-normal\">Account</h1>\n\n  <input type=\"email\" name=\"email\" id=\"inputEmail\" class=\"form-control\" placeholder=\"Email address\" required autofocus value={{account_form.initial.email}}>\n  \n  <input type=\"text\" name=\"username\" id=\"inputUsername\" class=\"form-control\" placeholder=\"Username\" required\n  value=\"{{account_form.initial.username}}\">\n\n  {% for field in account_form %}\n      <p>\n        {% for error in field.errors %}\n          <p style=\"color: red\">{{ error }}</p>\n        {% endfor %}\n      </p>\n  {% endfor %}\n  {% if account_form.non_field_errors %}\n    <div style=\"color: red\">\n      <p>{{account_form.non_field_errors}}</p>\n    </div>\n      \n  {% endif %}\n\n  {% if success_message %}\n    <p style=\"color:green; text-align: center;\">{{success_message}}</p>\n  {% endif  %}\n\n  <button class=\"btn btn-lg btn-primary btn-block\" type=\"submit\">Save changes</button>\n\n</form>\n\n<div class=\"d-flex flex-column\">\n  <a class=\"m-auto\" href=\"{% url 'password_change' %}\">Change password</a>\n</div>\n\n\n<div class=\"container mt-4 p-4\">\n  <div class=\"row\">\n    <div class=\"blog-posts\">\n      <h3 class=\"mb-3 font-weight-normal\">Blog posts:</h3>\n      {% if blog_posts %}\n      <ul>\n        {% for post in blog_posts %}\n          <a href=\"{% url 'blog:detail' post.slug %}\" style=\"text-decoration: none;\">\n            <li class=\"list-group-item\">{{post}}</li>\n          </a>\n        {% endfor %}\n      </ul>\n      {% else %}\n        <p>You have no blog posts. Create a post <a href=\"{% url 'blog:create' %}\">here</a>.</p>\n      {% endif %}\n\n    </div>\n  </div>\n</div>\n\n\n{% endblock content %}\n\n\n"
  },
  {
    "path": "src/account/templates/account/login.html",
    "content": "{% extends 'base.html' %}\n{% load static %}\n\n{% block content %}\n\n<style type=\"text/css\">\n  .form-signin {\n  width: 100%;\n  max-width: 330px;\n  padding: 15px;\n  margin: auto;\n  }\n\n  .form-signin .form-control {\n    position: relative;\n    box-sizing: border-box;\n    height: auto;\n    padding: 10px;\n    font-size: 16px;\n  }\n  .form-signin .form-control:focus {\n    z-index: 2;\n  }\n  .form-signin input[type=\"email\"] {\n    margin-bottom: -1px;\n    border-bottom-right-radius: 0;\n    border-bottom-left-radius: 0;\n  }\n  .form-signin input[type=\"password\"] {\n    margin-bottom: 10px;\n    border-top-left-radius: 0;\n    border-top-right-radius: 0;\n  }\n  .h3{\n    text-align: center;\n  }\n</style>\n\n\n<form class=\"form-signin\" method=\"post\">{% csrf_token %}\n<div class=\"d-flex flex-column pb-3\">\n  <img class=\"img-fluid mx-auto d-block\" src=\"{% static 'codingwithmitch_logo.png' %}\" alt=\"codingwithmitch logo\" width=\"72\" height=\"72\">\n</div>\n  <h1 class=\"h3 mb-3 font-weight-normal\">Login</h1>\n\n  <input type=\"email\" name=\"email\" id=\"inputEmail\" class=\"form-control\" placeholder=\"Email address\" required autofocus>\n  \n  <input type=\"password\" name=\"password\" id=\"inputPassword\" class=\"form-control\" placeholder=\"Password\" required>\n\n  {% for field in login_form %}\n      <p>\n        {% for error in field.errors %}\n          <p style=\"color: red\">{{ error }}</p>\n        {% endfor %}\n      </p>\n  {% endfor %}\n  {% if login_form.non_field_errors %}\n    <div style=\"color: red\">\n      <p>{{login_form.non_field_errors}}</p>\n    </div>\n      \n  {% endif %}\n\n  <button class=\"btn btn-lg btn-primary btn-block\" type=\"submit\">Log in</button>\n\n</form>\n\n<div class=\"d-flex flex-column\">\n  <a class=\"m-auto\" href=\"{% url 'password_reset' %}\">Reset password</a>\n</div>\n\n\n\n{% endblock content %}\n\n\n"
  },
  {
    "path": "src/account/templates/account/must_authenticate.html",
    "content": "{% extends 'base.html' %}\n\n\n{% block content %}\n\n<div class=\"container\">\n\t<div class=\"d-flex flex-column\">\n\t\t<p class=\"m-auto\">Must authenticate to view this page.</p>\n\t\t<p class=\"m-auto\">\n\t\t\t<a href=\"{% url 'register' %}\">Register</a> or\n\t\t\t<a href=\"{% url 'login' %}\">Login</a>\n\t\t</p>\n\t</div>\n</div>\n\n\n{% endblock content %}"
  },
  {
    "path": "src/account/templates/account/register.html",
    "content": "{% extends 'base.html' %}\n{% load static %}\n\n{% block content %}\n\n\n<style type=\"text/css\">\n  .form-signin {\n  width: 100%;\n  max-width: 330px;\n  padding: 15px;\n  margin: auto;\n  }\n\n  .form-signin .form-control {\n    position: relative;\n    box-sizing: border-box;\n    height: auto;\n    padding: 10px;\n    font-size: 16px;\n  }\n  .form-signin .form-control:focus {\n    z-index: 2;\n  }\n  .form-signin input[type=\"email\"] {\n    margin-bottom: 10px;\n    border-bottom-right-radius: 0;\n    border-bottom-left-radius: 0;\n  }\n  .form-signin input[type=\"text\"] {\n    margin-bottom: 10px;\n    border-bottom-right-radius: 0;\n    border-bottom-left-radius: 0;\n  }\n  .form-signin input[type=\"password\"] {\n    margin-bottom: -1px;\n    border-top-left-radius: 0;\n    border-top-right-radius: 0;\n  }\n\n  .h3{\n    text-align: center;\n  }\n\n</style>\n\n\n<form class=\"form-signin\" method=\"post\">{% csrf_token %}\n<div class=\"d-flex flex-column pb-3\">\n  <img class=\"img-fluid mx-auto d-block\" src=\"{% static 'codingwithmitch_logo.png' %}\" alt=\"codingwithmitch logo\" width=\"72\" height=\"72\">\n</div>\n  <h1 class=\"h3 mb-3 font-weight-normal\">Register an account</h1>\n\n  <input type=\"email\" name=\"email\" id=\"inputEmail\" class=\"form-control\" placeholder=\"Email address\" required autofocus>\n\n  <input type=\"text\" name=\"username\" id=\"inputUsername\" class=\"form-control\" placeholder=\"Username\" required>\n  \n  <input type=\"password\" name=\"password1\" id=\"inputPassword1\" class=\"form-control\" placeholder=\"Password\" required>\n\n  <input type=\"password\" name=\"password2\" id=\"inputPassword2\" class=\"form-control\" placeholder=\"Confirm password\" required>\n\n  {% for field in registration_form %}\n      <p>\n        {% for error in field.errors %}\n          <p style=\"color: red\">{{ error }}</p>\n        {% endfor %}\n      </p>\n  {% endfor %}\n  {% if registration_form.non_field_errors %}\n    <div style=\"color: red\">\n      <p>{{registration_form.non_field_errors}}</p>\n    </div>\n      \n  {% endif %}\n\n  <button class=\"btn btn-lg btn-primary btn-block\" type=\"submit\">Register</button>\n\n</form>\n\n\n{% endblock content %}\n\n\n\n"
  },
  {
    "path": "src/account/tests.py",
    "content": "from django.test import TestCase\n\n# Create your tests here.\n"
  },
  {
    "path": "src/account/views.py",
    "content": "from django.shortcuts import render, redirect\nfrom django.contrib.auth import login, authenticate, logout\nfrom account.forms import RegistrationForm, AccountAuthenticationForm, AccountUpdateForm\n\nfrom blog.models import BlogPost\n\ndef registration_view(request):\n\tcontext = {}\n\tif request.POST:\n\t\tform = RegistrationForm(request.POST)\n\t\tif form.is_valid():\n\t\t\tform.save()\n\t\t\temail = form.cleaned_data.get('email').lower()\n\t\t\traw_password = form.cleaned_data.get('password1')\n\t\t\taccount = authenticate(email=email, password=raw_password)\n\t\t\tlogin(request, account)\n\t\t\treturn redirect('home')\n\t\telse:\n\t\t\tcontext['registration_form'] = form\n\n\telse:\n\t\tform = RegistrationForm()\n\t\tcontext['registration_form'] = form\n\treturn render(request, 'account/register.html', context)\n\n\ndef logout_view(request):\n\tlogout(request)\n\treturn redirect('/')\n\n\ndef login_view(request):\n\n\tcontext = {}\n\n\tuser = request.user\n\tif user.is_authenticated: \n\t\treturn redirect(\"home\")\n\n\tif request.POST:\n\t\tform = AccountAuthenticationForm(request.POST)\n\t\tif form.is_valid():\n\t\t\temail = request.POST['email']\n\t\t\tpassword = request.POST['password']\n\t\t\tuser = authenticate(email=email, password=password)\n\n\t\t\tif user:\n\t\t\t\tlogin(request, user)\n\t\t\t\treturn redirect(\"home\")\n\n\telse:\n\t\tform = AccountAuthenticationForm()\n\n\tcontext['login_form'] = form\n\n\t# print(form)\n\treturn render(request, \"account/login.html\", context)\n\n\ndef account_view(request):\n\n\tif not request.user.is_authenticated:\n\t\t\treturn redirect(\"login\")\n\n\tcontext = {}\n\tif request.POST:\n\t\tform = AccountUpdateForm(request.POST, instance=request.user)\n\t\tif form.is_valid():\n\t\t\tform.initial = {\n\t\t\t\t\t\"email\": request.POST['email'],\n\t\t\t\t\t\"username\": request.POST['username'],\n\t\t\t}\n\t\t\tform.save()\n\t\t\tcontext['success_message'] = \"Updated\"\n\telse:\n\t\tform = AccountUpdateForm(\n\n\t\t\tinitial={\n\t\t\t\t\t\"email\": request.user.email, \n\t\t\t\t\t\"username\": request.user.username,\n\t\t\t\t}\n\t\t\t)\n\n\tcontext['account_form'] = form\n\n\tblog_posts = BlogPost.objects.filter(author=request.user)\n\tcontext['blog_posts'] = blog_posts\n\n\treturn render(request, \"account/account.html\", context)\n\n\ndef must_authenticate_view(request):\n\treturn render(request, 'account/must_authenticate.html', {})\n\n\n"
  },
  {
    "path": "src/blog/__init__.py",
    "content": ""
  },
  {
    "path": "src/blog/admin.py",
    "content": "from django.contrib import admin\n\nfrom blog.models import BlogPost\n\nadmin.site.register(BlogPost)\n"
  },
  {
    "path": "src/blog/api/__init__.py",
    "content": ""
  },
  {
    "path": "src/blog/api/serializers.py",
    "content": "from rest_framework import serializers\nfrom blog.models import BlogPost\n\nimport os\nfrom django.conf import settings\nfrom django.core.files.storage import default_storage\nfrom django.core.files.storage import FileSystemStorage\nIMAGE_SIZE_MAX_BYTES = 1024 * 1024 * 2 # 2MB\nMIN_TITLE_LENGTH = 5\nMIN_BODY_LENGTH = 50\n\nfrom blog.utils import is_image_aspect_ratio_valid, is_image_size_valid\n\n\nclass BlogPostSerializer(serializers.ModelSerializer):\n\n\tusername = serializers.SerializerMethodField('get_username_from_author')\n\timage \t = serializers.SerializerMethodField('validate_image_url')\n\n\tclass Meta:\n\t\tmodel = BlogPost\n\t\tfields = ['pk', 'title', 'slug', 'body', 'image', 'date_updated', 'username']\n\n\n\tdef get_username_from_author(self, blog_post):\n\t\tusername = blog_post.author.username\n\t\treturn username\n\n\tdef validate_image_url(self, blog_post):\n\t\timage = blog_post.image\n\t\tnew_url = image.url\n\t\tif \"?\" in new_url:\n\t\t\tnew_url = image.url[:image.url.rfind(\"?\")]\n\t\treturn new_url\n\n\n\n\nclass BlogPostUpdateSerializer(serializers.ModelSerializer):\n\n\tclass Meta:\n\t\tmodel = BlogPost\n\t\tfields = ['title', 'body', 'image']\n\n\tdef validate(self, blog_post):\n\t\ttry:\n\t\t\ttitle = blog_post['title']\n\t\t\tif len(title) < MIN_TITLE_LENGTH:\n\t\t\t\traise serializers.ValidationError({\"response\": \"Enter a title longer than \" + str(MIN_TITLE_LENGTH) + \" characters.\"})\n\t\t\t\n\t\t\tbody = blog_post['body']\n\t\t\tif len(body) < MIN_BODY_LENGTH:\n\t\t\t\traise serializers.ValidationError({\"response\": \"Enter a body longer than \" + str(MIN_BODY_LENGTH) + \" characters.\"})\n\t\t\t\n\t\t\timage = blog_post['image']\n\t\t\turl = os.path.join(settings.TEMP , str(image))\n\t\t\tstorage = FileSystemStorage(location=url)\n\n\t\t\twith storage.open('', 'wb+') as destination:\n\t\t\t\tfor chunk in image.chunks():\n\t\t\t\t\tdestination.write(chunk)\n\t\t\t\tdestination.close()\n\n\t\t\t# Check image size\n\t\t\tif not is_image_size_valid(url, IMAGE_SIZE_MAX_BYTES):\n\t\t\t\tos.remove(url)\n\t\t\t\traise serializers.ValidationError({\"response\": \"That image is too large. Images must be less than 2 MB. Try a different image.\"})\n\n\t\t\t# Check image aspect ratio\n\t\t\tif not is_image_aspect_ratio_valid(url):\n\t\t\t\tos.remove(url)\n\t\t\t\traise serializers.ValidationError({\"response\": \"Image height must not exceed image width. Try a different image.\"})\n\n\t\t\tos.remove(url)\n\t\texcept KeyError:\n\t\t\tpass\n\t\treturn blog_post\n\n\nclass BlogPostCreateSerializer(serializers.ModelSerializer):\n\n\n\tclass Meta:\n\t\tmodel = BlogPost\n\t\tfields = ['title', 'body', 'image', 'date_updated', 'author']\n\n\n\tdef save(self):\n\t\t\n\t\ttry:\n\t\t\timage = self.validated_data['image']\n\t\t\ttitle = self.validated_data['title']\n\t\t\tif len(title) < MIN_TITLE_LENGTH:\n\t\t\t\traise serializers.ValidationError({\"response\": \"Enter a title longer than \" + str(MIN_TITLE_LENGTH) + \" characters.\"})\n\t\t\t\n\t\t\tbody = self.validated_data['body']\n\t\t\tif len(body) < MIN_BODY_LENGTH:\n\t\t\t\traise serializers.ValidationError({\"response\": \"Enter a body longer than \" + str(MIN_BODY_LENGTH) + \" characters.\"})\n\t\t\t\n\t\t\tblog_post = BlogPost(\n\t\t\t\t\t\t\t\tauthor=self.validated_data['author'],\n\t\t\t\t\t\t\t\ttitle=title,\n\t\t\t\t\t\t\t\tbody=body,\n\t\t\t\t\t\t\t\timage=image,\n\t\t\t\t\t\t\t\t)\n\n\t\t\turl = os.path.join(settings.TEMP , str(image))\n\t\t\tstorage = FileSystemStorage(location=url)\n\n\t\t\twith storage.open('', 'wb+') as destination:\n\t\t\t\tfor chunk in image.chunks():\n\t\t\t\t\tdestination.write(chunk)\n\t\t\t\tdestination.close()\n\n\t\t\t# Check image size\n\t\t\tif not is_image_size_valid(url, IMAGE_SIZE_MAX_BYTES):\n\t\t\t\tos.remove(url)\n\t\t\t\traise serializers.ValidationError({\"response\": \"That image is too large. Images must be less than 2 MB. Try a different image.\"})\n\n\t\t\t# Check image aspect ratio\n\t\t\tif not is_image_aspect_ratio_valid(url):\n\t\t\t\tos.remove(url)\n\t\t\t\traise serializers.ValidationError({\"response\": \"Image height must not exceed image width. Try a different image.\"})\n\n\t\t\tos.remove(url)\n\t\t\tblog_post.save()\n\t\t\treturn blog_post\n\t\texcept KeyError:\n\t\t\traise serializers.ValidationError({\"response\": \"You must have a title, some content, and an image.\"})\n\n\n\n\n\n\n\n\n\n"
  },
  {
    "path": "src/blog/api/urls.py",
    "content": "from django.urls import path\nfrom blog.api.views import(\n\tapi_detail_blog_view,\n\tapi_update_blog_view,\n\tapi_delete_blog_view,\n\tapi_create_blog_view,\n\tapi_is_author_of_blogpost,\n\tApiBlogListView\n)\n\napp_name = 'blog'\n\nurlpatterns = [\n\tpath('<slug>/', api_detail_blog_view, name=\"detail\"),\n\tpath('<slug>/update', api_update_blog_view, name=\"update\"),\n\tpath('<slug>/delete', api_delete_blog_view, name=\"delete\"),\n\tpath('create', api_create_blog_view, name=\"create\"),\n\tpath('list', ApiBlogListView.as_view(), name=\"list\"),\n\tpath('<slug>/is_author', api_is_author_of_blogpost, name=\"is_author\"),\n]"
  },
  {
    "path": "src/blog/api/views.py",
    "content": "from rest_framework import status\nfrom rest_framework.response import Response\nfrom rest_framework.decorators import api_view, permission_classes\nfrom rest_framework.permissions import IsAuthenticated\nfrom rest_framework.authentication import TokenAuthentication\nfrom rest_framework.pagination import PageNumberPagination\nfrom rest_framework.generics import ListAPIView\nfrom rest_framework.filters import SearchFilter, OrderingFilter\n\nfrom account.models import Account\nfrom blog.models import BlogPost\nfrom blog.api.serializers import BlogPostSerializer, BlogPostUpdateSerializer, BlogPostCreateSerializer\n\nSUCCESS = 'success'\nERROR = 'error'\nDELETE_SUCCESS = 'deleted'\nUPDATE_SUCCESS = 'updated'\nCREATE_SUCCESS = 'created'\n\n# Response: https://gist.github.com/mitchtabian/93f287bd1370e7a1ad3c9588b0b22e3d\n# Url: https://<your-domain>/api/blog/<slug>/\n# Headers: Authorization: Token <token>\n@api_view(['GET', ])\n@permission_classes((IsAuthenticated, ))\ndef api_detail_blog_view(request, slug):\n\n\ttry:\n\t\tblog_post = BlogPost.objects.get(slug=slug)\n\texcept BlogPost.DoesNotExist:\n\t\treturn Response(status=status.HTTP_404_NOT_FOUND)\n\n\tif request.method == 'GET':\n\t\tserializer = BlogPostSerializer(blog_post)\n\t\treturn Response(serializer.data)\n\n\n# Response: https://gist.github.com/mitchtabian/32507e93c530aa5949bc08d795ba66df\n# Url: https://<your-domain>/api/blog/<slug>/update\n# Headers: Authorization: Token <token>\n@api_view(['PUT',])\n@permission_classes((IsAuthenticated,))\ndef api_update_blog_view(request, slug):\n\n\ttry:\n\t\tblog_post = BlogPost.objects.get(slug=slug)\n\texcept BlogPost.DoesNotExist:\n\t\treturn Response(status=status.HTTP_404_NOT_FOUND)\n\n\tuser = request.user\n\tif blog_post.author != user:\n\t\treturn Response({'response':\"You don't have permission to edit that.\"}) \n\t\t\n\tif request.method == 'PUT':\n\t\tserializer = BlogPostUpdateSerializer(blog_post, data=request.data, partial=True)\n\t\tdata = {}\n\t\tif serializer.is_valid():\n\t\t\tserializer.save()\n\t\t\tdata['response'] = UPDATE_SUCCESS\n\t\t\tdata['pk'] = blog_post.pk\n\t\t\tdata['title'] = blog_post.title\n\t\t\tdata['body'] = blog_post.body\n\t\t\tdata['slug'] = blog_post.slug\n\t\t\tdata['date_updated'] = blog_post.date_updated\n\t\t\timage_url = str(request.build_absolute_uri(blog_post.image.url))\n\t\t\tif \"?\" in image_url:\n\t\t\t\timage_url = image_url[:image_url.rfind(\"?\")]\n\t\t\tdata['image'] = image_url\n\t\t\tdata['username'] = blog_post.author.username\n\t\t\treturn Response(data=data)\n\t\treturn Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)\n\n\n\n@api_view(['GET',])\n@permission_classes((IsAuthenticated,))\ndef api_is_author_of_blogpost(request, slug):\n\ttry:\n\t\tblog_post = BlogPost.objects.get(slug=slug)\n\texcept BlogPost.DoesNotExist:\n\t\treturn Response(status=status.HTTP_404_NOT_FOUND)\n\n\tdata = {}\n\tuser = request.user\n\tif blog_post.author != user:\n\t\tdata['response'] = \"You don't have permission to edit that.\"\n\t\treturn Response(data=data)\n\tdata['response'] = \"You have permission to edit that.\"\n\treturn Response(data=data)\n\n\n# Response: https://gist.github.com/mitchtabian/a97be3f8b71c75d588e23b414898ae5c\n# Url: https://<your-domain>/api/blog/<slug>/delete\n# Headers: Authorization: Token <token>\n@api_view(['DELETE',])\n@permission_classes((IsAuthenticated, ))\ndef api_delete_blog_view(request, slug):\n\n\ttry:\n\t\tblog_post = BlogPost.objects.get(slug=slug)\n\texcept BlogPost.DoesNotExist:\n\t\treturn Response(status=status.HTTP_404_NOT_FOUND)\n\n\tuser = request.user\n\tif blog_post.author != user:\n\t\treturn Response({'response':\"You don't have permission to delete that.\"}) \n\n\tif request.method == 'DELETE':\n\t\toperation = blog_post.delete()\n\t\tdata = {}\n\t\tif operation:\n\t\t\tdata['response'] = DELETE_SUCCESS\n\t\treturn Response(data=data)\n\n\n# Response: https://gist.github.com/mitchtabian/78d7dcbeab4135c055ff6422238a31f9\n# Url: https://<your-domain>/api/blog/create\n# Headers: Authorization: Token <token>\n@api_view(['POST'])\n@permission_classes((IsAuthenticated,))\ndef api_create_blog_view(request):\n\n\tif request.method == 'POST':\n\n\t\tdata = request.data\n\t\tdata['author'] = request.user.pk\n\t\tserializer = BlogPostCreateSerializer(data=data)\n\n\t\tdata = {}\n\t\tif serializer.is_valid():\n\t\t\tblog_post = serializer.save()\n\t\t\tdata['response'] = CREATE_SUCCESS\n\t\t\tdata['pk'] = blog_post.pk\n\t\t\tdata['title'] = blog_post.title\n\t\t\tdata['body'] = blog_post.body\n\t\t\tdata['slug'] = blog_post.slug\n\t\t\tdata['date_updated'] = blog_post.date_updated\n\t\t\timage_url = str(request.build_absolute_uri(blog_post.image.url))\n\t\t\tif \"?\" in image_url:\n\t\t\t\timage_url = image_url[:image_url.rfind(\"?\")]\n\t\t\tdata['image'] = image_url\n\t\t\tdata['username'] = blog_post.author.username\n\t\t\treturn Response(data=data)\n\t\treturn Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)\n\n\n# Response: https://gist.github.com/mitchtabian/ae03573737067c9269701ea662460205\n# Url: \n#\t\t1) list: https://<your-domain>/api/blog/list\n#\t\t2) pagination: http://<your-domain>/api/blog/list?page=2\n#\t\t3) search: http://<your-domain>/api/blog/list?search=mitch\n#\t\t4) ordering: http://<your-domain>/api/blog/list?ordering=-date_updated\n#\t\t4) search + pagination + ordering: <your-domain>/api/blog/list?search=mitch&page=2&ordering=-date_updated\n# Headers: Authorization: Token <token>\nclass ApiBlogListView(ListAPIView):\n\tqueryset = BlogPost.objects.all()\n\tserializer_class = BlogPostSerializer\n\tauthentication_classes = (TokenAuthentication,)\n\tpermission_classes = (IsAuthenticated,)\n\tpagination_class = PageNumberPagination\n\tfilter_backends = (SearchFilter, OrderingFilter)\n\tsearch_fields = ('title', 'body', 'author__username')"
  },
  {
    "path": "src/blog/apps.py",
    "content": "from django.apps import AppConfig\n\n\nclass BlogConfig(AppConfig):\n    name = 'blog'\n"
  },
  {
    "path": "src/blog/forms.py",
    "content": "from django import forms\n\nfrom blog.models import BlogPost\n\n\nclass CreateBlogPostForm(forms.ModelForm):\n\n\tclass Meta:\n\t\tmodel = BlogPost\n\t\tfields = ['title', 'body', 'image']\n\n\n\nclass UpdateBlogPostForm(forms.ModelForm):\n\n\tclass Meta:\n\t\tmodel = BlogPost\n\t\tfields = ['title', 'body', 'image']\n\n\tdef save(self, commit=True):\n\t\tblog_post = self.instance\n\t\tblog_post.title = self.cleaned_data['title']\n\t\tblog_post.body = self.cleaned_data['body']\n\n\t\tif self.cleaned_data['image']:\n\t\t\tblog_post.image = self.cleaned_data['image']\n\n\t\tif commit:\n\t\t\tblog_post.save()\n\t\treturn blog_post"
  },
  {
    "path": "src/blog/migrations/0001_initial.py",
    "content": "# Generated by Django 2.2.2 on 2019-06-24 20:55\n\nimport blog.models\nfrom django.conf import settings\nfrom django.db import migrations, models\nimport django.db.models.deletion\n\n\nclass Migration(migrations.Migration):\n\n    initial = True\n\n    dependencies = [\n        migrations.swappable_dependency(settings.AUTH_USER_MODEL),\n    ]\n\n    operations = [\n        migrations.CreateModel(\n            name='BlogPost',\n            fields=[\n                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),\n                ('title', models.CharField(max_length=50)),\n                ('body', models.TextField(max_length=5000)),\n                ('image', models.ImageField(upload_to=blog.models.upload_location)),\n                ('date_published', models.DateTimeField(auto_now_add=True, verbose_name='date published')),\n                ('date_updated', models.DateTimeField(auto_now=True, verbose_name='date updated')),\n                ('slug', models.SlugField(blank=True, unique=True)),\n                ('author', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),\n            ],\n        ),\n    ]\n"
  },
  {
    "path": "src/blog/migrations/__init__.py",
    "content": ""
  },
  {
    "path": "src/blog/models.py",
    "content": "from django.db import models\n\nfrom django.utils.text import slugify\nfrom django.conf import settings\nfrom django.db.models.signals import post_delete, pre_save\nfrom django.dispatch import receiver\n\n\ndef upload_location(instance, filename, **kwargs):\n\tfile_path = 'blog/{author_id}/{title}-{filename}'.format(\n\t\t\tauthor_id=str(instance.author.id), title=str(instance.title), filename=filename\n\t\t) \n\treturn file_path\n\n\nclass BlogPost(models.Model):\n\ttitle \t\t\t\t= models.CharField(max_length=50, null=False, blank=True)\n\tbody \t\t\t\t= models.TextField(max_length=5000, null=False, blank=True)\n\timage \t\t\t\t= models.ImageField(upload_to=upload_location, null=False, blank=True)\n\tdate_published \t\t= models.DateTimeField(auto_now_add=True, verbose_name=\"date published\")\n\tdate_updated \t\t= models.DateTimeField(auto_now=True, verbose_name=\"date updated\")\n\tauthor \t\t\t\t= models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)\n\tslug \t\t\t\t= models.SlugField(blank=True, unique=True)\n\n\tdef __str__(self):\n\t\treturn self.title\n\n@receiver(post_delete, sender=BlogPost)\ndef submission_delete(sender, instance, **kwargs):\n\tinstance.image.delete(False)\n\ndef pre_save_blog_post_receiever(sender, instance, *args, **kwargs):\n\tif not instance.slug:\n\t\tinstance.slug = slugify(instance.author.username + \"-\" + instance.title)\n\npre_save.connect(pre_save_blog_post_receiever, sender=BlogPost)\n\n"
  },
  {
    "path": "src/blog/templates/blog/create_blog.html",
    "content": "{% extends 'base.html' %}\n\n\n{% block content %}\n\n<style type=\"text/css\">\n  .create-form {\n\t    width: 100%;\n\t    max-width: 100%;\n\t    padding: 15px;\n\t    margin: auto;\n  \t}\n  \t.submit-button{\n  \t\tmax-width: 200px;\n  \t}\n</style>\n\n<div class=\"container\">\n\t<div class=\"row\">\n\t\t<div class=\"col-lg-7 offset-lg-1\">\n\t\t\t<form class=\"create-form\" method=\"post\" enctype=\"multipart/form-data\">{% csrf_token %}\n\n\t\t\t\t<!-- title -->\n\t\t\t\t<div class=\"form-group\">\n\t\t\t\t\t<label for=\"id_title\">Title</label>\n\t\t\t\t\t<input class=\"form-control\" type=\"text\" name=\"title\" id=\"id_title\" placeholder=\"Title\" required autofocus>\n\t\t\t\t</div>\n\n\t\t\t\t<!-- Body -->\n\t\t\t\t<div class=\"form-group\">\n\t\t\t\t\t<label for=\"id_body\">Content</label>\n\t\t\t\t\t<textarea class=\"form-control\" rows=\"10\" type=\"text\" name=\"body\" id=\"id_body\" placeholder=\"This blog is about...\" required></textarea>\n\t\t\t\t</div>\n\n\t\t\t\t<!-- Image -->\n\t\t\t\t<div class=\"form-group\">\n\t\t\t\t\t<label for=\"id_image\">Image</label>\n\t\t\t\t\t<input  type=\"file\" name=\"image\" id=\"id_image\" accept=\"image/*\" required>\n\t\t\t\t</div>\n\n\t\t\t\t<!-- Submit btn -->\n\t\t\t\t<button class=\"submit-button btn btn-lg btn-primary btn-block\" type=\"submit\">POST</button>\n\t\t\t</form>\t\n\t\t</div>\n\t</div>\n</div>\n\n{% endblock content %}"
  },
  {
    "path": "src/blog/templates/blog/detail_blog.html",
    "content": "{% extends 'base.html' %}\n\n\n{% block content %}\n<style type=\"text/css\">\n\t\n\t.card {\n\t\tmax-width: 700px;\n\t}\n\n\t.container{\n\t\tpadding: 20px;\n\t}\n</style>\n\n\n<div class=\"container\">\n\t<div class=\"row\">\n\t\t\n\t\t<!-- Blog post -->\n\t\t<div class=\"card m-auto\">\n\t\t\t<img class=\"card-img-top\" src=\"{{blog_post.image.url}}\">\n\t\t\t<div class=\"card-body my-2\">\n\t\t\t\t<h2 class=\"card-title\">{{blog_post.title}}</h2>\n\t\t\t\t<p class=\"card-text\">{{blog_post.body|linebreaksbr}}</p>\n\t\t\t\t<p>\n\t\t\t\t\t{% if blog_post.author == request.user %}\n\t\t\t\t\t\t<a href=\"{% url 'blog:edit' blog_post.slug %}\" class=\"btn btn-primary\">Update</a>\n\t\t\t\t\t{% endif %}\n\t\t\t\t</p>\n\t\t\t\t\n\t\t\t</div>\n\t\t\t<div class=\"card-footer text-muted\">\n\t\t\t\tUpdated on {{blog_post.date_updated}} by {{blog_post.author}}\n\t\t\t</div>\n\t\t</div>\n\t\t<!-- end Blog post -->\n\n\t</div>\n</div>\n\n{% endblock content %}"
  },
  {
    "path": "src/blog/templates/blog/edit_blog.html",
    "content": "{% extends 'base.html' %}\n\n\n{% block content %}\n<style type=\"text/css\">\n   .create-form {\n\t    width: 100%;\n\t    max-width: 100%;\n\t    padding: 15px;\n\t    margin: auto;\n  \t}\n  \t.submit-button{\n  \t\tmax-width: 200px;\n  \t}\n\t.image {\n\t  opacity: 1;\n\t  transition: .5s ease;\n\t  backface-visibility: hidden;\n\t}\n\t.middle {\n\t  transition: .5s ease;\n\t  opacity: 0;\n\t  position: absolute;\n\t  text-align: center;\n\t  top: 50%;\n\t  left: 50%;\n\t  transform: translate(-50%, -50%);\n\t\n\t}\n\t.image-group{\n\t\tposition: relative;\n  \t\ttext-align: center;\n  \t\tcursor:pointer;\n\t}\n\t.image-group:hover .image {\n\t  opacity: 0.3;\n\t}\n\t.image-group:hover .middle {\n\t  opacity: 1;\n\t}\n\t.text {\n\t  margin: auto;\n\t  background-color: #4CAF50;\n\t  color: white;\n\t  font-size: 15px;\n\t  padding: 15px;\n\t}\n</style>\n\n<div class=\"container\">\n\t<div class=\"row\">\n\t\t<div class=\"col-lg-7 offset-lg-1\">\n\n\t\t\t{% if success_message %}\n\t\t\t\t<h3 style=\"color:green; text-align: center;\">{{success_message}}</h3>\n\t\t\t{% endif %}\n\n\t\t\t<form class=\"create-form\" method=\"post\" enctype=\"multipart/form-data\">{% csrf_token %}\n\n\t\t\t\t<!-- title -->\n\t\t\t\t<div class=\"form-group\">\n\t\t\t\t\t<label for=\"id_title\">Title</label>\n\t\t\t\t\t<input class=\"form-control\" type=\"text\" name=\"title\" id=\"id_title\" placeholder=\"Title\" value=\"{{form.initial.title}}\" required autofocus>\n\t\t\t\t</div>\n\n\t\t\t\t<!-- Body -->\n\t\t\t\t<div class=\"form-group\">\n\t\t\t\t\t<label for=\"id_body\">Content</label>\n\t\t\t\t\t<textarea class=\"form-control\" rows=\"10\" type=\"text\" name=\"body\" id=\"id_body\" placeholder=\"This blog is about...\" \n\t\t\t\t\trequired>{{form.initial.body}}</textarea>\n\t\t\t\t</div>\n\n\t\t\t\t<!-- Image -->\n\t\t\t\t<div class=\"form-group image-group\" id=\"id_image_group\">\n\t\t\t\t\t<img class=\"img-fluid image\" src=\"{{form.initial.image.url}}\" id=\"id_image_display\">\n\t\t\t\t\t  <div class=\"middle\">\n\t\t\t\t\t    <div class=\"text\">Change image</div>\n\t\t\t\t\t  </div>\n\t\t\t\t</div>\n\t\t\t\t<input type=\"file\" name=\"image\" id=\"id_image_file\" accept=\"image/*\" onchange=\"readURL(this)\">\n\t\t\t\t\n\n\t\t\t\t{% for field in form %}\n\t\t\t\t\t<p>\n\t\t\t\t\t\t{% for error in field.errors %}\n\t\t\t\t\t\t\t<p style=\"color: red\">{{ error }}</p>\n\t\t\t\t\t\t{% endfor %}\n\t\t\t\t\t</p>\n\t\t\t\t{% endfor %}\n\t\t\t\t{% if form.non_field_errors %}\n\t\t\t\t\t<div style=\"color: red\">\n\t\t\t\t\t\t<p>{{form.non_field_errors}}</p>\n\t\t\t\t\t</div>\n\t\t\t\t{% endif %}\n\n\t\t\t\t<!-- Submit btn -->\n\t\t\t\t<button class=\"submit-button btn btn-lg btn-primary btn-block\" type=\"submit\">Update</button>\n\t\t\t</form>\t\n\t\t</div>\n\t</div>\n</div>\n\n<script type=\"text/javascript\">\n\tdocument.getElementById('id_image_group').onclick = function(event){\n    \tdocument.getElementById('id_image_file').click();\n    };\n\tfunction readURL(input){\n\t\tvar reader = new FileReader();\n\t\treader.onload = function (e) {\n            $('#id_image_display')\n                .attr('src', e.target.result)\n        };\n\t\treader.readAsDataURL(input.files[0]);\n\t}\n</script>\n\n{% endblock content %}"
  },
  {
    "path": "src/blog/templates/blog/snippets/blog_post_pagination.html",
    "content": "<!-- FILTERED Pagination -->\n<div class=\"d-flex flex-column m-auto pagination mt-5\">\n<nav aria-label=\"Page navigation\">\n<ul class=\"pagination pg-grey justify-content-center\">\n\t{% if blog_posts.has_previous %}\n        <li class=\"page-item\">\n\t\t  <a class=\"page-link\" href=\"?{% if query %}q={{query}}&{% endif %}page={{ blog_posts.previous_page_number }}\">&laquo; Previous</a>\n\t\t</li>\n    {% endif %}\n\n\t{% for i in blog_posts.paginator.page_range %}\n\t\t{% if blog_posts.number == i %}\n\t\t\t<li class=\"page-item active\"><a class=\"page-link\">{{ i }}</a></li>\n\t\t{% else %}\n\t\t\t<li class=\"page-item\" ><a class=\"page-link\" href=\"?{% if query %}q={{query}}&{% endif %}page={{ i }}\">{{ i }}</a></li>\n\t\t{% endif %}\n\t{% endfor %}\n    \n    {% if blog_posts.has_next %}\n    \t<li class=\"page-item\">\n\t\t  <a class=\"page-link\" href=\"?{% if query %}q={{query}}&{% endif %}page={{ blog_posts.next_page_number }}\">Next</a>\n\t\t</li>\n\t\t<li class=\"page-item\">\n\t\t  <a class=\"page-link\"  href=\"?{% if query %}q={{query}}&{% endif %}page={{ blog_posts.paginator.num_pages }}\">Last &raquo;</a>\n\t\t</li>\n    {% endif %}\n</ul>\n</nav>\n</div>\n<!-- end pagination-->"
  },
  {
    "path": "src/blog/templates/blog/snippets/blog_post_snippet.html",
    "content": "<style type=\"text/css\">\n\t.card{\n\t\tmax-width: 700px;\n\t\twidth: 100%;\n\t}\n\t.card-body{\n\t\tpadding: 20px;\n\n\t}\n</style>\n\n{% if blog_post %}\n<div class=\"container\">\n\t<div class=\"row\">\n\n\t\t\n\t\t<!-- Blog Post -->\n\t\t<div class=\"card m-auto\">\n\t\t\t<a href=\"{% url 'blog:detail' post.slug %}\">\n\t\t\t\t<img class=\"card-img-top\" src=\"{{blog_post.image.url}}\">\n\t\t\t</a>\n\t\t\t\n\t\t\t<div class=\"card-body mt-2 mb-2\">\n\t\t\t\t<a href=\"{% url 'blog:detail' post.slug %}\">\n\t\t\t\t\t<h2 class=\"card-title\">{{blog_post.title}}</h2>\n\t\t\t\t</a>\n\t\t\t\t<p class=\"card-text\">{{blog_post.body|linebreaksbr|truncatechars:250}}</p>\n\t\t\t\t{% if blog_post.author == request.user %}\n\t\t\t\t\t<a href=\"{% url 'blog:edit' blog_post.slug %}\" class=\"btn btn-primary\">Update</a>\n\t\t\t\t{% endif %}\n\t\t\t</div>\n\t\t\t<div class=\"card-footer text-muted\">\n\t\t\t  Updated on {{blog_post.date_updated}} by {{blog_post.author}}\n\t\t\t</div>\n\t\t</div>\n\t\t\n\t</div>\n</div>\n\n{% else %}\n\n<div class=\"container\"> \n\t<div class=\"row\">\n\t\t<div class=\"card m-auto\">\n\t\t\t<div class=\"card-body mt-2 mb-2\">\n\t\t\t\t<h2 class=\"card-title\">\n\t\t\t\t\tNo results\n\t\t\t\t</h2>\n\t\t\t\t<p class=\"card-text\">There were no results matching your search: \"{{query}}\".</p>\n\t\t\t</div>\n\t\t</div>\n\t</div>\n</div>\n{% endif %}"
  },
  {
    "path": "src/blog/tests.py",
    "content": "from django.test import TestCase\n\n# Create your tests here.\n"
  },
  {
    "path": "src/blog/urls.py",
    "content": "from django.urls import path\nfrom blog.views import(\n\n\tcreate_blog_view,\n\tdetail_blog_view,\n\tedit_blog_view,\n\n)\n\napp_name = 'blog'\n\nurlpatterns = [\n\tpath('create/', create_blog_view, name=\"create\"),\n\tpath('<slug>/', detail_blog_view, name=\"detail\"),\n\tpath('<slug>/edit', edit_blog_view, name=\"edit\"),\n]"
  },
  {
    "path": "src/blog/utils.py",
    "content": "import cv2\nimport os\n\ndef is_image_aspect_ratio_valid(img_url):\n\timg = cv2.imread(img_url)\n\tdimensions = tuple(img.shape[1::-1]) # gives: (width, height)\n\t# print(\"dimensions: \" + str(dimensions))\n\taspect_ratio = dimensions[0] / dimensions[1] # divide w / h\n\t# print(\"aspect_ratio: \" + str(aspect_ratio))\n\tif aspect_ratio < 1:\n\t\treturn False\n\treturn True\n\n\ndef is_image_size_valid(img_url, mb_limit):\n\timage_size = os.path.getsize(img_url)\n\t# print(\"image size: \" + str(image_size))\n\tif image_size > mb_limit:\n\t\treturn False\n\treturn True"
  },
  {
    "path": "src/blog/views.py",
    "content": "from django.shortcuts import render, redirect, get_object_or_404\nfrom django.db.models import Q\nfrom django.http import HttpResponse\n\nfrom blog.models import BlogPost\nfrom blog.forms import CreateBlogPostForm, UpdateBlogPostForm\n\nfrom account.models import Account\n\n\ndef create_blog_view(request):\n\n\tcontext = {}\n\n\tuser = request.user\n\tif not user.is_authenticated:\n\t\treturn redirect('must_authenticate')\n\n\tform = CreateBlogPostForm(request.POST or None, request.FILES or None)\n\tif form.is_valid():\n\t\tobj = form.save(commit=False)\n\t\tauthor = Account.objects.filter(email=user.email).first()\n\t\tobj.author = author\n\t\tobj.save()\n\t\tform = CreateBlogPostForm()\n\n\tcontext['form'] = form\n\n\treturn render(request, \"blog/create_blog.html\", context)\n\n\ndef detail_blog_view(request, slug):\n\n\tcontext = {}\n\n\tblog_post = get_object_or_404(BlogPost, slug=slug)\n\tcontext['blog_post'] = blog_post\n\n\treturn render(request, 'blog/detail_blog.html', context)\n\n\n\ndef edit_blog_view(request, slug):\n\n\tcontext = {}\n\n\tuser = request.user\n\tif not user.is_authenticated:\n\t\treturn redirect(\"must_authenticate\")\n\n\tblog_post = get_object_or_404(BlogPost, slug=slug)\n\n\tif blog_post.author != user:\n\t\treturn HttpResponse(\"You are not the author of that post.\")\n\n\tif request.POST:\n\t\tform = UpdateBlogPostForm(request.POST or None, request.FILES or None, instance=blog_post)\n\t\tif form.is_valid():\n\t\t\tobj = form.save(commit=False)\n\t\t\tobj.save()\n\t\t\tcontext['success_message'] = \"Updated\"\n\t\t\tblog_post = obj\n\n\tform = UpdateBlogPostForm(\n\t\t\tinitial = {\n\t\t\t\t\t\"title\": blog_post.title,\n\t\t\t\t\t\"body\": blog_post.body,\n\t\t\t\t\t\"image\": blog_post.image,\n\t\t\t}\n\t\t)\n\n\tcontext['form'] = form\n\treturn render(request, 'blog/edit_blog.html', context)\n\n\ndef get_blog_queryset(query=None):\n\tqueryset = []\n\tqueries = query.split(\" \") # python install 2019 = [python, install, 2019]\n\tfor q in queries:\n\t\tposts = BlogPost.objects.filter(\n\t\t\t\tQ(title__icontains=q) | \n\t\t\t\tQ(body__icontains=q)\n\t\t\t).distinct()\n\n\t\tfor post in posts:\n\t\t\tqueryset.append(post)\n\n\treturn list(set(queryset))\t\n"
  },
  {
    "path": "src/manage.py",
    "content": "#!/usr/bin/env python\n\"\"\"Django's command-line utility for administrative tasks.\"\"\"\nimport os\nimport sys\n\n\ndef main():\n    os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'mysite.settings')\n    try:\n        from django.core.management import execute_from_command_line\n    except ImportError as exc:\n        raise ImportError(\n            \"Couldn't import Django. Are you sure it's installed and \"\n            \"available on your PYTHONPATH environment variable? Did you \"\n            \"forget to activate a virtual environment?\"\n        ) from exc\n    execute_from_command_line(sys.argv)\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "src/mysite/__init__.py",
    "content": ""
  },
  {
    "path": "src/mysite/settings.py",
    "content": "\"\"\"\nDjango settings for mysite project.\n\nGenerated by 'django-admin startproject' using Django 2.2.2.\n\nFor more information on this file, see\nhttps://docs.djangoproject.com/en/2.2/topics/settings/\n\nFor the full list of settings and their values, see\nhttps://docs.djangoproject.com/en/2.2/ref/settings/\n\"\"\"\n\nimport os\nfrom decouple import config\n\n# Build paths inside the project like this: os.path.join(BASE_DIR, ...)\nBASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))\n\n\n# Quick-start development settings - unsuitable for production\n# See https://docs.djangoproject.com/en/2.2/howto/deployment/checklist/\n\n# SECURITY WARNING: keep the secret key used in production secret!\nSECRET_KEY = '!p1ai_b373g3bmz-**m@%h9+0_8xm7*41etdbi+t266-mogm08'\n\n# SECURITY WARNING: don't run with debug turned on in production!\nDEBUG = True\n\nALLOWED_HOSTS = []\n\nif DEBUG:\n    EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend' # During development only\n\n\n# Application definition\n\nINSTALLED_APPS = [\n\n    # My apps\n    'personal',\n    'account',\n    'blog',\n\n\n    # django apps\n    'django.contrib.admin',\n    'django.contrib.auth',\n    'django.contrib.contenttypes',\n    'django.contrib.sessions',\n    'django.contrib.messages',\n    'django.contrib.staticfiles',\n    'rest_framework',\n    'rest_framework.authtoken',\n]\n\nAUTH_USER_MODEL = 'account.Account'\nAUTHENTICATION_BACKENDS = ( \n    'django.contrib.auth.backends.AllowAllUsersModelBackend', \n    'account.backends.CaseInsensitiveModelBackend',\n    )\n\nREST_FRAMEWORK = {\n    'DEFAULT_AUTHENTICATION_CLASSES': (\n        'rest_framework.authentication.TokenAuthentication',\n    ),\n    'DEFAULT_PERMISSION_CLASSES': (\n        'rest_framework.permissions.IsAuthenticated',\n    ),\n    'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',\n    'PAGE_SIZE': 10,\n}\n\nMIDDLEWARE = [\n    'django.middleware.security.SecurityMiddleware',\n    'django.contrib.sessions.middleware.SessionMiddleware',\n    'django.middleware.common.CommonMiddleware',\n    'django.middleware.csrf.CsrfViewMiddleware',\n    'django.contrib.auth.middleware.AuthenticationMiddleware',\n    'django.contrib.messages.middleware.MessageMiddleware',\n    'django.middleware.clickjacking.XFrameOptionsMiddleware',\n]\n\nROOT_URLCONF = 'mysite.urls'\n\nTEMPLATES = [\n    {\n        'BACKEND': 'django.template.backends.django.DjangoTemplates',\n        'DIRS': [os.path.join(BASE_DIR, 'templates')],\n        'APP_DIRS': True,\n        'OPTIONS': {\n            'context_processors': [\n                'django.template.context_processors.debug',\n                'django.template.context_processors.request',\n                'django.contrib.auth.context_processors.auth',\n                'django.contrib.messages.context_processors.messages',\n            ],\n        },\n    },\n]\n\n\nWSGI_APPLICATION = 'mysite.wsgi.application'\n\n\n# Database\n# https://docs.djangoproject.com/en/2.2/ref/settings/#databases\n\nDATABASES = {\n    'default': {\n        'ENGINE': 'django.db.backends.sqlite3',\n        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),\n    }\n}\n\n\n# Password validation\n# https://docs.djangoproject.com/en/2.2/ref/settings/#auth-password-validators\n\nAUTH_PASSWORD_VALIDATORS = [\n    {\n        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',\n    },\n    {\n        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',\n    },\n    {\n        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',\n    },\n    {\n        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',\n    },\n]\n\n\n# Internationalization\n# https://docs.djangoproject.com/en/2.2/topics/i18n/\n\nLANGUAGE_CODE = 'en-us'\n\nTIME_ZONE = 'UTC'\n\nUSE_I18N = True\n\nUSE_L10N = True\n\nUSE_TZ = True\n\n\n# Static files (CSS, JavaScript, Images)\n# https://docs.djangoproject.com/en/2.2/howto/static-files/\nSTATICFILES_DIRS = [\n    os.path.join(BASE_DIR, 'static'),\n    os.path.join(BASE_DIR, 'media'),\n]\nSTATIC_URL = '/static/'\nMEDIA_URL = '/media/'\nSTATIC_ROOT = os.path.join(BASE_DIR, 'static_cdn')\nMEDIA_ROOT = os.path.join(BASE_DIR, 'media_cdn')\nTEMP = os.path.join(BASE_DIR, 'temp')"
  },
  {
    "path": "src/mysite/urls.py",
    "content": "\"\"\"mysite URL Configuration\n\nThe `urlpatterns` list routes URLs to views. For more information please see:\n    https://docs.djangoproject.com/en/2.2/topics/http/urls/\nExamples:\nFunction views\n    1. Add an import:  from my_app import views\n    2. Add a URL to urlpatterns:  path('', views.home, name='home')\nClass-based views\n    1. Add an import:  from other_app.views import Home\n    2. Add a URL to urlpatterns:  path('', Home.as_view(), name='home')\nIncluding another URLconf\n    1. Import the include() function: from django.urls import include, path\n    2. Add a URL to urlpatterns:  path('blog/', include('blog.urls'))\n\"\"\"\nfrom django.contrib import admin\nfrom django.urls import path, include\nfrom django.contrib.auth import views as auth_views\nfrom django.conf.urls.static import static\nfrom django.conf import settings\n\nfrom personal.views import (\n\thome_screen_view,\n)\n\nfrom account.views import (\n    registration_view,\n    logout_view,\n    login_view,\n    account_view,\n    must_authenticate_view,\n)\n\nurlpatterns = [\n    path('', home_screen_view, name=\"home\"),\n    path('admin/', admin.site.urls),\n    path('account/', account_view, name=\"account\"),\n    path('blog/', include('blog.urls', 'blog')),\n    path('login/', login_view, name=\"login\"),\n    path('logout/', logout_view, name=\"logout\"),\n    path('must_authenticate/', must_authenticate_view, name=\"must_authenticate\"),\n    path('register/', registration_view, name=\"register\"),\n\t\n\t# REST-framework\n    path('api/blog/', include('blog.api.urls', 'blog_api')),\n    path('api/account/', include('account.api.urls', 'account_api')),\n\n    # Password reset links (ref: https://github.com/django/django/blob/master/django/contrib/auth/views.py)\n    path('password_change/done/', auth_views.PasswordChangeDoneView.as_view(template_name='registration/password_change_done.html'), \n        name='password_change_done'),\n\n    path('password_change/', auth_views.PasswordChangeView.as_view(template_name='registration/password_change.html'), \n        name='password_change'),\n\n    path('password_reset/done/', auth_views.PasswordResetCompleteView.as_view(template_name='registration/password_reset_done.html'),\n     name='password_reset_done'),\n\n    path('reset/<uidb64>/<token>/', auth_views.PasswordResetConfirmView.as_view(), name='password_reset_confirm'),\n    path('password_reset/', auth_views.PasswordResetView.as_view(), name='password_reset'),\n    \n    path('reset/done/', auth_views.PasswordResetCompleteView.as_view(template_name='registration/password_reset_complete.html'),\n     name='password_reset_complete'),\n]\n\nif settings.DEBUG:\n    urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)\n    urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)\n"
  },
  {
    "path": "src/mysite/wsgi.py",
    "content": "\"\"\"\nWSGI config for mysite project.\n\nIt exposes the WSGI callable as a module-level variable named ``application``.\n\nFor more information on this file, see\nhttps://docs.djangoproject.com/en/2.2/howto/deployment/wsgi/\n\"\"\"\n\nimport os\n\nfrom django.core.wsgi import get_wsgi_application\n\nos.environ.setdefault('DJANGO_SETTINGS_MODULE', 'mysite.settings')\n\napplication = get_wsgi_application()\n"
  },
  {
    "path": "src/personal/__init__.py",
    "content": ""
  },
  {
    "path": "src/personal/admin.py",
    "content": "from django.contrib import admin\n\n"
  },
  {
    "path": "src/personal/apps.py",
    "content": "from django.apps import AppConfig\n\n\nclass PersonalConfig(AppConfig):\n    name = 'personal'\n"
  },
  {
    "path": "src/personal/migrations/0001_initial.py",
    "content": "# Generated by Django 2.2.2 on 2019-06-19 18:01\n\nfrom django.db import migrations, models\n\n\nclass Migration(migrations.Migration):\n\n    initial = True\n\n    dependencies = [\n    ]\n\n    operations = [\n        migrations.CreateModel(\n            name='Question',\n            fields=[\n                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),\n                ('title', models.CharField(max_length=60)),\n                ('question', models.TextField(max_length=400)),\n                ('priority', models.CharField(choices=[('L', 'Low'), ('M', 'Medium'), ('H', 'High')], max_length=1)),\n            ],\n            options={\n                'verbose_name': 'The Question',\n                'verbose_name_plural': 'Questions from People',\n            },\n        ),\n    ]\n"
  },
  {
    "path": "src/personal/migrations/0002_delete_question.py",
    "content": "# Generated by Django 2.2.2 on 2019-06-19 18:24\n\nfrom django.db import migrations\n\n\nclass Migration(migrations.Migration):\n\n    dependencies = [\n        ('personal', '0001_initial'),\n    ]\n\n    operations = [\n        migrations.DeleteModel(\n            name='Question',\n        ),\n    ]\n"
  },
  {
    "path": "src/personal/migrations/__init__.py",
    "content": ""
  },
  {
    "path": "src/personal/models.py",
    "content": "from django.db import models\n\n# #Two tuple structure\n# #The first element in each tuple is the value that will be stored in the database. The second element is displayed by the field’s form widget.\n# #Tuple\n# PRIORITY = [\n# \t('L', 'Low'), #Tuple1\n# \t('M', 'Medium'), #Tuple2\n# \t('H', 'High'), #Tuple3\n# ]\n\n# class Question(models.Model):\n# \ttitle\t\t \t\t\t= models.CharField(max_length=60)\n# \tquestion \t\t\t\t= models.TextField(max_length=400)\n# \tpriority \t\t\t\t= models.CharField(max_length=1, choices=PRIORITY)\n\n# \tdef __str__(self):\n# \t\treturn self.title\n\n\n# \tclass Meta:\n# \t\tverbose_name = 'The Question'\n# \t\tverbose_name_plural = 'Questions from People'"
  },
  {
    "path": "src/personal/templates/personal/home.html",
    "content": "{% extends 'base.html' %}\n{% load static %}\n\n{% block content %}\n<style type=\"text/css\">\n\t@media (max-width: 768px) { \n\t\t.right-column{\n\t\t\tmargin-left: 0px;\n\t\t}\n\t}\n\t@media (min-width: 768px) { \n\t\t.right-column{\n\t\t\tmargin-left: 20px;\n\t\t}\n\t}\n\t.blog-post-container{\n\t\tmargin-bottom: 20px;\n\t\twidth: 100%;\n\t}\n\t.create-post-bar{\n\t\tbackground-color: #fff;\n\t\tmargin-bottom:20px;\n\t}\n\t.left-column{\n\t\tpadding:0px;\n\t}\n\t.right-column{\n\t\tpadding:0px;\n\t}\n\t.lead{\n\t\tfont-size: 17px;\n\t}\n</style>\n<div class=\"container\">\n\t<div class=\"row\">\n\n\t\t<!-- blog feed -->\n\t\t<div class=\"left-column col-lg-7 offset-lg-1\">\n\n\t\t\t<!-- Top 'create post' bar -->\n\t\t\t<div class=\"d-lg-none mb-3\">\n\t\t\t\t<div class=\"card m-auto d-flex flex-column p-3\">\n\t\t\t\t\t<img class=\"img-fluid d-block m-auto pb-2\" src=\"{% static 'codingwithmitch_logo.png' %}\" width=\"72\" height=\"72\">\n\t\t\t\t\t<p class=\"lead\">In this course you'll learn how to build a simple blog with user registration and blog CRUD functionality. Django is a powerful \n\t  \t\t\t\t\tframework and you'll see why in this course.</p>\n\t\t\t\t\t<p class=\"m-auto\"><a class=\"btn btn-primary\" href=\"{% url 'blog:create' %}\">Create post</a></p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t\t<!-- end Top 'create post' bar -->\n\n\t\t\t<!-- Blog posts-->\n\t\t\t{% if blog_posts %}\n\t\t\t\t{% for post in blog_posts %}\n\t\t\t\t\t<div class=\"blog-post-container\">\n\t\t\t\t\t\t{% include 'blog/snippets/blog_post_snippet.html' with blog_post=post %}\n\t\t\t\t\t</div>\n\t\t\t\t{% endfor %}\n\t\t\t{% else %}\n\t\t\t\t<div class=\"blog-post-container\">\n\t\t\t\t\t{% include 'blog/snippets/blog_post_snippet.html' with query=query %}\n\t\t\t\t</div>\n\t\t\t{% endif %}\n\t\t\t<!-- End Blog posts-->\n\t\t\t\n\t\t\t<!-- Pagination -->\n\t\t\t{% include 'blog/snippets/blog_post_pagination.html' with blog_posts=blog_posts %}\n\n\t\t</div>\n\t\t<!-- end blog feed -->\n\n\n\n\t\t<!-- Right 'create post' column  -->\n\t\t<div class=\"right-column col-lg-3 d-lg-flex d-none flex-column\">\n\n\t\t\t<div class=\"card create-post-bar d-flex flex-column p-3\">\n\t\t\t\t<img class=\"img-fluid d-block m-auto pb-2\" src=\"{% static 'codingwithmitch_logo.png' %}\" width=\"72\" height=\"72\">\n\t\t\t\t<p class=\"lead\">In this course you'll learn how to build a simple blog with user registration and blog CRUD functionality. Django is a powerful \n  \t\t\t\t\tframework and you'll see why in this course.</p>\n\t\t\t\t<p class=\"m-auto\"><a class=\"btn btn-primary\" href=\"{% url 'blog:create' %}\">Create post</a></p>\n\t\t\t</div>\n\t\t\n\t\t</div>\n\t\t<!-- end Right 'create post' column  -->\n\n\t</div>\n</div>\n\n{% endblock content %}"
  },
  {
    "path": "src/personal/tests.py",
    "content": "from django.test import TestCase\n\n# Create your tests here.\n"
  },
  {
    "path": "src/personal/views.py",
    "content": "from django.shortcuts import render\nfrom operator import attrgetter\nfrom django.core.paginator import EmptyPage, PageNotAnInteger, Paginator\n\nfrom blog.views import get_blog_queryset\nfrom blog.models import BlogPost\n\nBLOG_POSTS_PER_PAGE = 10\n\ndef home_screen_view(request):\n\t\n\tcontext = {}\n\n\tquery = \"\"\n\tquery = request.GET.get('q', '')\n\tcontext['query'] = str(query)\n\tprint(\"home_screen_view: \" + str(query))\n\n\tblog_posts = sorted(get_blog_queryset(query), key=attrgetter('date_updated'), reverse=True)\n\t\n\t# Pagination\n\tpage = request.GET.get('page', 1)\n\tblog_posts_paginator = Paginator(blog_posts, BLOG_POSTS_PER_PAGE)\n\n\ttry:\n\t\tblog_posts = blog_posts_paginator.page(page)\n\texcept PageNotAnInteger:\n\t\tblog_posts = blog_posts_paginator.page(BLOG_POSTS_PER_PAGE)\n\texcept EmptyPage:\n\t\tblog_posts = blog_posts_paginator.page(blog_posts_paginator.num_pages)\n\n\tcontext['blog_posts'] = blog_posts\n\n\treturn render(request, \"personal/home.html\", context)\n"
  },
  {
    "path": "src/requirements.txt",
    "content": "amqp==2.5.0\nanyjson==0.3.3\nbilliard==3.6.0.0\ncelery==4.3.0\ncertifi==2019.6.16\nchardet==3.0.4\nDjango==2.2.2\ndjango-celery-beat==1.5.0\ndjango-celery-results==1.1.2\ndjango-timezone-field==3.0\ndjangorestframework==3.9.4\nidna==2.8\nkombu==4.6.3\nnumpy==1.16.4\nopencv-python==4.1.0.25\nPillow==6.0.0\npython-crontab==2.3.8\npython-dateutil==2.8.0\npython-decouple==3.1\npytz==2019.1\nredis==3.2.1\nrequests==2.22.0\nsix==1.12.0\nsqlparse==0.3.0\nurllib3==1.25.3\nvine==1.3.0\nvirtualenv==16.6.0\n"
  },
  {
    "path": "src/static_cdn/admin/css/autocomplete.css",
    "content": "select.admin-autocomplete {\n    width: 20em;\n}\n\n.select2-container--admin-autocomplete.select2-container {\n    min-height: 30px;\n}\n\n.select2-container--admin-autocomplete .select2-selection--single,\n.select2-container--admin-autocomplete .select2-selection--multiple {\n    min-height: 30px;\n    padding: 0;\n}\n\n.select2-container--admin-autocomplete.select2-container--focus .select2-selection,\n.select2-container--admin-autocomplete.select2-container--open .select2-selection {\n    border-color: #999;\n    min-height: 30px;\n}\n\n.select2-container--admin-autocomplete.select2-container--focus .select2-selection.select2-selection--single,\n.select2-container--admin-autocomplete.select2-container--open .select2-selection.select2-selection--single {\n    padding: 0;\n}\n\n.select2-container--admin-autocomplete.select2-container--focus .select2-selection.select2-selection--multiple,\n.select2-container--admin-autocomplete.select2-container--open .select2-selection.select2-selection--multiple {\n    padding: 0;\n}\n\n.select2-container--admin-autocomplete .select2-selection--single {\n    background-color: #fff;\n    border: 1px solid #ccc;\n    border-radius: 4px;\n}\n\n.select2-container--admin-autocomplete .select2-selection--single .select2-selection__rendered {\n    color: #444;\n    line-height: 30px;\n}\n\n.select2-container--admin-autocomplete .select2-selection--single .select2-selection__clear {\n    cursor: pointer;\n    float: right;\n    font-weight: bold;\n}\n\n.select2-container--admin-autocomplete .select2-selection--single .select2-selection__placeholder {\n    color: #999;\n}\n\n.select2-container--admin-autocomplete .select2-selection--single .select2-selection__arrow {\n    height: 26px;\n    position: absolute;\n    top: 1px;\n    right: 1px;\n    width: 20px;\n}\n\n.select2-container--admin-autocomplete .select2-selection--single .select2-selection__arrow b {\n    border-color: #888 transparent transparent transparent;\n    border-style: solid;\n    border-width: 5px 4px 0 4px;\n    height: 0;\n    left: 50%;\n    margin-left: -4px;\n    margin-top: -2px;\n    position: absolute;\n    top: 50%;\n    width: 0;\n}\n\n.select2-container--admin-autocomplete[dir=\"rtl\"] .select2-selection--single .select2-selection__clear {\n    float: left;\n}\n\n.select2-container--admin-autocomplete[dir=\"rtl\"] .select2-selection--single .select2-selection__arrow {\n    left: 1px;\n    right: auto;\n}\n\n.select2-container--admin-autocomplete.select2-container--disabled .select2-selection--single {\n    background-color: #eee;\n    cursor: default;\n}\n\n.select2-container--admin-autocomplete.select2-container--disabled .select2-selection--single .select2-selection__clear {\n    display: none;\n}\n\n.select2-container--admin-autocomplete.select2-container--open .select2-selection--single .select2-selection__arrow b {\n    border-color: transparent transparent #888 transparent;\n    border-width: 0 4px 5px 4px;\n}\n\n.select2-container--admin-autocomplete .select2-selection--multiple {\n    background-color: white;\n    border: 1px solid #ccc;\n    border-radius: 4px;\n    cursor: text;\n}\n\n.select2-container--admin-autocomplete .select2-selection--multiple .select2-selection__rendered {\n    box-sizing: border-box;\n    list-style: none;\n    margin: 0;\n    padding: 0 5px;\n    width: 100%;\n}\n\n.select2-container--admin-autocomplete .select2-selection--multiple .select2-selection__rendered li {\n    list-style: none;\n}\n\n.select2-container--admin-autocomplete .select2-selection--multiple .select2-selection__placeholder {\n    color: #999;\n    margin-top: 5px;\n    float: left;\n}\n\n.select2-container--admin-autocomplete .select2-selection--multiple .select2-selection__clear {\n    cursor: pointer;\n    float: right;\n    font-weight: bold;\n    margin: 5px;\n}\n\n.select2-container--admin-autocomplete .select2-selection--multiple .select2-selection__choice {\n    background-color: #e4e4e4;\n    border: 1px solid #ccc;\n    border-radius: 4px;\n    cursor: default;\n    float: left;\n    margin-right: 5px;\n    margin-top: 5px;\n    padding: 0 5px;\n}\n\n.select2-container--admin-autocomplete .select2-selection--multiple .select2-selection__choice__remove {\n    color: #999;\n    cursor: pointer;\n    display: inline-block;\n    font-weight: bold;\n    margin-right: 2px;\n}\n\n.select2-container--admin-autocomplete .select2-selection--multiple .select2-selection__choice__remove:hover {\n    color: #333;\n}\n\n.select2-container--admin-autocomplete[dir=\"rtl\"] .select2-selection--multiple .select2-selection__choice, .select2-container--admin-autocomplete[dir=\"rtl\"] .select2-selection--multiple .select2-selection__placeholder, .select2-container--admin-autocomplete[dir=\"rtl\"] .select2-selection--multiple .select2-search--inline {\n    float: right;\n}\n\n.select2-container--admin-autocomplete[dir=\"rtl\"] .select2-selection--multiple .select2-selection__choice {\n    margin-left: 5px;\n    margin-right: auto;\n}\n\n.select2-container--admin-autocomplete[dir=\"rtl\"] .select2-selection--multiple .select2-selection__choice__remove {\n    margin-left: 2px;\n    margin-right: auto;\n}\n\n.select2-container--admin-autocomplete.select2-container--focus .select2-selection--multiple {\n    border: solid #999 1px;\n    outline: 0;\n}\n\n.select2-container--admin-autocomplete.select2-container--disabled .select2-selection--multiple {\n    background-color: #eee;\n    cursor: default;\n}\n\n.select2-container--admin-autocomplete.select2-container--disabled .select2-selection__choice__remove {\n    display: none;\n}\n\n.select2-container--admin-autocomplete.select2-container--open.select2-container--above .select2-selection--single, .select2-container--admin-autocomplete.select2-container--open.select2-container--above .select2-selection--multiple {\n    border-top-left-radius: 0;\n    border-top-right-radius: 0;\n}\n\n.select2-container--admin-autocomplete.select2-container--open.select2-container--below .select2-selection--single, .select2-container--admin-autocomplete.select2-container--open.select2-container--below .select2-selection--multiple {\n    border-bottom-left-radius: 0;\n    border-bottom-right-radius: 0;\n}\n\n.select2-container--admin-autocomplete .select2-search--dropdown .select2-search__field {\n    border: 1px solid #ccc;\n}\n\n.select2-container--admin-autocomplete .select2-search--inline .select2-search__field {\n    background: transparent;\n    border: none;\n    outline: 0;\n    box-shadow: none;\n    -webkit-appearance: textfield;\n}\n\n.select2-container--admin-autocomplete .select2-results > .select2-results__options {\n    max-height: 200px;\n    overflow-y: auto;\n}\n\n.select2-container--admin-autocomplete .select2-results__option[role=group] {\n    padding: 0;\n}\n\n.select2-container--admin-autocomplete .select2-results__option[aria-disabled=true] {\n    color: #999;\n}\n\n.select2-container--admin-autocomplete .select2-results__option[aria-selected=true] {\n    background-color: #ddd;\n}\n\n.select2-container--admin-autocomplete .select2-results__option .select2-results__option {\n    padding-left: 1em;\n}\n\n.select2-container--admin-autocomplete .select2-results__option .select2-results__option .select2-results__group {\n    padding-left: 0;\n}\n\n.select2-container--admin-autocomplete .select2-results__option .select2-results__option .select2-results__option {\n    margin-left: -1em;\n    padding-left: 2em;\n}\n\n.select2-container--admin-autocomplete .select2-results__option .select2-results__option .select2-results__option .select2-results__option {\n    margin-left: -2em;\n    padding-left: 3em;\n}\n\n.select2-container--admin-autocomplete .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option {\n    margin-left: -3em;\n    padding-left: 4em;\n}\n\n.select2-container--admin-autocomplete .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option {\n    margin-left: -4em;\n    padding-left: 5em;\n}\n\n.select2-container--admin-autocomplete .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option {\n    margin-left: -5em;\n    padding-left: 6em;\n}\n\n.select2-container--admin-autocomplete .select2-results__option--highlighted[aria-selected] {\n    background-color: #79aec8;\n    color: white;\n}\n\n.select2-container--admin-autocomplete .select2-results__group {\n    cursor: default;\n    display: block;\n    padding: 6px;\n}\n"
  },
  {
    "path": "src/static_cdn/admin/css/base.css",
    "content": "/*\n    DJANGO Admin styles\n*/\n\n@import url(fonts.css);\n\nbody {\n    margin: 0;\n    padding: 0;\n    font-size: 14px;\n    font-family: \"Roboto\",\"Lucida Grande\",\"DejaVu Sans\",\"Bitstream Vera Sans\",Verdana,Arial,sans-serif;\n    color: #333;\n    background: #fff;\n}\n\n/* LINKS */\n\na:link, a:visited {\n    color: #447e9b;\n    text-decoration: none;\n}\n\na:focus, a:hover {\n    color: #036;\n}\n\na:focus {\n    text-decoration: underline;\n}\n\na img {\n    border: none;\n}\n\na.section:link, a.section:visited {\n    color: #fff;\n    text-decoration: none;\n}\n\na.section:focus, a.section:hover {\n    text-decoration: underline;\n}\n\n/* GLOBAL DEFAULTS */\n\np, ol, ul, dl {\n    margin: .2em 0 .8em 0;\n}\n\np {\n    padding: 0;\n    line-height: 140%;\n}\n\nh1,h2,h3,h4,h5 {\n    font-weight: bold;\n}\n\nh1 {\n    margin: 0 0 20px;\n    font-weight: 300;\n    font-size: 20px;\n    color: #666;\n}\n\nh2 {\n    font-size: 16px;\n    margin: 1em 0 .5em 0;\n}\n\nh2.subhead {\n    font-weight: normal;\n    margin-top: 0;\n}\n\nh3 {\n    font-size: 14px;\n    margin: .8em 0 .3em 0;\n    color: #666;\n    font-weight: bold;\n}\n\nh4 {\n    font-size: 12px;\n    margin: 1em 0 .8em 0;\n    padding-bottom: 3px;\n}\n\nh5 {\n    font-size: 10px;\n    margin: 1.5em 0 .5em 0;\n    color: #666;\n    text-transform: uppercase;\n    letter-spacing: 1px;\n}\n\nul li {\n    list-style-type: square;\n    padding: 1px 0;\n}\n\nli ul {\n    margin-bottom: 0;\n}\n\nli, dt, dd {\n    font-size: 13px;\n    line-height: 20px;\n}\n\ndt {\n    font-weight: bold;\n    margin-top: 4px;\n}\n\ndd {\n    margin-left: 0;\n}\n\nform {\n    margin: 0;\n    padding: 0;\n}\n\nfieldset {\n    margin: 0;\n    padding: 0;\n    border: none;\n    border-top: 1px solid #eee;\n}\n\nblockquote {\n    font-size: 11px;\n    color: #777;\n    margin-left: 2px;\n    padding-left: 10px;\n    border-left: 5px solid #ddd;\n}\n\ncode, pre {\n    font-family: \"Bitstream Vera Sans Mono\", Monaco, \"Courier New\", Courier, monospace;\n    color: #666;\n    font-size: 12px;\n}\n\npre.literal-block {\n    margin: 10px;\n    background: #eee;\n    padding: 6px 8px;\n}\n\ncode strong {\n    color: #930;\n}\n\nhr {\n    clear: both;\n    color: #eee;\n    background-color: #eee;\n    height: 1px;\n    border: none;\n    margin: 0;\n    padding: 0;\n    font-size: 1px;\n    line-height: 1px;\n}\n\n/* TEXT STYLES & MODIFIERS */\n\n.small {\n    font-size: 11px;\n}\n\n.tiny {\n    font-size: 10px;\n}\n\np.tiny {\n    margin-top: -2px;\n}\n\n.mini {\n    font-size: 10px;\n}\n\np.mini {\n    margin-top: -3px;\n}\n\n.help, p.help, form p.help, div.help, form div.help, div.help li {\n    font-size: 11px;\n    color: #999;\n}\n\ndiv.help ul {\n     margin-bottom: 0;\n}\n\n.help-tooltip {\n    cursor: help;\n}\n\np img, h1 img, h2 img, h3 img, h4 img, td img {\n    vertical-align: middle;\n}\n\n.quiet, a.quiet:link, a.quiet:visited {\n    color: #999;\n    font-weight: normal;\n}\n\n.float-right {\n    float: right;\n}\n\n.float-left {\n    float: left;\n}\n\n.clear {\n    clear: both;\n}\n\n.align-left {\n    text-align: left;\n}\n\n.align-right {\n    text-align: right;\n}\n\n.example {\n    margin: 10px 0;\n    padding: 5px 10px;\n    background: #efefef;\n}\n\n.nowrap {\n    white-space: nowrap;\n}\n\n/* TABLES */\n\ntable {\n    border-collapse: collapse;\n    border-color: #ccc;\n}\n\ntd, th {\n    font-size: 13px;\n    line-height: 16px;\n    border-bottom: 1px solid #eee;\n    vertical-align: top;\n    padding: 8px;\n    font-family: \"Roboto\", \"Lucida Grande\", Verdana, Arial, sans-serif;\n}\n\nth {\n    font-weight: 600;\n    text-align: left;\n}\n\nthead th,\ntfoot td {\n    color: #666;\n    padding: 5px 10px;\n    font-size: 11px;\n    background: #fff;\n    border: none;\n    border-top: 1px solid #eee;\n    border-bottom: 1px solid #eee;\n}\n\ntfoot td {\n    border-bottom: none;\n    border-top: 1px solid #eee;\n}\n\nthead th.required {\n    color: #000;\n}\n\ntr.alt {\n    background: #f6f6f6;\n}\n\n.row1 {\n    background: #fff;\n}\n\n.row2 {\n    background: #f9f9f9;\n}\n\n/* SORTABLE TABLES */\n\nthead th {\n    padding: 5px 10px;\n    line-height: normal;\n    text-transform: uppercase;\n    background: #f6f6f6;\n}\n\nthead th a:link, thead th a:visited {\n    color: #666;\n}\n\nthead th.sorted {\n    background: #eee;\n}\n\nthead th.sorted .text {\n    padding-right: 42px;\n}\n\ntable thead th .text span {\n    padding: 8px 10px;\n    display: block;\n}\n\ntable thead th .text a {\n    display: block;\n    cursor: pointer;\n    padding: 8px 10px;\n}\n\ntable thead th .text a:focus, table thead th .text a:hover {\n    background: #eee;\n}\n\nthead th.sorted a.sortremove {\n    visibility: hidden;\n}\n\ntable thead th.sorted:hover a.sortremove {\n    visibility: visible;\n}\n\ntable thead th.sorted .sortoptions {\n    display: block;\n    padding: 9px 5px 0 5px;\n    float: right;\n    text-align: right;\n}\n\ntable thead th.sorted .sortpriority {\n    font-size: .8em;\n    min-width: 12px;\n    text-align: center;\n    vertical-align: 3px;\n    margin-left: 2px;\n    margin-right: 2px;\n}\n\ntable thead th.sorted .sortoptions a {\n    position: relative;\n    width: 14px;\n    height: 14px;\n    display: inline-block;\n    background: url(../img/sorting-icons.svg) 0 0 no-repeat;\n    background-size: 14px auto;\n}\n\ntable thead th.sorted .sortoptions a.sortremove {\n    background-position: 0 0;\n}\n\ntable thead th.sorted .sortoptions a.sortremove:after {\n    content: '\\\\';\n    position: absolute;\n    top: -6px;\n    left: 3px;\n    font-weight: 200;\n    font-size: 18px;\n    color: #999;\n}\n\ntable thead th.sorted .sortoptions a.sortremove:focus:after,\ntable thead th.sorted .sortoptions a.sortremove:hover:after {\n    color: #447e9b;\n}\n\ntable thead th.sorted .sortoptions a.sortremove:focus,\ntable thead th.sorted .sortoptions a.sortremove:hover {\n    background-position: 0 -14px;\n}\n\ntable thead th.sorted .sortoptions a.ascending {\n    background-position: 0 -28px;\n}\n\ntable thead th.sorted .sortoptions a.ascending:focus,\ntable thead th.sorted .sortoptions a.ascending:hover {\n    background-position: 0 -42px;\n}\n\ntable thead th.sorted .sortoptions a.descending {\n    top: 1px;\n    background-position: 0 -56px;\n}\n\ntable thead th.sorted .sortoptions a.descending:focus,\ntable thead th.sorted .sortoptions a.descending:hover {\n    background-position: 0 -70px;\n}\n\n/* FORM DEFAULTS */\n\ninput, textarea, select, .form-row p, form .button {\n    margin: 2px 0;\n    padding: 2px 3px;\n    vertical-align: middle;\n    font-family: \"Roboto\", \"Lucida Grande\", Verdana, Arial, sans-serif;\n    font-weight: normal;\n    font-size: 13px;\n}\n.form-row div.help {\n    padding: 2px 3px;\n}\n\ntextarea {\n    vertical-align: top;\n}\n\ninput[type=text], input[type=password], input[type=email], input[type=url],\ninput[type=number], input[type=tel], textarea, select, .vTextField {\n    border: 1px solid #ccc;\n    border-radius: 4px;\n    padding: 5px 6px;\n    margin-top: 0;\n}\n\ninput[type=text]:focus, input[type=password]:focus, input[type=email]:focus,\ninput[type=url]:focus, input[type=number]:focus, input[type=tel]:focus,\ntextarea:focus, select:focus, .vTextField:focus {\n    border-color: #999;\n}\n\nselect {\n    height: 30px;\n}\n\nselect[multiple] {\n    /* Allow HTML size attribute to override the height in the rule above. */\n    height: auto;\n    min-height: 150px;\n}\n\n/* FORM BUTTONS */\n\n.button, input[type=submit], input[type=button], .submit-row input, a.button {\n    background: #79aec8;\n    padding: 10px 15px;\n    border: none;\n    border-radius: 4px;\n    color: #fff;\n    cursor: pointer;\n}\n\na.button {\n    padding: 4px 5px;\n}\n\n.button:active, input[type=submit]:active, input[type=button]:active,\n.button:focus, input[type=submit]:focus, input[type=button]:focus,\n.button:hover, input[type=submit]:hover, input[type=button]:hover {\n    background: #609ab6;\n}\n\n.button[disabled], input[type=submit][disabled], input[type=button][disabled] {\n    opacity: 0.4;\n}\n\n.button.default, input[type=submit].default, .submit-row input.default {\n    float: right;\n    border: none;\n    font-weight: 400;\n    background: #417690;\n}\n\n.button.default:active, input[type=submit].default:active,\n.button.default:focus, input[type=submit].default:focus,\n.button.default:hover, input[type=submit].default:hover {\n    background: #205067;\n}\n\n.button[disabled].default,\ninput[type=submit][disabled].default,\ninput[type=button][disabled].default {\n    opacity: 0.4;\n}\n\n\n/* MODULES */\n\n.module {\n    border: none;\n    margin-bottom: 30px;\n    background: #fff;\n}\n\n.module p, .module ul, .module h3, .module h4, .module dl, .module pre {\n    padding-left: 10px;\n    padding-right: 10px;\n}\n\n.module blockquote {\n    margin-left: 12px;\n}\n\n.module ul, .module ol {\n    margin-left: 1.5em;\n}\n\n.module h3 {\n    margin-top: .6em;\n}\n\n.module h2, .module caption, .inline-group h2 {\n    margin: 0;\n    padding: 8px;\n    font-weight: 400;\n    font-size: 13px;\n    text-align: left;\n    background: #79aec8;\n    color: #fff;\n}\n\n.module caption,\n.inline-group h2 {\n    font-size: 12px;\n    letter-spacing: 0.5px;\n    text-transform: uppercase;\n}\n\n.module table {\n    border-collapse: collapse;\n}\n\n/* MESSAGES & ERRORS */\n\nul.messagelist {\n    padding: 0;\n    margin: 0;\n}\n\nul.messagelist li {\n    display: block;\n    font-weight: 400;\n    font-size: 13px;\n    padding: 10px 10px 10px 65px;\n    margin: 0 0 10px 0;\n    background: #dfd url(../img/icon-yes.svg) 40px 12px no-repeat;\n    background-size: 16px auto;\n    color: #333;\n}\n\nul.messagelist li.warning {\n    background: #ffc url(../img/icon-alert.svg) 40px 14px no-repeat;\n    background-size: 14px auto;\n}\n\nul.messagelist li.error {\n    background: #ffefef url(../img/icon-no.svg) 40px 12px no-repeat;\n    background-size: 16px auto;\n}\n\n.errornote {\n    font-size: 14px;\n    font-weight: 700;\n    display: block;\n    padding: 10px 12px;\n    margin: 0 0 10px 0;\n    color: #ba2121;\n    border: 1px solid #ba2121;\n    border-radius: 4px;\n    background-color: #fff;\n    background-position: 5px 12px;\n}\n\nul.errorlist {\n    margin: 0 0 4px;\n    padding: 0;\n    color: #ba2121;\n    background: #fff;\n}\n\nul.errorlist li {\n    font-size: 13px;\n    display: block;\n    margin-bottom: 4px;\n}\n\nul.errorlist li:first-child {\n    margin-top: 0;\n}\n\nul.errorlist li a {\n    color: inherit;\n    text-decoration: underline;\n}\n\ntd ul.errorlist {\n    margin: 0;\n    padding: 0;\n}\n\ntd ul.errorlist li {\n    margin: 0;\n}\n\n.form-row.errors {\n    margin: 0;\n    border: none;\n    border-bottom: 1px solid #eee;\n    background: none;\n}\n\n.form-row.errors ul.errorlist li {\n    padding-left: 0;\n}\n\n.errors input, .errors select, .errors textarea {\n    border: 1px solid #ba2121;\n}\n\ndiv.system-message {\n    background: #ffc;\n    margin: 10px;\n    padding: 6px 8px;\n    font-size: .8em;\n}\n\ndiv.system-message p.system-message-title {\n    padding: 4px 5px 4px 25px;\n    margin: 0;\n    color: #c11;\n    background: #ffefef url(../img/icon-no.svg) 5px 5px no-repeat;\n}\n\n.description {\n    font-size: 12px;\n    padding: 5px 0 0 12px;\n}\n\n/* BREADCRUMBS */\n\ndiv.breadcrumbs {\n    background: #79aec8;\n    padding: 10px 40px;\n    border: none;\n    font-size: 14px;\n    color: #c4dce8;\n    text-align: left;\n}\n\ndiv.breadcrumbs a {\n    color: #fff;\n}\n\ndiv.breadcrumbs a:focus, div.breadcrumbs a:hover {\n    color: #c4dce8;\n}\n\n/* ACTION ICONS */\n\n.viewlink, .inlineviewlink {\n    padding-left: 16px;\n    background: url(../img/icon-viewlink.svg) 0 1px no-repeat;\n}\n\n.addlink {\n    padding-left: 16px;\n    background: url(../img/icon-addlink.svg) 0 1px no-repeat;\n}\n\n.changelink, .inlinechangelink {\n    padding-left: 16px;\n    background: url(../img/icon-changelink.svg) 0 1px no-repeat;\n}\n\n.deletelink {\n    padding-left: 16px;\n    background: url(../img/icon-deletelink.svg) 0 1px no-repeat;\n}\n\na.deletelink:link, a.deletelink:visited {\n    color: #CC3434;\n}\n\na.deletelink:focus, a.deletelink:hover {\n    color: #993333;\n    text-decoration: none;\n}\n\n/* OBJECT TOOLS */\n\n.object-tools {\n    font-size: 10px;\n    font-weight: bold;\n    padding-left: 0;\n    float: right;\n    position: relative;\n    margin-top: -48px;\n}\n\n.form-row .object-tools {\n    margin-top: 5px;\n    margin-bottom: 5px;\n    float: none;\n    height: 2em;\n    padding-left: 3.5em;\n}\n\n.object-tools li {\n    display: block;\n    float: left;\n    margin-left: 5px;\n    height: 16px;\n}\n\n.object-tools a {\n    border-radius: 15px;\n}\n\n.object-tools a:link, .object-tools a:visited {\n    display: block;\n    float: left;\n    padding: 3px 12px;\n    background: #999;\n    font-weight: 400;\n    font-size: 11px;\n    text-transform: uppercase;\n    letter-spacing: 0.5px;\n    color: #fff;\n}\n\n.object-tools a:focus, .object-tools a:hover {\n    background-color: #417690;\n}\n\n.object-tools a:focus{\n    text-decoration: none;\n}\n\n.object-tools a.viewsitelink, .object-tools a.golink,.object-tools a.addlink {\n    background-repeat: no-repeat;\n    background-position: right 7px center;\n    padding-right: 26px;\n}\n\n.object-tools a.viewsitelink, .object-tools a.golink {\n    background-image: url(../img/tooltag-arrowright.svg);\n}\n\n.object-tools a.addlink {\n    background-image: url(../img/tooltag-add.svg);\n}\n\n/* OBJECT HISTORY */\n\ntable#change-history {\n    width: 100%;\n}\n\ntable#change-history tbody th {\n    width: 16em;\n}\n\n/* PAGE STRUCTURE */\n\n#container {\n    position: relative;\n    width: 100%;\n    min-width: 980px;\n    padding: 0;\n}\n\n#content {\n    padding: 20px 40px;\n}\n\n.dashboard #content {\n    width: 600px;\n}\n\n#content-main {\n    float: left;\n    width: 100%;\n}\n\n#content-related {\n    float: right;\n    width: 260px;\n    position: relative;\n    margin-right: -300px;\n}\n\n#footer {\n    clear: both;\n    padding: 10px;\n}\n\n/* COLUMN TYPES */\n\n.colMS {\n    margin-right: 300px;\n}\n\n.colSM {\n    margin-left: 300px;\n}\n\n.colSM #content-related {\n    float: left;\n    margin-right: 0;\n    margin-left: -300px;\n}\n\n.colSM #content-main {\n    float: right;\n}\n\n.popup .colM {\n    width: auto;\n}\n\n/* HEADER */\n\n#header {\n    width: auto;\n    height: auto;\n    display: flex;\n    justify-content: space-between;\n    align-items: center;\n    padding: 10px 40px;\n    background: #417690;\n    color: #ffc;\n    overflow: hidden;\n}\n\n#header a:link, #header a:visited {\n    color: #fff;\n}\n\n#header a:focus , #header a:hover {\n    text-decoration: underline;\n}\n\n#branding {\n    float: left;\n}\n\n#branding h1 {\n    padding: 0;\n    margin: 0 20px 0 0;\n    font-weight: 300;\n    font-size: 24px;\n    color: #f5dd5d;\n}\n\n#branding h1, #branding h1 a:link, #branding h1 a:visited {\n    color: #f5dd5d;\n}\n\n#branding h2 {\n    padding: 0 10px;\n    font-size: 14px;\n    margin: -8px 0 8px 0;\n    font-weight: normal;\n    color: #ffc;\n}\n\n#branding a:hover {\n    text-decoration: none;\n}\n\n#user-tools {\n    float: right;\n    padding: 0;\n    margin: 0 0 0 20px;\n    font-weight: 300;\n    font-size: 11px;\n    letter-spacing: 0.5px;\n    text-transform: uppercase;\n    text-align: right;\n}\n\n#user-tools a {\n    border-bottom: 1px solid rgba(255, 255, 255, 0.25);\n}\n\n#user-tools a:focus, #user-tools a:hover {\n    text-decoration: none;\n    border-bottom-color: #79aec8;\n    color: #79aec8;\n}\n\n/* SIDEBAR */\n\n#content-related {\n    background: #f8f8f8;\n}\n\n#content-related .module {\n    background: none;\n}\n\n#content-related h3 {\n    font-size: 14px;\n    color: #666;\n    padding: 0 16px;\n    margin: 0 0 16px;\n}\n\n#content-related h4 {\n    font-size: 13px;\n}\n\n#content-related p {\n    padding-left: 16px;\n    padding-right: 16px;\n}\n\n#content-related .actionlist {\n    padding: 0;\n    margin: 16px;\n}\n\n#content-related .actionlist li {\n    line-height: 1.2;\n    margin-bottom: 10px;\n    padding-left: 18px;\n}\n\n#content-related .module h2 {\n    background: none;\n    padding: 16px;\n    margin-bottom: 16px;\n    border-bottom: 1px solid #eaeaea;\n    font-size: 18px;\n    color: #333;\n}\n\n.delete-confirmation form input[type=\"submit\"] {\n    background: #ba2121;\n    border-radius: 4px;\n    padding: 10px 15px;\n    color: #fff;\n}\n\n.delete-confirmation form input[type=\"submit\"]:active,\n.delete-confirmation form input[type=\"submit\"]:focus,\n.delete-confirmation form input[type=\"submit\"]:hover {\n    background: #a41515;\n}\n\n.delete-confirmation form .cancel-link {\n    display: inline-block;\n    vertical-align: middle;\n    height: 15px;\n    line-height: 15px;\n    background: #ddd;\n    border-radius: 4px;\n    padding: 10px 15px;\n    color: #333;\n    margin: 0 0 0 10px;\n}\n\n.delete-confirmation form .cancel-link:active,\n.delete-confirmation form .cancel-link:focus,\n.delete-confirmation form .cancel-link:hover {\n    background: #ccc;\n}\n\n/* POPUP */\n.popup #content {\n    padding: 20px;\n}\n\n.popup #container {\n    min-width: 0;\n}\n\n.popup #header {\n    padding: 10px 20px;\n}\n"
  },
  {
    "path": "src/static_cdn/admin/css/changelists.css",
    "content": "/* CHANGELISTS */\n\n#changelist {\n    position: relative;\n    width: 100%;\n}\n\n#changelist table {\n    width: 100%;\n}\n\n.change-list .hiddenfields { display:none; }\n\n.change-list .filtered table {\n    border-right: none;\n}\n\n.change-list .filtered {\n    min-height: 400px;\n}\n\n.change-list .filtered .results, .change-list .filtered .paginator,\n.filtered #toolbar, .filtered div.xfull {\n    margin-right: 280px;\n    width: auto;\n}\n\n.change-list .filtered table tbody th {\n    padding-right: 1em;\n}\n\n#changelist-form .results {\n  overflow-x: auto;\n}\n\n#changelist .toplinks {\n    border-bottom: 1px solid #ddd;\n}\n\n#changelist .paginator {\n    color: #666;\n    border-bottom: 1px solid #eee;\n    background: #fff;\n    overflow: hidden;\n}\n\n/* CHANGELIST TABLES */\n\n#changelist table thead th {\n    padding: 0;\n    white-space: nowrap;\n    vertical-align: middle;\n}\n\n#changelist table thead th.action-checkbox-column {\n    width: 1.5em;\n    text-align: center;\n}\n\n#changelist table tbody td.action-checkbox {\n    text-align: center;\n}\n\n#changelist table tfoot {\n    color: #666;\n}\n\n/* TOOLBAR */\n\n#changelist #toolbar {\n    padding: 8px 10px;\n    margin-bottom: 15px;\n    border-top: 1px solid #eee;\n    border-bottom: 1px solid #eee;\n    background: #f8f8f8;\n    color: #666;\n}\n\n#changelist #toolbar form input {\n    border-radius: 4px;\n    font-size: 14px;\n    padding: 5px;\n    color: #333;\n}\n\n#changelist #toolbar form #searchbar {\n    height: 19px;\n    border: 1px solid #ccc;\n    padding: 2px 5px;\n    margin: 0;\n    vertical-align: top;\n    font-size: 13px;\n}\n\n#changelist #toolbar form #searchbar:focus {\n    border-color: #999;\n}\n\n#changelist #toolbar form input[type=\"submit\"] {\n    border: 1px solid #ccc;\n    padding: 2px 10px;\n    margin: 0;\n    vertical-align: middle;\n    background: #fff;\n    box-shadow: 0 -15px 20px -10px rgba(0, 0, 0, 0.15) inset;\n    cursor: pointer;\n    color: #333;\n}\n\n#changelist #toolbar form input[type=\"submit\"]:focus,\n#changelist #toolbar form input[type=\"submit\"]:hover {\n    border-color: #999;\n}\n\n#changelist #changelist-search img {\n    vertical-align: middle;\n    margin-right: 4px;\n}\n\n/* FILTER COLUMN */\n\n#changelist-filter {\n    position: absolute;\n    top: 0;\n    right: 0;\n    z-index: 1000;\n    width: 240px;\n    background: #f8f8f8;\n    border-left: none;\n    margin: 0;\n}\n\n#changelist-filter h2 {\n    font-size: 14px;\n    text-transform: uppercase;\n    letter-spacing: 0.5px;\n    padding: 5px 15px;\n    margin-bottom: 12px;\n    border-bottom: none;\n}\n\n#changelist-filter h3 {\n    font-weight: 400;\n    font-size: 14px;\n    padding: 0 15px;\n    margin-bottom: 10px;\n}\n\n#changelist-filter ul {\n    margin: 5px 0;\n    padding: 0 15px 15px;\n    border-bottom: 1px solid #eaeaea;\n}\n\n#changelist-filter ul:last-child {\n    border-bottom: none;\n    padding-bottom: none;\n}\n\n#changelist-filter li {\n    list-style-type: none;\n    margin-left: 0;\n    padding-left: 0;\n}\n\n#changelist-filter a {\n    display: block;\n    color: #999;\n    text-overflow: ellipsis;\n    overflow-x: hidden;\n}\n\n#changelist-filter li.selected {\n    border-left: 5px solid #eaeaea;\n    padding-left: 10px;\n    margin-left: -15px;\n}\n\n#changelist-filter li.selected a {\n    color: #5b80b2;\n}\n\n#changelist-filter a:focus, #changelist-filter a:hover,\n#changelist-filter li.selected a:focus,\n#changelist-filter li.selected a:hover {\n    color: #036;\n}\n\n/* DATE DRILLDOWN */\n\n.change-list ul.toplinks {\n    display: block;\n    float: left;\n    padding: 0;\n    margin: 0;\n    width: 100%;\n}\n\n.change-list ul.toplinks li {\n    padding: 3px 6px;\n    font-weight: bold;\n    list-style-type: none;\n    display: inline-block;\n}\n\n.change-list ul.toplinks .date-back a {\n    color: #999;\n}\n\n.change-list ul.toplinks .date-back a:focus,\n.change-list ul.toplinks .date-back a:hover {\n    color: #036;\n}\n\n/* PAGINATOR */\n\n.paginator {\n    font-size: 13px;\n    padding-top: 10px;\n    padding-bottom: 10px;\n    line-height: 22px;\n    margin: 0;\n    border-top: 1px solid #ddd;\n}\n\n.paginator a:link, .paginator a:visited {\n    padding: 2px 6px;\n    background: #79aec8;\n    text-decoration: none;\n    color: #fff;\n}\n\n.paginator a.showall {\n    padding: 0;\n    border: none;\n    background: none;\n    color: #5b80b2;\n}\n\n.paginator a.showall:focus, .paginator a.showall:hover {\n    background: none;\n    color: #036;\n}\n\n.paginator .end {\n    margin-right: 6px;\n}\n\n.paginator .this-page {\n    padding: 2px 6px;\n    font-weight: bold;\n    font-size: 13px;\n    vertical-align: top;\n}\n\n.paginator a:focus, .paginator a:hover {\n    color: white;\n    background: #036;\n}\n\n/* ACTIONS */\n\n.filtered .actions {\n    margin-right: 280px;\n    border-right: none;\n}\n\n#changelist table input {\n    margin: 0;\n    vertical-align: baseline;\n}\n\n#changelist table tbody tr.selected {\n    background-color: #FFFFCC;\n}\n\n#changelist .actions {\n    padding: 10px;\n    background: #fff;\n    border-top: none;\n    border-bottom: none;\n    line-height: 24px;\n    color: #999;\n}\n\n#changelist .actions.selected {\n    background: #fffccf;\n    border-top: 1px solid #fffee8;\n    border-bottom: 1px solid #edecd6;\n}\n\n#changelist .actions span.all,\n#changelist .actions span.action-counter,\n#changelist .actions span.clear,\n#changelist .actions span.question {\n    font-size: 13px;\n    margin: 0 0.5em;\n    display: none;\n}\n\n#changelist .actions:last-child {\n    border-bottom: none;\n}\n\n#changelist .actions select {\n    vertical-align: top;\n    height: 24px;\n    background: none;\n    color: #000;\n    border: 1px solid #ccc;\n    border-radius: 4px;\n    font-size: 14px;\n    padding: 0 0 0 4px;\n    margin: 0;\n    margin-left: 10px;\n}\n\n#changelist .actions select:focus {\n    border-color: #999;\n}\n\n#changelist .actions label {\n    display: inline-block;\n    vertical-align: middle;\n    font-size: 13px;\n}\n\n#changelist .actions .button {\n    font-size: 13px;\n    border: 1px solid #ccc;\n    border-radius: 4px;\n    background: #fff;\n    box-shadow: 0 -15px 20px -10px rgba(0, 0, 0, 0.15) inset;\n    cursor: pointer;\n    height: 24px;\n    line-height: 1;\n    padding: 4px 8px;\n    margin: 0;\n    color: #333;\n}\n\n#changelist .actions .button:focus, #changelist .actions .button:hover {\n    border-color: #999;\n}\n"
  },
  {
    "path": "src/static_cdn/admin/css/dashboard.css",
    "content": "/* DASHBOARD */\n\n.dashboard .module table th {\n    width: 100%;\n}\n\n.dashboard .module table td {\n    white-space: nowrap;\n}\n\n.dashboard .module table td a {\n    display: block;\n    padding-right: .6em;\n}\n\n/* RECENT ACTIONS MODULE */\n\n.module ul.actionlist {\n    margin-left: 0;\n}\n\nul.actionlist li {\n    list-style-type: none;\n    overflow: hidden;\n    text-overflow: ellipsis;\n    -o-text-overflow: ellipsis;\n}\n"
  },
  {
    "path": "src/static_cdn/admin/css/fonts.css",
    "content": "@font-face {\n    font-family: 'Roboto';\n    src: url('../fonts/Roboto-Bold-webfont.woff');\n    font-weight: 700;\n    font-style: normal;\n}\n\n@font-face {\n    font-family: 'Roboto';\n    src: url('../fonts/Roboto-Regular-webfont.woff');\n    font-weight: 400;\n    font-style: normal;\n}\n\n@font-face {\n    font-family: 'Roboto';\n    src: url('../fonts/Roboto-Light-webfont.woff');\n    font-weight: 300;\n    font-style: normal;\n}\n"
  },
  {
    "path": "src/static_cdn/admin/css/forms.css",
    "content": "@import url('widgets.css');\n\n/* FORM ROWS */\n\n.form-row {\n    overflow: hidden;\n    padding: 10px;\n    font-size: 13px;\n    border-bottom: 1px solid #eee;\n}\n\n.form-row img, .form-row input {\n    vertical-align: middle;\n}\n\n.form-row label input[type=\"checkbox\"] {\n    margin-top: 0;\n    vertical-align: 0;\n}\n\nform .form-row p {\n    padding-left: 0;\n}\n\n.hidden {\n    display: none;\n}\n\n/* FORM LABELS */\n\nlabel {\n    font-weight: normal;\n    color: #666;\n    font-size: 13px;\n}\n\n.required label, label.required {\n    font-weight: bold;\n    color: #333;\n}\n\n/* RADIO BUTTONS */\n\nform ul.radiolist li {\n    list-style-type: none;\n}\n\nform ul.radiolist label {\n    float: none;\n    display: inline;\n}\n\nform ul.radiolist input[type=\"radio\"] {\n    margin: -2px 4px 0 0;\n    padding: 0;\n}\n\nform ul.inline {\n    margin-left: 0;\n    padding: 0;\n}\n\nform ul.inline li {\n    float: left;\n    padding-right: 7px;\n}\n\n/* ALIGNED FIELDSETS */\n\n.aligned label {\n    display: block;\n    padding: 4px 10px 0 0;\n    float: left;\n    width: 160px;\n    word-wrap: break-word;\n    line-height: 1;\n}\n\n.aligned label:not(.vCheckboxLabel):after {\n    content: '';\n    display: inline-block;\n    vertical-align: middle;\n    height: 26px;\n}\n\n.aligned label + p, .aligned label + div.help, .aligned label + div.readonly {\n    padding: 6px 0;\n    margin-top: 0;\n    margin-bottom: 0;\n    margin-left: 170px;\n}\n\n.aligned ul label {\n    display: inline;\n    float: none;\n    width: auto;\n}\n\n.aligned .form-row input {\n    margin-bottom: 0;\n}\n\n.colMS .aligned .vLargeTextField, .colMS .aligned .vXMLLargeTextField {\n    width: 350px;\n}\n\nform .aligned ul {\n    margin-left: 160px;\n    padding-left: 10px;\n}\n\nform .aligned ul.radiolist {\n    display: inline-block;\n    margin: 0;\n    padding: 0;\n}\n\nform .aligned p.help,\nform .aligned div.help {\n    clear: left;\n    margin-top: 0;\n    margin-left: 160px;\n    padding-left: 10px;\n}\n\nform .aligned label + p.help,\nform .aligned label + div.help {\n    margin-left: 0;\n    padding-left: 0;\n}\n\nform .aligned p.help:last-child,\nform .aligned div.help:last-child {\n    margin-bottom: 0;\n    padding-bottom: 0;\n}\n\nform .aligned input + p.help,\nform .aligned textarea + p.help,\nform .aligned select + p.help,\nform .aligned input + div.help,\nform .aligned textarea + div.help,\nform .aligned select + div.help {\n    margin-left: 160px;\n    padding-left: 10px;\n}\n\nform .aligned ul li {\n    list-style: none;\n}\n\nform .aligned table p {\n    margin-left: 0;\n    padding-left: 0;\n}\n\n.aligned .vCheckboxLabel {\n    float: none;\n    width: auto;\n    display: inline-block;\n    vertical-align: -3px;\n    padding: 0 0 5px 5px;\n}\n\n.aligned .vCheckboxLabel + p.help,\n.aligned .vCheckboxLabel + div.help {\n    margin-top: -4px;\n}\n\n.colM .aligned .vLargeTextField, .colM .aligned .vXMLLargeTextField {\n    width: 610px;\n}\n\n.checkbox-row p.help,\n.checkbox-row div.help {\n    margin-left: 0;\n    padding-left: 0;\n}\n\nfieldset .fieldBox {\n    float: left;\n    margin-right: 20px;\n}\n\n/* WIDE FIELDSETS */\n\n.wide label {\n    width: 200px;\n}\n\nform .wide p,\nform .wide input + p.help,\nform .wide input + div.help {\n    margin-left: 200px;\n}\n\nform .wide p.help,\nform .wide div.help {\n    padding-left: 38px;\n}\n\nform div.help ul {\n    padding-left: 0;\n    margin-left: 0;\n}\n\n.colM fieldset.wide .vLargeTextField, .colM fieldset.wide .vXMLLargeTextField {\n    width: 450px;\n}\n\n/* COLLAPSED FIELDSETS */\n\nfieldset.collapsed * {\n    display: none;\n}\n\nfieldset.collapsed h2, fieldset.collapsed {\n    display: block;\n}\n\nfieldset.collapsed {\n    border: 1px solid #eee;\n    border-radius: 4px;\n    overflow: hidden;\n}\n\nfieldset.collapsed h2 {\n    background: #f8f8f8;\n    color: #666;\n}\n\nfieldset .collapse-toggle {\n    color: #fff;\n}\n\nfieldset.collapsed .collapse-toggle {\n    background: transparent;\n    display: inline;\n    color: #447e9b;\n}\n\n/* MONOSPACE TEXTAREAS */\n\nfieldset.monospace textarea {\n    font-family: \"Bitstream Vera Sans Mono\", Monaco, \"Courier New\", Courier, monospace;\n}\n\n/* SUBMIT ROW */\n\n.submit-row {\n    padding: 12px 14px;\n    margin: 0 0 20px;\n    background: #f8f8f8;\n    border: 1px solid #eee;\n    border-radius: 4px;\n    text-align: right;\n    overflow: hidden;\n}\n\nbody.popup .submit-row {\n    overflow: auto;\n}\n\n.submit-row input {\n    height: 35px;\n    line-height: 15px;\n    margin: 0 0 0 5px;\n}\n\n.submit-row input.default {\n    margin: 0 0 0 8px;\n    text-transform: uppercase;\n}\n\n.submit-row p {\n    margin: 0.3em;\n}\n\n.submit-row p.deletelink-box {\n    float: left;\n    margin: 0;\n}\n\n.submit-row a.deletelink {\n    display: block;\n    background: #ba2121;\n    border-radius: 4px;\n    padding: 10px 15px;\n    height: 15px;\n    line-height: 15px;\n    color: #fff;\n}\n\n.submit-row a.closelink {\n    display: inline-block;\n    background: #bbbbbb;\n    border-radius: 4px;\n    padding: 10px 15px;\n    height: 15px;\n    line-height: 15px;\n    margin: 0 0 0 5px;\n    color: #fff;\n}\n\n.submit-row a.deletelink:focus,\n.submit-row a.deletelink:hover,\n.submit-row a.deletelink:active {\n    background: #a41515;\n}\n\n.submit-row a.closelink:focus,\n.submit-row a.closelink:hover,\n.submit-row a.closelink:active {\n    background: #aaaaaa;\n}\n\n/* CUSTOM FORM FIELDS */\n\n.vSelectMultipleField {\n    vertical-align: top;\n}\n\n.vCheckboxField {\n    border: none;\n}\n\n.vDateField, .vTimeField {\n    margin-right: 2px;\n    margin-bottom: 4px;\n}\n\n.vDateField {\n    min-width: 6.85em;\n}\n\n.vTimeField {\n    min-width: 4.7em;\n}\n\n.vURLField {\n    width: 30em;\n}\n\n.vLargeTextField, .vXMLLargeTextField {\n    width: 48em;\n}\n\n.flatpages-flatpage #id_content {\n    height: 40.2em;\n}\n\n.module table .vPositiveSmallIntegerField {\n    width: 2.2em;\n}\n\n.vTextField, .vUUIDField {\n    width: 20em;\n}\n\n.vIntegerField {\n    width: 5em;\n}\n\n.vBigIntegerField {\n    width: 10em;\n}\n\n.vForeignKeyRawIdAdminField {\n    width: 5em;\n}\n\n/* INLINES */\n\n.inline-group {\n    padding: 0;\n    margin: 0 0 30px;\n}\n\n.inline-group thead th {\n    padding: 8px 10px;\n}\n\n.inline-group .aligned label {\n    width: 160px;\n}\n\n.inline-related {\n    position: relative;\n}\n\n.inline-related h3 {\n    margin: 0;\n    color: #666;\n    padding: 5px;\n    font-size: 13px;\n    background: #f8f8f8;\n    border-top: 1px solid #eee;\n    border-bottom: 1px solid #eee;\n}\n\n.inline-related h3 span.delete {\n    float: right;\n}\n\n.inline-related h3 span.delete label {\n    margin-left: 2px;\n    font-size: 11px;\n}\n\n.inline-related fieldset {\n    margin: 0;\n    background: #fff;\n    border: none;\n    width: 100%;\n}\n\n.inline-related fieldset.module h3 {\n    margin: 0;\n    padding: 2px 5px 3px 5px;\n    font-size: 11px;\n    text-align: left;\n    font-weight: bold;\n    background: #bcd;\n    color: #fff;\n}\n\n.inline-group .tabular fieldset.module {\n    border: none;\n}\n\n.inline-related.tabular fieldset.module table {\n    width: 100%;\n}\n\n.last-related fieldset {\n    border: none;\n}\n\n.inline-group .tabular tr.has_original td {\n    padding-top: 2em;\n}\n\n.inline-group .tabular tr td.original {\n    padding: 2px 0 0 0;\n    width: 0;\n    _position: relative;\n}\n\n.inline-group .tabular th.original {\n    width: 0px;\n    padding: 0;\n}\n\n.inline-group .tabular td.original p {\n    position: absolute;\n    left: 0;\n    height: 1.1em;\n    padding: 2px 9px;\n    overflow: hidden;\n    font-size: 9px;\n    font-weight: bold;\n    color: #666;\n    _width: 700px;\n}\n\n.inline-group ul.tools {\n    padding: 0;\n    margin: 0;\n    list-style: none;\n}\n\n.inline-group ul.tools li {\n    display: inline;\n    padding: 0 5px;\n}\n\n.inline-group div.add-row,\n.inline-group .tabular tr.add-row td {\n    color: #666;\n    background: #f8f8f8;\n    padding: 8px 10px;\n    border-bottom: 1px solid #eee;\n}\n\n.inline-group .tabular tr.add-row td {\n    padding: 8px 10px;\n    border-bottom: 1px solid #eee;\n}\n\n.inline-group ul.tools a.add,\n.inline-group div.add-row a,\n.inline-group .tabular tr.add-row td a {\n    background: url(../img/icon-addlink.svg) 0 1px no-repeat;\n    padding-left: 16px;\n    font-size: 12px;\n}\n\n.empty-form {\n    display: none;\n}\n\n/* RELATED FIELD ADD ONE / LOOKUP */\n\n.add-another, .related-lookup {\n    margin-left: 5px;\n    display: inline-block;\n    vertical-align: middle;\n    background-repeat: no-repeat;\n    background-size: 14px;\n}\n\n.add-another {\n    width: 16px;\n    height: 16px;\n    background-image: url(../img/icon-addlink.svg);\n}\n\n.related-lookup {\n    width: 16px;\n    height: 16px;\n    background-image: url(../img/search.svg);\n}\n\nform .related-widget-wrapper ul {\n    display: inline-block;\n    margin-left: 0;\n    padding-left: 0;\n}\n\n.clearable-file-input input {\n    margin-top: 0;\n}\n"
  },
  {
    "path": "src/static_cdn/admin/css/login.css",
    "content": "/* LOGIN FORM */\n\nbody.login {\n    background: #f8f8f8;\n}\n\n.login #header {\n    height: auto;\n    padding: 15px 16px;\n    justify-content: center;\n}\n\n.login #header h1 {\n    font-size: 18px;\n}\n\n.login #header h1 a {\n    color: #fff;\n}\n\n.login #content {\n    padding: 20px 20px 0;\n}\n\n.login #container {\n    background: #fff;\n    border: 1px solid #eaeaea;\n    border-radius: 4px;\n    overflow: hidden;\n    width: 28em;\n    min-width: 300px;\n    margin: 100px auto;\n}\n\n.login #content-main {\n    width: 100%;\n}\n\n.login .form-row {\n    padding: 4px 0;\n    float: left;\n    width: 100%;\n    border-bottom: none;\n}\n\n.login .form-row label {\n    padding-right: 0.5em;\n    line-height: 2em;\n    font-size: 1em;\n    clear: both;\n    color: #333;\n}\n\n.login .form-row #id_username, .login .form-row #id_password {\n    clear: both;\n    padding: 8px;\n    width: 100%;\n    -webkit-box-sizing: border-box;\n       -moz-box-sizing: border-box;\n            box-sizing: border-box;\n}\n\n.login span.help {\n    font-size: 10px;\n    display: block;\n}\n\n.login .submit-row {\n    clear: both;\n    padding: 1em 0 0 9.4em;\n    margin: 0;\n    border: none;\n    background: none;\n    text-align: left;\n}\n\n.login .password-reset-link {\n    text-align: center;\n}\n"
  },
  {
    "path": "src/static_cdn/admin/css/responsive.css",
    "content": "/* Tablets */\n\ninput[type=\"submit\"], button {\n    -webkit-appearance: none;\n    appearance: none;\n}\n\n@media (max-width: 1024px) {\n    /* Basic */\n\n    html {\n        -webkit-text-size-adjust: 100%;\n    }\n\n    td, th {\n        padding: 10px;\n        font-size: 14px;\n    }\n\n    .small {\n        font-size: 12px;\n    }\n\n    /* Layout */\n\n    #container {\n        min-width: 0;\n    }\n\n    #content {\n        padding: 20px 30px 30px;\n    }\n\n    div.breadcrumbs {\n        padding: 10px 30px;\n    }\n\n    /* Header */\n\n    #header {\n        flex-direction: column;\n        padding: 15px 30px;\n        justify-content: flex-start;\n    }\n\n    #branding h1 {\n        margin: 0 0 8px;\n        font-size: 20px;\n        line-height: 1.2;\n    }\n\n    #user-tools {\n        margin: 0;\n        font-weight: 400;\n        line-height: 1.85;\n        text-align: left;\n    }\n\n    #user-tools a {\n        display: inline-block;\n        line-height: 1.4;\n    }\n\n    /* Dashboard */\n\n    .dashboard #content {\n        width: auto;\n    }\n\n    #content-related {\n        margin-right: -290px;\n    }\n\n    .colSM #content-related {\n        margin-left: -290px;\n    }\n\n    .colMS {\n        margin-right: 290px;\n    }\n\n    .colSM {\n        margin-left: 290px;\n    }\n\n    .dashboard .module table td a {\n        padding-right: 0;\n    }\n\n    td .changelink, td .addlink {\n        font-size: 13px;\n    }\n\n    /* Changelist */\n\n    #changelist #toolbar {\n        border: none;\n        padding: 15px;\n    }\n\n    #changelist-search > div {\n        display: -webkit-flex;\n        display: flex;\n        -webkit-flex-wrap: wrap;\n        flex-wrap: wrap;\n        max-width: 480px;\n    }\n\n    #changelist-search label {\n        line-height: 22px;\n    }\n\n    #changelist #toolbar form #searchbar {\n        -webkit-flex: 1 0 auto;\n        flex: 1 0 auto;\n        width: 0;\n        height: 22px;\n        margin: 0 10px 0 6px;\n    }\n\n    #changelist-search .quiet {\n        width: 100%;\n        margin: 5px 0 0 25px;\n    }\n\n    #changelist .actions {\n        display: flex;\n        flex-wrap: wrap;\n        padding: 15px 0;\n    }\n\n    #changelist .actions.selected {\n        border: none;\n    }\n\n    #changelist .actions label {\n        display: flex;\n    }\n\n    #changelist .actions select {\n        background: #fff;\n    }\n\n    #changelist .actions .button {\n        min-width: 48px;\n        margin: 0 10px;\n    }\n\n    #changelist .actions span.all,\n    #changelist .actions span.clear,\n    #changelist .actions span.question,\n    #changelist .actions span.action-counter {\n        font-size: 11px;\n        margin: 0 10px 0 0;\n    }\n\n    #changelist-filter {\n        width: 200px;\n    }\n\n    .change-list .filtered .results,\n    .change-list .filtered .paginator,\n    .filtered #toolbar,\n    .filtered .actions,\n    .filtered div.xfull {\n        margin-right: 230px;\n    }\n\n    #changelist .paginator {\n        border-top-color: #eee;\n    }\n\n    #changelist .results + .paginator {\n        border-top: none;\n    }\n\n    /* Forms */\n\n    label {\n        font-size: 14px;\n    }\n\n    .form-row input[type=text],\n    .form-row input[type=password],\n    .form-row input[type=email],\n    .form-row input[type=url],\n    .form-row input[type=tel],\n    .form-row input[type=number],\n    .form-row textarea,\n    .form-row select,\n    .form-row .vTextField {\n        box-sizing: border-box;\n        margin: 0;\n        padding: 6px 8px;\n        min-height: 36px;\n        font-size: 14px;\n    }\n\n    .form-row select {\n        height: 36px;\n    }\n\n    .form-row select[multiple] {\n        height: auto;\n        min-height: 0;\n    }\n\n    fieldset .fieldBox {\n        float: none;\n        margin: 0 -10px;\n        padding: 0 10px;\n    }\n\n    fieldset .fieldBox + .fieldBox {\n        margin-top: 10px;\n        padding-top: 10px;\n        border-top: 1px solid #eee;\n    }\n\n    textarea {\n        max-width: 518px;\n        max-height: 120px;\n    }\n\n    .aligned label {\n        padding-top: 6px;\n    }\n\n    .aligned .add-another,\n    .aligned .related-lookup,\n    .aligned .datetimeshortcuts,\n    .aligned .related-lookup + strong {\n        align-self: center;\n        margin-left: 15px;\n    }\n\n    form .aligned ul.radiolist {\n        margin-left: 2px;\n    }\n\n    /* Related widget */\n\n    .related-widget-wrapper {\n        float: none;\n    }\n\n    .related-widget-wrapper-link + .selector {\n        max-width: calc(100% - 30px);\n        margin-right: 15px;\n    }\n\n    select + .related-widget-wrapper-link,\n    .related-widget-wrapper-link + .related-widget-wrapper-link {\n        margin-left: 10px;\n    }\n\n    /* Selector */\n\n    .selector {\n        display: flex;\n        width: 100%;\n    }\n\n    .selector .selector-filter {\n        display: flex;\n        align-items: center;\n    }\n\n    .selector .selector-filter label {\n        margin: 0 8px 0 0;\n    }\n\n    .selector .selector-filter input {\n        width: auto;\n        min-height: 0;\n        flex: 1 1;\n    }\n\n    .selector-available, .selector-chosen {\n        width: auto;\n        flex: 1 1;\n        display: flex;\n        flex-direction: column;\n    }\n\n    .selector select {\n        width: 100%;\n        flex: 1 0 auto;\n        margin-bottom: 5px;\n    }\n\n    .selector ul.selector-chooser {\n        width: 26px;\n        height: 52px;\n        padding: 2px 0;\n        margin: auto 15px;\n        border-radius: 20px;\n        transform: translateY(-10px);\n    }\n\n    .selector-add, .selector-remove {\n        width: 20px;\n        height: 20px;\n        background-size: 20px auto;\n    }\n\n    .selector-add {\n        background-position: 0 -120px;\n    }\n\n    .selector-remove {\n        background-position: 0 -80px;\n    }\n\n    a.selector-chooseall, a.selector-clearall {\n        align-self: center;\n    }\n\n    .stacked {\n        flex-direction: column;\n        max-width: 480px;\n    }\n\n    .stacked > * {\n        flex: 0 1 auto;\n    }\n\n    .stacked select {\n        margin-bottom: 0;\n    }\n\n    .stacked .selector-available, .stacked .selector-chosen {\n        width: auto;\n    }\n\n    .stacked ul.selector-chooser {\n        width: 52px;\n        height: 26px;\n        padding: 0 2px;\n        margin: 15px auto;\n        transform: none;\n    }\n\n    .stacked .selector-chooser li {\n        padding: 3px;\n    }\n\n    .stacked .selector-add, .stacked .selector-remove {\n        background-size: 20px auto;\n    }\n\n    .stacked .selector-add {\n        background-position: 0 -40px;\n    }\n\n    .stacked .active.selector-add {\n        background-position: 0 -60px;\n    }\n\n    .stacked .selector-remove {\n        background-position: 0 0;\n    }\n\n    .stacked .active.selector-remove {\n        background-position: 0 -20px;\n    }\n\n    .help-tooltip, .selector .help-icon {\n        display: none;\n    }\n\n    form .form-row p.datetime {\n        width: 100%;\n    }\n\n    .datetime input {\n        width: 50%;\n        max-width: 120px;\n    }\n\n    .datetime span {\n        font-size: 13px;\n    }\n\n    .datetime .timezonewarning {\n        display: block;\n        font-size: 11px;\n        color: #999;\n    }\n\n    .datetimeshortcuts {\n        color: #ccc;\n    }\n\n    .inline-group {\n        overflow: auto;\n    }\n\n    /* Messages */\n\n    ul.messagelist li {\n        padding-left: 55px;\n        background-position: 30px 12px;\n    }\n\n    ul.messagelist li.error {\n        background-position: 30px 12px;\n    }\n\n    ul.messagelist li.warning {\n        background-position: 30px 14px;\n    }\n\n    /* Login */\n\n    .login #header {\n        padding: 15px 20px;\n    }\n\n    .login #branding h1 {\n        margin: 0;\n    }\n\n    /* GIS */\n\n    div.olMap {\n        max-width: calc(100vw - 30px);\n        max-height: 300px;\n    }\n\n    .olMap + .clear_features {\n        display: block;\n        margin-top: 10px;\n    }\n\n    /* Docs */\n\n    .module table.xfull {\n        width: 100%;\n    }\n\n    pre.literal-block {\n        overflow: auto;\n    }\n}\n\n/* Mobile */\n\n@media (max-width: 767px) {\n    /* Layout */\n\n    #header, #content, #footer {\n        padding: 15px;\n    }\n\n    #footer:empty {\n        padding: 0;\n    }\n\n    div.breadcrumbs {\n        padding: 10px 15px;\n    }\n\n    /* Dashboard */\n\n    .colMS, .colSM {\n        margin: 0;\n    }\n\n    #content-related, .colSM #content-related {\n        width: 100%;\n        margin: 0;\n    }\n\n    #content-related .module {\n        margin-bottom: 0;\n    }\n\n    #content-related .module h2 {\n        padding: 10px 15px;\n        font-size: 16px;\n    }\n\n    /* Changelist */\n\n    #changelist {\n        display: flex;\n        flex-direction: column;\n    }\n\n    #changelist #toolbar {\n        order: 1;\n        padding: 10px;\n    }\n\n    #changelist .xfull {\n        order: 2;\n    }\n\n    #changelist-form {\n        order: 3;\n    }\n\n    #changelist-filter {\n        order: 4;\n    }\n\n    #changelist .actions label {\n        flex: 1 1;\n    }\n\n    #changelist .actions select {\n        flex: 1 0;\n        width: 100%;\n    }\n\n    #changelist .actions span {\n        flex: 1 0 100%;\n    }\n\n    .change-list .filtered .results, .change-list .filtered .paginator,\n    .filtered #toolbar, .filtered .actions, .filtered div.xfull {\n        margin-right: 0;\n    }\n\n    #changelist-filter {\n        position: static;\n        width: auto;\n        margin-top: 30px;\n    }\n\n    .object-tools {\n        float: none;\n        margin: 0 0 15px;\n        padding: 0;\n        overflow: hidden;\n    }\n\n    .object-tools li {\n        height: auto;\n        margin-left: 0;\n    }\n\n    .object-tools li + li {\n        margin-left: 15px;\n    }\n\n    /* Forms */\n\n    .form-row {\n        padding: 15px 0;\n    }\n\n    .aligned .form-row,\n    .aligned .form-row > div {\n        display: flex;\n        flex-wrap: wrap;\n        max-width: 100vw;\n    }\n\n    .aligned .form-row > div {\n        width: calc(100vw - 30px);\n    }\n\n    textarea {\n        max-width: none;\n    }\n\n    .vURLField {\n        width: auto;\n    }\n\n    fieldset .fieldBox + .fieldBox {\n        margin-top: 15px;\n        padding-top: 15px;\n    }\n\n    fieldset.collapsed .form-row {\n        display: none;\n    }\n\n    .aligned label {\n        width: 100%;\n        padding: 0 0 10px;\n    }\n\n    .aligned label:after {\n        max-height: 0;\n    }\n\n    .aligned .form-row input,\n    .aligned .form-row select,\n    .aligned .form-row textarea {\n        flex: 1 1 auto;\n        max-width: 100%;\n    }\n\n    .aligned .checkbox-row {\n        align-items: center;\n    }\n\n    .aligned .checkbox-row input {\n        flex: 0 1 auto;\n        margin: 0;\n    }\n\n    .aligned .vCheckboxLabel {\n        flex: 1 0;\n        padding: 1px 0 0 5px;\n    }\n\n    .aligned label + p,\n    .aligned label + div.help,\n    .aligned label + div.readonly {\n        padding: 0;\n        margin-left: 0;\n    }\n\n    .aligned p.file-upload {\n        margin-left: 0;\n        font-size: 13px;\n    }\n\n    span.clearable-file-input {\n        margin-left: 15px;\n    }\n\n    span.clearable-file-input label {\n        font-size: 13px;\n        padding-bottom: 0;\n    }\n\n    .aligned .timezonewarning {\n        flex: 1 0 100%;\n        margin-top: 5px;\n    }\n\n    form .aligned .form-row div.help {\n        width: 100%;\n        margin: 5px 0 0;\n        padding: 0;\n    }\n\n    form .aligned ul {\n        margin-left: 0;\n        padding-left: 0;\n    }\n\n    form .aligned ul.radiolist {\n        margin-right: 15px;\n        margin-bottom: -3px;\n    }\n\n    form .aligned ul.radiolist li + li {\n        margin-top: 5px;\n    }\n\n    /* Related widget */\n\n    .related-widget-wrapper {\n        width: 100%;\n        display: flex;\n        align-items: flex-start;\n    }\n\n    .related-widget-wrapper .selector {\n        order: 1;\n    }\n\n    .related-widget-wrapper > a {\n        order: 2;\n    }\n\n    .related-widget-wrapper .radiolist ~ a {\n        align-self: flex-end;\n    }\n\n    .related-widget-wrapper > select ~ a {\n        align-self: center;\n    }\n\n    select + .related-widget-wrapper-link,\n    .related-widget-wrapper-link + .related-widget-wrapper-link {\n        margin-left: 15px;\n    }\n\n    /* Selector */\n\n    .selector {\n        flex-direction: column;\n    }\n\n    .selector > * {\n        float: none;\n    }\n\n    .selector-available, .selector-chosen {\n        margin-bottom: 0;\n        flex: 1 1 auto;\n    }\n\n    .selector select {\n        max-height: 96px;\n    }\n\n    .selector ul.selector-chooser {\n        display: block;\n        float: none;\n        width: 52px;\n        height: 26px;\n        padding: 0 2px;\n        margin: 15px auto 20px;\n        transform: none;\n    }\n\n    .selector ul.selector-chooser li {\n        float: left;\n    }\n\n    .selector-remove {\n        background-position: 0 0;\n    }\n\n    .selector-add  {\n        background-position: 0 -40px;\n    }\n\n    /* Inlines */\n\n    .inline-group[data-inline-type=\"stacked\"] .inline-related {\n        border: 2px solid #eee;\n        border-radius: 4px;\n        margin-top: 15px;\n        overflow: auto;\n    }\n\n    .inline-group[data-inline-type=\"stacked\"] .inline-related > * {\n        box-sizing: border-box;\n    }\n\n    .inline-group[data-inline-type=\"stacked\"] .inline-related + .inline-related {\n        margin-top: 30px;\n    }\n\n    .inline-group[data-inline-type=\"stacked\"] .inline-related .module {\n        padding: 0 10px;\n    }\n\n    .inline-group[data-inline-type=\"stacked\"] .inline-related .module .form-row:last-child {\n        border-bottom: none;\n    }\n\n    .inline-group[data-inline-type=\"stacked\"] .inline-related h3 {\n        padding: 10px;\n        border-top-width: 0;\n        border-bottom-width: 2px;\n        display: flex;\n        flex-wrap: wrap;\n        align-items: center;\n    }\n\n    .inline-group[data-inline-type=\"stacked\"] .inline-related h3 .inline_label {\n        margin-right: auto;\n    }\n\n    .inline-group[data-inline-type=\"stacked\"] .inline-related h3 span.delete {\n        float: none;\n        flex: 1 1 100%;\n        margin-top: 5px;\n    }\n\n    .inline-group[data-inline-type=\"stacked\"] .aligned .form-row > div:not([class]) {\n        width: 100%;\n    }\n\n    .inline-group[data-inline-type=\"stacked\"] .aligned label {\n        width: 100%;\n    }\n\n    .inline-group[data-inline-type=\"stacked\"] div.add-row {\n        margin-top: 15px;\n        border: 1px solid #eee;\n        border-radius: 4px;\n    }\n\n    .inline-group div.add-row,\n    .inline-group .tabular tr.add-row td {\n        padding: 0;\n    }\n\n    .inline-group div.add-row a,\n    .inline-group .tabular tr.add-row td a {\n        display: block;\n        padding: 8px 10px 8px 26px;\n        background-position: 8px 9px;\n    }\n\n    /* Submit row */\n\n    .submit-row {\n        padding: 10px 10px 0;\n        margin: 0 0 15px;\n        display: flex;\n        flex-direction: column;\n    }\n\n    .submit-row > * {\n        width: 100%;\n    }\n\n    .submit-row input, .submit-row input.default, .submit-row a, .submit-row a.closelink {\n        float: none;\n        margin: 0 0 10px;\n        text-align: center;\n    }\n\n    .submit-row a.closelink {\n        padding: 10px 0;\n    }\n\n    .submit-row p.deletelink-box {\n        order: 4;\n    }\n\n    /* Messages */\n\n    ul.messagelist li {\n        padding-left: 40px;\n        background-position: 15px 12px;\n    }\n\n    ul.messagelist li.error {\n        background-position: 15px 12px;\n    }\n\n    ul.messagelist li.warning {\n        background-position: 15px 14px;\n    }\n\n    /* Paginator */\n\n    .paginator .this-page, .paginator a:link, .paginator a:visited {\n        padding: 4px 10px;\n    }\n\n    /* Login */\n\n    body.login {\n        padding: 0 15px;\n    }\n\n    .login #container {\n        width: auto;\n        max-width: 480px;\n        margin: 50px auto;\n    }\n\n    .login #header,\n    .login #content {\n        padding: 15px;\n    }\n\n    .login #content-main {\n        float: none;\n    }\n\n    .login .form-row {\n        padding: 0;\n    }\n\n    .login .form-row + .form-row {\n        margin-top: 15px;\n    }\n\n    .login .form-row label {\n        display: block;\n        margin: 0 0 5px;\n        padding: 0;\n        line-height: 1.2;\n    }\n\n    .login .submit-row {\n        padding: 15px 0 0;\n    }\n\n    .login br, .login .submit-row label {\n        display: none;\n    }\n\n    .login .submit-row input {\n        margin: 0;\n        text-transform: uppercase;\n    }\n\n    .errornote {\n        margin: 0 0 20px;\n        padding: 8px 12px;\n        font-size: 13px;\n    }\n\n    /* Calendar and clock */\n\n    .calendarbox, .clockbox {\n        position: fixed !important;\n        top: 50% !important;\n        left: 50% !important;\n        transform: translate(-50%, -50%);\n        margin: 0;\n        border: none;\n        overflow: visible;\n    }\n\n    .calendarbox:before, .clockbox:before {\n        content: '';\n        position: fixed;\n        top: 50%;\n        left: 50%;\n        width: 100vw;\n        height: 100vh;\n        background: rgba(0, 0, 0, 0.75);\n        transform: translate(-50%, -50%);\n    }\n\n    .calendarbox > *, .clockbox > * {\n        position: relative;\n        z-index: 1;\n    }\n\n    .calendarbox > div:first-child {\n        z-index: 2;\n    }\n\n    .calendarbox .calendar, .clockbox h2 {\n        border-radius: 4px 4px 0 0;\n        overflow: hidden;\n    }\n\n    .calendarbox .calendar-cancel, .clockbox .calendar-cancel {\n        border-radius: 0 0 4px 4px;\n        overflow: hidden;\n    }\n\n    .calendar-shortcuts {\n        padding: 10px 0;\n        font-size: 12px;\n        line-height: 12px;\n    }\n\n    .calendar-shortcuts a {\n        margin: 0 4px;\n    }\n\n    .timelist a {\n        background: #fff;\n        padding: 4px;\n    }\n\n    .calendar-cancel {\n        padding: 8px 10px;\n    }\n\n    .clockbox h2 {\n        padding: 8px 15px;\n    }\n\n    .calendar caption {\n        padding: 10px;\n    }\n\n    .calendarbox .calendarnav-previous, .calendarbox .calendarnav-next {\n        z-index: 1;\n        top: 10px;\n    }\n\n    /* History */\n\n    table#change-history tbody th, table#change-history tbody td {\n        font-size: 13px;\n        word-break: break-word;\n    }\n\n    table#change-history tbody th {\n        width: auto;\n    }\n\n    /* Docs */\n\n    table.model tbody th, table.model tbody td {\n        font-size: 13px;\n        word-break: break-word;\n    }\n}\n"
  },
  {
    "path": "src/static_cdn/admin/css/responsive_rtl.css",
    "content": "/* TABLETS */\n\n@media (max-width: 1024px) {\n    [dir=\"rtl\"] .colMS {\n        margin-right: 0;\n    }\n\n    [dir=\"rtl\"] #user-tools {\n        text-align: right;\n    }\n\n    [dir=\"rtl\"] #changelist .actions label {\n        padding-left: 10px;\n        padding-right: 0;\n    }\n\n    [dir=\"rtl\"] #changelist .actions select {\n        margin-left: 0;\n        margin-right: 15px;\n    }\n\n    [dir=\"rtl\"] .change-list .filtered .results,\n    [dir=\"rtl\"] .change-list .filtered .paginator,\n    [dir=\"rtl\"] .filtered #toolbar,\n    [dir=\"rtl\"] .filtered div.xfull,\n    [dir=\"rtl\"] .filtered .actions {\n        margin-right: 0;\n        margin-left: 230px;\n    }\n\n    [dir=\"rtl\"] .inline-group ul.tools a.add,\n    [dir=\"rtl\"] .inline-group div.add-row a,\n    [dir=\"rtl\"] .inline-group .tabular tr.add-row td a {\n        padding: 8px 26px 8px 10px;\n        background-position: calc(100% - 8px) 9px;\n    }\n\n    [dir=\"rtl\"] .related-widget-wrapper-link + .selector {\n        margin-right: 0;\n        margin-left: 15px;\n    }\n\n    [dir=\"rtl\"] .selector .selector-filter label {\n        margin-right: 0;\n        margin-left: 8px;\n    }\n\n    [dir=\"rtl\"] .object-tools li {\n        float: right;\n    }\n\n    [dir=\"rtl\"] .object-tools li + li {\n        margin-left: 0;\n        margin-right: 15px;\n    }\n\n    [dir=\"rtl\"] .dashboard .module table td a {\n        padding-left: 0;\n        padding-right: 16px;\n    }\n}\n\n/* MOBILE */\n\n@media (max-width: 767px) {\n    [dir=\"rtl\"] .change-list .filtered .results,\n    [dir=\"rtl\"] .change-list .filtered .paginator,\n    [dir=\"rtl\"] .filtered #toolbar,\n    [dir=\"rtl\"] .filtered div.xfull,\n    [dir=\"rtl\"] .filtered .actions {\n        margin-left: 0;\n    }\n\n    [dir=\"rtl\"] .aligned .add-another,\n    [dir=\"rtl\"] .aligned .related-lookup,\n    [dir=\"rtl\"] .aligned .datetimeshortcuts {\n        margin-left: 0;\n        margin-right: 15px;\n    }\n\n    [dir=\"rtl\"] .aligned ul {\n        margin-right: 0;\n    }\n}\n"
  },
  {
    "path": "src/static_cdn/admin/css/rtl.css",
    "content": "body {\n    direction: rtl;\n}\n\n/* LOGIN */\n\n.login .form-row {\n    float: right;\n}\n\n.login .form-row label {\n    float: right;\n    padding-left: 0.5em;\n    padding-right: 0;\n    text-align: left;\n}\n\n.login .submit-row {\n    clear: both;\n    padding: 1em 9.4em 0 0;\n}\n\n/* GLOBAL */\n\nth {\n    text-align: right;\n}\n\n.module h2, .module caption {\n    text-align: right;\n}\n\n.module ul, .module ol {\n    margin-left: 0;\n    margin-right: 1.5em;\n}\n\n.viewlink, .addlink, .changelink {\n    padding-left: 0;\n    padding-right: 16px;\n    background-position: 100% 1px;\n}\n\n.deletelink {\n    padding-left: 0;\n    padding-right: 16px;\n    background-position: 100% 1px;\n}\n\n.object-tools {\n    float: left;\n}\n\nthead th:first-child,\ntfoot td:first-child {\n    border-left: none;\n}\n\n/* LAYOUT */\n\n#user-tools {\n    right: auto;\n    left: 0;\n    text-align: left;\n}\n\ndiv.breadcrumbs {\n    text-align: right;\n}\n\n#content-main {\n    float: right;\n}\n\n#content-related {\n    float: left;\n    margin-left: -300px;\n    margin-right: auto;\n}\n\n.colMS {\n    margin-left: 300px;\n    margin-right: 0;\n}\n\n/* SORTABLE TABLES */\n\ntable thead th.sorted .sortoptions {\n   float: left;\n}\n\nthead th.sorted .text {\n    padding-right: 0;\n    padding-left: 42px;\n}\n\n/* dashboard styles */\n\n.dashboard .module table td a {\n    padding-left: .6em;\n    padding-right: 16px;\n}\n\n/* changelists styles */\n\n.change-list .filtered table {\n    border-left: none;\n    border-right: 0px none;\n}\n\n#changelist-filter {\n    right: auto;\n    left: 0;\n    border-left: none;\n    border-right: none;\n}\n\n.change-list .filtered .results, .change-list .filtered .paginator, .filtered #toolbar, .filtered div.xfull {\n    margin-right: 0;\n    margin-left: 280px;\n}\n\n#changelist-filter li.selected {\n    border-left: none;\n    padding-left: 10px;\n    margin-left: 0;\n    border-right: 5px solid #eaeaea;\n    padding-right: 10px;\n    margin-right: -15px;\n}\n\n.filtered .actions {\n    margin-left: 280px;\n    margin-right: 0;\n}\n\n#changelist table tbody td:first-child, #changelist table tbody th:first-child {\n    border-right: none;\n    border-left: none;\n}\n\n/* FORMS */\n\n.aligned label {\n    padding: 0 0 3px 1em;\n    float: right;\n}\n\n.submit-row {\n    text-align: left\n}\n\n.submit-row p.deletelink-box {\n    float: right;\n}\n\n.submit-row input.default {\n    margin-left: 0;\n}\n\n.vDateField, .vTimeField {\n    margin-left: 2px;\n}\n\n.aligned .form-row input {\n    margin-left: 5px;\n}\n\nform .aligned p.help, form .aligned div.help {\n    clear: right;\n}\n\nform .aligned ul {\n    margin-right: 163px;\n    margin-left: 0;\n}\n\nform ul.inline li {\n    float: right;\n    padding-right: 0;\n    padding-left: 7px;\n}\n\ninput[type=submit].default, .submit-row input.default {\n    float: left;\n}\n\nfieldset .fieldBox {\n    float: right;\n    margin-left: 20px;\n    margin-right: 0;\n}\n\n.errorlist li {\n    background-position: 100% 12px;\n    padding: 0;\n}\n\n.errornote {\n    background-position: 100% 12px;\n    padding: 10px 12px;\n}\n\n/* WIDGETS */\n\n.calendarnav-previous {\n    top: 0;\n    left: auto;\n    right: 10px;\n}\n\n.calendarnav-next {\n    top: 0;\n    right: auto;\n    left: 10px;\n}\n\n.calendar caption, .calendarbox h2 {\n    text-align: center;\n}\n\n.selector {\n    float: right;\n}\n\n.selector .selector-filter {\n    text-align: right;\n}\n\n.inline-deletelink {\n    float: left;\n}\n\nform .form-row p.datetime {\n    overflow: hidden;\n}\n\n.related-widget-wrapper {\n    float: right;\n}\n\n/* MISC */\n\n.inline-related h2, .inline-group h2 {\n    text-align: right\n}\n\n.inline-related h3 span.delete {\n    padding-right: 20px;\n    padding-left: inherit;\n    left: 10px;\n    right: inherit;\n    float:left;\n}\n\n.inline-related h3 span.delete label {\n    margin-left: inherit;\n    margin-right: 2px;\n}\n\n/* IE7 specific bug fixes */\n\ndiv.colM {\n    position: relative;\n}\n\n.submit-row input {\n    float: left;\n}\n"
  },
  {
    "path": "src/static_cdn/admin/css/vendor/select2/LICENSE-SELECT2.md",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2012-2015 Kevin Brown, Igor Vaynberg, and Select2 contributors\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n"
  },
  {
    "path": "src/static_cdn/admin/css/vendor/select2/select2.css",
    "content": ".select2-container {\n  box-sizing: border-box;\n  display: inline-block;\n  margin: 0;\n  position: relative;\n  vertical-align: middle; }\n  .select2-container .select2-selection--single {\n    box-sizing: border-box;\n    cursor: pointer;\n    display: block;\n    height: 28px;\n    user-select: none;\n    -webkit-user-select: none; }\n    .select2-container .select2-selection--single .select2-selection__rendered {\n      display: block;\n      padding-left: 8px;\n      padding-right: 20px;\n      overflow: hidden;\n      text-overflow: ellipsis;\n      white-space: nowrap; }\n    .select2-container .select2-selection--single .select2-selection__clear {\n      position: relative; }\n  .select2-container[dir=\"rtl\"] .select2-selection--single .select2-selection__rendered {\n    padding-right: 8px;\n    padding-left: 20px; }\n  .select2-container .select2-selection--multiple {\n    box-sizing: border-box;\n    cursor: pointer;\n    display: block;\n    min-height: 32px;\n    user-select: none;\n    -webkit-user-select: none; }\n    .select2-container .select2-selection--multiple .select2-selection__rendered {\n      display: inline-block;\n      overflow: hidden;\n      padding-left: 8px;\n      text-overflow: ellipsis;\n      white-space: nowrap; }\n  .select2-container .select2-search--inline {\n    float: left; }\n    .select2-container .select2-search--inline .select2-search__field {\n      box-sizing: border-box;\n      border: none;\n      font-size: 100%;\n      margin-top: 5px;\n      padding: 0; }\n      .select2-container .select2-search--inline .select2-search__field::-webkit-search-cancel-button {\n        -webkit-appearance: none; }\n\n.select2-dropdown {\n  background-color: white;\n  border: 1px solid #aaa;\n  border-radius: 4px;\n  box-sizing: border-box;\n  display: block;\n  position: absolute;\n  left: -100000px;\n  width: 100%;\n  z-index: 1051; }\n\n.select2-results {\n  display: block; }\n\n.select2-results__options {\n  list-style: none;\n  margin: 0;\n  padding: 0; }\n\n.select2-results__option {\n  padding: 6px;\n  user-select: none;\n  -webkit-user-select: none; }\n  .select2-results__option[aria-selected] {\n    cursor: pointer; }\n\n.select2-container--open .select2-dropdown {\n  left: 0; }\n\n.select2-container--open .select2-dropdown--above {\n  border-bottom: none;\n  border-bottom-left-radius: 0;\n  border-bottom-right-radius: 0; }\n\n.select2-container--open .select2-dropdown--below {\n  border-top: none;\n  border-top-left-radius: 0;\n  border-top-right-radius: 0; }\n\n.select2-search--dropdown {\n  display: block;\n  padding: 4px; }\n  .select2-search--dropdown .select2-search__field {\n    padding: 4px;\n    width: 100%;\n    box-sizing: border-box; }\n    .select2-search--dropdown .select2-search__field::-webkit-search-cancel-button {\n      -webkit-appearance: none; }\n  .select2-search--dropdown.select2-search--hide {\n    display: none; }\n\n.select2-close-mask {\n  border: 0;\n  margin: 0;\n  padding: 0;\n  display: block;\n  position: fixed;\n  left: 0;\n  top: 0;\n  min-height: 100%;\n  min-width: 100%;\n  height: auto;\n  width: auto;\n  opacity: 0;\n  z-index: 99;\n  background-color: #fff;\n  filter: alpha(opacity=0); }\n\n.select2-hidden-accessible {\n  border: 0 !important;\n  clip: rect(0 0 0 0) !important;\n  height: 1px !important;\n  margin: -1px !important;\n  overflow: hidden !important;\n  padding: 0 !important;\n  position: absolute !important;\n  width: 1px !important; }\n\n.select2-container--default .select2-selection--single {\n  background-color: #fff;\n  border: 1px solid #aaa;\n  border-radius: 4px; }\n  .select2-container--default .select2-selection--single .select2-selection__rendered {\n    color: #444;\n    line-height: 28px; }\n  .select2-container--default .select2-selection--single .select2-selection__clear {\n    cursor: pointer;\n    float: right;\n    font-weight: bold; }\n  .select2-container--default .select2-selection--single .select2-selection__placeholder {\n    color: #999; }\n  .select2-container--default .select2-selection--single .select2-selection__arrow {\n    height: 26px;\n    position: absolute;\n    top: 1px;\n    right: 1px;\n    width: 20px; }\n    .select2-container--default .select2-selection--single .select2-selection__arrow b {\n      border-color: #888 transparent transparent transparent;\n      border-style: solid;\n      border-width: 5px 4px 0 4px;\n      height: 0;\n      left: 50%;\n      margin-left: -4px;\n      margin-top: -2px;\n      position: absolute;\n      top: 50%;\n      width: 0; }\n\n.select2-container--default[dir=\"rtl\"] .select2-selection--single .select2-selection__clear {\n  float: left; }\n\n.select2-container--default[dir=\"rtl\"] .select2-selection--single .select2-selection__arrow {\n  left: 1px;\n  right: auto; }\n\n.select2-container--default.select2-container--disabled .select2-selection--single {\n  background-color: #eee;\n  cursor: default; }\n  .select2-container--default.select2-container--disabled .select2-selection--single .select2-selection__clear {\n    display: none; }\n\n.select2-container--default.select2-container--open .select2-selection--single .select2-selection__arrow b {\n  border-color: transparent transparent #888 transparent;\n  border-width: 0 4px 5px 4px; }\n\n.select2-container--default .select2-selection--multiple {\n  background-color: white;\n  border: 1px solid #aaa;\n  border-radius: 4px;\n  cursor: text; }\n  .select2-container--default .select2-selection--multiple .select2-selection__rendered {\n    box-sizing: border-box;\n    list-style: none;\n    margin: 0;\n    padding: 0 5px;\n    width: 100%; }\n    .select2-container--default .select2-selection--multiple .select2-selection__rendered li {\n      list-style: none; }\n  .select2-container--default .select2-selection--multiple .select2-selection__placeholder {\n    color: #999;\n    margin-top: 5px;\n    float: left; }\n  .select2-container--default .select2-selection--multiple .select2-selection__clear {\n    cursor: pointer;\n    float: right;\n    font-weight: bold;\n    margin-top: 5px;\n    margin-right: 10px; }\n  .select2-container--default .select2-selection--multiple .select2-selection__choice {\n    background-color: #e4e4e4;\n    border: 1px solid #aaa;\n    border-radius: 4px;\n    cursor: default;\n    float: left;\n    margin-right: 5px;\n    margin-top: 5px;\n    padding: 0 5px; }\n  .select2-container--default .select2-selection--multiple .select2-selection__choice__remove {\n    color: #999;\n    cursor: pointer;\n    display: inline-block;\n    font-weight: bold;\n    margin-right: 2px; }\n    .select2-container--default .select2-selection--multiple .select2-selection__choice__remove:hover {\n      color: #333; }\n\n.select2-container--default[dir=\"rtl\"] .select2-selection--multiple .select2-selection__choice, .select2-container--default[dir=\"rtl\"] .select2-selection--multiple .select2-selection__placeholder, .select2-container--default[dir=\"rtl\"] .select2-selection--multiple .select2-search--inline {\n  float: right; }\n\n.select2-container--default[dir=\"rtl\"] .select2-selection--multiple .select2-selection__choice {\n  margin-left: 5px;\n  margin-right: auto; }\n\n.select2-container--default[dir=\"rtl\"] .select2-selection--multiple .select2-selection__choice__remove {\n  margin-left: 2px;\n  margin-right: auto; }\n\n.select2-container--default.select2-container--focus .select2-selection--multiple {\n  border: solid black 1px;\n  outline: 0; }\n\n.select2-container--default.select2-container--disabled .select2-selection--multiple {\n  background-color: #eee;\n  cursor: default; }\n\n.select2-container--default.select2-container--disabled .select2-selection__choice__remove {\n  display: none; }\n\n.select2-container--default.select2-container--open.select2-container--above .select2-selection--single, .select2-container--default.select2-container--open.select2-container--above .select2-selection--multiple {\n  border-top-left-radius: 0;\n  border-top-right-radius: 0; }\n\n.select2-container--default.select2-container--open.select2-container--below .select2-selection--single, .select2-container--default.select2-container--open.select2-container--below .select2-selection--multiple {\n  border-bottom-left-radius: 0;\n  border-bottom-right-radius: 0; }\n\n.select2-container--default .select2-search--dropdown .select2-search__field {\n  border: 1px solid #aaa; }\n\n.select2-container--default .select2-search--inline .select2-search__field {\n  background: transparent;\n  border: none;\n  outline: 0;\n  box-shadow: none;\n  -webkit-appearance: textfield; }\n\n.select2-container--default .select2-results > .select2-results__options {\n  max-height: 200px;\n  overflow-y: auto; }\n\n.select2-container--default .select2-results__option[role=group] {\n  padding: 0; }\n\n.select2-container--default .select2-results__option[aria-disabled=true] {\n  color: #999; }\n\n.select2-container--default .select2-results__option[aria-selected=true] {\n  background-color: #ddd; }\n\n.select2-container--default .select2-results__option .select2-results__option {\n  padding-left: 1em; }\n  .select2-container--default .select2-results__option .select2-results__option .select2-results__group {\n    padding-left: 0; }\n  .select2-container--default .select2-results__option .select2-results__option .select2-results__option {\n    margin-left: -1em;\n    padding-left: 2em; }\n    .select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option {\n      margin-left: -2em;\n      padding-left: 3em; }\n      .select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option {\n        margin-left: -3em;\n        padding-left: 4em; }\n        .select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option {\n          margin-left: -4em;\n          padding-left: 5em; }\n          .select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option {\n            margin-left: -5em;\n            padding-left: 6em; }\n\n.select2-container--default .select2-results__option--highlighted[aria-selected] {\n  background-color: #5897fb;\n  color: white; }\n\n.select2-container--default .select2-results__group {\n  cursor: default;\n  display: block;\n  padding: 6px; }\n\n.select2-container--classic .select2-selection--single {\n  background-color: #f7f7f7;\n  border: 1px solid #aaa;\n  border-radius: 4px;\n  outline: 0;\n  background-image: -webkit-linear-gradient(top, white 50%, #eeeeee 100%);\n  background-image: -o-linear-gradient(top, white 50%, #eeeeee 100%);\n  background-image: linear-gradient(to bottom, white 50%, #eeeeee 100%);\n  background-repeat: repeat-x;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFFFF', endColorstr='#FFEEEEEE', GradientType=0); }\n  .select2-container--classic .select2-selection--single:focus {\n    border: 1px solid #5897fb; }\n  .select2-container--classic .select2-selection--single .select2-selection__rendered {\n    color: #444;\n    line-height: 28px; }\n  .select2-container--classic .select2-selection--single .select2-selection__clear {\n    cursor: pointer;\n    float: right;\n    font-weight: bold;\n    margin-right: 10px; }\n  .select2-container--classic .select2-selection--single .select2-selection__placeholder {\n    color: #999; }\n  .select2-container--classic .select2-selection--single .select2-selection__arrow {\n    background-color: #ddd;\n    border: none;\n    border-left: 1px solid #aaa;\n    border-top-right-radius: 4px;\n    border-bottom-right-radius: 4px;\n    height: 26px;\n    position: absolute;\n    top: 1px;\n    right: 1px;\n    width: 20px;\n    background-image: -webkit-linear-gradient(top, #eeeeee 50%, #cccccc 100%);\n    background-image: -o-linear-gradient(top, #eeeeee 50%, #cccccc 100%);\n    background-image: linear-gradient(to bottom, #eeeeee 50%, #cccccc 100%);\n    background-repeat: repeat-x;\n    filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFEEEEEE', endColorstr='#FFCCCCCC', GradientType=0); }\n    .select2-container--classic .select2-selection--single .select2-selection__arrow b {\n      border-color: #888 transparent transparent transparent;\n      border-style: solid;\n      border-width: 5px 4px 0 4px;\n      height: 0;\n      left: 50%;\n      margin-left: -4px;\n      margin-top: -2px;\n      position: absolute;\n      top: 50%;\n      width: 0; }\n\n.select2-container--classic[dir=\"rtl\"] .select2-selection--single .select2-selection__clear {\n  float: left; }\n\n.select2-container--classic[dir=\"rtl\"] .select2-selection--single .select2-selection__arrow {\n  border: none;\n  border-right: 1px solid #aaa;\n  border-radius: 0;\n  border-top-left-radius: 4px;\n  border-bottom-left-radius: 4px;\n  left: 1px;\n  right: auto; }\n\n.select2-container--classic.select2-container--open .select2-selection--single {\n  border: 1px solid #5897fb; }\n  .select2-container--classic.select2-container--open .select2-selection--single .select2-selection__arrow {\n    background: transparent;\n    border: none; }\n    .select2-container--classic.select2-container--open .select2-selection--single .select2-selection__arrow b {\n      border-color: transparent transparent #888 transparent;\n      border-width: 0 4px 5px 4px; }\n\n.select2-container--classic.select2-container--open.select2-container--above .select2-selection--single {\n  border-top: none;\n  border-top-left-radius: 0;\n  border-top-right-radius: 0;\n  background-image: -webkit-linear-gradient(top, white 0%, #eeeeee 50%);\n  background-image: -o-linear-gradient(top, white 0%, #eeeeee 50%);\n  background-image: linear-gradient(to bottom, white 0%, #eeeeee 50%);\n  background-repeat: repeat-x;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFFFF', endColorstr='#FFEEEEEE', GradientType=0); }\n\n.select2-container--classic.select2-container--open.select2-container--below .select2-selection--single {\n  border-bottom: none;\n  border-bottom-left-radius: 0;\n  border-bottom-right-radius: 0;\n  background-image: -webkit-linear-gradient(top, #eeeeee 50%, white 100%);\n  background-image: -o-linear-gradient(top, #eeeeee 50%, white 100%);\n  background-image: linear-gradient(to bottom, #eeeeee 50%, white 100%);\n  background-repeat: repeat-x;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFEEEEEE', endColorstr='#FFFFFFFF', GradientType=0); }\n\n.select2-container--classic .select2-selection--multiple {\n  background-color: white;\n  border: 1px solid #aaa;\n  border-radius: 4px;\n  cursor: text;\n  outline: 0; }\n  .select2-container--classic .select2-selection--multiple:focus {\n    border: 1px solid #5897fb; }\n  .select2-container--classic .select2-selection--multiple .select2-selection__rendered {\n    list-style: none;\n    margin: 0;\n    padding: 0 5px; }\n  .select2-container--classic .select2-selection--multiple .select2-selection__clear {\n    display: none; }\n  .select2-container--classic .select2-selection--multiple .select2-selection__choice {\n    background-color: #e4e4e4;\n    border: 1px solid #aaa;\n    border-radius: 4px;\n    cursor: default;\n    float: left;\n    margin-right: 5px;\n    margin-top: 5px;\n    padding: 0 5px; }\n  .select2-container--classic .select2-selection--multiple .select2-selection__choice__remove {\n    color: #888;\n    cursor: pointer;\n    display: inline-block;\n    font-weight: bold;\n    margin-right: 2px; }\n    .select2-container--classic .select2-selection--multiple .select2-selection__choice__remove:hover {\n      color: #555; }\n\n.select2-container--classic[dir=\"rtl\"] .select2-selection--multiple .select2-selection__choice {\n  float: right; }\n\n.select2-container--classic[dir=\"rtl\"] .select2-selection--multiple .select2-selection__choice {\n  margin-left: 5px;\n  margin-right: auto; }\n\n.select2-container--classic[dir=\"rtl\"] .select2-selection--multiple .select2-selection__choice__remove {\n  margin-left: 2px;\n  margin-right: auto; }\n\n.select2-container--classic.select2-container--open .select2-selection--multiple {\n  border: 1px solid #5897fb; }\n\n.select2-container--classic.select2-container--open.select2-container--above .select2-selection--multiple {\n  border-top: none;\n  border-top-left-radius: 0;\n  border-top-right-radius: 0; }\n\n.select2-container--classic.select2-container--open.select2-container--below .select2-selection--multiple {\n  border-bottom: none;\n  border-bottom-left-radius: 0;\n  border-bottom-right-radius: 0; }\n\n.select2-container--classic .select2-search--dropdown .select2-search__field {\n  border: 1px solid #aaa;\n  outline: 0; }\n\n.select2-container--classic .select2-search--inline .select2-search__field {\n  outline: 0;\n  box-shadow: none; }\n\n.select2-container--classic .select2-dropdown {\n  background-color: white;\n  border: 1px solid transparent; }\n\n.select2-container--classic .select2-dropdown--above {\n  border-bottom: none; }\n\n.select2-container--classic .select2-dropdown--below {\n  border-top: none; }\n\n.select2-container--classic .select2-results > .select2-results__options {\n  max-height: 200px;\n  overflow-y: auto; }\n\n.select2-container--classic .select2-results__option[role=group] {\n  padding: 0; }\n\n.select2-container--classic .select2-results__option[aria-disabled=true] {\n  color: grey; }\n\n.select2-container--classic .select2-results__option--highlighted[aria-selected] {\n  background-color: #3875d7;\n  color: white; }\n\n.select2-container--classic .select2-results__group {\n  cursor: default;\n  display: block;\n  padding: 6px; }\n\n.select2-container--classic.select2-container--open .select2-dropdown {\n  border-color: #5897fb; }\n"
  },
  {
    "path": "src/static_cdn/admin/css/widgets.css",
    "content": "/* SELECTOR (FILTER INTERFACE) */\n\n.selector {\n    width: 800px;\n    float: left;\n}\n\n.selector select {\n    width: 380px;\n    height: 17.2em;\n}\n\n.selector-available, .selector-chosen {\n    float: left;\n    width: 380px;\n    text-align: center;\n    margin-bottom: 5px;\n}\n\n.selector-chosen select {\n    border-top: none;\n}\n\n.selector-available h2, .selector-chosen h2 {\n    border: 1px solid #ccc;\n    border-radius: 4px 4px 0 0;\n}\n\n.selector-chosen h2 {\n    background: #79aec8;\n    color: #fff;\n}\n\n.selector .selector-available h2 {\n    background: #f8f8f8;\n    color: #666;\n}\n\n.selector .selector-filter {\n    background: white;\n    border: 1px solid #ccc;\n    border-width: 0 1px;\n    padding: 8px;\n    color: #999;\n    font-size: 10px;\n    margin: 0;\n    text-align: left;\n}\n\n.selector .selector-filter label,\n.inline-group .aligned .selector .selector-filter label {\n    float: left;\n    margin: 7px 0 0;\n    width: 18px;\n    height: 18px;\n    padding: 0;\n    overflow: hidden;\n    line-height: 1;\n}\n\n.selector .selector-available input {\n    width: 320px;\n    margin-left: 8px;\n}\n\n.selector ul.selector-chooser {\n    float: left;\n    width: 22px;\n    background-color: #eee;\n    border-radius: 10px;\n    margin: 10em 5px 0 5px;\n    padding: 0;\n}\n\n.selector-chooser li {\n    margin: 0;\n    padding: 3px;\n    list-style-type: none;\n}\n\n.selector select {\n    padding: 0 10px;\n    margin: 0 0 10px;\n    border-radius: 0 0 4px 4px;\n}\n\n.selector-add, .selector-remove {\n    width: 16px;\n    height: 16px;\n    display: block;\n    text-indent: -3000px;\n    overflow: hidden;\n    cursor: default;\n    opacity: 0.3;\n}\n\n.active.selector-add, .active.selector-remove {\n    opacity: 1;\n}\n\n.active.selector-add:hover, .active.selector-remove:hover {\n    cursor: pointer;\n}\n\n.selector-add {\n    background: url(../img/selector-icons.svg) 0 -96px no-repeat;\n}\n\n.active.selector-add:focus, .active.selector-add:hover {\n    background-position: 0 -112px;\n}\n\n.selector-remove {\n    background: url(../img/selector-icons.svg) 0 -64px no-repeat;\n}\n\n.active.selector-remove:focus, .active.selector-remove:hover {\n    background-position: 0 -80px;\n}\n\na.selector-chooseall, a.selector-clearall {\n    display: inline-block;\n    height: 16px;\n    text-align: left;\n    margin: 1px auto 3px;\n    overflow: hidden;\n    font-weight: bold;\n    line-height: 16px;\n    color: #666;\n    text-decoration: none;\n    opacity: 0.3;\n}\n\na.active.selector-chooseall:focus, a.active.selector-clearall:focus,\na.active.selector-chooseall:hover, a.active.selector-clearall:hover {\n    color: #447e9b;\n}\n\na.active.selector-chooseall, a.active.selector-clearall {\n    opacity: 1;\n}\n\na.active.selector-chooseall:hover, a.active.selector-clearall:hover {\n    cursor: pointer;\n}\n\na.selector-chooseall {\n    padding: 0 18px 0 0;\n    background: url(../img/selector-icons.svg) right -160px no-repeat;\n    cursor: default;\n}\n\na.active.selector-chooseall:focus, a.active.selector-chooseall:hover {\n    background-position: 100% -176px;\n}\n\na.selector-clearall {\n    padding: 0 0 0 18px;\n    background: url(../img/selector-icons.svg) 0 -128px no-repeat;\n    cursor: default;\n}\n\na.active.selector-clearall:focus, a.active.selector-clearall:hover {\n    background-position: 0 -144px;\n}\n\n/* STACKED SELECTORS */\n\n.stacked {\n    float: left;\n    width: 490px;\n}\n\n.stacked select {\n    width: 480px;\n    height: 10.1em;\n}\n\n.stacked .selector-available, .stacked .selector-chosen {\n    width: 480px;\n}\n\n.stacked .selector-available {\n    margin-bottom: 0;\n}\n\n.stacked .selector-available input {\n    width: 422px;\n}\n\n.stacked ul.selector-chooser {\n    height: 22px;\n    width: 50px;\n    margin: 0 0 10px 40%;\n    background-color: #eee;\n    border-radius: 10px;\n}\n\n.stacked .selector-chooser li {\n    float: left;\n    padding: 3px 3px 3px 5px;\n}\n\n.stacked .selector-chooseall, .stacked .selector-clearall {\n    display: none;\n}\n\n.stacked .selector-add {\n    background: url(../img/selector-icons.svg) 0 -32px no-repeat;\n    cursor: default;\n}\n\n.stacked .active.selector-add {\n    background-position: 0 -48px;\n    cursor: pointer;\n}\n\n.stacked .selector-remove {\n    background: url(../img/selector-icons.svg) 0 0 no-repeat;\n    cursor: default;\n}\n\n.stacked .active.selector-remove {\n    background-position: 0 -16px;\n    cursor: pointer;\n}\n\n.selector .help-icon {\n    background: url(../img/icon-unknown.svg) 0 0 no-repeat;\n    display: inline-block;\n    vertical-align: middle;\n    margin: -2px 0 0 2px;\n    width: 13px;\n    height: 13px;\n}\n\n.selector .selector-chosen .help-icon {\n    background: url(../img/icon-unknown-alt.svg) 0 0 no-repeat;\n}\n\n.selector .search-label-icon {\n    background: url(../img/search.svg) 0 0 no-repeat;\n    display: inline-block;\n    height: 18px;\n    width: 18px;\n}\n\n/* DATE AND TIME */\n\np.datetime {\n    line-height: 20px;\n    margin: 0;\n    padding: 0;\n    color: #666;\n    font-weight: bold;\n}\n\n.datetime span {\n    white-space: nowrap;\n    font-weight: normal;\n    font-size: 11px;\n    color: #ccc;\n}\n\n.datetime input, .form-row .datetime input.vDateField, .form-row .datetime input.vTimeField {\n    min-width: 0;\n    margin-left: 5px;\n    margin-bottom: 4px;\n}\n\ntable p.datetime {\n    font-size: 11px;\n    margin-left: 0;\n    padding-left: 0;\n}\n\n.datetimeshortcuts .clock-icon, .datetimeshortcuts .date-icon {\n    position: relative;\n    display: inline-block;\n    vertical-align: middle;\n    height: 16px;\n    width: 16px;\n    overflow: hidden;\n}\n\n.datetimeshortcuts .clock-icon {\n    background: url(../img/icon-clock.svg) 0 0 no-repeat;\n}\n\n.datetimeshortcuts a:focus .clock-icon,\n.datetimeshortcuts a:hover .clock-icon {\n    background-position: 0 -16px;\n}\n\n.datetimeshortcuts .date-icon {\n    background: url(../img/icon-calendar.svg) 0 0 no-repeat;\n    top: -1px;\n}\n\n.datetimeshortcuts a:focus .date-icon,\n.datetimeshortcuts a:hover .date-icon {\n    background-position: 0 -16px;\n}\n\n.timezonewarning {\n    font-size: 11px;\n    color: #999;\n}\n\n/* URL */\n\np.url {\n    line-height: 20px;\n    margin: 0;\n    padding: 0;\n    color: #666;\n    font-size: 11px;\n    font-weight: bold;\n}\n\n.url a {\n    font-weight: normal;\n}\n\n/* FILE UPLOADS */\n\np.file-upload {\n    line-height: 20px;\n    margin: 0;\n    padding: 0;\n    color: #666;\n    font-size: 11px;\n    font-weight: bold;\n}\n\n.aligned p.file-upload {\n    margin-left: 170px;\n}\n\n.file-upload a {\n    font-weight: normal;\n}\n\n.file-upload .deletelink {\n    margin-left: 5px;\n}\n\nspan.clearable-file-input label {\n    color: #333;\n    font-size: 11px;\n    display: inline;\n    float: none;\n}\n\n/* CALENDARS & CLOCKS */\n\n.calendarbox, .clockbox {\n    margin: 5px auto;\n    font-size: 12px;\n    width: 19em;\n    text-align: center;\n    background: white;\n    border: 1px solid #ddd;\n    border-radius: 4px;\n    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.15);\n    overflow: hidden;\n    position: relative;\n}\n\n.clockbox {\n    width: auto;\n}\n\n.calendar {\n    margin: 0;\n    padding: 0;\n}\n\n.calendar table {\n    margin: 0;\n    padding: 0;\n    border-collapse: collapse;\n    background: white;\n    width: 100%;\n}\n\n.calendar caption, .calendarbox h2 {\n    margin: 0;\n    text-align: center;\n    border-top: none;\n    background: #f5dd5d;\n    font-weight: 700;\n    font-size: 12px;\n    color: #333;\n}\n\n.calendar th {\n    padding: 8px 5px;\n    background: #f8f8f8;\n    border-bottom: 1px solid #ddd;\n    font-weight: 400;\n    font-size: 12px;\n    text-align: center;\n    color: #666;\n}\n\n.calendar td {\n    font-weight: 400;\n    font-size: 12px;\n    text-align: center;\n    padding: 0;\n    border-top: 1px solid #eee;\n    border-bottom: none;\n}\n\n.calendar td.selected a {\n    background: #79aec8;\n    color: #fff;\n}\n\n.calendar td.nonday {\n    background: #f8f8f8;\n}\n\n.calendar td.today a {\n    font-weight: 700;\n}\n\n.calendar td a, .timelist a {\n    display: block;\n    font-weight: 400;\n    padding: 6px;\n    text-decoration: none;\n    color: #444;\n}\n\n.calendar td a:focus, .timelist a:focus,\n.calendar td a:hover, .timelist a:hover {\n    background: #79aec8;\n    color: white;\n}\n\n.calendar td a:active, .timelist a:active {\n    background: #417690;\n    color: white;\n}\n\n.calendarnav {\n    font-size: 10px;\n    text-align: center;\n    color: #ccc;\n    margin: 0;\n    padding: 1px 3px;\n}\n\n.calendarnav a:link, #calendarnav a:visited,\n#calendarnav a:focus, #calendarnav a:hover {\n    color: #999;\n}\n\n.calendar-shortcuts {\n    background: white;\n    font-size: 11px;\n    line-height: 11px;\n    border-top: 1px solid #eee;\n    padding: 8px 0;\n    color: #ccc;\n}\n\n.calendarbox .calendarnav-previous, .calendarbox .calendarnav-next {\n    display: block;\n    position: absolute;\n    top: 8px;\n    width: 15px;\n    height: 15px;\n    text-indent: -9999px;\n    padding: 0;\n}\n\n.calendarnav-previous {\n    left: 10px;\n    background: url(../img/calendar-icons.svg) 0 0 no-repeat;\n}\n\n.calendarbox .calendarnav-previous:focus,\n.calendarbox .calendarnav-previous:hover {\n    background-position: 0 -15px;\n}\n\n.calendarnav-next {\n    right: 10px;\n    background: url(../img/calendar-icons.svg) 0 -30px no-repeat;\n}\n\n.calendarbox .calendarnav-next:focus,\n.calendarbox .calendarnav-next:hover {\n    background-position: 0 -45px;\n}\n\n.calendar-cancel {\n    margin: 0;\n    padding: 4px 0;\n    font-size: 12px;\n    background: #eee;\n    border-top: 1px solid #ddd;\n    color: #333;\n}\n\n.calendar-cancel:focus, .calendar-cancel:hover {\n    background: #ddd;\n}\n\n.calendar-cancel a {\n    color: black;\n    display: block;\n}\n\nul.timelist, .timelist li {\n    list-style-type: none;\n    margin: 0;\n    padding: 0;\n}\n\n.timelist a {\n    padding: 2px;\n}\n\n/* EDIT INLINE */\n\n.inline-deletelink {\n    float: right;\n    text-indent: -9999px;\n    background: url(../img/inline-delete.svg) 0 0 no-repeat;\n    width: 16px;\n    height: 16px;\n    border: 0px none;\n}\n\n.inline-deletelink:focus, .inline-deletelink:hover {\n    cursor: pointer;\n}\n\n/* RELATED WIDGET WRAPPER */\n.related-widget-wrapper {\n    float: left;       /* display properly in form rows with multiple fields */\n    overflow: hidden;  /* clear floated contents */\n}\n\n.related-widget-wrapper-link {\n    opacity: 0.3;\n}\n\n.related-widget-wrapper-link:link {\n    opacity: .8;\n}\n\n.related-widget-wrapper-link:link:focus,\n.related-widget-wrapper-link:link:hover {\n    opacity: 1;\n}\n\nselect + .related-widget-wrapper-link,\n.related-widget-wrapper-link + .related-widget-wrapper-link {\n    margin-left: 7px;\n}\n"
  },
  {
    "path": "src/static_cdn/admin/fonts/LICENSE.txt",
    "content": "\n                                 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.\n"
  },
  {
    "path": "src/static_cdn/admin/fonts/README.txt",
    "content": "Roboto webfont source: https://www.google.com/fonts/specimen/Roboto\nWOFF files extracted using https://github.com/majodev/google-webfonts-helper\nWeights used in this project: Light (300), Regular (400), Bold (700)\n"
  },
  {
    "path": "src/static_cdn/admin/img/LICENSE",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2014 Code Charm Ltd\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of\nthis software and associated documentation files (the \"Software\"), to deal in\nthe Software without restriction, including without limitation the rights to\nuse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\nthe Software, and to permit persons to whom the Software is furnished to do so,\nsubject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\nFOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\nCOPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\nIN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\nCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "src/static_cdn/admin/img/README.txt",
    "content": "All icons are taken from Font Awesome (http://fontawesome.io/) project.\nThe Font Awesome font is licensed under the SIL OFL 1.1:\n- https://scripts.sil.org/OFL\n\nSVG icons source: https://github.com/encharm/Font-Awesome-SVG-PNG\nFont-Awesome-SVG-PNG is licensed under the MIT license (see file license\nin current folder).\n"
  },
  {
    "path": "src/static_cdn/admin/js/SelectBox.js",
    "content": "(function($) {\n    'use strict';\n    var SelectBox = {\n        cache: {},\n        init: function(id) {\n            var box = document.getElementById(id);\n            var node;\n            SelectBox.cache[id] = [];\n            var cache = SelectBox.cache[id];\n            var boxOptions = box.options;\n            var boxOptionsLength = boxOptions.length;\n            for (var i = 0, j = boxOptionsLength; i < j; i++) {\n                node = boxOptions[i];\n                cache.push({value: node.value, text: node.text, displayed: 1});\n            }\n        },\n        redisplay: function(id) {\n            // Repopulate HTML select box from cache\n            var box = document.getElementById(id);\n            var node;\n            $(box).empty(); // clear all options\n            var new_options = box.outerHTML.slice(0, -9);  // grab just the opening tag\n            var cache = SelectBox.cache[id];\n            for (var i = 0, j = cache.length; i < j; i++) {\n                node = cache[i];\n                if (node.displayed) {\n                    var new_option = new Option(node.text, node.value, false, false);\n                    // Shows a tooltip when hovering over the option\n                    new_option.setAttribute(\"title\", node.text);\n                    new_options += new_option.outerHTML;\n                }\n            }\n            new_options += '</select>';\n            box.outerHTML = new_options;\n        },\n        filter: function(id, text) {\n            // Redisplay the HTML select box, displaying only the choices containing ALL\n            // the words in text. (It's an AND search.)\n            var tokens = text.toLowerCase().split(/\\s+/);\n            var node, token;\n            var cache = SelectBox.cache[id];\n            for (var i = 0, j = cache.length; i < j; i++) {\n                node = cache[i];\n                node.displayed = 1;\n                var node_text = node.text.toLowerCase();\n                var numTokens = tokens.length;\n                for (var k = 0; k < numTokens; k++) {\n                    token = tokens[k];\n                    if (node_text.indexOf(token) === -1) {\n                        node.displayed = 0;\n                        break;  // Once the first token isn't found we're done\n                    }\n                }\n            }\n            SelectBox.redisplay(id);\n        },\n        delete_from_cache: function(id, value) {\n            var node, delete_index = null;\n            var cache = SelectBox.cache[id];\n            for (var i = 0, j = cache.length; i < j; i++) {\n                node = cache[i];\n                if (node.value === value) {\n                    delete_index = i;\n                    break;\n                }\n            }\n            cache.splice(delete_index, 1);\n        },\n        add_to_cache: function(id, option) {\n            SelectBox.cache[id].push({value: option.value, text: option.text, displayed: 1});\n        },\n        cache_contains: function(id, value) {\n            // Check if an item is contained in the cache\n            var node;\n            var cache = SelectBox.cache[id];\n            for (var i = 0, j = cache.length; i < j; i++) {\n                node = cache[i];\n                if (node.value === value) {\n                    return true;\n                }\n            }\n            return false;\n        },\n        move: function(from, to) {\n            var from_box = document.getElementById(from);\n            var option;\n            var boxOptions = from_box.options;\n            var boxOptionsLength = boxOptions.length;\n            for (var i = 0, j = boxOptionsLength; i < j; i++) {\n                option = boxOptions[i];\n                var option_value = option.value;\n                if (option.selected && SelectBox.cache_contains(from, option_value)) {\n                    SelectBox.add_to_cache(to, {value: option_value, text: option.text, displayed: 1});\n                    SelectBox.delete_from_cache(from, option_value);\n                }\n            }\n            SelectBox.redisplay(from);\n            SelectBox.redisplay(to);\n        },\n        move_all: function(from, to) {\n            var from_box = document.getElementById(from);\n            var option;\n            var boxOptions = from_box.options;\n            var boxOptionsLength = boxOptions.length;\n            for (var i = 0, j = boxOptionsLength; i < j; i++) {\n                option = boxOptions[i];\n                var option_value = option.value;\n                if (SelectBox.cache_contains(from, option_value)) {\n                    SelectBox.add_to_cache(to, {value: option_value, text: option.text, displayed: 1});\n                    SelectBox.delete_from_cache(from, option_value);\n                }\n            }\n            SelectBox.redisplay(from);\n            SelectBox.redisplay(to);\n        },\n        sort: function(id) {\n            SelectBox.cache[id].sort(function(a, b) {\n                a = a.text.toLowerCase();\n                b = b.text.toLowerCase();\n                try {\n                    if (a > b) {\n                        return 1;\n                    }\n                    if (a < b) {\n                        return -1;\n                    }\n                }\n                catch (e) {\n                    // silently fail on IE 'unknown' exception\n                }\n                return 0;\n            } );\n        },\n        select_all: function(id) {\n            var box = document.getElementById(id);\n            var boxOptions = box.options;\n            var boxOptionsLength = boxOptions.length;\n            for (var i = 0; i < boxOptionsLength; i++) {\n                boxOptions[i].selected = 'selected';\n            }\n        }\n    };\n    window.SelectBox = SelectBox;\n})(django.jQuery);\n"
  },
  {
    "path": "src/static_cdn/admin/js/SelectFilter2.js",
    "content": "/*global SelectBox, gettext, interpolate, quickElement, SelectFilter*/\n/*\nSelectFilter2 - Turns a multiple-select box into a filter interface.\n\nRequires jQuery, core.js, and SelectBox.js.\n*/\n(function($) {\n    'use strict';\n    function findForm(node) {\n        // returns the node of the form containing the given node\n        if (node.tagName.toLowerCase() !== 'form') {\n            return findForm(node.parentNode);\n        }\n        return node;\n    }\n\n    window.SelectFilter = {\n        init: function(field_id, field_name, is_stacked) {\n            if (field_id.match(/__prefix__/)) {\n                // Don't initialize on empty forms.\n                return;\n            }\n            var from_box = document.getElementById(field_id);\n            from_box.id += '_from'; // change its ID\n            from_box.className = 'filtered';\n\n            var ps = from_box.parentNode.getElementsByTagName('p');\n            for (var i = 0; i < ps.length; i++) {\n                if (ps[i].className.indexOf(\"info\") !== -1) {\n                    // Remove <p class=\"info\">, because it just gets in the way.\n                    from_box.parentNode.removeChild(ps[i]);\n                } else if (ps[i].className.indexOf(\"help\") !== -1) {\n                    // Move help text up to the top so it isn't below the select\n                    // boxes or wrapped off on the side to the right of the add\n                    // button:\n                    from_box.parentNode.insertBefore(ps[i], from_box.parentNode.firstChild);\n                }\n            }\n\n            // <div class=\"selector\"> or <div class=\"selector stacked\">\n            var selector_div = quickElement('div', from_box.parentNode);\n            selector_div.className = is_stacked ? 'selector stacked' : 'selector';\n\n            // <div class=\"selector-available\">\n            var selector_available = quickElement('div', selector_div);\n            selector_available.className = 'selector-available';\n            var title_available = quickElement('h2', selector_available, interpolate(gettext('Available %s') + ' ', [field_name]));\n            quickElement(\n                'span', title_available, '',\n                'class', 'help help-tooltip help-icon',\n                'title', interpolate(\n                    gettext(\n                        'This is the list of available %s. You may choose some by ' +\n                        'selecting them in the box below and then clicking the ' +\n                        '\"Choose\" arrow between the two boxes.'\n                    ),\n                    [field_name]\n                )\n            );\n\n            var filter_p = quickElement('p', selector_available, '', 'id', field_id + '_filter');\n            filter_p.className = 'selector-filter';\n\n            var search_filter_label = quickElement('label', filter_p, '', 'for', field_id + '_input');\n\n            quickElement(\n                'span', search_filter_label, '',\n                'class', 'help-tooltip search-label-icon',\n                'title', interpolate(gettext(\"Type into this box to filter down the list of available %s.\"), [field_name])\n            );\n\n            filter_p.appendChild(document.createTextNode(' '));\n\n            var filter_input = quickElement('input', filter_p, '', 'type', 'text', 'placeholder', gettext(\"Filter\"));\n            filter_input.id = field_id + '_input';\n\n            selector_available.appendChild(from_box);\n            var choose_all = quickElement('a', selector_available, gettext('Choose all'), 'title', interpolate(gettext('Click to choose all %s at once.'), [field_name]), 'href', '#', 'id', field_id + '_add_all_link');\n            choose_all.className = 'selector-chooseall';\n\n            // <ul class=\"selector-chooser\">\n            var selector_chooser = quickElement('ul', selector_div);\n            selector_chooser.className = 'selector-chooser';\n            var add_link = quickElement('a', quickElement('li', selector_chooser), gettext('Choose'), 'title', gettext('Choose'), 'href', '#', 'id', field_id + '_add_link');\n            add_link.className = 'selector-add';\n            var remove_link = quickElement('a', quickElement('li', selector_chooser), gettext('Remove'), 'title', gettext('Remove'), 'href', '#', 'id', field_id + '_remove_link');\n            remove_link.className = 'selector-remove';\n\n            // <div class=\"selector-chosen\">\n            var selector_chosen = quickElement('div', selector_div);\n            selector_chosen.className = 'selector-chosen';\n            var title_chosen = quickElement('h2', selector_chosen, interpolate(gettext('Chosen %s') + ' ', [field_name]));\n            quickElement(\n                'span', title_chosen, '',\n                'class', 'help help-tooltip help-icon',\n                'title', interpolate(\n                    gettext(\n                        'This is the list of chosen %s. You may remove some by ' +\n                        'selecting them in the box below and then clicking the ' +\n                        '\"Remove\" arrow between the two boxes.'\n                    ),\n                    [field_name]\n                )\n            );\n\n            var to_box = quickElement('select', selector_chosen, '', 'id', field_id + '_to', 'multiple', 'multiple', 'size', from_box.size, 'name', from_box.getAttribute('name'));\n            to_box.className = 'filtered';\n            var clear_all = quickElement('a', selector_chosen, gettext('Remove all'), 'title', interpolate(gettext('Click to remove all chosen %s at once.'), [field_name]), 'href', '#', 'id', field_id + '_remove_all_link');\n            clear_all.className = 'selector-clearall';\n\n            from_box.setAttribute('name', from_box.getAttribute('name') + '_old');\n\n            // Set up the JavaScript event handlers for the select box filter interface\n            var move_selection = function(e, elem, move_func, from, to) {\n                if (elem.className.indexOf('active') !== -1) {\n                    move_func(from, to);\n                    SelectFilter.refresh_icons(field_id);\n                }\n                e.preventDefault();\n            };\n            choose_all.addEventListener('click', function(e) {\n                move_selection(e, this, SelectBox.move_all, field_id + '_from', field_id + '_to');\n            });\n            add_link.addEventListener('click', function(e) {\n                move_selection(e, this, SelectBox.move, field_id + '_from', field_id + '_to');\n            });\n            remove_link.addEventListener('click', function(e) {\n                move_selection(e, this, SelectBox.move, field_id + '_to', field_id + '_from');\n            });\n            clear_all.addEventListener('click', function(e) {\n                move_selection(e, this, SelectBox.move_all, field_id + '_to', field_id + '_from');\n            });\n            filter_input.addEventListener('keypress', function(e) {\n                SelectFilter.filter_key_press(e, field_id);\n            });\n            filter_input.addEventListener('keyup', function(e) {\n                SelectFilter.filter_key_up(e, field_id);\n            });\n            filter_input.addEventListener('keydown', function(e) {\n                SelectFilter.filter_key_down(e, field_id);\n            });\n            selector_div.addEventListener('change', function(e) {\n                if (e.target.tagName === 'SELECT') {\n                    SelectFilter.refresh_icons(field_id);\n                }\n            });\n            selector_div.addEventListener('dblclick', function(e) {\n                if (e.target.tagName === 'OPTION') {\n                    if (e.target.closest('select').id === field_id + '_to') {\n                        SelectBox.move(field_id + '_to', field_id + '_from');\n                    } else {\n                        SelectBox.move(field_id + '_from', field_id + '_to');\n                    }\n                    SelectFilter.refresh_icons(field_id);\n                }\n            });\n            findForm(from_box).addEventListener('submit', function() {\n                SelectBox.select_all(field_id + '_to');\n            });\n            SelectBox.init(field_id + '_from');\n            SelectBox.init(field_id + '_to');\n            // Move selected from_box options to to_box\n            SelectBox.move(field_id + '_from', field_id + '_to');\n\n            if (!is_stacked) {\n                // In horizontal mode, give the same height to the two boxes.\n                var j_from_box = $('#' + field_id + '_from');\n                var j_to_box = $('#' + field_id + '_to');\n                j_to_box.height($(filter_p).outerHeight() + j_from_box.outerHeight());\n            }\n\n            // Initial icon refresh\n            SelectFilter.refresh_icons(field_id);\n        },\n        any_selected: function(field) {\n            var any_selected = false;\n            try {\n                // Temporarily add the required attribute and check validity.\n                // This is much faster in WebKit browsers than the fallback.\n                field.attr('required', 'required');\n                any_selected = field.is(':valid');\n                field.removeAttr('required');\n            } catch (e) {\n                // Browsers that don't support :valid (IE < 10)\n                any_selected = field.find('option:selected').length > 0;\n            }\n            return any_selected;\n        },\n        refresh_icons: function(field_id) {\n            var from = $('#' + field_id + '_from');\n            var to = $('#' + field_id + '_to');\n            // Active if at least one item is selected\n            $('#' + field_id + '_add_link').toggleClass('active', SelectFilter.any_selected(from));\n            $('#' + field_id + '_remove_link').toggleClass('active', SelectFilter.any_selected(to));\n            // Active if the corresponding box isn't empty\n            $('#' + field_id + '_add_all_link').toggleClass('active', from.find('option').length > 0);\n            $('#' + field_id + '_remove_all_link').toggleClass('active', to.find('option').length > 0);\n        },\n        filter_key_press: function(event, field_id) {\n            var from = document.getElementById(field_id + '_from');\n            // don't submit form if user pressed Enter\n            if ((event.which && event.which === 13) || (event.keyCode && event.keyCode === 13)) {\n                from.selectedIndex = 0;\n                SelectBox.move(field_id + '_from', field_id + '_to');\n                from.selectedIndex = 0;\n                event.preventDefault();\n                return false;\n            }\n        },\n        filter_key_up: function(event, field_id) {\n            var from = document.getElementById(field_id + '_from');\n            var temp = from.selectedIndex;\n            SelectBox.filter(field_id + '_from', document.getElementById(field_id + '_input').value);\n            from.selectedIndex = temp;\n            return true;\n        },\n        filter_key_down: function(event, field_id) {\n            var from = document.getElementById(field_id + '_from');\n            // right arrow -- move across\n            if ((event.which && event.which === 39) || (event.keyCode && event.keyCode === 39)) {\n                var old_index = from.selectedIndex;\n                SelectBox.move(field_id + '_from', field_id + '_to');\n                from.selectedIndex = (old_index === from.length) ? from.length - 1 : old_index;\n                return false;\n            }\n            // down arrow -- wrap around\n            if ((event.which && event.which === 40) || (event.keyCode && event.keyCode === 40)) {\n                from.selectedIndex = (from.length === from.selectedIndex + 1) ? 0 : from.selectedIndex + 1;\n            }\n            // up arrow -- wrap around\n            if ((event.which && event.which === 38) || (event.keyCode && event.keyCode === 38)) {\n                from.selectedIndex = (from.selectedIndex === 0) ? from.length - 1 : from.selectedIndex - 1;\n            }\n            return true;\n        }\n    };\n\n    window.addEventListener('load', function(e) {\n        $('select.selectfilter, select.selectfilterstacked').each(function() {\n            var $el = $(this),\n                data = $el.data();\n            SelectFilter.init($el.attr('id'), data.fieldName, parseInt(data.isStacked, 10));\n        });\n    });\n\n})(django.jQuery);\n"
  },
  {
    "path": "src/static_cdn/admin/js/actions.js",
    "content": "/*global gettext, interpolate, ngettext*/\n(function($) {\n    'use strict';\n    var lastChecked;\n\n    $.fn.actions = function(opts) {\n        var options = $.extend({}, $.fn.actions.defaults, opts);\n        var actionCheckboxes = $(this);\n        var list_editable_changed = false;\n        var showQuestion = function() {\n            $(options.acrossClears).hide();\n            $(options.acrossQuestions).show();\n            $(options.allContainer).hide();\n        },\n        showClear = function() {\n            $(options.acrossClears).show();\n            $(options.acrossQuestions).hide();\n            $(options.actionContainer).toggleClass(options.selectedClass);\n            $(options.allContainer).show();\n            $(options.counterContainer).hide();\n        },\n        reset = function() {\n            $(options.acrossClears).hide();\n            $(options.acrossQuestions).hide();\n            $(options.allContainer).hide();\n            $(options.counterContainer).show();\n        },\n        clearAcross = function() {\n            reset();\n            $(options.acrossInput).val(0);\n            $(options.actionContainer).removeClass(options.selectedClass);\n        },\n        checker = function(checked) {\n            if (checked) {\n                showQuestion();\n            } else {\n                reset();\n            }\n            $(actionCheckboxes).prop(\"checked\", checked)\n                .parent().parent().toggleClass(options.selectedClass, checked);\n        },\n        updateCounter = function() {\n            var sel = $(actionCheckboxes).filter(\":checked\").length;\n            // data-actions-icnt is defined in the generated HTML\n            // and contains the total amount of objects in the queryset\n            var actions_icnt = $('.action-counter').data('actionsIcnt');\n            $(options.counterContainer).html(interpolate(\n            ngettext('%(sel)s of %(cnt)s selected', '%(sel)s of %(cnt)s selected', sel), {\n                sel: sel,\n                cnt: actions_icnt\n            }, true));\n            $(options.allToggle).prop(\"checked\", function() {\n                var value;\n                if (sel === actionCheckboxes.length) {\n                    value = true;\n                    showQuestion();\n                } else {\n                    value = false;\n                    clearAcross();\n                }\n                return value;\n            });\n        };\n        // Show counter by default\n        $(options.counterContainer).show();\n        // Check state of checkboxes and reinit state if needed\n        $(this).filter(\":checked\").each(function(i) {\n            $(this).parent().parent().toggleClass(options.selectedClass);\n            updateCounter();\n            if ($(options.acrossInput).val() === 1) {\n                showClear();\n            }\n        });\n        $(options.allToggle).show().on('click', function() {\n            checker($(this).prop(\"checked\"));\n            updateCounter();\n        });\n        $(\"a\", options.acrossQuestions).on('click', function(event) {\n            event.preventDefault();\n            $(options.acrossInput).val(1);\n            showClear();\n        });\n        $(\"a\", options.acrossClears).on('click', function(event) {\n            event.preventDefault();\n            $(options.allToggle).prop(\"checked\", false);\n            clearAcross();\n            checker(0);\n            updateCounter();\n        });\n        lastChecked = null;\n        $(actionCheckboxes).on('click', function(event) {\n            if (!event) { event = window.event; }\n            var target = event.target ? event.target : event.srcElement;\n            if (lastChecked && $.data(lastChecked) !== $.data(target) && event.shiftKey === true) {\n                var inrange = false;\n                $(lastChecked).prop(\"checked\", target.checked)\n                    .parent().parent().toggleClass(options.selectedClass, target.checked);\n                $(actionCheckboxes).each(function() {\n                    if ($.data(this) === $.data(lastChecked) || $.data(this) === $.data(target)) {\n                        inrange = (inrange) ? false : true;\n                    }\n                    if (inrange) {\n                        $(this).prop(\"checked\", target.checked)\n                            .parent().parent().toggleClass(options.selectedClass, target.checked);\n                    }\n                });\n            }\n            $(target).parent().parent().toggleClass(options.selectedClass, target.checked);\n            lastChecked = target;\n            updateCounter();\n        });\n        $('form#changelist-form table#result_list tr').on('change', 'td:gt(0) :input', function() {\n            list_editable_changed = true;\n        });\n        $('form#changelist-form button[name=\"index\"]').on('click', function(event) {\n            if (list_editable_changed) {\n                return confirm(gettext(\"You have unsaved changes on individual editable fields. If you run an action, your unsaved changes will be lost.\"));\n            }\n        });\n        $('form#changelist-form input[name=\"_save\"]').on('click', function(event) {\n            var action_changed = false;\n            $('select option:selected', options.actionContainer).each(function() {\n                if ($(this).val()) {\n                    action_changed = true;\n                }\n            });\n            if (action_changed) {\n                if (list_editable_changed) {\n                    return confirm(gettext(\"You have selected an action, but you haven't saved your changes to individual fields yet. Please click OK to save. You'll need to re-run the action.\"));\n                } else {\n                    return confirm(gettext(\"You have selected an action, and you haven't made any changes on individual fields. You're probably looking for the Go button rather than the Save button.\"));\n                }\n            }\n        });\n    };\n    /* Setup plugin defaults */\n    $.fn.actions.defaults = {\n        actionContainer: \"div.actions\",\n        counterContainer: \"span.action-counter\",\n        allContainer: \"div.actions span.all\",\n        acrossInput: \"div.actions input.select-across\",\n        acrossQuestions: \"div.actions span.question\",\n        acrossClears: \"div.actions span.clear\",\n        allToggle: \"#action-toggle\",\n        selectedClass: \"selected\"\n    };\n    $(document).ready(function() {\n        var $actionsEls = $('tr input.action-select');\n        if ($actionsEls.length > 0) {\n            $actionsEls.actions();\n        }\n    });\n})(django.jQuery);\n"
  },
  {
    "path": "src/static_cdn/admin/js/admin/DateTimeShortcuts.js",
    "content": "/*global Calendar, findPosX, findPosY, getStyle, get_format, gettext, gettext_noop, interpolate, ngettext, quickElement*/\n// Inserts shortcut buttons after all of the following:\n//     <input type=\"text\" class=\"vDateField\">\n//     <input type=\"text\" class=\"vTimeField\">\n(function() {\n    'use strict';\n    var DateTimeShortcuts = {\n        calendars: [],\n        calendarInputs: [],\n        clockInputs: [],\n        clockHours: {\n            default_: [\n                [gettext_noop('Now'), -1],\n                [gettext_noop('Midnight'), 0],\n                [gettext_noop('6 a.m.'), 6],\n                [gettext_noop('Noon'), 12],\n                [gettext_noop('6 p.m.'), 18]\n            ]\n        },\n        dismissClockFunc: [],\n        dismissCalendarFunc: [],\n        calendarDivName1: 'calendarbox', // name of calendar <div> that gets toggled\n        calendarDivName2: 'calendarin',  // name of <div> that contains calendar\n        calendarLinkName: 'calendarlink',// name of the link that is used to toggle\n        clockDivName: 'clockbox',        // name of clock <div> that gets toggled\n        clockLinkName: 'clocklink',      // name of the link that is used to toggle\n        shortCutsClass: 'datetimeshortcuts', // class of the clock and cal shortcuts\n        timezoneWarningClass: 'timezonewarning', // class of the warning for timezone mismatch\n        timezoneOffset: 0,\n        init: function() {\n            var body = document.getElementsByTagName('body')[0];\n            var serverOffset = body.getAttribute('data-admin-utc-offset');\n            if (serverOffset) {\n                var localOffset = new Date().getTimezoneOffset() * -60;\n                DateTimeShortcuts.timezoneOffset = localOffset - serverOffset;\n            }\n\n            var inputs = document.getElementsByTagName('input');\n            for (var i = 0; i < inputs.length; i++) {\n                var inp = inputs[i];\n                if (inp.getAttribute('type') === 'text' && inp.className.match(/vTimeField/)) {\n                    DateTimeShortcuts.addClock(inp);\n                    DateTimeShortcuts.addTimezoneWarning(inp);\n                }\n                else if (inp.getAttribute('type') === 'text' && inp.className.match(/vDateField/)) {\n                    DateTimeShortcuts.addCalendar(inp);\n                    DateTimeShortcuts.addTimezoneWarning(inp);\n                }\n            }\n        },\n        // Return the current time while accounting for the server timezone.\n        now: function() {\n            var body = document.getElementsByTagName('body')[0];\n            var serverOffset = body.getAttribute('data-admin-utc-offset');\n            if (serverOffset) {\n                var localNow = new Date();\n                var localOffset = localNow.getTimezoneOffset() * -60;\n                localNow.setTime(localNow.getTime() + 1000 * (serverOffset - localOffset));\n                return localNow;\n            } else {\n                return new Date();\n            }\n        },\n        // Add a warning when the time zone in the browser and backend do not match.\n        addTimezoneWarning: function(inp) {\n            var warningClass = DateTimeShortcuts.timezoneWarningClass;\n            var timezoneOffset = DateTimeShortcuts.timezoneOffset / 3600;\n\n            // Only warn if there is a time zone mismatch.\n            if (!timezoneOffset) {\n                return;\n            }\n\n            // Check if warning is already there.\n            if (inp.parentNode.querySelectorAll('.' + warningClass).length) {\n                return;\n            }\n\n            var message;\n            if (timezoneOffset > 0) {\n                message = ngettext(\n                    'Note: You are %s hour ahead of server time.',\n                    'Note: You are %s hours ahead of server time.',\n                    timezoneOffset\n                );\n            }\n            else {\n                timezoneOffset *= -1;\n                message = ngettext(\n                    'Note: You are %s hour behind server time.',\n                    'Note: You are %s hours behind server time.',\n                    timezoneOffset\n                );\n            }\n            message = interpolate(message, [timezoneOffset]);\n\n            var warning = document.createElement('span');\n            warning.className = warningClass;\n            warning.textContent = message;\n            inp.parentNode.appendChild(document.createElement('br'));\n            inp.parentNode.appendChild(warning);\n        },\n        // Add clock widget to a given field\n        addClock: function(inp) {\n            var num = DateTimeShortcuts.clockInputs.length;\n            DateTimeShortcuts.clockInputs[num] = inp;\n            DateTimeShortcuts.dismissClockFunc[num] = function() { DateTimeShortcuts.dismissClock(num); return true; };\n\n            // Shortcut links (clock icon and \"Now\" link)\n            var shortcuts_span = document.createElement('span');\n            shortcuts_span.className = DateTimeShortcuts.shortCutsClass;\n            inp.parentNode.insertBefore(shortcuts_span, inp.nextSibling);\n            var now_link = document.createElement('a');\n            now_link.setAttribute('href', \"#\");\n            now_link.textContent = gettext('Now');\n            now_link.addEventListener('click', function(e) {\n                e.preventDefault();\n                DateTimeShortcuts.handleClockQuicklink(num, -1);\n            });\n            var clock_link = document.createElement('a');\n            clock_link.setAttribute('href', '#');\n            clock_link.id = DateTimeShortcuts.clockLinkName + num;\n            clock_link.addEventListener('click', function(e) {\n                e.preventDefault();\n                // avoid triggering the document click handler to dismiss the clock\n                e.stopPropagation();\n                DateTimeShortcuts.openClock(num);\n            });\n\n            quickElement(\n                'span', clock_link, '',\n                'class', 'clock-icon',\n                'title', gettext('Choose a Time')\n            );\n            shortcuts_span.appendChild(document.createTextNode('\\u00A0'));\n            shortcuts_span.appendChild(now_link);\n            shortcuts_span.appendChild(document.createTextNode('\\u00A0|\\u00A0'));\n            shortcuts_span.appendChild(clock_link);\n\n            // Create clock link div\n            //\n            // Markup looks like:\n            // <div id=\"clockbox1\" class=\"clockbox module\">\n            //     <h2>Choose a time</h2>\n            //     <ul class=\"timelist\">\n            //         <li><a href=\"#\">Now</a></li>\n            //         <li><a href=\"#\">Midnight</a></li>\n            //         <li><a href=\"#\">6 a.m.</a></li>\n            //         <li><a href=\"#\">Noon</a></li>\n            //         <li><a href=\"#\">6 p.m.</a></li>\n            //     </ul>\n            //     <p class=\"calendar-cancel\"><a href=\"#\">Cancel</a></p>\n            // </div>\n\n            var clock_box = document.createElement('div');\n            clock_box.style.display = 'none';\n            clock_box.style.position = 'absolute';\n            clock_box.className = 'clockbox module';\n            clock_box.setAttribute('id', DateTimeShortcuts.clockDivName + num);\n            document.body.appendChild(clock_box);\n            clock_box.addEventListener('click', function(e) { e.stopPropagation(); });\n\n            quickElement('h2', clock_box, gettext('Choose a time'));\n            var time_list = quickElement('ul', clock_box);\n            time_list.className = 'timelist';\n            // The list of choices can be overridden in JavaScript like this:\n            // DateTimeShortcuts.clockHours.name = [['3 a.m.', 3]];\n            // where name is the name attribute of the <input>.\n            var name = typeof DateTimeShortcuts.clockHours[inp.name] === 'undefined' ? 'default_' : inp.name;\n            DateTimeShortcuts.clockHours[name].forEach(function(element) {\n                var time_link = quickElement('a', quickElement('li', time_list), gettext(element[0]), 'href', '#');\n                time_link.addEventListener('click', function(e) {\n                    e.preventDefault();\n                    DateTimeShortcuts.handleClockQuicklink(num, element[1]);\n                });\n            });\n\n            var cancel_p = quickElement('p', clock_box);\n            cancel_p.className = 'calendar-cancel';\n            var cancel_link = quickElement('a', cancel_p, gettext('Cancel'), 'href', '#');\n            cancel_link.addEventListener('click', function(e) {\n                e.preventDefault();\n                DateTimeShortcuts.dismissClock(num);\n            });\n\n            document.addEventListener('keyup', function(event) {\n                if (event.which === 27) {\n                    // ESC key closes popup\n                    DateTimeShortcuts.dismissClock(num);\n                    event.preventDefault();\n                }\n            });\n        },\n        openClock: function(num) {\n            var clock_box = document.getElementById(DateTimeShortcuts.clockDivName + num);\n            var clock_link = document.getElementById(DateTimeShortcuts.clockLinkName + num);\n\n            // Recalculate the clockbox position\n            // is it left-to-right or right-to-left layout ?\n            if (getStyle(document.body, 'direction') !== 'rtl') {\n                clock_box.style.left = findPosX(clock_link) + 17 + 'px';\n            }\n            else {\n                // since style's width is in em, it'd be tough to calculate\n                // px value of it. let's use an estimated px for now\n                // TODO: IE returns wrong value for findPosX when in rtl mode\n                //       (it returns as it was left aligned), needs to be fixed.\n                clock_box.style.left = findPosX(clock_link) - 110 + 'px';\n            }\n            clock_box.style.top = Math.max(0, findPosY(clock_link) - 30) + 'px';\n\n            // Show the clock box\n            clock_box.style.display = 'block';\n            document.addEventListener('click', DateTimeShortcuts.dismissClockFunc[num]);\n        },\n        dismissClock: function(num) {\n            document.getElementById(DateTimeShortcuts.clockDivName + num).style.display = 'none';\n            document.removeEventListener('click', DateTimeShortcuts.dismissClockFunc[num]);\n        },\n        handleClockQuicklink: function(num, val) {\n            var d;\n            if (val === -1) {\n                d = DateTimeShortcuts.now();\n            }\n            else {\n                d = new Date(1970, 1, 1, val, 0, 0, 0);\n            }\n            DateTimeShortcuts.clockInputs[num].value = d.strftime(get_format('TIME_INPUT_FORMATS')[0]);\n            DateTimeShortcuts.clockInputs[num].focus();\n            DateTimeShortcuts.dismissClock(num);\n        },\n        // Add calendar widget to a given field.\n        addCalendar: function(inp) {\n            var num = DateTimeShortcuts.calendars.length;\n\n            DateTimeShortcuts.calendarInputs[num] = inp;\n            DateTimeShortcuts.dismissCalendarFunc[num] = function() { DateTimeShortcuts.dismissCalendar(num); return true; };\n\n            // Shortcut links (calendar icon and \"Today\" link)\n            var shortcuts_span = document.createElement('span');\n            shortcuts_span.className = DateTimeShortcuts.shortCutsClass;\n            inp.parentNode.insertBefore(shortcuts_span, inp.nextSibling);\n            var today_link = document.createElement('a');\n            today_link.setAttribute('href', '#');\n            today_link.appendChild(document.createTextNode(gettext('Today')));\n            today_link.addEventListener('click', function(e) {\n                e.preventDefault();\n                DateTimeShortcuts.handleCalendarQuickLink(num, 0);\n            });\n            var cal_link = document.createElement('a');\n            cal_link.setAttribute('href', '#');\n            cal_link.id = DateTimeShortcuts.calendarLinkName + num;\n            cal_link.addEventListener('click', function(e) {\n                e.preventDefault();\n                // avoid triggering the document click handler to dismiss the calendar\n                e.stopPropagation();\n                DateTimeShortcuts.openCalendar(num);\n            });\n            quickElement(\n                'span', cal_link, '',\n                'class', 'date-icon',\n                'title', gettext('Choose a Date')\n            );\n            shortcuts_span.appendChild(document.createTextNode('\\u00A0'));\n            shortcuts_span.appendChild(today_link);\n            shortcuts_span.appendChild(document.createTextNode('\\u00A0|\\u00A0'));\n            shortcuts_span.appendChild(cal_link);\n\n            // Create calendarbox div.\n            //\n            // Markup looks like:\n            //\n            // <div id=\"calendarbox3\" class=\"calendarbox module\">\n            //     <h2>\n            //           <a href=\"#\" class=\"link-previous\">&lsaquo;</a>\n            //           <a href=\"#\" class=\"link-next\">&rsaquo;</a> February 2003\n            //     </h2>\n            //     <div class=\"calendar\" id=\"calendarin3\">\n            //         <!-- (cal) -->\n            //     </div>\n            //     <div class=\"calendar-shortcuts\">\n            //          <a href=\"#\">Yesterday</a> | <a href=\"#\">Today</a> | <a href=\"#\">Tomorrow</a>\n            //     </div>\n            //     <p class=\"calendar-cancel\"><a href=\"#\">Cancel</a></p>\n            // </div>\n            var cal_box = document.createElement('div');\n            cal_box.style.display = 'none';\n            cal_box.style.position = 'absolute';\n            cal_box.className = 'calendarbox module';\n            cal_box.setAttribute('id', DateTimeShortcuts.calendarDivName1 + num);\n            document.body.appendChild(cal_box);\n            cal_box.addEventListener('click', function(e) { e.stopPropagation(); });\n\n            // next-prev links\n            var cal_nav = quickElement('div', cal_box);\n            var cal_nav_prev = quickElement('a', cal_nav, '<', 'href', '#');\n            cal_nav_prev.className = 'calendarnav-previous';\n            cal_nav_prev.addEventListener('click', function(e) {\n                e.preventDefault();\n                DateTimeShortcuts.drawPrev(num);\n            });\n\n            var cal_nav_next = quickElement('a', cal_nav, '>', 'href', '#');\n            cal_nav_next.className = 'calendarnav-next';\n            cal_nav_next.addEventListener('click', function(e) {\n                e.preventDefault();\n                DateTimeShortcuts.drawNext(num);\n            });\n\n            // main box\n            var cal_main = quickElement('div', cal_box, '', 'id', DateTimeShortcuts.calendarDivName2 + num);\n            cal_main.className = 'calendar';\n            DateTimeShortcuts.calendars[num] = new Calendar(DateTimeShortcuts.calendarDivName2 + num, DateTimeShortcuts.handleCalendarCallback(num));\n            DateTimeShortcuts.calendars[num].drawCurrent();\n\n            // calendar shortcuts\n            var shortcuts = quickElement('div', cal_box);\n            shortcuts.className = 'calendar-shortcuts';\n            var day_link = quickElement('a', shortcuts, gettext('Yesterday'), 'href', '#');\n            day_link.addEventListener('click', function(e) {\n                e.preventDefault();\n                DateTimeShortcuts.handleCalendarQuickLink(num, -1);\n            });\n            shortcuts.appendChild(document.createTextNode('\\u00A0|\\u00A0'));\n            day_link = quickElement('a', shortcuts, gettext('Today'), 'href', '#');\n            day_link.addEventListener('click', function(e) {\n                e.preventDefault();\n                DateTimeShortcuts.handleCalendarQuickLink(num, 0);\n            });\n            shortcuts.appendChild(document.createTextNode('\\u00A0|\\u00A0'));\n            day_link = quickElement('a', shortcuts, gettext('Tomorrow'), 'href', '#');\n            day_link.addEventListener('click', function(e) {\n                e.preventDefault();\n                DateTimeShortcuts.handleCalendarQuickLink(num, +1);\n            });\n\n            // cancel bar\n            var cancel_p = quickElement('p', cal_box);\n            cancel_p.className = 'calendar-cancel';\n            var cancel_link = quickElement('a', cancel_p, gettext('Cancel'), 'href', '#');\n            cancel_link.addEventListener('click', function(e) {\n                e.preventDefault();\n                DateTimeShortcuts.dismissCalendar(num);\n            });\n            document.addEventListener('keyup', function(event) {\n                if (event.which === 27) {\n                    // ESC key closes popup\n                    DateTimeShortcuts.dismissCalendar(num);\n                    event.preventDefault();\n                }\n            });\n        },\n        openCalendar: function(num) {\n            var cal_box = document.getElementById(DateTimeShortcuts.calendarDivName1 + num);\n            var cal_link = document.getElementById(DateTimeShortcuts.calendarLinkName + num);\n            var inp = DateTimeShortcuts.calendarInputs[num];\n\n            // Determine if the current value in the input has a valid date.\n            // If so, draw the calendar with that date's year and month.\n            if (inp.value) {\n                var format = get_format('DATE_INPUT_FORMATS')[0];\n                var selected = inp.value.strptime(format);\n                var year = selected.getUTCFullYear();\n                var month = selected.getUTCMonth() + 1;\n                var re = /\\d{4}/;\n                if (re.test(year.toString()) && month >= 1 && month <= 12) {\n                    DateTimeShortcuts.calendars[num].drawDate(month, year, selected);\n                }\n            }\n\n            // Recalculate the clockbox position\n            // is it left-to-right or right-to-left layout ?\n            if (getStyle(document.body, 'direction') !== 'rtl') {\n                cal_box.style.left = findPosX(cal_link) + 17 + 'px';\n            }\n            else {\n                // since style's width is in em, it'd be tough to calculate\n                // px value of it. let's use an estimated px for now\n                // TODO: IE returns wrong value for findPosX when in rtl mode\n                //       (it returns as it was left aligned), needs to be fixed.\n                cal_box.style.left = findPosX(cal_link) - 180 + 'px';\n            }\n            cal_box.style.top = Math.max(0, findPosY(cal_link) - 75) + 'px';\n\n            cal_box.style.display = 'block';\n            document.addEventListener('click', DateTimeShortcuts.dismissCalendarFunc[num]);\n        },\n        dismissCalendar: function(num) {\n            document.getElementById(DateTimeShortcuts.calendarDivName1 + num).style.display = 'none';\n            document.removeEventListener('click', DateTimeShortcuts.dismissCalendarFunc[num]);\n        },\n        drawPrev: function(num) {\n            DateTimeShortcuts.calendars[num].drawPreviousMonth();\n        },\n        drawNext: function(num) {\n            DateTimeShortcuts.calendars[num].drawNextMonth();\n        },\n        handleCalendarCallback: function(num) {\n            var format = get_format('DATE_INPUT_FORMATS')[0];\n            // the format needs to be escaped a little\n            format = format.replace('\\\\', '\\\\\\\\')\n                           .replace('\\r', '\\\\r')\n                           .replace('\\n', '\\\\n')\n                           .replace('\\t', '\\\\t')\n                           .replace(\"'\", \"\\\\'\");\n            return function(y, m, d) {\n                DateTimeShortcuts.calendarInputs[num].value = new Date(y, m - 1, d).strftime(format);\n                DateTimeShortcuts.calendarInputs[num].focus();\n                document.getElementById(DateTimeShortcuts.calendarDivName1 + num).style.display = 'none';\n            };\n        },\n        handleCalendarQuickLink: function(num, offset) {\n            var d = DateTimeShortcuts.now();\n            d.setDate(d.getDate() + offset);\n            DateTimeShortcuts.calendarInputs[num].value = d.strftime(get_format('DATE_INPUT_FORMATS')[0]);\n            DateTimeShortcuts.calendarInputs[num].focus();\n            DateTimeShortcuts.dismissCalendar(num);\n        }\n    };\n\n    window.addEventListener('load', DateTimeShortcuts.init);\n    window.DateTimeShortcuts = DateTimeShortcuts;\n})();\n"
  },
  {
    "path": "src/static_cdn/admin/js/admin/RelatedObjectLookups.js",
    "content": "/*global SelectBox, interpolate*/\n// Handles related-objects functionality: lookup link for raw_id_fields\n// and Add Another links.\n\n(function($) {\n    'use strict';\n\n    // IE doesn't accept periods or dashes in the window name, but the element IDs\n    // we use to generate popup window names may contain them, therefore we map them\n    // to allowed characters in a reversible way so that we can locate the correct\n    // element when the popup window is dismissed.\n    function id_to_windowname(text) {\n        text = text.replace(/\\./g, '__dot__');\n        text = text.replace(/\\-/g, '__dash__');\n        return text;\n    }\n\n    function windowname_to_id(text) {\n        text = text.replace(/__dot__/g, '.');\n        text = text.replace(/__dash__/g, '-');\n        return text;\n    }\n\n    function showAdminPopup(triggeringLink, name_regexp, add_popup) {\n        var name = triggeringLink.id.replace(name_regexp, '');\n        name = id_to_windowname(name);\n        var href = triggeringLink.href;\n        if (add_popup) {\n            if (href.indexOf('?') === -1) {\n                href += '?_popup=1';\n            } else {\n                href += '&_popup=1';\n            }\n        }\n        var win = window.open(href, name, 'height=500,width=800,resizable=yes,scrollbars=yes');\n        win.focus();\n        return false;\n    }\n\n    function showRelatedObjectLookupPopup(triggeringLink) {\n        return showAdminPopup(triggeringLink, /^lookup_/, true);\n    }\n\n    function dismissRelatedLookupPopup(win, chosenId) {\n        var name = windowname_to_id(win.name);\n        var elem = document.getElementById(name);\n        if (elem.className.indexOf('vManyToManyRawIdAdminField') !== -1 && elem.value) {\n            elem.value += ',' + chosenId;\n        } else {\n            document.getElementById(name).value = chosenId;\n        }\n        win.close();\n    }\n\n    function showRelatedObjectPopup(triggeringLink) {\n        return showAdminPopup(triggeringLink, /^(change|add|delete)_/, false);\n    }\n\n    function updateRelatedObjectLinks(triggeringLink) {\n        var $this = $(triggeringLink);\n        var siblings = $this.nextAll('.view-related, .change-related, .delete-related');\n        if (!siblings.length) {\n            return;\n        }\n        var value = $this.val();\n        if (value) {\n            siblings.each(function() {\n                var elm = $(this);\n                elm.attr('href', elm.attr('data-href-template').replace('__fk__', value));\n            });\n        } else {\n            siblings.removeAttr('href');\n        }\n    }\n\n    function dismissAddRelatedObjectPopup(win, newId, newRepr) {\n        var name = windowname_to_id(win.name);\n        var elem = document.getElementById(name);\n        if (elem) {\n            var elemName = elem.nodeName.toUpperCase();\n            if (elemName === 'SELECT') {\n                elem.options[elem.options.length] = new Option(newRepr, newId, true, true);\n            } else if (elemName === 'INPUT') {\n                if (elem.className.indexOf('vManyToManyRawIdAdminField') !== -1 && elem.value) {\n                    elem.value += ',' + newId;\n                } else {\n                    elem.value = newId;\n                }\n            }\n            // Trigger a change event to update related links if required.\n            $(elem).trigger('change');\n        } else {\n            var toId = name + \"_to\";\n            var o = new Option(newRepr, newId);\n            SelectBox.add_to_cache(toId, o);\n            SelectBox.redisplay(toId);\n        }\n        win.close();\n    }\n\n    function dismissChangeRelatedObjectPopup(win, objId, newRepr, newId) {\n        var id = windowname_to_id(win.name).replace(/^edit_/, '');\n        var selectsSelector = interpolate('#%s, #%s_from, #%s_to', [id, id, id]);\n        var selects = $(selectsSelector);\n        selects.find('option').each(function() {\n            if (this.value === objId) {\n                this.textContent = newRepr;\n                this.value = newId;\n            }\n        });\n        selects.next().find('.select2-selection__rendered').each(function() {\n            // The element can have a clear button as a child.\n            // Use the lastChild to modify only the displayed value.\n            this.lastChild.textContent = newRepr;\n            this.title = newRepr;\n        });\n        win.close();\n    }\n\n    function dismissDeleteRelatedObjectPopup(win, objId) {\n        var id = windowname_to_id(win.name).replace(/^delete_/, '');\n        var selectsSelector = interpolate('#%s, #%s_from, #%s_to', [id, id, id]);\n        var selects = $(selectsSelector);\n        selects.find('option').each(function() {\n            if (this.value === objId) {\n                $(this).remove();\n            }\n        }).trigger('change');\n        win.close();\n    }\n\n    // Global for testing purposes\n    window.id_to_windowname = id_to_windowname;\n    window.windowname_to_id = windowname_to_id;\n\n    window.showRelatedObjectLookupPopup = showRelatedObjectLookupPopup;\n    window.dismissRelatedLookupPopup = dismissRelatedLookupPopup;\n    window.showRelatedObjectPopup = showRelatedObjectPopup;\n    window.updateRelatedObjectLinks = updateRelatedObjectLinks;\n    window.dismissAddRelatedObjectPopup = dismissAddRelatedObjectPopup;\n    window.dismissChangeRelatedObjectPopup = dismissChangeRelatedObjectPopup;\n    window.dismissDeleteRelatedObjectPopup = dismissDeleteRelatedObjectPopup;\n\n    // Kept for backward compatibility\n    window.showAddAnotherPopup = showRelatedObjectPopup;\n    window.dismissAddAnotherPopup = dismissAddRelatedObjectPopup;\n\n    $(document).ready(function() {\n        $(\"a[data-popup-opener]\").on('click', function(event) {\n            event.preventDefault();\n            opener.dismissRelatedLookupPopup(window, $(this).data(\"popup-opener\"));\n        });\n        $('body').on('click', '.related-widget-wrapper-link', function(e) {\n            e.preventDefault();\n            if (this.href) {\n                var event = $.Event('django:show-related', {href: this.href});\n                $(this).trigger(event);\n                if (!event.isDefaultPrevented()) {\n                    showRelatedObjectPopup(this);\n                }\n            }\n        });\n        $('body').on('change', '.related-widget-wrapper select', function(e) {\n            var event = $.Event('django:update-related');\n            $(this).trigger(event);\n            if (!event.isDefaultPrevented()) {\n                updateRelatedObjectLinks(this);\n            }\n        });\n        $('.related-widget-wrapper select').trigger('change');\n        $('body').on('click', '.related-lookup', function(e) {\n            e.preventDefault();\n            var event = $.Event('django:lookup-related');\n            $(this).trigger(event);\n            if (!event.isDefaultPrevented()) {\n                showRelatedObjectLookupPopup(this);\n            }\n        });\n    });\n\n})(django.jQuery);\n"
  },
  {
    "path": "src/static_cdn/admin/js/autocomplete.js",
    "content": "(function($) {\n    'use strict';\n    var init = function($element, options) {\n        var settings = $.extend({\n            ajax: {\n                data: function(params) {\n                    return {\n                        term: params.term,\n                        page: params.page\n                    };\n                }\n            }\n        }, options);\n        $element.select2(settings);\n    };\n\n    $.fn.djangoAdminSelect2 = function(options) {\n        var settings = $.extend({}, options);\n        $.each(this, function(i, element) {\n            var $element = $(element);\n            init($element, settings);\n        });\n        return this;\n    };\n\n    $(function() {\n        // Initialize all autocomplete widgets except the one in the template\n        // form used when a new formset is added.\n        $('.admin-autocomplete').not('[name*=__prefix__]').djangoAdminSelect2();\n    });\n\n    $(document).on('formset:added', (function() {\n        return function(event, $newFormset) {\n            return $newFormset.find('.admin-autocomplete').djangoAdminSelect2();\n        };\n    })(this));\n}(django.jQuery));\n"
  },
  {
    "path": "src/static_cdn/admin/js/calendar.js",
    "content": "/*global gettext, pgettext, get_format, quickElement, removeChildren*/\n/*\ncalendar.js - Calendar functions by Adrian Holovaty\ndepends on core.js for utility functions like removeChildren or quickElement\n*/\n\n(function() {\n    'use strict';\n    // CalendarNamespace -- Provides a collection of HTML calendar-related helper functions\n    var CalendarNamespace = {\n        monthsOfYear: [\n            gettext('January'),\n            gettext('February'),\n            gettext('March'),\n            gettext('April'),\n            gettext('May'),\n            gettext('June'),\n            gettext('July'),\n            gettext('August'),\n            gettext('September'),\n            gettext('October'),\n            gettext('November'),\n            gettext('December')\n        ],\n        daysOfWeek: [\n            pgettext('one letter Sunday', 'S'),\n            pgettext('one letter Monday', 'M'),\n            pgettext('one letter Tuesday', 'T'),\n            pgettext('one letter Wednesday', 'W'),\n            pgettext('one letter Thursday', 'T'),\n            pgettext('one letter Friday', 'F'),\n            pgettext('one letter Saturday', 'S')\n        ],\n        firstDayOfWeek: parseInt(get_format('FIRST_DAY_OF_WEEK')),\n        isLeapYear: function(year) {\n            return (((year % 4) === 0) && ((year % 100) !== 0 ) || ((year % 400) === 0));\n        },\n        getDaysInMonth: function(month, year) {\n            var days;\n            if (month === 1 || month === 3 || month === 5 || month === 7 || month === 8 || month === 10 || month === 12) {\n                days = 31;\n            }\n            else if (month === 4 || month === 6 || month === 9 || month === 11) {\n                days = 30;\n            }\n            else if (month === 2 && CalendarNamespace.isLeapYear(year)) {\n                days = 29;\n            }\n            else {\n                days = 28;\n            }\n            return days;\n        },\n        draw: function(month, year, div_id, callback, selected) { // month = 1-12, year = 1-9999\n            var today = new Date();\n            var todayDay = today.getDate();\n            var todayMonth = today.getMonth() + 1;\n            var todayYear = today.getFullYear();\n            var todayClass = '';\n\n            // Use UTC functions here because the date field does not contain time\n            // and using the UTC function variants prevent the local time offset\n            // from altering the date, specifically the day field.  For example:\n            //\n            // ```\n            // var x = new Date('2013-10-02');\n            // var day = x.getDate();\n            // ```\n            //\n            // The day variable above will be 1 instead of 2 in, say, US Pacific time\n            // zone.\n            var isSelectedMonth = false;\n            if (typeof selected !== 'undefined') {\n                isSelectedMonth = (selected.getUTCFullYear() === year && (selected.getUTCMonth() + 1) === month);\n            }\n\n            month = parseInt(month);\n            year = parseInt(year);\n            var calDiv = document.getElementById(div_id);\n            removeChildren(calDiv);\n            var calTable = document.createElement('table');\n            quickElement('caption', calTable, CalendarNamespace.monthsOfYear[month - 1] + ' ' + year);\n            var tableBody = quickElement('tbody', calTable);\n\n            // Draw days-of-week header\n            var tableRow = quickElement('tr', tableBody);\n            for (var i = 0; i < 7; i++) {\n                quickElement('th', tableRow, CalendarNamespace.daysOfWeek[(i + CalendarNamespace.firstDayOfWeek) % 7]);\n            }\n\n            var startingPos = new Date(year, month - 1, 1 - CalendarNamespace.firstDayOfWeek).getDay();\n            var days = CalendarNamespace.getDaysInMonth(month, year);\n\n            var nonDayCell;\n\n            // Draw blanks before first of month\n            tableRow = quickElement('tr', tableBody);\n            for (i = 0; i < startingPos; i++) {\n                nonDayCell = quickElement('td', tableRow, ' ');\n                nonDayCell.className = \"nonday\";\n            }\n\n            function calendarMonth(y, m) {\n                function onClick(e) {\n                    e.preventDefault();\n                    callback(y, m, this.textContent);\n                }\n                return onClick;\n            }\n\n            // Draw days of month\n            var currentDay = 1;\n            for (i = startingPos; currentDay <= days; i++) {\n                if (i % 7 === 0 && currentDay !== 1) {\n                    tableRow = quickElement('tr', tableBody);\n                }\n                if ((currentDay === todayDay) && (month === todayMonth) && (year === todayYear)) {\n                    todayClass = 'today';\n                } else {\n                    todayClass = '';\n                }\n\n                // use UTC function; see above for explanation.\n                if (isSelectedMonth && currentDay === selected.getUTCDate()) {\n                    if (todayClass !== '') {\n                        todayClass += \" \";\n                    }\n                    todayClass += \"selected\";\n                }\n\n                var cell = quickElement('td', tableRow, '', 'class', todayClass);\n                var link = quickElement('a', cell, currentDay, 'href', '#');\n                link.addEventListener('click', calendarMonth(year, month));\n                currentDay++;\n            }\n\n            // Draw blanks after end of month (optional, but makes for valid code)\n            while (tableRow.childNodes.length < 7) {\n                nonDayCell = quickElement('td', tableRow, ' ');\n                nonDayCell.className = \"nonday\";\n            }\n\n            calDiv.appendChild(calTable);\n        }\n    };\n\n    // Calendar -- A calendar instance\n    function Calendar(div_id, callback, selected) {\n        // div_id (string) is the ID of the element in which the calendar will\n        //     be displayed\n        // callback (string) is the name of a JavaScript function that will be\n        //     called with the parameters (year, month, day) when a day in the\n        //     calendar is clicked\n        this.div_id = div_id;\n        this.callback = callback;\n        this.today = new Date();\n        this.currentMonth = this.today.getMonth() + 1;\n        this.currentYear = this.today.getFullYear();\n        if (typeof selected !== 'undefined') {\n            this.selected = selected;\n        }\n    }\n    Calendar.prototype = {\n        drawCurrent: function() {\n            CalendarNamespace.draw(this.currentMonth, this.currentYear, this.div_id, this.callback, this.selected);\n        },\n        drawDate: function(month, year, selected) {\n            this.currentMonth = month;\n            this.currentYear = year;\n\n            if(selected) {\n                this.selected = selected;\n            }\n\n            this.drawCurrent();\n        },\n        drawPreviousMonth: function() {\n            if (this.currentMonth === 1) {\n                this.currentMonth = 12;\n                this.currentYear--;\n            }\n            else {\n                this.currentMonth--;\n            }\n            this.drawCurrent();\n        },\n        drawNextMonth: function() {\n            if (this.currentMonth === 12) {\n                this.currentMonth = 1;\n                this.currentYear++;\n            }\n            else {\n                this.currentMonth++;\n            }\n            this.drawCurrent();\n        },\n        drawPreviousYear: function() {\n            this.currentYear--;\n            this.drawCurrent();\n        },\n        drawNextYear: function() {\n            this.currentYear++;\n            this.drawCurrent();\n        }\n    };\n    window.Calendar = Calendar;\n    window.CalendarNamespace = CalendarNamespace;\n})();\n"
  },
  {
    "path": "src/static_cdn/admin/js/cancel.js",
    "content": "(function($) {\n    'use strict';\n    $(function() {\n        $('.cancel-link').on('click', function(e) {\n            e.preventDefault();\n            if (window.location.search.indexOf('&_popup=1') === -1) {\n                window.history.back();  // Go back if not a popup.\n            } else {\n                window.close(); // Otherwise, close the popup.\n            }\n        });\n    });\n})(django.jQuery);\n"
  },
  {
    "path": "src/static_cdn/admin/js/change_form.js",
    "content": "/*global showAddAnotherPopup, showRelatedObjectLookupPopup showRelatedObjectPopup updateRelatedObjectLinks*/\n\n(function($) {\n    'use strict';\n    $(document).ready(function() {\n        var modelName = $('#django-admin-form-add-constants').data('modelName');\n        $('body').on('click', '.add-another', function(e) {\n            e.preventDefault();\n            var event = $.Event('django:add-another-related');\n            $(this).trigger(event);\n            if (!event.isDefaultPrevented()) {\n                showAddAnotherPopup(this);\n            }\n        });\n\n        if (modelName) {\n            $('form#' + modelName + '_form :input:visible:enabled:first').focus();\n        }\n    });\n})(django.jQuery);\n"
  },
  {
    "path": "src/static_cdn/admin/js/collapse.js",
    "content": "/*global gettext*/\n(function() {\n    'use strict';\n    var closestElem = function(elem, tagName) {\n        if (elem.nodeName === tagName.toUpperCase()) {\n            return elem;\n        }\n        if (elem.parentNode.nodeName === 'BODY') {\n            return null;\n        }\n        return elem.parentNode && closestElem(elem.parentNode, tagName);\n    };\n\n    window.addEventListener('load', function() {\n        // Add anchor tag for Show/Hide link\n        var fieldsets = document.querySelectorAll('fieldset.collapse');\n        for (var i = 0; i < fieldsets.length; i++) {\n            var elem = fieldsets[i];\n            // Don't hide if fields in this fieldset have errors\n            if (elem.querySelectorAll('div.errors').length === 0) {\n                elem.classList.add('collapsed');\n                var h2 = elem.querySelector('h2');\n                var link = document.createElement('a');\n                link.setAttribute('id', 'fieldsetcollapser' + i);\n                link.setAttribute('class', 'collapse-toggle');\n                link.setAttribute('href', '#');\n                link.textContent = gettext('Show');\n                h2.appendChild(document.createTextNode(' ('));\n                h2.appendChild(link);\n                h2.appendChild(document.createTextNode(')'));\n            }\n        }\n        // Add toggle to hide/show anchor tag\n        var toggleFunc = function(ev) {\n            if (ev.target.matches('.collapse-toggle')) {\n                ev.preventDefault();\n                ev.stopPropagation();\n                var fieldset = closestElem(ev.target, 'fieldset');\n                if (fieldset.classList.contains('collapsed')) {\n                    // Show\n                    ev.target.textContent = gettext('Hide');\n                    fieldset.classList.remove('collapsed');\n                } else {\n                    // Hide\n                    ev.target.textContent = gettext('Show');\n                    fieldset.classList.add('collapsed');\n                }\n            }\n        };\n        var inlineDivs = document.querySelectorAll('fieldset.module');\n        for (i = 0; i < inlineDivs.length; i++) {\n            inlineDivs[i].addEventListener('click', toggleFunc);\n        }\n    });\n})();\n"
  },
  {
    "path": "src/static_cdn/admin/js/core.js",
    "content": "// Core javascript helper functions\n\n// basic browser identification & version\nvar isOpera = (navigator.userAgent.indexOf(\"Opera\") >= 0) && parseFloat(navigator.appVersion);\nvar isIE = ((document.all) && (!isOpera)) && parseFloat(navigator.appVersion.split(\"MSIE \")[1].split(\";\")[0]);\n\n// quickElement(tagType, parentReference [, textInChildNode, attribute, attributeValue ...]);\nfunction quickElement() {\n    'use strict';\n    var obj = document.createElement(arguments[0]);\n    if (arguments[2]) {\n        var textNode = document.createTextNode(arguments[2]);\n        obj.appendChild(textNode);\n    }\n    var len = arguments.length;\n    for (var i = 3; i < len; i += 2) {\n        obj.setAttribute(arguments[i], arguments[i + 1]);\n    }\n    arguments[1].appendChild(obj);\n    return obj;\n}\n\n// \"a\" is reference to an object\nfunction removeChildren(a) {\n    'use strict';\n    while (a.hasChildNodes()) {\n        a.removeChild(a.lastChild);\n    }\n}\n\n// ----------------------------------------------------------------------------\n// Find-position functions by PPK\n// See https://www.quirksmode.org/js/findpos.html\n// ----------------------------------------------------------------------------\nfunction findPosX(obj) {\n    'use strict';\n    var curleft = 0;\n    if (obj.offsetParent) {\n        while (obj.offsetParent) {\n            curleft += obj.offsetLeft - ((isOpera) ? 0 : obj.scrollLeft);\n            obj = obj.offsetParent;\n        }\n        // IE offsetParent does not include the top-level\n        if (isIE && obj.parentElement) {\n            curleft += obj.offsetLeft - obj.scrollLeft;\n        }\n    } else if (obj.x) {\n        curleft += obj.x;\n    }\n    return curleft;\n}\n\nfunction findPosY(obj) {\n    'use strict';\n    var curtop = 0;\n    if (obj.offsetParent) {\n        while (obj.offsetParent) {\n            curtop += obj.offsetTop - ((isOpera) ? 0 : obj.scrollTop);\n            obj = obj.offsetParent;\n        }\n        // IE offsetParent does not include the top-level\n        if (isIE && obj.parentElement) {\n            curtop += obj.offsetTop - obj.scrollTop;\n        }\n    } else if (obj.y) {\n        curtop += obj.y;\n    }\n    return curtop;\n}\n\n//-----------------------------------------------------------------------------\n// Date object extensions\n// ----------------------------------------------------------------------------\n(function() {\n    'use strict';\n    Date.prototype.getTwelveHours = function() {\n        var hours = this.getHours();\n        if (hours === 0) {\n            return 12;\n        }\n        else {\n            return hours <= 12 ? hours : hours - 12;\n        }\n    };\n\n    Date.prototype.getTwoDigitMonth = function() {\n        return (this.getMonth() < 9) ? '0' + (this.getMonth() + 1) : (this.getMonth() + 1);\n    };\n\n    Date.prototype.getTwoDigitDate = function() {\n        return (this.getDate() < 10) ? '0' + this.getDate() : this.getDate();\n    };\n\n    Date.prototype.getTwoDigitTwelveHour = function() {\n        return (this.getTwelveHours() < 10) ? '0' + this.getTwelveHours() : this.getTwelveHours();\n    };\n\n    Date.prototype.getTwoDigitHour = function() {\n        return (this.getHours() < 10) ? '0' + this.getHours() : this.getHours();\n    };\n\n    Date.prototype.getTwoDigitMinute = function() {\n        return (this.getMinutes() < 10) ? '0' + this.getMinutes() : this.getMinutes();\n    };\n\n    Date.prototype.getTwoDigitSecond = function() {\n        return (this.getSeconds() < 10) ? '0' + this.getSeconds() : this.getSeconds();\n    };\n\n    Date.prototype.getHourMinute = function() {\n        return this.getTwoDigitHour() + ':' + this.getTwoDigitMinute();\n    };\n\n    Date.prototype.getHourMinuteSecond = function() {\n        return this.getTwoDigitHour() + ':' + this.getTwoDigitMinute() + ':' + this.getTwoDigitSecond();\n    };\n\n    Date.prototype.getFullMonthName = function() {\n        return typeof window.CalendarNamespace === \"undefined\"\n            ? this.getTwoDigitMonth()\n            : window.CalendarNamespace.monthsOfYear[this.getMonth()];\n    };\n\n    Date.prototype.strftime = function(format) {\n        var fields = {\n            B: this.getFullMonthName(),\n            c: this.toString(),\n            d: this.getTwoDigitDate(),\n            H: this.getTwoDigitHour(),\n            I: this.getTwoDigitTwelveHour(),\n            m: this.getTwoDigitMonth(),\n            M: this.getTwoDigitMinute(),\n            p: (this.getHours() >= 12) ? 'PM' : 'AM',\n            S: this.getTwoDigitSecond(),\n            w: '0' + this.getDay(),\n            x: this.toLocaleDateString(),\n            X: this.toLocaleTimeString(),\n            y: ('' + this.getFullYear()).substr(2, 4),\n            Y: '' + this.getFullYear(),\n            '%': '%'\n        };\n        var result = '', i = 0;\n        while (i < format.length) {\n            if (format.charAt(i) === '%') {\n                result = result + fields[format.charAt(i + 1)];\n                ++i;\n            }\n            else {\n                result = result + format.charAt(i);\n            }\n            ++i;\n        }\n        return result;\n    };\n\n// ----------------------------------------------------------------------------\n// String object extensions\n// ----------------------------------------------------------------------------\n    String.prototype.pad_left = function(pad_length, pad_string) {\n        var new_string = this;\n        for (var i = 0; new_string.length < pad_length; i++) {\n            new_string = pad_string + new_string;\n        }\n        return new_string;\n    };\n\n    String.prototype.strptime = function(format) {\n        var split_format = format.split(/[.\\-/]/);\n        var date = this.split(/[.\\-/]/);\n        var i = 0;\n        var day, month, year;\n        while (i < split_format.length) {\n            switch (split_format[i]) {\n                case \"%d\":\n                    day = date[i];\n                    break;\n                case \"%m\":\n                    month = date[i] - 1;\n                    break;\n                case \"%Y\":\n                    year = date[i];\n                    break;\n                case \"%y\":\n                    year = date[i];\n                    break;\n            }\n            ++i;\n        }\n        // Create Date object from UTC since the parsed value is supposed to be\n        // in UTC, not local time. Also, the calendar uses UTC functions for\n        // date extraction.\n        return new Date(Date.UTC(year, month, day));\n    };\n\n})();\n// ----------------------------------------------------------------------------\n// Get the computed style for and element\n// ----------------------------------------------------------------------------\nfunction getStyle(oElm, strCssRule) {\n    'use strict';\n    var strValue = \"\";\n    if(document.defaultView && document.defaultView.getComputedStyle) {\n        strValue = document.defaultView.getComputedStyle(oElm, \"\").getPropertyValue(strCssRule);\n    }\n    else if(oElm.currentStyle) {\n        strCssRule = strCssRule.replace(/\\-(\\w)/g, function(strMatch, p1) {\n            return p1.toUpperCase();\n        });\n        strValue = oElm.currentStyle[strCssRule];\n    }\n    return strValue;\n}\n"
  },
  {
    "path": "src/static_cdn/admin/js/inlines.js",
    "content": "/*global DateTimeShortcuts, SelectFilter*/\n/**\n * Django admin inlines\n *\n * Based on jQuery Formset 1.1\n * @author Stanislaus Madueke (stan DOT madueke AT gmail DOT com)\n * @requires jQuery 1.2.6 or later\n *\n * Copyright (c) 2009, Stanislaus Madueke\n * All rights reserved.\n *\n * Spiced up with Code from Zain Memon's GSoC project 2009\n * and modified for Django by Jannis Leidel, Travis Swicegood and Julien Phalip.\n *\n * Licensed under the New BSD License\n * See: https://opensource.org/licenses/bsd-license.php\n */\n(function($) {\n    'use strict';\n    $.fn.formset = function(opts) {\n        var options = $.extend({}, $.fn.formset.defaults, opts);\n        var $this = $(this);\n        var $parent = $this.parent();\n        var updateElementIndex = function(el, prefix, ndx) {\n            var id_regex = new RegExp(\"(\" + prefix + \"-(\\\\d+|__prefix__))\");\n            var replacement = prefix + \"-\" + ndx;\n            if ($(el).prop(\"for\")) {\n                $(el).prop(\"for\", $(el).prop(\"for\").replace(id_regex, replacement));\n            }\n            if (el.id) {\n                el.id = el.id.replace(id_regex, replacement);\n            }\n            if (el.name) {\n                el.name = el.name.replace(id_regex, replacement);\n            }\n        };\n        var totalForms = $(\"#id_\" + options.prefix + \"-TOTAL_FORMS\").prop(\"autocomplete\", \"off\");\n        var nextIndex = parseInt(totalForms.val(), 10);\n        var maxForms = $(\"#id_\" + options.prefix + \"-MAX_NUM_FORMS\").prop(\"autocomplete\", \"off\");\n        // only show the add button if we are allowed to add more items,\n        // note that max_num = None translates to a blank string.\n        var showAddButton = maxForms.val() === '' || (maxForms.val() - totalForms.val()) > 0;\n        $this.each(function(i) {\n            $(this).not(\".\" + options.emptyCssClass).addClass(options.formCssClass);\n        });\n        if ($this.length && showAddButton) {\n            var addButton = options.addButton;\n            if (addButton === null) {\n                if ($this.prop(\"tagName\") === \"TR\") {\n                    // If forms are laid out as table rows, insert the\n                    // \"add\" button in a new table row:\n                    var numCols = this.eq(-1).children().length;\n                    $parent.append('<tr class=\"' + options.addCssClass + '\"><td colspan=\"' + numCols + '\"><a href=\"#\">' + options.addText + \"</a></tr>\");\n                    addButton = $parent.find(\"tr:last a\");\n                } else {\n                    // Otherwise, insert it immediately after the last form:\n                    $this.filter(\":last\").after('<div class=\"' + options.addCssClass + '\"><a href=\"#\">' + options.addText + \"</a></div>\");\n                    addButton = $this.filter(\":last\").next().find(\"a\");\n                }\n            }\n            addButton.on('click', function(e) {\n                e.preventDefault();\n                var template = $(\"#\" + options.prefix + \"-empty\");\n                var row = template.clone(true);\n                row.removeClass(options.emptyCssClass)\n                .addClass(options.formCssClass)\n                .attr(\"id\", options.prefix + \"-\" + nextIndex);\n                if (row.is(\"tr\")) {\n                    // If the forms are laid out in table rows, insert\n                    // the remove button into the last table cell:\n                    row.children(\":last\").append('<div><a class=\"' + options.deleteCssClass + '\" href=\"#\">' + options.deleteText + \"</a></div>\");\n                } else if (row.is(\"ul\") || row.is(\"ol\")) {\n                    // If they're laid out as an ordered/unordered list,\n                    // insert an <li> after the last list item:\n                    row.append('<li><a class=\"' + options.deleteCssClass + '\" href=\"#\">' + options.deleteText + \"</a></li>\");\n                } else {\n                    // Otherwise, just insert the remove button as the\n                    // last child element of the form's container:\n                    row.children(\":first\").append('<span><a class=\"' + options.deleteCssClass + '\" href=\"#\">' + options.deleteText + \"</a></span>\");\n                }\n                row.find(\"*\").each(function() {\n                    updateElementIndex(this, options.prefix, totalForms.val());\n                });\n                // Insert the new form when it has been fully edited\n                row.insertBefore($(template));\n                // Update number of total forms\n                $(totalForms).val(parseInt(totalForms.val(), 10) + 1);\n                nextIndex += 1;\n                // Hide add button in case we've hit the max, except we want to add infinitely\n                if ((maxForms.val() !== '') && (maxForms.val() - totalForms.val()) <= 0) {\n                    addButton.parent().hide();\n                }\n                // The delete button of each row triggers a bunch of other things\n                row.find(\"a.\" + options.deleteCssClass).on('click', function(e1) {\n                    e1.preventDefault();\n                    // Remove the parent form containing this button:\n                    row.remove();\n                    nextIndex -= 1;\n                    // If a post-delete callback was provided, call it with the deleted form:\n                    if (options.removed) {\n                        options.removed(row);\n                    }\n                    $(document).trigger('formset:removed', [row, options.prefix]);\n                    // Update the TOTAL_FORMS form count.\n                    var forms = $(\".\" + options.formCssClass);\n                    $(\"#id_\" + options.prefix + \"-TOTAL_FORMS\").val(forms.length);\n                    // Show add button again once we drop below max\n                    if ((maxForms.val() === '') || (maxForms.val() - forms.length) > 0) {\n                        addButton.parent().show();\n                    }\n                    // Also, update names and ids for all remaining form controls\n                    // so they remain in sequence:\n                    var i, formCount;\n                    var updateElementCallback = function() {\n                        updateElementIndex(this, options.prefix, i);\n                    };\n                    for (i = 0, formCount = forms.length; i < formCount; i++) {\n                        updateElementIndex($(forms).get(i), options.prefix, i);\n                        $(forms.get(i)).find(\"*\").each(updateElementCallback);\n                    }\n                });\n                // If a post-add callback was supplied, call it with the added form:\n                if (options.added) {\n                    options.added(row);\n                }\n                $(document).trigger('formset:added', [row, options.prefix]);\n            });\n        }\n        return this;\n    };\n\n    /* Setup plugin defaults */\n    $.fn.formset.defaults = {\n        prefix: \"form\",          // The form prefix for your django formset\n        addText: \"add another\",      // Text for the add link\n        deleteText: \"remove\",      // Text for the delete link\n        addCssClass: \"add-row\",      // CSS class applied to the add link\n        deleteCssClass: \"delete-row\",  // CSS class applied to the delete link\n        emptyCssClass: \"empty-row\",    // CSS class applied to the empty row\n        formCssClass: \"dynamic-form\",  // CSS class applied to each form in a formset\n        added: null,          // Function called each time a new form is added\n        removed: null,          // Function called each time a form is deleted\n        addButton: null       // Existing add button to use\n    };\n\n\n    // Tabular inlines ---------------------------------------------------------\n    $.fn.tabularFormset = function(selector, options) {\n        var $rows = $(this);\n        var alternatingRows = function(row) {\n            $(selector).not(\".add-row\").removeClass(\"row1 row2\")\n            .filter(\":even\").addClass(\"row1\").end()\n            .filter(\":odd\").addClass(\"row2\");\n        };\n\n        var reinitDateTimeShortCuts = function() {\n            // Reinitialize the calendar and clock widgets by force\n            if (typeof DateTimeShortcuts !== \"undefined\") {\n                $(\".datetimeshortcuts\").remove();\n                DateTimeShortcuts.init();\n            }\n        };\n\n        var updateSelectFilter = function() {\n            // If any SelectFilter widgets are a part of the new form,\n            // instantiate a new SelectFilter instance for it.\n            if (typeof SelectFilter !== 'undefined') {\n                $('.selectfilter').each(function(index, value) {\n                    var namearr = value.name.split('-');\n                    SelectFilter.init(value.id, namearr[namearr.length - 1], false);\n                });\n                $('.selectfilterstacked').each(function(index, value) {\n                    var namearr = value.name.split('-');\n                    SelectFilter.init(value.id, namearr[namearr.length - 1], true);\n                });\n            }\n        };\n\n        var initPrepopulatedFields = function(row) {\n            row.find('.prepopulated_field').each(function() {\n                var field = $(this),\n                    input = field.find('input, select, textarea'),\n                    dependency_list = input.data('dependency_list') || [],\n                    dependencies = [];\n                $.each(dependency_list, function(i, field_name) {\n                    dependencies.push('#' + row.find('.field-' + field_name).find('input, select, textarea').attr('id'));\n                });\n                if (dependencies.length) {\n                    input.prepopulate(dependencies, input.attr('maxlength'));\n                }\n            });\n        };\n\n        $rows.formset({\n            prefix: options.prefix,\n            addText: options.addText,\n            formCssClass: \"dynamic-\" + options.prefix,\n            deleteCssClass: \"inline-deletelink\",\n            deleteText: options.deleteText,\n            emptyCssClass: \"empty-form\",\n            removed: alternatingRows,\n            added: function(row) {\n                initPrepopulatedFields(row);\n                reinitDateTimeShortCuts();\n                updateSelectFilter();\n                alternatingRows(row);\n            },\n            addButton: options.addButton\n        });\n\n        return $rows;\n    };\n\n    // Stacked inlines ---------------------------------------------------------\n    $.fn.stackedFormset = function(selector, options) {\n        var $rows = $(this);\n        var updateInlineLabel = function(row) {\n            $(selector).find(\".inline_label\").each(function(i) {\n                var count = i + 1;\n                $(this).html($(this).html().replace(/(#\\d+)/g, \"#\" + count));\n            });\n        };\n\n        var reinitDateTimeShortCuts = function() {\n            // Reinitialize the calendar and clock widgets by force, yuck.\n            if (typeof DateTimeShortcuts !== \"undefined\") {\n                $(\".datetimeshortcuts\").remove();\n                DateTimeShortcuts.init();\n            }\n        };\n\n        var updateSelectFilter = function() {\n            // If any SelectFilter widgets were added, instantiate a new instance.\n            if (typeof SelectFilter !== \"undefined\") {\n                $(\".selectfilter\").each(function(index, value) {\n                    var namearr = value.name.split('-');\n                    SelectFilter.init(value.id, namearr[namearr.length - 1], false);\n                });\n                $(\".selectfilterstacked\").each(function(index, value) {\n                    var namearr = value.name.split('-');\n                    SelectFilter.init(value.id, namearr[namearr.length - 1], true);\n                });\n            }\n        };\n\n        var initPrepopulatedFields = function(row) {\n            row.find('.prepopulated_field').each(function() {\n                var field = $(this),\n                    input = field.find('input, select, textarea'),\n                    dependency_list = input.data('dependency_list') || [],\n                    dependencies = [];\n                $.each(dependency_list, function(i, field_name) {\n                    dependencies.push('#' + row.find('.form-row .field-' + field_name).find('input, select, textarea').attr('id'));\n                });\n                if (dependencies.length) {\n                    input.prepopulate(dependencies, input.attr('maxlength'));\n                }\n            });\n        };\n\n        $rows.formset({\n            prefix: options.prefix,\n            addText: options.addText,\n            formCssClass: \"dynamic-\" + options.prefix,\n            deleteCssClass: \"inline-deletelink\",\n            deleteText: options.deleteText,\n            emptyCssClass: \"empty-form\",\n            removed: updateInlineLabel,\n            added: function(row) {\n                initPrepopulatedFields(row);\n                reinitDateTimeShortCuts();\n                updateSelectFilter();\n                updateInlineLabel(row);\n            },\n            addButton: options.addButton\n        });\n\n        return $rows;\n    };\n\n    $(document).ready(function() {\n        $(\".js-inline-admin-formset\").each(function() {\n            var data = $(this).data(),\n                inlineOptions = data.inlineFormset,\n                selector;\n            switch(data.inlineType) {\n            case \"stacked\":\n                selector = inlineOptions.name + \"-group .inline-related\";\n                $(selector).stackedFormset(selector, inlineOptions.options);\n                break;\n            case \"tabular\":\n                selector = inlineOptions.name + \"-group .tabular.inline-related tbody:first > tr\";\n                $(selector).tabularFormset(selector, inlineOptions.options);\n                break;\n            }\n        });\n    });\n})(django.jQuery);\n"
  },
  {
    "path": "src/static_cdn/admin/js/jquery.init.js",
    "content": "/*global django:true, jQuery:false*/\n/* Puts the included jQuery into our own namespace using noConflict and passing\n * it 'true'. This ensures that the included jQuery doesn't pollute the global\n * namespace (i.e. this preserves pre-existing values for both window.$ and\n * window.jQuery).\n */\nvar django = django || {};\ndjango.jQuery = jQuery.noConflict(true);\n"
  },
  {
    "path": "src/static_cdn/admin/js/popup_response.js",
    "content": "/*global opener */\n(function() {\n    'use strict';\n    var initData = JSON.parse(document.getElementById('django-admin-popup-response-constants').dataset.popupResponse);\n    switch(initData.action) {\n    case 'change':\n        opener.dismissChangeRelatedObjectPopup(window, initData.value, initData.obj, initData.new_value);\n        break;\n    case 'delete':\n        opener.dismissDeleteRelatedObjectPopup(window, initData.value);\n        break;\n    default:\n        opener.dismissAddRelatedObjectPopup(window, initData.value, initData.obj);\n        break;\n    }\n})();\n"
  },
  {
    "path": "src/static_cdn/admin/js/prepopulate.js",
    "content": "/*global URLify*/\n(function($) {\n    'use strict';\n    $.fn.prepopulate = function(dependencies, maxLength, allowUnicode) {\n        /*\n            Depends on urlify.js\n            Populates a selected field with the values of the dependent fields,\n            URLifies and shortens the string.\n            dependencies - array of dependent fields ids\n            maxLength - maximum length of the URLify'd string\n            allowUnicode - Unicode support of the URLify'd string\n        */\n        return this.each(function() {\n            var prepopulatedField = $(this);\n\n            var populate = function() {\n                // Bail if the field's value has been changed by the user\n                if (prepopulatedField.data('_changed')) {\n                    return;\n                }\n\n                var values = [];\n                $.each(dependencies, function(i, field) {\n                    field = $(field);\n                    if (field.val().length > 0) {\n                        values.push(field.val());\n                    }\n                });\n                prepopulatedField.val(URLify(values.join(' '), maxLength, allowUnicode));\n            };\n\n            prepopulatedField.data('_changed', false);\n            prepopulatedField.on('change', function() {\n                prepopulatedField.data('_changed', true);\n            });\n\n            if (!prepopulatedField.val()) {\n                $(dependencies.join(',')).on('keyup change focus', populate);\n            }\n        });\n    };\n})(django.jQuery);\n"
  },
  {
    "path": "src/static_cdn/admin/js/prepopulate_init.js",
    "content": "(function($) {\n    'use strict';\n    var fields = $('#django-admin-prepopulated-fields-constants').data('prepopulatedFields');\n    $.each(fields, function(index, field) {\n        $('.empty-form .form-row .field-' + field.name + ', .empty-form.form-row .field-' + field.name).addClass('prepopulated_field');\n        $(field.id).data('dependency_list', field.dependency_list).prepopulate(\n            field.dependency_ids, field.maxLength, field.allowUnicode\n        );\n    });\n})(django.jQuery);\n"
  },
  {
    "path": "src/static_cdn/admin/js/timeparse.js",
    "content": "(function() {\n    'use strict';\n    var timeParsePatterns = [\n        // 9\n        {\n            re: /^\\d{1,2}$/i,\n            handler: function(bits) {\n                if (bits[0].length === 1) {\n                    return '0' + bits[0] + ':00';\n                } else {\n                    return bits[0] + ':00';\n                }\n            }\n        },\n        // 13:00\n        {\n            re: /^\\d{2}[:.]\\d{2}$/i,\n            handler: function(bits) {\n                return bits[0].replace('.', ':');\n            }\n        },\n        // 9:00\n        {\n            re: /^\\d[:.]\\d{2}$/i,\n            handler: function(bits) {\n                return '0' + bits[0].replace('.', ':');\n            }\n        },\n        // 3 am / 3 a.m. / 3am\n        {\n            re: /^(\\d+)\\s*([ap])(?:.?m.?)?$/i,\n            handler: function(bits) {\n                var hour = parseInt(bits[1]);\n                if (hour === 12) {\n                    hour = 0;\n                }\n                if (bits[2].toLowerCase() === 'p') {\n                    if (hour === 12) {\n                        hour = 0;\n                    }\n                    return (hour + 12) + ':00';\n                } else {\n                    if (hour < 10) {\n                        return '0' + hour + ':00';\n                    } else {\n                        return hour + ':00';\n                    }\n                }\n            }\n        },\n        // 3.30 am / 3:15 a.m. / 3.00am\n        {\n            re: /^(\\d+)[.:](\\d{2})\\s*([ap]).?m.?$/i,\n            handler: function(bits) {\n                var hour = parseInt(bits[1]);\n                var mins = parseInt(bits[2]);\n                if (mins < 10) {\n                    mins = '0' + mins;\n                }\n                if (hour === 12) {\n                    hour = 0;\n                }\n                if (bits[3].toLowerCase() === 'p') {\n                    if (hour === 12) {\n                        hour = 0;\n                    }\n                    return (hour + 12) + ':' + mins;\n                } else {\n                    if (hour < 10) {\n                        return '0' + hour + ':' + mins;\n                    } else {\n                        return hour + ':' + mins;\n                    }\n                }\n            }\n        },\n        // noon\n        {\n            re: /^no/i,\n            handler: function(bits) {\n                return '12:00';\n            }\n        },\n        // midnight\n        {\n            re: /^mid/i,\n            handler: function(bits) {\n                return '00:00';\n            }\n        }\n    ];\n\n    function parseTimeString(s) {\n        for (var i = 0; i < timeParsePatterns.length; i++) {\n            var re = timeParsePatterns[i].re;\n            var handler = timeParsePatterns[i].handler;\n            var bits = re.exec(s);\n            if (bits) {\n                return handler(bits);\n            }\n        }\n        return s;\n    }\n\n    window.parseTimeString = parseTimeString;\n})();\n"
  },
  {
    "path": "src/static_cdn/admin/js/urlify.js",
    "content": "/*global XRegExp*/\n(function() {\n    'use strict';\n\n    var LATIN_MAP = {\n        'À': 'A', 'Á': 'A', 'Â': 'A', 'Ã': 'A', 'Ä': 'A', 'Å': 'A', 'Æ': 'AE',\n        'Ç': 'C', 'È': 'E', 'É': 'E', 'Ê': 'E', 'Ë': 'E', 'Ì': 'I', 'Í': 'I',\n        'Î': 'I', 'Ï': 'I', 'Ð': 'D', 'Ñ': 'N', 'Ò': 'O', 'Ó': 'O', 'Ô': 'O',\n        'Õ': 'O', 'Ö': 'O', 'Ő': 'O', 'Ø': 'O', 'Ù': 'U', 'Ú': 'U', 'Û': 'U',\n        'Ü': 'U', 'Ű': 'U', 'Ý': 'Y', 'Þ': 'TH', 'Ÿ': 'Y', 'ß': 'ss', 'à': 'a',\n        'á': 'a', 'â': 'a', 'ã': 'a', 'ä': 'a', 'å': 'a', 'æ': 'ae', 'ç': 'c',\n        'è': 'e', 'é': 'e', 'ê': 'e', 'ë': 'e', 'ì': 'i', 'í': 'i', 'î': 'i',\n        'ï': 'i', 'ð': 'd', 'ñ': 'n', 'ò': 'o', 'ó': 'o', 'ô': 'o', 'õ': 'o',\n        'ö': 'o', 'ő': 'o', 'ø': 'o', 'ù': 'u', 'ú': 'u', 'û': 'u', 'ü': 'u',\n        'ű': 'u', 'ý': 'y', 'þ': 'th', 'ÿ': 'y'\n    };\n    var LATIN_SYMBOLS_MAP = {\n        '©': '(c)'\n    };\n    var GREEK_MAP = {\n        'α': 'a', 'β': 'b', 'γ': 'g', 'δ': 'd', 'ε': 'e', 'ζ': 'z', 'η': 'h',\n        'θ': '8', 'ι': 'i', 'κ': 'k', 'λ': 'l', 'μ': 'm', 'ν': 'n', 'ξ': '3',\n        'ο': 'o', 'π': 'p', 'ρ': 'r', 'σ': 's', 'τ': 't', 'υ': 'y', 'φ': 'f',\n        'χ': 'x', 'ψ': 'ps', 'ω': 'w', 'ά': 'a', 'έ': 'e', 'ί': 'i', 'ό': 'o',\n        'ύ': 'y', 'ή': 'h', 'ώ': 'w', 'ς': 's', 'ϊ': 'i', 'ΰ': 'y', 'ϋ': 'y',\n        'ΐ': 'i', 'Α': 'A', 'Β': 'B', 'Γ': 'G', 'Δ': 'D', 'Ε': 'E', 'Ζ': 'Z',\n        'Η': 'H', 'Θ': '8', 'Ι': 'I', 'Κ': 'K', 'Λ': 'L', 'Μ': 'M', 'Ν': 'N',\n        'Ξ': '3', 'Ο': 'O', 'Π': 'P', 'Ρ': 'R', 'Σ': 'S', 'Τ': 'T', 'Υ': 'Y',\n        'Φ': 'F', 'Χ': 'X', 'Ψ': 'PS', 'Ω': 'W', 'Ά': 'A', 'Έ': 'E', 'Ί': 'I',\n        'Ό': 'O', 'Ύ': 'Y', 'Ή': 'H', 'Ώ': 'W', 'Ϊ': 'I', 'Ϋ': 'Y'\n    };\n    var TURKISH_MAP = {\n        'ş': 's', 'Ş': 'S', 'ı': 'i', 'İ': 'I', 'ç': 'c', 'Ç': 'C', 'ü': 'u',\n        'Ü': 'U', 'ö': 'o', 'Ö': 'O', 'ğ': 'g', 'Ğ': 'G'\n    };\n    var ROMANIAN_MAP = {\n        'ă': 'a', 'î': 'i', 'ș': 's', 'ț': 't', 'â': 'a',\n        'Ă': 'A', 'Î': 'I', 'Ș': 'S', 'Ț': 'T', 'Â': 'A'\n    };\n    var RUSSIAN_MAP = {\n        'а': 'a', 'б': 'b', 'в': 'v', 'г': 'g', 'д': 'd', 'е': 'e', 'ё': 'yo',\n        'ж': 'zh', 'з': 'z', 'и': 'i', 'й': 'j', 'к': 'k', 'л': 'l', 'м': 'm',\n        'н': 'n', 'о': 'o', 'п': 'p', 'р': 'r', 'с': 's', 'т': 't', 'у': 'u',\n        'ф': 'f', 'х': 'h', 'ц': 'c', 'ч': 'ch', 'ш': 'sh', 'щ': 'sh', 'ъ': '',\n        'ы': 'y', 'ь': '', 'э': 'e', 'ю': 'yu', 'я': 'ya',\n        'А': 'A', 'Б': 'B', 'В': 'V', 'Г': 'G', 'Д': 'D', 'Е': 'E', 'Ё': 'Yo',\n        'Ж': 'Zh', 'З': 'Z', 'И': 'I', 'Й': 'J', 'К': 'K', 'Л': 'L', 'М': 'M',\n        'Н': 'N', 'О': 'O', 'П': 'P', 'Р': 'R', 'С': 'S', 'Т': 'T', 'У': 'U',\n        'Ф': 'F', 'Х': 'H', 'Ц': 'C', 'Ч': 'Ch', 'Ш': 'Sh', 'Щ': 'Sh', 'Ъ': '',\n        'Ы': 'Y', 'Ь': '', 'Э': 'E', 'Ю': 'Yu', 'Я': 'Ya'\n    };\n    var UKRAINIAN_MAP = {\n        'Є': 'Ye', 'І': 'I', 'Ї': 'Yi', 'Ґ': 'G', 'є': 'ye', 'і': 'i',\n        'ї': 'yi', 'ґ': 'g'\n    };\n    var CZECH_MAP = {\n        'č': 'c', 'ď': 'd', 'ě': 'e', 'ň': 'n', 'ř': 'r', 'š': 's', 'ť': 't',\n        'ů': 'u', 'ž': 'z', 'Č': 'C', 'Ď': 'D', 'Ě': 'E', 'Ň': 'N', 'Ř': 'R',\n        'Š': 'S', 'Ť': 'T', 'Ů': 'U', 'Ž': 'Z'\n    };\n    var SLOVAK_MAP = {\n        'á': 'a', 'ä': 'a', 'č': 'c', 'ď': 'd', 'é': 'e', 'í': 'i', 'ľ': 'l',\n        'ĺ': 'l', 'ň': 'n', 'ó': 'o', 'ô': 'o', 'ŕ': 'r', 'š': 's', 'ť': 't',\n        'ú': 'u', 'ý': 'y', 'ž': 'z',\n        'Á': 'a', 'Ä': 'A', 'Č': 'C', 'Ď': 'D', 'É': 'E', 'Í': 'I', 'Ľ': 'L',\n        'Ĺ': 'L', 'Ň': 'N', 'Ó': 'O', 'Ô': 'O', 'Ŕ': 'R', 'Š': 'S', 'Ť': 'T',\n        'Ú': 'U', 'Ý': 'Y', 'Ž': 'Z'\n    };\n    var POLISH_MAP = {\n        'ą': 'a', 'ć': 'c', 'ę': 'e', 'ł': 'l', 'ń': 'n', 'ó': 'o', 'ś': 's',\n        'ź': 'z', 'ż': 'z',\n        'Ą': 'A', 'Ć': 'C', 'Ę': 'E', 'Ł': 'L', 'Ń': 'N', 'Ó': 'O', 'Ś': 'S',\n        'Ź': 'Z', 'Ż': 'Z'\n    };\n    var LATVIAN_MAP = {\n        'ā': 'a', 'č': 'c', 'ē': 'e', 'ģ': 'g', 'ī': 'i', 'ķ': 'k', 'ļ': 'l',\n        'ņ': 'n', 'š': 's', 'ū': 'u', 'ž': 'z',\n        'Ā': 'A', 'Č': 'C', 'Ē': 'E', 'Ģ': 'G', 'Ī': 'I', 'Ķ': 'K', 'Ļ': 'L',\n        'Ņ': 'N', 'Š': 'S', 'Ū': 'U', 'Ž': 'Z'\n    };\n    var ARABIC_MAP = {\n        'أ': 'a', 'ب': 'b', 'ت': 't', 'ث': 'th', 'ج': 'g', 'ح': 'h', 'خ': 'kh', 'د': 'd',\n        'ذ': 'th', 'ر': 'r', 'ز': 'z', 'س': 's', 'ش': 'sh', 'ص': 's', 'ض': 'd', 'ط': 't',\n        'ظ': 'th', 'ع': 'aa', 'غ': 'gh', 'ف': 'f', 'ق': 'k', 'ك': 'k', 'ل': 'l', 'م': 'm',\n        'ن': 'n', 'ه': 'h', 'و': 'o', 'ي': 'y'\n    };\n    var LITHUANIAN_MAP = {\n        'ą': 'a', 'č': 'c', 'ę': 'e', 'ė': 'e', 'į': 'i', 'š': 's', 'ų': 'u',\n        'ū': 'u', 'ž': 'z',\n        'Ą': 'A', 'Č': 'C', 'Ę': 'E', 'Ė': 'E', 'Į': 'I', 'Š': 'S', 'Ų': 'U',\n        'Ū': 'U', 'Ž': 'Z'\n    };\n    var SERBIAN_MAP = {\n        'ђ': 'dj', 'ј': 'j', 'љ': 'lj', 'њ': 'nj', 'ћ': 'c', 'џ': 'dz',\n        'đ': 'dj', 'Ђ': 'Dj', 'Ј': 'j', 'Љ': 'Lj', 'Њ': 'Nj', 'Ћ': 'C',\n        'Џ': 'Dz', 'Đ': 'Dj'\n    };\n    var AZERBAIJANI_MAP = {\n        'ç': 'c', 'ə': 'e', 'ğ': 'g', 'ı': 'i', 'ö': 'o', 'ş': 's', 'ü': 'u',\n        'Ç': 'C', 'Ə': 'E', 'Ğ': 'G', 'İ': 'I', 'Ö': 'O', 'Ş': 'S', 'Ü': 'U'\n    };\n    var GEORGIAN_MAP = {\n        'ა': 'a', 'ბ': 'b', 'გ': 'g', 'დ': 'd', 'ე': 'e', 'ვ': 'v', 'ზ': 'z',\n        'თ': 't', 'ი': 'i', 'კ': 'k', 'ლ': 'l', 'მ': 'm', 'ნ': 'n', 'ო': 'o',\n        'პ': 'p', 'ჟ': 'j', 'რ': 'r', 'ს': 's', 'ტ': 't', 'უ': 'u', 'ფ': 'f',\n        'ქ': 'q', 'ღ': 'g', 'ყ': 'y', 'შ': 'sh', 'ჩ': 'ch', 'ც': 'c', 'ძ': 'dz',\n        'წ': 'w', 'ჭ': 'ch', 'ხ': 'x', 'ჯ': 'j', 'ჰ': 'h'\n    };\n\n    var ALL_DOWNCODE_MAPS = [\n        LATIN_MAP,\n        LATIN_SYMBOLS_MAP,\n        GREEK_MAP,\n        TURKISH_MAP,\n        ROMANIAN_MAP,\n        RUSSIAN_MAP,\n        UKRAINIAN_MAP,\n        CZECH_MAP,\n        SLOVAK_MAP,\n        POLISH_MAP,\n        LATVIAN_MAP,\n        ARABIC_MAP,\n        LITHUANIAN_MAP,\n        SERBIAN_MAP,\n        AZERBAIJANI_MAP,\n        GEORGIAN_MAP\n    ];\n\n    var Downcoder = {\n        'Initialize': function() {\n            if (Downcoder.map) {  // already made\n                return;\n            }\n            Downcoder.map = {};\n            Downcoder.chars = [];\n            for (var i = 0; i < ALL_DOWNCODE_MAPS.length; i++) {\n                var lookup = ALL_DOWNCODE_MAPS[i];\n                for (var c in lookup) {\n                    if (lookup.hasOwnProperty(c)) {\n                        Downcoder.map[c] = lookup[c];\n                    }\n                }\n            }\n            for (var k in Downcoder.map) {\n                if (Downcoder.map.hasOwnProperty(k)) {\n                    Downcoder.chars.push(k);\n                }\n            }\n            Downcoder.regex = new RegExp(Downcoder.chars.join('|'), 'g');\n        }\n    };\n\n    function downcode(slug) {\n        Downcoder.Initialize();\n        return slug.replace(Downcoder.regex, function(m) {\n            return Downcoder.map[m];\n        });\n    }\n\n\n    function URLify(s, num_chars, allowUnicode) {\n        // changes, e.g., \"Petty theft\" to \"petty-theft\"\n        // remove all these words from the string before urlifying\n        if (!allowUnicode) {\n            s = downcode(s);\n        }\n        var hasUnicodeChars = /[^\\u0000-\\u007f]/.test(s);\n        // Remove English words only if the string contains ASCII (English)\n        // characters.\n        if (!hasUnicodeChars) {\n            var removeList = [\n                \"a\", \"an\", \"as\", \"at\", \"before\", \"but\", \"by\", \"for\", \"from\",\n                \"is\", \"in\", \"into\", \"like\", \"of\", \"off\", \"on\", \"onto\", \"per\",\n                \"since\", \"than\", \"the\", \"this\", \"that\", \"to\", \"up\", \"via\",\n                \"with\"\n            ];\n            var r = new RegExp('\\\\b(' + removeList.join('|') + ')\\\\b', 'gi');\n            s = s.replace(r, '');\n        }\n        // if downcode doesn't hit, the char will be stripped here\n        if (allowUnicode) {\n            // Keep Unicode letters including both lowercase and uppercase\n            // characters, whitespace, and dash; remove other characters.\n            s = XRegExp.replace(s, XRegExp('[^-_\\\\p{L}\\\\p{N}\\\\s]', 'g'), '');\n        } else {\n            s = s.replace(/[^-\\w\\s]/g, '');  // remove unneeded chars\n        }\n        s = s.replace(/^\\s+|\\s+$/g, '');   // trim leading/trailing spaces\n        s = s.replace(/[-\\s]+/g, '-');     // convert spaces to hyphens\n        s = s.substring(0, num_chars);     // trim to first num_chars chars\n        s = s.replace(/-+$/g, '');         // trim any trailing hyphens\n        return s.toLowerCase();            // convert to lowercase\n    }\n    window.URLify = URLify;\n})();\n"
  },
  {
    "path": "src/static_cdn/admin/js/vendor/jquery/LICENSE.txt",
    "content": "Copyright jQuery Foundation and other contributors, https://jquery.org/\n\nThis software consists of voluntary contributions made by many\nindividuals. For exact contribution history, see the revision history\navailable at https://github.com/jquery/jquery\n\n====\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "src/static_cdn/admin/js/vendor/jquery/jquery.js",
    "content": "/*!\n * jQuery JavaScript Library v3.3.1\n * https://jquery.com/\n *\n * Includes Sizzle.js\n * https://sizzlejs.com/\n *\n * Copyright JS Foundation and other contributors\n * Released under the MIT license\n * https://jquery.org/license\n *\n * Date: 2018-01-20T17:24Z\n */\n( function( global, factory ) {\n\n\t\"use strict\";\n\n\tif ( typeof module === \"object\" && typeof module.exports === \"object\" ) {\n\n\t\t// For CommonJS and CommonJS-like environments where a proper `window`\n\t\t// is present, execute the factory and get jQuery.\n\t\t// For environments that do not have a `window` with a `document`\n\t\t// (such as Node.js), expose a factory as module.exports.\n\t\t// This accentuates the need for the creation of a real `window`.\n\t\t// e.g. var jQuery = require(\"jquery\")(window);\n\t\t// See ticket #14549 for more info.\n\t\tmodule.exports = global.document ?\n\t\t\tfactory( global, true ) :\n\t\t\tfunction( w ) {\n\t\t\t\tif ( !w.document ) {\n\t\t\t\t\tthrow new Error( \"jQuery requires a window with a document\" );\n\t\t\t\t}\n\t\t\t\treturn factory( w );\n\t\t\t};\n\t} else {\n\t\tfactory( global );\n\t}\n\n// Pass this if window is not defined yet\n} )( typeof window !== \"undefined\" ? window : this, function( window, noGlobal ) {\n\n// Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1\n// throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode\n// arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), strict mode should be common\n// enough that all such attempts are guarded in a try block.\n\"use strict\";\n\nvar arr = [];\n\nvar document = window.document;\n\nvar getProto = Object.getPrototypeOf;\n\nvar slice = arr.slice;\n\nvar concat = arr.concat;\n\nvar push = arr.push;\n\nvar indexOf = arr.indexOf;\n\nvar class2type = {};\n\nvar toString = class2type.toString;\n\nvar hasOwn = class2type.hasOwnProperty;\n\nvar fnToString = hasOwn.toString;\n\nvar ObjectFunctionString = fnToString.call( Object );\n\nvar support = {};\n\nvar isFunction = function isFunction( obj ) {\n\n      // Support: Chrome <=57, Firefox <=52\n      // In some browsers, typeof returns \"function\" for HTML <object> elements\n      // (i.e., `typeof document.createElement( \"object\" ) === \"function\"`).\n      // We don't want to classify *any* DOM node as a function.\n      return typeof obj === \"function\" && typeof obj.nodeType !== \"number\";\n  };\n\n\nvar isWindow = function isWindow( obj ) {\n\t\treturn obj != null && obj === obj.window;\n\t};\n\n\n\n\n\tvar preservedScriptAttributes = {\n\t\ttype: true,\n\t\tsrc: true,\n\t\tnoModule: true\n\t};\n\n\tfunction DOMEval( code, doc, node ) {\n\t\tdoc = doc || document;\n\n\t\tvar i,\n\t\t\tscript = doc.createElement( \"script\" );\n\n\t\tscript.text = code;\n\t\tif ( node ) {\n\t\t\tfor ( i in preservedScriptAttributes ) {\n\t\t\t\tif ( node[ i ] ) {\n\t\t\t\t\tscript[ i ] = node[ i ];\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tdoc.head.appendChild( script ).parentNode.removeChild( script );\n\t}\n\n\nfunction toType( obj ) {\n\tif ( obj == null ) {\n\t\treturn obj + \"\";\n\t}\n\n\t// Support: Android <=2.3 only (functionish RegExp)\n\treturn typeof obj === \"object\" || typeof obj === \"function\" ?\n\t\tclass2type[ toString.call( obj ) ] || \"object\" :\n\t\ttypeof obj;\n}\n/* global Symbol */\n// Defining this global in .eslintrc.json would create a danger of using the global\n// unguarded in another place, it seems safer to define global only for this module\n\n\n\nvar\n\tversion = \"3.3.1\",\n\n\t// Define a local copy of jQuery\n\tjQuery = function( selector, context ) {\n\n\t\t// The jQuery object is actually just the init constructor 'enhanced'\n\t\t// Need init if jQuery is called (just allow error to be thrown if not included)\n\t\treturn new jQuery.fn.init( selector, context );\n\t},\n\n\t// Support: Android <=4.0 only\n\t// Make sure we trim BOM and NBSP\n\trtrim = /^[\\s\\uFEFF\\xA0]+|[\\s\\uFEFF\\xA0]+$/g;\n\njQuery.fn = jQuery.prototype = {\n\n\t// The current version of jQuery being used\n\tjquery: version,\n\n\tconstructor: jQuery,\n\n\t// The default length of a jQuery object is 0\n\tlength: 0,\n\n\ttoArray: function() {\n\t\treturn slice.call( this );\n\t},\n\n\t// Get the Nth element in the matched element set OR\n\t// Get the whole matched element set as a clean array\n\tget: function( num ) {\n\n\t\t// Return all the elements in a clean array\n\t\tif ( num == null ) {\n\t\t\treturn slice.call( this );\n\t\t}\n\n\t\t// Return just the one element from the set\n\t\treturn num < 0 ? this[ num + this.length ] : this[ num ];\n\t},\n\n\t// Take an array of elements and push it onto the stack\n\t// (returning the new matched element set)\n\tpushStack: function( elems ) {\n\n\t\t// Build a new jQuery matched element set\n\t\tvar ret = jQuery.merge( this.constructor(), elems );\n\n\t\t// Add the old object onto the stack (as a reference)\n\t\tret.prevObject = this;\n\n\t\t// Return the newly-formed element set\n\t\treturn ret;\n\t},\n\n\t// Execute a callback for every element in the matched set.\n\teach: function( callback ) {\n\t\treturn jQuery.each( this, callback );\n\t},\n\n\tmap: function( callback ) {\n\t\treturn this.pushStack( jQuery.map( this, function( elem, i ) {\n\t\t\treturn callback.call( elem, i, elem );\n\t\t} ) );\n\t},\n\n\tslice: function() {\n\t\treturn this.pushStack( slice.apply( this, arguments ) );\n\t},\n\n\tfirst: function() {\n\t\treturn this.eq( 0 );\n\t},\n\n\tlast: function() {\n\t\treturn this.eq( -1 );\n\t},\n\n\teq: function( i ) {\n\t\tvar len = this.length,\n\t\t\tj = +i + ( i < 0 ? len : 0 );\n\t\treturn this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] );\n\t},\n\n\tend: function() {\n\t\treturn this.prevObject || this.constructor();\n\t},\n\n\t// For internal use only.\n\t// Behaves like an Array's method, not like a jQuery method.\n\tpush: push,\n\tsort: arr.sort,\n\tsplice: arr.splice\n};\n\njQuery.extend = jQuery.fn.extend = function() {\n\tvar options, name, src, copy, copyIsArray, clone,\n\t\ttarget = arguments[ 0 ] || {},\n\t\ti = 1,\n\t\tlength = arguments.length,\n\t\tdeep = false;\n\n\t// Handle a deep copy situation\n\tif ( typeof target === \"boolean\" ) {\n\t\tdeep = target;\n\n\t\t// Skip the boolean and the target\n\t\ttarget = arguments[ i ] || {};\n\t\ti++;\n\t}\n\n\t// Handle case when target is a string or something (possible in deep copy)\n\tif ( typeof target !== \"object\" && !isFunction( target ) ) {\n\t\ttarget = {};\n\t}\n\n\t// Extend jQuery itself if only one argument is passed\n\tif ( i === length ) {\n\t\ttarget = this;\n\t\ti--;\n\t}\n\n\tfor ( ; i < length; i++ ) {\n\n\t\t// Only deal with non-null/undefined values\n\t\tif ( ( options = arguments[ i ] ) != null ) {\n\n\t\t\t// Extend the base object\n\t\t\tfor ( name in options ) {\n\t\t\t\tsrc = target[ name ];\n\t\t\t\tcopy = options[ name ];\n\n\t\t\t\t// Prevent Object.prototype pollution\n\t\t\t\t// Prevent never-ending loop\n\t\t\t\tif ( name === \"__proto__\" || target === copy ) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\t// Recurse if we're merging plain objects or arrays\n\t\t\t\tif ( deep && copy && ( jQuery.isPlainObject( copy ) ||\n\t\t\t\t\t( copyIsArray = Array.isArray( copy ) ) ) ) {\n\n\t\t\t\t\tif ( copyIsArray ) {\n\t\t\t\t\t\tcopyIsArray = false;\n\t\t\t\t\t\tclone = src && Array.isArray( src ) ? src : [];\n\n\t\t\t\t\t} else {\n\t\t\t\t\t\tclone = src && jQuery.isPlainObject( src ) ? src : {};\n\t\t\t\t\t}\n\n\t\t\t\t\t// Never move original objects, clone them\n\t\t\t\t\ttarget[ name ] = jQuery.extend( deep, clone, copy );\n\n\t\t\t\t// Don't bring in undefined values\n\t\t\t\t} else if ( copy !== undefined ) {\n\t\t\t\t\ttarget[ name ] = copy;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Return the modified object\n\treturn target;\n};\n\njQuery.extend( {\n\n\t// Unique for each copy of jQuery on the page\n\texpando: \"jQuery\" + ( version + Math.random() ).replace( /\\D/g, \"\" ),\n\n\t// Assume jQuery is ready without the ready module\n\tisReady: true,\n\n\terror: function( msg ) {\n\t\tthrow new Error( msg );\n\t},\n\n\tnoop: function() {},\n\n\tisPlainObject: function( obj ) {\n\t\tvar proto, Ctor;\n\n\t\t// Detect obvious negatives\n\t\t// Use toString instead of jQuery.type to catch host objects\n\t\tif ( !obj || toString.call( obj ) !== \"[object Object]\" ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tproto = getProto( obj );\n\n\t\t// Objects with no prototype (e.g., `Object.create( null )`) are plain\n\t\tif ( !proto ) {\n\t\t\treturn true;\n\t\t}\n\n\t\t// Objects with prototype are plain iff they were constructed by a global Object function\n\t\tCtor = hasOwn.call( proto, \"constructor\" ) && proto.constructor;\n\t\treturn typeof Ctor === \"function\" && fnToString.call( Ctor ) === ObjectFunctionString;\n\t},\n\n\tisEmptyObject: function( obj ) {\n\n\t\t/* eslint-disable no-unused-vars */\n\t\t// See https://github.com/eslint/eslint/issues/6125\n\t\tvar name;\n\n\t\tfor ( name in obj ) {\n\t\t\treturn false;\n\t\t}\n\t\treturn true;\n\t},\n\n\t// Evaluates a script in a global context\n\tglobalEval: function( code ) {\n\t\tDOMEval( code );\n\t},\n\n\teach: function( obj, callback ) {\n\t\tvar length, i = 0;\n\n\t\tif ( isArrayLike( obj ) ) {\n\t\t\tlength = obj.length;\n\t\t\tfor ( ; i < length; i++ ) {\n\t\t\t\tif ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tfor ( i in obj ) {\n\t\t\t\tif ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn obj;\n\t},\n\n\t// Support: Android <=4.0 only\n\ttrim: function( text ) {\n\t\treturn text == null ?\n\t\t\t\"\" :\n\t\t\t( text + \"\" ).replace( rtrim, \"\" );\n\t},\n\n\t// results is for internal usage only\n\tmakeArray: function( arr, results ) {\n\t\tvar ret = results || [];\n\n\t\tif ( arr != null ) {\n\t\t\tif ( isArrayLike( Object( arr ) ) ) {\n\t\t\t\tjQuery.merge( ret,\n\t\t\t\t\ttypeof arr === \"string\" ?\n\t\t\t\t\t[ arr ] : arr\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tpush.call( ret, arr );\n\t\t\t}\n\t\t}\n\n\t\treturn ret;\n\t},\n\n\tinArray: function( elem, arr, i ) {\n\t\treturn arr == null ? -1 : indexOf.call( arr, elem, i );\n\t},\n\n\t// Support: Android <=4.0 only, PhantomJS 1 only\n\t// push.apply(_, arraylike) throws on ancient WebKit\n\tmerge: function( first, second ) {\n\t\tvar len = +second.length,\n\t\t\tj = 0,\n\t\t\ti = first.length;\n\n\t\tfor ( ; j < len; j++ ) {\n\t\t\tfirst[ i++ ] = second[ j ];\n\t\t}\n\n\t\tfirst.length = i;\n\n\t\treturn first;\n\t},\n\n\tgrep: function( elems, callback, invert ) {\n\t\tvar callbackInverse,\n\t\t\tmatches = [],\n\t\t\ti = 0,\n\t\t\tlength = elems.length,\n\t\t\tcallbackExpect = !invert;\n\n\t\t// Go through the array, only saving the items\n\t\t// that pass the validator function\n\t\tfor ( ; i < length; i++ ) {\n\t\t\tcallbackInverse = !callback( elems[ i ], i );\n\t\t\tif ( callbackInverse !== callbackExpect ) {\n\t\t\t\tmatches.push( elems[ i ] );\n\t\t\t}\n\t\t}\n\n\t\treturn matches;\n\t},\n\n\t// arg is for internal usage only\n\tmap: function( elems, callback, arg ) {\n\t\tvar length, value,\n\t\t\ti = 0,\n\t\t\tret = [];\n\n\t\t// Go through the array, translating each of the items to their new values\n\t\tif ( isArrayLike( elems ) ) {\n\t\t\tlength = elems.length;\n\t\t\tfor ( ; i < length; i++ ) {\n\t\t\t\tvalue = callback( elems[ i ], i, arg );\n\n\t\t\t\tif ( value != null ) {\n\t\t\t\t\tret.push( value );\n\t\t\t\t}\n\t\t\t}\n\n\t\t// Go through every key on the object,\n\t\t} else {\n\t\t\tfor ( i in elems ) {\n\t\t\t\tvalue = callback( elems[ i ], i, arg );\n\n\t\t\t\tif ( value != null ) {\n\t\t\t\t\tret.push( value );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Flatten any nested arrays\n\t\treturn concat.apply( [], ret );\n\t},\n\n\t// A global GUID counter for objects\n\tguid: 1,\n\n\t// jQuery.support is not used in Core but other projects attach their\n\t// properties to it so it needs to exist.\n\tsupport: support\n} );\n\nif ( typeof Symbol === \"function\" ) {\n\tjQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ];\n}\n\n// Populate the class2type map\njQuery.each( \"Boolean Number String Function Array Date RegExp Object Error Symbol\".split( \" \" ),\nfunction( i, name ) {\n\tclass2type[ \"[object \" + name + \"]\" ] = name.toLowerCase();\n} );\n\nfunction isArrayLike( obj ) {\n\n\t// Support: real iOS 8.2 only (not reproducible in simulator)\n\t// `in` check used to prevent JIT error (gh-2145)\n\t// hasOwn isn't used here due to false negatives\n\t// regarding Nodelist length in IE\n\tvar length = !!obj && \"length\" in obj && obj.length,\n\t\ttype = toType( obj );\n\n\tif ( isFunction( obj ) || isWindow( obj ) ) {\n\t\treturn false;\n\t}\n\n\treturn type === \"array\" || length === 0 ||\n\t\ttypeof length === \"number\" && length > 0 && ( length - 1 ) in obj;\n}\nvar Sizzle =\n/*!\n * Sizzle CSS Selector Engine v2.3.3\n * https://sizzlejs.com/\n *\n * Copyright jQuery Foundation and other contributors\n * Released under the MIT license\n * http://jquery.org/license\n *\n * Date: 2016-08-08\n */\n(function( window ) {\n\nvar i,\n\tsupport,\n\tExpr,\n\tgetText,\n\tisXML,\n\ttokenize,\n\tcompile,\n\tselect,\n\toutermostContext,\n\tsortInput,\n\thasDuplicate,\n\n\t// Local document vars\n\tsetDocument,\n\tdocument,\n\tdocElem,\n\tdocumentIsHTML,\n\trbuggyQSA,\n\trbuggyMatches,\n\tmatches,\n\tcontains,\n\n\t// Instance-specific data\n\texpando = \"sizzle\" + 1 * new Date(),\n\tpreferredDoc = window.document,\n\tdirruns = 0,\n\tdone = 0,\n\tclassCache = createCache(),\n\ttokenCache = createCache(),\n\tcompilerCache = createCache(),\n\tsortOrder = function( a, b ) {\n\t\tif ( a === b ) {\n\t\t\thasDuplicate = true;\n\t\t}\n\t\treturn 0;\n\t},\n\n\t// Instance methods\n\thasOwn = ({}).hasOwnProperty,\n\tarr = [],\n\tpop = arr.pop,\n\tpush_native = arr.push,\n\tpush = arr.push,\n\tslice = arr.slice,\n\t// Use a stripped-down indexOf as it's faster than native\n\t// https://jsperf.com/thor-indexof-vs-for/5\n\tindexOf = function( list, elem ) {\n\t\tvar i = 0,\n\t\t\tlen = list.length;\n\t\tfor ( ; i < len; i++ ) {\n\t\t\tif ( list[i] === elem ) {\n\t\t\t\treturn i;\n\t\t\t}\n\t\t}\n\t\treturn -1;\n\t},\n\n\tbooleans = \"checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped\",\n\n\t// Regular expressions\n\n\t// http://www.w3.org/TR/css3-selectors/#whitespace\n\twhitespace = \"[\\\\x20\\\\t\\\\r\\\\n\\\\f]\",\n\n\t// http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier\n\tidentifier = \"(?:\\\\\\\\.|[\\\\w-]|[^\\0-\\\\xa0])+\",\n\n\t// Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors\n\tattributes = \"\\\\[\" + whitespace + \"*(\" + identifier + \")(?:\" + whitespace +\n\t\t// Operator (capture 2)\n\t\t\"*([*^$|!~]?=)\" + whitespace +\n\t\t// \"Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]\"\n\t\t\"*(?:'((?:\\\\\\\\.|[^\\\\\\\\'])*)'|\\\"((?:\\\\\\\\.|[^\\\\\\\\\\\"])*)\\\"|(\" + identifier + \"))|)\" + whitespace +\n\t\t\"*\\\\]\",\n\n\tpseudos = \":(\" + identifier + \")(?:\\\\((\" +\n\t\t// To reduce the number of selectors needing tokenize in the preFilter, prefer arguments:\n\t\t// 1. quoted (capture 3; capture 4 or capture 5)\n\t\t\"('((?:\\\\\\\\.|[^\\\\\\\\'])*)'|\\\"((?:\\\\\\\\.|[^\\\\\\\\\\\"])*)\\\")|\" +\n\t\t// 2. simple (capture 6)\n\t\t\"((?:\\\\\\\\.|[^\\\\\\\\()[\\\\]]|\" + attributes + \")*)|\" +\n\t\t// 3. anything else (capture 2)\n\t\t\".*\" +\n\t\t\")\\\\)|)\",\n\n\t// Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter\n\trwhitespace = new RegExp( whitespace + \"+\", \"g\" ),\n\trtrim = new RegExp( \"^\" + whitespace + \"+|((?:^|[^\\\\\\\\])(?:\\\\\\\\.)*)\" + whitespace + \"+$\", \"g\" ),\n\n\trcomma = new RegExp( \"^\" + whitespace + \"*,\" + whitespace + \"*\" ),\n\trcombinators = new RegExp( \"^\" + whitespace + \"*([>+~]|\" + whitespace + \")\" + whitespace + \"*\" ),\n\n\trattributeQuotes = new RegExp( \"=\" + whitespace + \"*([^\\\\]'\\\"]*?)\" + whitespace + \"*\\\\]\", \"g\" ),\n\n\trpseudo = new RegExp( pseudos ),\n\tridentifier = new RegExp( \"^\" + identifier + \"$\" ),\n\n\tmatchExpr = {\n\t\t\"ID\": new RegExp( \"^#(\" + identifier + \")\" ),\n\t\t\"CLASS\": new RegExp( \"^\\\\.(\" + identifier + \")\" ),\n\t\t\"TAG\": new RegExp( \"^(\" + identifier + \"|[*])\" ),\n\t\t\"ATTR\": new RegExp( \"^\" + attributes ),\n\t\t\"PSEUDO\": new RegExp( \"^\" + pseudos ),\n\t\t\"CHILD\": new RegExp( \"^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\\\(\" + whitespace +\n\t\t\t\"*(even|odd|(([+-]|)(\\\\d*)n|)\" + whitespace + \"*(?:([+-]|)\" + whitespace +\n\t\t\t\"*(\\\\d+)|))\" + whitespace + \"*\\\\)|)\", \"i\" ),\n\t\t\"bool\": new RegExp( \"^(?:\" + booleans + \")$\", \"i\" ),\n\t\t// For use in libraries implementing .is()\n\t\t// We use this for POS matching in `select`\n\t\t\"needsContext\": new RegExp( \"^\" + whitespace + \"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\\\(\" +\n\t\t\twhitespace + \"*((?:-\\\\d)?\\\\d*)\" + whitespace + \"*\\\\)|)(?=[^-]|$)\", \"i\" )\n\t},\n\n\trinputs = /^(?:input|select|textarea|button)$/i,\n\trheader = /^h\\d$/i,\n\n\trnative = /^[^{]+\\{\\s*\\[native \\w/,\n\n\t// Easily-parseable/retrievable ID or TAG or CLASS selectors\n\trquickExpr = /^(?:#([\\w-]+)|(\\w+)|\\.([\\w-]+))$/,\n\n\trsibling = /[+~]/,\n\n\t// CSS escapes\n\t// http://www.w3.org/TR/CSS21/syndata.html#escaped-characters\n\trunescape = new RegExp( \"\\\\\\\\([\\\\da-f]{1,6}\" + whitespace + \"?|(\" + whitespace + \")|.)\", \"ig\" ),\n\tfunescape = function( _, escaped, escapedWhitespace ) {\n\t\tvar high = \"0x\" + escaped - 0x10000;\n\t\t// NaN means non-codepoint\n\t\t// Support: Firefox<24\n\t\t// Workaround erroneous numeric interpretation of +\"0x\"\n\t\treturn high !== high || escapedWhitespace ?\n\t\t\tescaped :\n\t\t\thigh < 0 ?\n\t\t\t\t// BMP codepoint\n\t\t\t\tString.fromCharCode( high + 0x10000 ) :\n\t\t\t\t// Supplemental Plane codepoint (surrogate pair)\n\t\t\t\tString.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );\n\t},\n\n\t// CSS string/identifier serialization\n\t// https://drafts.csswg.org/cssom/#common-serializing-idioms\n\trcssescape = /([\\0-\\x1f\\x7f]|^-?\\d)|^-$|[^\\0-\\x1f\\x7f-\\uFFFF\\w-]/g,\n\tfcssescape = function( ch, asCodePoint ) {\n\t\tif ( asCodePoint ) {\n\n\t\t\t// U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER\n\t\t\tif ( ch === \"\\0\" ) {\n\t\t\t\treturn \"\\uFFFD\";\n\t\t\t}\n\n\t\t\t// Control characters and (dependent upon position) numbers get escaped as code points\n\t\t\treturn ch.slice( 0, -1 ) + \"\\\\\" + ch.charCodeAt( ch.length - 1 ).toString( 16 ) + \" \";\n\t\t}\n\n\t\t// Other potentially-special ASCII characters get backslash-escaped\n\t\treturn \"\\\\\" + ch;\n\t},\n\n\t// Used for iframes\n\t// See setDocument()\n\t// Removing the function wrapper causes a \"Permission Denied\"\n\t// error in IE\n\tunloadHandler = function() {\n\t\tsetDocument();\n\t},\n\n\tdisabledAncestor = addCombinator(\n\t\tfunction( elem ) {\n\t\t\treturn elem.disabled === true && (\"form\" in elem || \"label\" in elem);\n\t\t},\n\t\t{ dir: \"parentNode\", next: \"legend\" }\n\t);\n\n// Optimize for push.apply( _, NodeList )\ntry {\n\tpush.apply(\n\t\t(arr = slice.call( preferredDoc.childNodes )),\n\t\tpreferredDoc.childNodes\n\t);\n\t// Support: Android<4.0\n\t// Detect silently failing push.apply\n\tarr[ preferredDoc.childNodes.length ].nodeType;\n} catch ( e ) {\n\tpush = { apply: arr.length ?\n\n\t\t// Leverage slice if possible\n\t\tfunction( target, els ) {\n\t\t\tpush_native.apply( target, slice.call(els) );\n\t\t} :\n\n\t\t// Support: IE<9\n\t\t// Otherwise append directly\n\t\tfunction( target, els ) {\n\t\t\tvar j = target.length,\n\t\t\t\ti = 0;\n\t\t\t// Can't trust NodeList.length\n\t\t\twhile ( (target[j++] = els[i++]) ) {}\n\t\t\ttarget.length = j - 1;\n\t\t}\n\t};\n}\n\nfunction Sizzle( selector, context, results, seed ) {\n\tvar m, i, elem, nid, match, groups, newSelector,\n\t\tnewContext = context && context.ownerDocument,\n\n\t\t// nodeType defaults to 9, since context defaults to document\n\t\tnodeType = context ? context.nodeType : 9;\n\n\tresults = results || [];\n\n\t// Return early from calls with invalid selector or context\n\tif ( typeof selector !== \"string\" || !selector ||\n\t\tnodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) {\n\n\t\treturn results;\n\t}\n\n\t// Try to shortcut find operations (as opposed to filters) in HTML documents\n\tif ( !seed ) {\n\n\t\tif ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) {\n\t\t\tsetDocument( context );\n\t\t}\n\t\tcontext = context || document;\n\n\t\tif ( documentIsHTML ) {\n\n\t\t\t// If the selector is sufficiently simple, try using a \"get*By*\" DOM method\n\t\t\t// (excepting DocumentFragment context, where the methods don't exist)\n\t\t\tif ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) {\n\n\t\t\t\t// ID selector\n\t\t\t\tif ( (m = match[1]) ) {\n\n\t\t\t\t\t// Document context\n\t\t\t\t\tif ( nodeType === 9 ) {\n\t\t\t\t\t\tif ( (elem = context.getElementById( m )) ) {\n\n\t\t\t\t\t\t\t// Support: IE, Opera, Webkit\n\t\t\t\t\t\t\t// TODO: identify versions\n\t\t\t\t\t\t\t// getElementById can match elements by name instead of ID\n\t\t\t\t\t\t\tif ( elem.id === m ) {\n\t\t\t\t\t\t\t\tresults.push( elem );\n\t\t\t\t\t\t\t\treturn results;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\treturn results;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t// Element context\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t// Support: IE, Opera, Webkit\n\t\t\t\t\t\t// TODO: identify versions\n\t\t\t\t\t\t// getElementById can match elements by name instead of ID\n\t\t\t\t\t\tif ( newContext && (elem = newContext.getElementById( m )) &&\n\t\t\t\t\t\t\tcontains( context, elem ) &&\n\t\t\t\t\t\t\telem.id === m ) {\n\n\t\t\t\t\t\t\tresults.push( elem );\n\t\t\t\t\t\t\treturn results;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t// Type selector\n\t\t\t\t} else if ( match[2] ) {\n\t\t\t\t\tpush.apply( results, context.getElementsByTagName( selector ) );\n\t\t\t\t\treturn results;\n\n\t\t\t\t// Class selector\n\t\t\t\t} else if ( (m = match[3]) && support.getElementsByClassName &&\n\t\t\t\t\tcontext.getElementsByClassName ) {\n\n\t\t\t\t\tpush.apply( results, context.getElementsByClassName( m ) );\n\t\t\t\t\treturn results;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Take advantage of querySelectorAll\n\t\t\tif ( support.qsa &&\n\t\t\t\t!compilerCache[ selector + \" \" ] &&\n\t\t\t\t(!rbuggyQSA || !rbuggyQSA.test( selector )) ) {\n\n\t\t\t\tif ( nodeType !== 1 ) {\n\t\t\t\t\tnewContext = context;\n\t\t\t\t\tnewSelector = selector;\n\n\t\t\t\t// qSA looks outside Element context, which is not what we want\n\t\t\t\t// Thanks to Andrew Dupont for this workaround technique\n\t\t\t\t// Support: IE <=8\n\t\t\t\t// Exclude object elements\n\t\t\t\t} else if ( context.nodeName.toLowerCase() !== \"object\" ) {\n\n\t\t\t\t\t// Capture the context ID, setting it first if necessary\n\t\t\t\t\tif ( (nid = context.getAttribute( \"id\" )) ) {\n\t\t\t\t\t\tnid = nid.replace( rcssescape, fcssescape );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tcontext.setAttribute( \"id\", (nid = expando) );\n\t\t\t\t\t}\n\n\t\t\t\t\t// Prefix every selector in the list\n\t\t\t\t\tgroups = tokenize( selector );\n\t\t\t\t\ti = groups.length;\n\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\tgroups[i] = \"#\" + nid + \" \" + toSelector( groups[i] );\n\t\t\t\t\t}\n\t\t\t\t\tnewSelector = groups.join( \",\" );\n\n\t\t\t\t\t// Expand context for sibling selectors\n\t\t\t\t\tnewContext = rsibling.test( selector ) && testContext( context.parentNode ) ||\n\t\t\t\t\t\tcontext;\n\t\t\t\t}\n\n\t\t\t\tif ( newSelector ) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tpush.apply( results,\n\t\t\t\t\t\t\tnewContext.querySelectorAll( newSelector )\n\t\t\t\t\t\t);\n\t\t\t\t\t\treturn results;\n\t\t\t\t\t} catch ( qsaError ) {\n\t\t\t\t\t} finally {\n\t\t\t\t\t\tif ( nid === expando ) {\n\t\t\t\t\t\t\tcontext.removeAttribute( \"id\" );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// All others\n\treturn select( selector.replace( rtrim, \"$1\" ), context, results, seed );\n}\n\n/**\n * Create key-value caches of limited size\n * @returns {function(string, object)} Returns the Object data after storing it on itself with\n *\tproperty name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)\n *\tdeleting the oldest entry\n */\nfunction createCache() {\n\tvar keys = [];\n\n\tfunction cache( key, value ) {\n\t\t// Use (key + \" \") to avoid collision with native prototype properties (see Issue #157)\n\t\tif ( keys.push( key + \" \" ) > Expr.cacheLength ) {\n\t\t\t// Only keep the most recent entries\n\t\t\tdelete cache[ keys.shift() ];\n\t\t}\n\t\treturn (cache[ key + \" \" ] = value);\n\t}\n\treturn cache;\n}\n\n/**\n * Mark a function for special use by Sizzle\n * @param {Function} fn The function to mark\n */\nfunction markFunction( fn ) {\n\tfn[ expando ] = true;\n\treturn fn;\n}\n\n/**\n * Support testing using an element\n * @param {Function} fn Passed the created element and returns a boolean result\n */\nfunction assert( fn ) {\n\tvar el = document.createElement(\"fieldset\");\n\n\ttry {\n\t\treturn !!fn( el );\n\t} catch (e) {\n\t\treturn false;\n\t} finally {\n\t\t// Remove from its parent by default\n\t\tif ( el.parentNode ) {\n\t\t\tel.parentNode.removeChild( el );\n\t\t}\n\t\t// release memory in IE\n\t\tel = null;\n\t}\n}\n\n/**\n * Adds the same handler for all of the specified attrs\n * @param {String} attrs Pipe-separated list of attributes\n * @param {Function} handler The method that will be applied\n */\nfunction addHandle( attrs, handler ) {\n\tvar arr = attrs.split(\"|\"),\n\t\ti = arr.length;\n\n\twhile ( i-- ) {\n\t\tExpr.attrHandle[ arr[i] ] = handler;\n\t}\n}\n\n/**\n * Checks document order of two siblings\n * @param {Element} a\n * @param {Element} b\n * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b\n */\nfunction siblingCheck( a, b ) {\n\tvar cur = b && a,\n\t\tdiff = cur && a.nodeType === 1 && b.nodeType === 1 &&\n\t\t\ta.sourceIndex - b.sourceIndex;\n\n\t// Use IE sourceIndex if available on both nodes\n\tif ( diff ) {\n\t\treturn diff;\n\t}\n\n\t// Check if b follows a\n\tif ( cur ) {\n\t\twhile ( (cur = cur.nextSibling) ) {\n\t\t\tif ( cur === b ) {\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn a ? 1 : -1;\n}\n\n/**\n * Returns a function to use in pseudos for input types\n * @param {String} type\n */\nfunction createInputPseudo( type ) {\n\treturn function( elem ) {\n\t\tvar name = elem.nodeName.toLowerCase();\n\t\treturn name === \"input\" && elem.type === type;\n\t};\n}\n\n/**\n * Returns a function to use in pseudos for buttons\n * @param {String} type\n */\nfunction createButtonPseudo( type ) {\n\treturn function( elem ) {\n\t\tvar name = elem.nodeName.toLowerCase();\n\t\treturn (name === \"input\" || name === \"button\") && elem.type === type;\n\t};\n}\n\n/**\n * Returns a function to use in pseudos for :enabled/:disabled\n * @param {Boolean} disabled true for :disabled; false for :enabled\n */\nfunction createDisabledPseudo( disabled ) {\n\n\t// Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable\n\treturn function( elem ) {\n\n\t\t// Only certain elements can match :enabled or :disabled\n\t\t// https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled\n\t\t// https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled\n\t\tif ( \"form\" in elem ) {\n\n\t\t\t// Check for inherited disabledness on relevant non-disabled elements:\n\t\t\t// * listed form-associated elements in a disabled fieldset\n\t\t\t//   https://html.spec.whatwg.org/multipage/forms.html#category-listed\n\t\t\t//   https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled\n\t\t\t// * option elements in a disabled optgroup\n\t\t\t//   https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled\n\t\t\t// All such elements have a \"form\" property.\n\t\t\tif ( elem.parentNode && elem.disabled === false ) {\n\n\t\t\t\t// Option elements defer to a parent optgroup if present\n\t\t\t\tif ( \"label\" in elem ) {\n\t\t\t\t\tif ( \"label\" in elem.parentNode ) {\n\t\t\t\t\t\treturn elem.parentNode.disabled === disabled;\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn elem.disabled === disabled;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Support: IE 6 - 11\n\t\t\t\t// Use the isDisabled shortcut property to check for disabled fieldset ancestors\n\t\t\t\treturn elem.isDisabled === disabled ||\n\n\t\t\t\t\t// Where there is no isDisabled, check manually\n\t\t\t\t\t/* jshint -W018 */\n\t\t\t\t\telem.isDisabled !== !disabled &&\n\t\t\t\t\t\tdisabledAncestor( elem ) === disabled;\n\t\t\t}\n\n\t\t\treturn elem.disabled === disabled;\n\n\t\t// Try to winnow out elements that can't be disabled before trusting the disabled property.\n\t\t// Some victims get caught in our net (label, legend, menu, track), but it shouldn't\n\t\t// even exist on them, let alone have a boolean value.\n\t\t} else if ( \"label\" in elem ) {\n\t\t\treturn elem.disabled === disabled;\n\t\t}\n\n\t\t// Remaining elements are neither :enabled nor :disabled\n\t\treturn false;\n\t};\n}\n\n/**\n * Returns a function to use in pseudos for positionals\n * @param {Function} fn\n */\nfunction createPositionalPseudo( fn ) {\n\treturn markFunction(function( argument ) {\n\t\targument = +argument;\n\t\treturn markFunction(function( seed, matches ) {\n\t\t\tvar j,\n\t\t\t\tmatchIndexes = fn( [], seed.length, argument ),\n\t\t\t\ti = matchIndexes.length;\n\n\t\t\t// Match elements found at the specified indexes\n\t\t\twhile ( i-- ) {\n\t\t\t\tif ( seed[ (j = matchIndexes[i]) ] ) {\n\t\t\t\t\tseed[j] = !(matches[j] = seed[j]);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t});\n}\n\n/**\n * Checks a node for validity as a Sizzle context\n * @param {Element|Object=} context\n * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value\n */\nfunction testContext( context ) {\n\treturn context && typeof context.getElementsByTagName !== \"undefined\" && context;\n}\n\n// Expose support vars for convenience\nsupport = Sizzle.support = {};\n\n/**\n * Detects XML nodes\n * @param {Element|Object} elem An element or a document\n * @returns {Boolean} True iff elem is a non-HTML XML node\n */\nisXML = Sizzle.isXML = function( elem ) {\n\t// documentElement is verified for cases where it doesn't yet exist\n\t// (such as loading iframes in IE - #4833)\n\tvar documentElement = elem && (elem.ownerDocument || elem).documentElement;\n\treturn documentElement ? documentElement.nodeName !== \"HTML\" : false;\n};\n\n/**\n * Sets document-related variables once based on the current document\n * @param {Element|Object} [doc] An element or document object to use to set the document\n * @returns {Object} Returns the current document\n */\nsetDocument = Sizzle.setDocument = function( node ) {\n\tvar hasCompare, subWindow,\n\t\tdoc = node ? node.ownerDocument || node : preferredDoc;\n\n\t// Return early if doc is invalid or already selected\n\tif ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) {\n\t\treturn document;\n\t}\n\n\t// Update global variables\n\tdocument = doc;\n\tdocElem = document.documentElement;\n\tdocumentIsHTML = !isXML( document );\n\n\t// Support: IE 9-11, Edge\n\t// Accessing iframe documents after unload throws \"permission denied\" errors (jQuery #13936)\n\tif ( preferredDoc !== document &&\n\t\t(subWindow = document.defaultView) && subWindow.top !== subWindow ) {\n\n\t\t// Support: IE 11, Edge\n\t\tif ( subWindow.addEventListener ) {\n\t\t\tsubWindow.addEventListener( \"unload\", unloadHandler, false );\n\n\t\t// Support: IE 9 - 10 only\n\t\t} else if ( subWindow.attachEvent ) {\n\t\t\tsubWindow.attachEvent( \"onunload\", unloadHandler );\n\t\t}\n\t}\n\n\t/* Attributes\n\t---------------------------------------------------------------------- */\n\n\t// Support: IE<8\n\t// Verify that getAttribute really returns attributes and not properties\n\t// (excepting IE8 booleans)\n\tsupport.attributes = assert(function( el ) {\n\t\tel.className = \"i\";\n\t\treturn !el.getAttribute(\"className\");\n\t});\n\n\t/* getElement(s)By*\n\t---------------------------------------------------------------------- */\n\n\t// Check if getElementsByTagName(\"*\") returns only elements\n\tsupport.getElementsByTagName = assert(function( el ) {\n\t\tel.appendChild( document.createComment(\"\") );\n\t\treturn !el.getElementsByTagName(\"*\").length;\n\t});\n\n\t// Support: IE<9\n\tsupport.getElementsByClassName = rnative.test( document.getElementsByClassName );\n\n\t// Support: IE<10\n\t// Check if getElementById returns elements by name\n\t// The broken getElementById methods don't pick up programmatically-set names,\n\t// so use a roundabout getElementsByName test\n\tsupport.getById = assert(function( el ) {\n\t\tdocElem.appendChild( el ).id = expando;\n\t\treturn !document.getElementsByName || !document.getElementsByName( expando ).length;\n\t});\n\n\t// ID filter and find\n\tif ( support.getById ) {\n\t\tExpr.filter[\"ID\"] = function( id ) {\n\t\t\tvar attrId = id.replace( runescape, funescape );\n\t\t\treturn function( elem ) {\n\t\t\t\treturn elem.getAttribute(\"id\") === attrId;\n\t\t\t};\n\t\t};\n\t\tExpr.find[\"ID\"] = function( id, context ) {\n\t\t\tif ( typeof context.getElementById !== \"undefined\" && documentIsHTML ) {\n\t\t\t\tvar elem = context.getElementById( id );\n\t\t\t\treturn elem ? [ elem ] : [];\n\t\t\t}\n\t\t};\n\t} else {\n\t\tExpr.filter[\"ID\"] =  function( id ) {\n\t\t\tvar attrId = id.replace( runescape, funescape );\n\t\t\treturn function( elem ) {\n\t\t\t\tvar node = typeof elem.getAttributeNode !== \"undefined\" &&\n\t\t\t\t\telem.getAttributeNode(\"id\");\n\t\t\t\treturn node && node.value === attrId;\n\t\t\t};\n\t\t};\n\n\t\t// Support: IE 6 - 7 only\n\t\t// getElementById is not reliable as a find shortcut\n\t\tExpr.find[\"ID\"] = function( id, context ) {\n\t\t\tif ( typeof context.getElementById !== \"undefined\" && documentIsHTML ) {\n\t\t\t\tvar node, i, elems,\n\t\t\t\t\telem = context.getElementById( id );\n\n\t\t\t\tif ( elem ) {\n\n\t\t\t\t\t// Verify the id attribute\n\t\t\t\t\tnode = elem.getAttributeNode(\"id\");\n\t\t\t\t\tif ( node && node.value === id ) {\n\t\t\t\t\t\treturn [ elem ];\n\t\t\t\t\t}\n\n\t\t\t\t\t// Fall back on getElementsByName\n\t\t\t\t\telems = context.getElementsByName( id );\n\t\t\t\t\ti = 0;\n\t\t\t\t\twhile ( (elem = elems[i++]) ) {\n\t\t\t\t\t\tnode = elem.getAttributeNode(\"id\");\n\t\t\t\t\t\tif ( node && node.value === id ) {\n\t\t\t\t\t\t\treturn [ elem ];\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn [];\n\t\t\t}\n\t\t};\n\t}\n\n\t// Tag\n\tExpr.find[\"TAG\"] = support.getElementsByTagName ?\n\t\tfunction( tag, context ) {\n\t\t\tif ( typeof context.getElementsByTagName !== \"undefined\" ) {\n\t\t\t\treturn context.getElementsByTagName( tag );\n\n\t\t\t// DocumentFragment nodes don't have gEBTN\n\t\t\t} else if ( support.qsa ) {\n\t\t\t\treturn context.querySelectorAll( tag );\n\t\t\t}\n\t\t} :\n\n\t\tfunction( tag, context ) {\n\t\t\tvar elem,\n\t\t\t\ttmp = [],\n\t\t\t\ti = 0,\n\t\t\t\t// By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too\n\t\t\t\tresults = context.getElementsByTagName( tag );\n\n\t\t\t// Filter out possible comments\n\t\t\tif ( tag === \"*\" ) {\n\t\t\t\twhile ( (elem = results[i++]) ) {\n\t\t\t\t\tif ( elem.nodeType === 1 ) {\n\t\t\t\t\t\ttmp.push( elem );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn tmp;\n\t\t\t}\n\t\t\treturn results;\n\t\t};\n\n\t// Class\n\tExpr.find[\"CLASS\"] = support.getElementsByClassName && function( className, context ) {\n\t\tif ( typeof context.getElementsByClassName !== \"undefined\" && documentIsHTML ) {\n\t\t\treturn context.getElementsByClassName( className );\n\t\t}\n\t};\n\n\t/* QSA/matchesSelector\n\t---------------------------------------------------------------------- */\n\n\t// QSA and matchesSelector support\n\n\t// matchesSelector(:active) reports false when true (IE9/Opera 11.5)\n\trbuggyMatches = [];\n\n\t// qSa(:focus) reports false when true (Chrome 21)\n\t// We allow this because of a bug in IE8/9 that throws an error\n\t// whenever `document.activeElement` is accessed on an iframe\n\t// So, we allow :focus to pass through QSA all the time to avoid the IE error\n\t// See https://bugs.jquery.com/ticket/13378\n\trbuggyQSA = [];\n\n\tif ( (support.qsa = rnative.test( document.querySelectorAll )) ) {\n\t\t// Build QSA regex\n\t\t// Regex strategy adopted from Diego Perini\n\t\tassert(function( el ) {\n\t\t\t// Select is set to empty string on purpose\n\t\t\t// This is to test IE's treatment of not explicitly\n\t\t\t// setting a boolean content attribute,\n\t\t\t// since its presence should be enough\n\t\t\t// https://bugs.jquery.com/ticket/12359\n\t\t\tdocElem.appendChild( el ).innerHTML = \"<a id='\" + expando + \"'></a>\" +\n\t\t\t\t\"<select id='\" + expando + \"-\\r\\\\' msallowcapture=''>\" +\n\t\t\t\t\"<option selected=''></option></select>\";\n\n\t\t\t// Support: IE8, Opera 11-12.16\n\t\t\t// Nothing should be selected when empty strings follow ^= or $= or *=\n\t\t\t// The test attribute must be unknown in Opera but \"safe\" for WinRT\n\t\t\t// https://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section\n\t\t\tif ( el.querySelectorAll(\"[msallowcapture^='']\").length ) {\n\t\t\t\trbuggyQSA.push( \"[*^$]=\" + whitespace + \"*(?:''|\\\"\\\")\" );\n\t\t\t}\n\n\t\t\t// Support: IE8\n\t\t\t// Boolean attributes and \"value\" are not treated correctly\n\t\t\tif ( !el.querySelectorAll(\"[selected]\").length ) {\n\t\t\t\trbuggyQSA.push( \"\\\\[\" + whitespace + \"*(?:value|\" + booleans + \")\" );\n\t\t\t}\n\n\t\t\t// Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+\n\t\t\tif ( !el.querySelectorAll( \"[id~=\" + expando + \"-]\" ).length ) {\n\t\t\t\trbuggyQSA.push(\"~=\");\n\t\t\t}\n\n\t\t\t// Webkit/Opera - :checked should return selected option elements\n\t\t\t// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked\n\t\t\t// IE8 throws error here and will not see later tests\n\t\t\tif ( !el.querySelectorAll(\":checked\").length ) {\n\t\t\t\trbuggyQSA.push(\":checked\");\n\t\t\t}\n\n\t\t\t// Support: Safari 8+, iOS 8+\n\t\t\t// https://bugs.webkit.org/show_bug.cgi?id=136851\n\t\t\t// In-page `selector#id sibling-combinator selector` fails\n\t\t\tif ( !el.querySelectorAll( \"a#\" + expando + \"+*\" ).length ) {\n\t\t\t\trbuggyQSA.push(\".#.+[+~]\");\n\t\t\t}\n\t\t});\n\n\t\tassert(function( el ) {\n\t\t\tel.innerHTML = \"<a href='' disabled='disabled'></a>\" +\n\t\t\t\t\"<select disabled='disabled'><option/></select>\";\n\n\t\t\t// Support: Windows 8 Native Apps\n\t\t\t// The type and name attributes are restricted during .innerHTML assignment\n\t\t\tvar input = document.createElement(\"input\");\n\t\t\tinput.setAttribute( \"type\", \"hidden\" );\n\t\t\tel.appendChild( input ).setAttribute( \"name\", \"D\" );\n\n\t\t\t// Support: IE8\n\t\t\t// Enforce case-sensitivity of name attribute\n\t\t\tif ( el.querySelectorAll(\"[name=d]\").length ) {\n\t\t\t\trbuggyQSA.push( \"name\" + whitespace + \"*[*^$|!~]?=\" );\n\t\t\t}\n\n\t\t\t// FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)\n\t\t\t// IE8 throws error here and will not see later tests\n\t\t\tif ( el.querySelectorAll(\":enabled\").length !== 2 ) {\n\t\t\t\trbuggyQSA.push( \":enabled\", \":disabled\" );\n\t\t\t}\n\n\t\t\t// Support: IE9-11+\n\t\t\t// IE's :disabled selector does not pick up the children of disabled fieldsets\n\t\t\tdocElem.appendChild( el ).disabled = true;\n\t\t\tif ( el.querySelectorAll(\":disabled\").length !== 2 ) {\n\t\t\t\trbuggyQSA.push( \":enabled\", \":disabled\" );\n\t\t\t}\n\n\t\t\t// Opera 10-11 does not throw on post-comma invalid pseudos\n\t\t\tel.querySelectorAll(\"*,:x\");\n\t\t\trbuggyQSA.push(\",.*:\");\n\t\t});\n\t}\n\n\tif ( (support.matchesSelector = rnative.test( (matches = docElem.matches ||\n\t\tdocElem.webkitMatchesSelector ||\n\t\tdocElem.mozMatchesSelector ||\n\t\tdocElem.oMatchesSelector ||\n\t\tdocElem.msMatchesSelector) )) ) {\n\n\t\tassert(function( el ) {\n\t\t\t// Check to see if it's possible to do matchesSelector\n\t\t\t// on a disconnected node (IE 9)\n\t\t\tsupport.disconnectedMatch = matches.call( el, \"*\" );\n\n\t\t\t// This should fail with an exception\n\t\t\t// Gecko does not error, returns false instead\n\t\t\tmatches.call( el, \"[s!='']:x\" );\n\t\t\trbuggyMatches.push( \"!=\", pseudos );\n\t\t});\n\t}\n\n\trbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join(\"|\") );\n\trbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join(\"|\") );\n\n\t/* Contains\n\t---------------------------------------------------------------------- */\n\thasCompare = rnative.test( docElem.compareDocumentPosition );\n\n\t// Element contains another\n\t// Purposefully self-exclusive\n\t// As in, an element does not contain itself\n\tcontains = hasCompare || rnative.test( docElem.contains ) ?\n\t\tfunction( a, b ) {\n\t\t\tvar adown = a.nodeType === 9 ? a.documentElement : a,\n\t\t\t\tbup = b && b.parentNode;\n\t\t\treturn a === bup || !!( bup && bup.nodeType === 1 && (\n\t\t\t\tadown.contains ?\n\t\t\t\t\tadown.contains( bup ) :\n\t\t\t\t\ta.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16\n\t\t\t));\n\t\t} :\n\t\tfunction( a, b ) {\n\t\t\tif ( b ) {\n\t\t\t\twhile ( (b = b.parentNode) ) {\n\t\t\t\t\tif ( b === a ) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t};\n\n\t/* Sorting\n\t---------------------------------------------------------------------- */\n\n\t// Document order sorting\n\tsortOrder = hasCompare ?\n\tfunction( a, b ) {\n\n\t\t// Flag for duplicate removal\n\t\tif ( a === b ) {\n\t\t\thasDuplicate = true;\n\t\t\treturn 0;\n\t\t}\n\n\t\t// Sort on method existence if only one input has compareDocumentPosition\n\t\tvar compare = !a.compareDocumentPosition - !b.compareDocumentPosition;\n\t\tif ( compare ) {\n\t\t\treturn compare;\n\t\t}\n\n\t\t// Calculate position if both inputs belong to the same document\n\t\tcompare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ?\n\t\t\ta.compareDocumentPosition( b ) :\n\n\t\t\t// Otherwise we know they are disconnected\n\t\t\t1;\n\n\t\t// Disconnected nodes\n\t\tif ( compare & 1 ||\n\t\t\t(!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) {\n\n\t\t\t// Choose the first element that is related to our preferred document\n\t\t\tif ( a === document || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) {\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t\tif ( b === document || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) {\n\t\t\t\treturn 1;\n\t\t\t}\n\n\t\t\t// Maintain original order\n\t\t\treturn sortInput ?\n\t\t\t\t( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :\n\t\t\t\t0;\n\t\t}\n\n\t\treturn compare & 4 ? -1 : 1;\n\t} :\n\tfunction( a, b ) {\n\t\t// Exit early if the nodes are identical\n\t\tif ( a === b ) {\n\t\t\thasDuplicate = true;\n\t\t\treturn 0;\n\t\t}\n\n\t\tvar cur,\n\t\t\ti = 0,\n\t\t\taup = a.parentNode,\n\t\t\tbup = b.parentNode,\n\t\t\tap = [ a ],\n\t\t\tbp = [ b ];\n\n\t\t// Parentless nodes are either documents or disconnected\n\t\tif ( !aup || !bup ) {\n\t\t\treturn a === document ? -1 :\n\t\t\t\tb === document ? 1 :\n\t\t\t\taup ? -1 :\n\t\t\t\tbup ? 1 :\n\t\t\t\tsortInput ?\n\t\t\t\t( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :\n\t\t\t\t0;\n\n\t\t// If the nodes are siblings, we can do a quick check\n\t\t} else if ( aup === bup ) {\n\t\t\treturn siblingCheck( a, b );\n\t\t}\n\n\t\t// Otherwise we need full lists of their ancestors for comparison\n\t\tcur = a;\n\t\twhile ( (cur = cur.parentNode) ) {\n\t\t\tap.unshift( cur );\n\t\t}\n\t\tcur = b;\n\t\twhile ( (cur = cur.parentNode) ) {\n\t\t\tbp.unshift( cur );\n\t\t}\n\n\t\t// Walk down the tree looking for a discrepancy\n\t\twhile ( ap[i] === bp[i] ) {\n\t\t\ti++;\n\t\t}\n\n\t\treturn i ?\n\t\t\t// Do a sibling check if the nodes have a common ancestor\n\t\t\tsiblingCheck( ap[i], bp[i] ) :\n\n\t\t\t// Otherwise nodes in our document sort first\n\t\t\tap[i] === preferredDoc ? -1 :\n\t\t\tbp[i] === preferredDoc ? 1 :\n\t\t\t0;\n\t};\n\n\treturn document;\n};\n\nSizzle.matches = function( expr, elements ) {\n\treturn Sizzle( expr, null, null, elements );\n};\n\nSizzle.matchesSelector = function( elem, expr ) {\n\t// Set document vars if needed\n\tif ( ( elem.ownerDocument || elem ) !== document ) {\n\t\tsetDocument( elem );\n\t}\n\n\t// Make sure that attribute selectors are quoted\n\texpr = expr.replace( rattributeQuotes, \"='$1']\" );\n\n\tif ( support.matchesSelector && documentIsHTML &&\n\t\t!compilerCache[ expr + \" \" ] &&\n\t\t( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&\n\t\t( !rbuggyQSA     || !rbuggyQSA.test( expr ) ) ) {\n\n\t\ttry {\n\t\t\tvar ret = matches.call( elem, expr );\n\n\t\t\t// IE 9's matchesSelector returns false on disconnected nodes\n\t\t\tif ( ret || support.disconnectedMatch ||\n\t\t\t\t\t// As well, disconnected nodes are said to be in a document\n\t\t\t\t\t// fragment in IE 9\n\t\t\t\t\telem.document && elem.document.nodeType !== 11 ) {\n\t\t\t\treturn ret;\n\t\t\t}\n\t\t} catch (e) {}\n\t}\n\n\treturn Sizzle( expr, document, null, [ elem ] ).length > 0;\n};\n\nSizzle.contains = function( context, elem ) {\n\t// Set document vars if needed\n\tif ( ( context.ownerDocument || context ) !== document ) {\n\t\tsetDocument( context );\n\t}\n\treturn contains( context, elem );\n};\n\nSizzle.attr = function( elem, name ) {\n\t// Set document vars if needed\n\tif ( ( elem.ownerDocument || elem ) !== document ) {\n\t\tsetDocument( elem );\n\t}\n\n\tvar fn = Expr.attrHandle[ name.toLowerCase() ],\n\t\t// Don't get fooled by Object.prototype properties (jQuery #13807)\n\t\tval = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?\n\t\t\tfn( elem, name, !documentIsHTML ) :\n\t\t\tundefined;\n\n\treturn val !== undefined ?\n\t\tval :\n\t\tsupport.attributes || !documentIsHTML ?\n\t\t\telem.getAttribute( name ) :\n\t\t\t(val = elem.getAttributeNode(name)) && val.specified ?\n\t\t\t\tval.value :\n\t\t\t\tnull;\n};\n\nSizzle.escape = function( sel ) {\n\treturn (sel + \"\").replace( rcssescape, fcssescape );\n};\n\nSizzle.error = function( msg ) {\n\tthrow new Error( \"Syntax error, unrecognized expression: \" + msg );\n};\n\n/**\n * Document sorting and removing duplicates\n * @param {ArrayLike} results\n */\nSizzle.uniqueSort = function( results ) {\n\tvar elem,\n\t\tduplicates = [],\n\t\tj = 0,\n\t\ti = 0;\n\n\t// Unless we *know* we can detect duplicates, assume their presence\n\thasDuplicate = !support.detectDuplicates;\n\tsortInput = !support.sortStable && results.slice( 0 );\n\tresults.sort( sortOrder );\n\n\tif ( hasDuplicate ) {\n\t\twhile ( (elem = results[i++]) ) {\n\t\t\tif ( elem === results[ i ] ) {\n\t\t\t\tj = duplicates.push( i );\n\t\t\t}\n\t\t}\n\t\twhile ( j-- ) {\n\t\t\tresults.splice( duplicates[ j ], 1 );\n\t\t}\n\t}\n\n\t// Clear input after sorting to release objects\n\t// See https://github.com/jquery/sizzle/pull/225\n\tsortInput = null;\n\n\treturn results;\n};\n\n/**\n * Utility function for retrieving the text value of an array of DOM nodes\n * @param {Array|Element} elem\n */\ngetText = Sizzle.getText = function( elem ) {\n\tvar node,\n\t\tret = \"\",\n\t\ti = 0,\n\t\tnodeType = elem.nodeType;\n\n\tif ( !nodeType ) {\n\t\t// If no nodeType, this is expected to be an array\n\t\twhile ( (node = elem[i++]) ) {\n\t\t\t// Do not traverse comment nodes\n\t\t\tret += getText( node );\n\t\t}\n\t} else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {\n\t\t// Use textContent for elements\n\t\t// innerText usage removed for consistency of new lines (jQuery #11153)\n\t\tif ( typeof elem.textContent === \"string\" ) {\n\t\t\treturn elem.textContent;\n\t\t} else {\n\t\t\t// Traverse its children\n\t\t\tfor ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {\n\t\t\t\tret += getText( elem );\n\t\t\t}\n\t\t}\n\t} else if ( nodeType === 3 || nodeType === 4 ) {\n\t\treturn elem.nodeValue;\n\t}\n\t// Do not include comment or processing instruction nodes\n\n\treturn ret;\n};\n\nExpr = Sizzle.selectors = {\n\n\t// Can be adjusted by the user\n\tcacheLength: 50,\n\n\tcreatePseudo: markFunction,\n\n\tmatch: matchExpr,\n\n\tattrHandle: {},\n\n\tfind: {},\n\n\trelative: {\n\t\t\">\": { dir: \"parentNode\", first: true },\n\t\t\" \": { dir: \"parentNode\" },\n\t\t\"+\": { dir: \"previousSibling\", first: true },\n\t\t\"~\": { dir: \"previousSibling\" }\n\t},\n\n\tpreFilter: {\n\t\t\"ATTR\": function( match ) {\n\t\t\tmatch[1] = match[1].replace( runescape, funescape );\n\n\t\t\t// Move the given value to match[3] whether quoted or unquoted\n\t\t\tmatch[3] = ( match[3] || match[4] || match[5] || \"\" ).replace( runescape, funescape );\n\n\t\t\tif ( match[2] === \"~=\" ) {\n\t\t\t\tmatch[3] = \" \" + match[3] + \" \";\n\t\t\t}\n\n\t\t\treturn match.slice( 0, 4 );\n\t\t},\n\n\t\t\"CHILD\": function( match ) {\n\t\t\t/* matches from matchExpr[\"CHILD\"]\n\t\t\t\t1 type (only|nth|...)\n\t\t\t\t2 what (child|of-type)\n\t\t\t\t3 argument (even|odd|\\d*|\\d*n([+-]\\d+)?|...)\n\t\t\t\t4 xn-component of xn+y argument ([+-]?\\d*n|)\n\t\t\t\t5 sign of xn-component\n\t\t\t\t6 x of xn-component\n\t\t\t\t7 sign of y-component\n\t\t\t\t8 y of y-component\n\t\t\t*/\n\t\t\tmatch[1] = match[1].toLowerCase();\n\n\t\t\tif ( match[1].slice( 0, 3 ) === \"nth\" ) {\n\t\t\t\t// nth-* requires argument\n\t\t\t\tif ( !match[3] ) {\n\t\t\t\t\tSizzle.error( match[0] );\n\t\t\t\t}\n\n\t\t\t\t// numeric x and y parameters for Expr.filter.CHILD\n\t\t\t\t// remember that false/true cast respectively to 0/1\n\t\t\t\tmatch[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === \"even\" || match[3] === \"odd\" ) );\n\t\t\t\tmatch[5] = +( ( match[7] + match[8] ) || match[3] === \"odd\" );\n\n\t\t\t// other types prohibit arguments\n\t\t\t} else if ( match[3] ) {\n\t\t\t\tSizzle.error( match[0] );\n\t\t\t}\n\n\t\t\treturn match;\n\t\t},\n\n\t\t\"PSEUDO\": function( match ) {\n\t\t\tvar excess,\n\t\t\t\tunquoted = !match[6] && match[2];\n\n\t\t\tif ( matchExpr[\"CHILD\"].test( match[0] ) ) {\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\t// Accept quoted arguments as-is\n\t\t\tif ( match[3] ) {\n\t\t\t\tmatch[2] = match[4] || match[5] || \"\";\n\n\t\t\t// Strip excess characters from unquoted arguments\n\t\t\t} else if ( unquoted && rpseudo.test( unquoted ) &&\n\t\t\t\t// Get excess from tokenize (recursively)\n\t\t\t\t(excess = tokenize( unquoted, true )) &&\n\t\t\t\t// advance to the next closing parenthesis\n\t\t\t\t(excess = unquoted.indexOf( \")\", unquoted.length - excess ) - unquoted.length) ) {\n\n\t\t\t\t// excess is a negative index\n\t\t\t\tmatch[0] = match[0].slice( 0, excess );\n\t\t\t\tmatch[2] = unquoted.slice( 0, excess );\n\t\t\t}\n\n\t\t\t// Return only captures needed by the pseudo filter method (type and argument)\n\t\t\treturn match.slice( 0, 3 );\n\t\t}\n\t},\n\n\tfilter: {\n\n\t\t\"TAG\": function( nodeNameSelector ) {\n\t\t\tvar nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();\n\t\t\treturn nodeNameSelector === \"*\" ?\n\t\t\t\tfunction() { return true; } :\n\t\t\t\tfunction( elem ) {\n\t\t\t\t\treturn elem.nodeName && elem.nodeName.toLowerCase() === nodeName;\n\t\t\t\t};\n\t\t},\n\n\t\t\"CLASS\": function( className ) {\n\t\t\tvar pattern = classCache[ className + \" \" ];\n\n\t\t\treturn pattern ||\n\t\t\t\t(pattern = new RegExp( \"(^|\" + whitespace + \")\" + className + \"(\" + whitespace + \"|$)\" )) &&\n\t\t\t\tclassCache( className, function( elem ) {\n\t\t\t\t\treturn pattern.test( typeof elem.className === \"string\" && elem.className || typeof elem.getAttribute !== \"undefined\" && elem.getAttribute(\"class\") || \"\" );\n\t\t\t\t});\n\t\t},\n\n\t\t\"ATTR\": function( name, operator, check ) {\n\t\t\treturn function( elem ) {\n\t\t\t\tvar result = Sizzle.attr( elem, name );\n\n\t\t\t\tif ( result == null ) {\n\t\t\t\t\treturn operator === \"!=\";\n\t\t\t\t}\n\t\t\t\tif ( !operator ) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\n\t\t\t\tresult += \"\";\n\n\t\t\t\treturn operator === \"=\" ? result === check :\n\t\t\t\t\toperator === \"!=\" ? result !== check :\n\t\t\t\t\toperator === \"^=\" ? check && result.indexOf( check ) === 0 :\n\t\t\t\t\toperator === \"*=\" ? check && result.indexOf( check ) > -1 :\n\t\t\t\t\toperator === \"$=\" ? check && result.slice( -check.length ) === check :\n\t\t\t\t\toperator === \"~=\" ? ( \" \" + result.replace( rwhitespace, \" \" ) + \" \" ).indexOf( check ) > -1 :\n\t\t\t\t\toperator === \"|=\" ? result === check || result.slice( 0, check.length + 1 ) === check + \"-\" :\n\t\t\t\t\tfalse;\n\t\t\t};\n\t\t},\n\n\t\t\"CHILD\": function( type, what, argument, first, last ) {\n\t\t\tvar simple = type.slice( 0, 3 ) !== \"nth\",\n\t\t\t\tforward = type.slice( -4 ) !== \"last\",\n\t\t\t\tofType = what === \"of-type\";\n\n\t\t\treturn first === 1 && last === 0 ?\n\n\t\t\t\t// Shortcut for :nth-*(n)\n\t\t\t\tfunction( elem ) {\n\t\t\t\t\treturn !!elem.parentNode;\n\t\t\t\t} :\n\n\t\t\t\tfunction( elem, context, xml ) {\n\t\t\t\t\tvar cache, uniqueCache, outerCache, node, nodeIndex, start,\n\t\t\t\t\t\tdir = simple !== forward ? \"nextSibling\" : \"previousSibling\",\n\t\t\t\t\t\tparent = elem.parentNode,\n\t\t\t\t\t\tname = ofType && elem.nodeName.toLowerCase(),\n\t\t\t\t\t\tuseCache = !xml && !ofType,\n\t\t\t\t\t\tdiff = false;\n\n\t\t\t\t\tif ( parent ) {\n\n\t\t\t\t\t\t// :(first|last|only)-(child|of-type)\n\t\t\t\t\t\tif ( simple ) {\n\t\t\t\t\t\t\twhile ( dir ) {\n\t\t\t\t\t\t\t\tnode = elem;\n\t\t\t\t\t\t\t\twhile ( (node = node[ dir ]) ) {\n\t\t\t\t\t\t\t\t\tif ( ofType ?\n\t\t\t\t\t\t\t\t\t\tnode.nodeName.toLowerCase() === name :\n\t\t\t\t\t\t\t\t\t\tnode.nodeType === 1 ) {\n\n\t\t\t\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t// Reverse direction for :only-* (if we haven't yet done so)\n\t\t\t\t\t\t\t\tstart = dir = type === \"only\" && !start && \"nextSibling\";\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tstart = [ forward ? parent.firstChild : parent.lastChild ];\n\n\t\t\t\t\t\t// non-xml :nth-child(...) stores cache data on `parent`\n\t\t\t\t\t\tif ( forward && useCache ) {\n\n\t\t\t\t\t\t\t// Seek `elem` from a previously-cached index\n\n\t\t\t\t\t\t\t// ...in a gzip-friendly way\n\t\t\t\t\t\t\tnode = parent;\n\t\t\t\t\t\t\touterCache = node[ expando ] || (node[ expando ] = {});\n\n\t\t\t\t\t\t\t// Support: IE <9 only\n\t\t\t\t\t\t\t// Defend against cloned attroperties (jQuery gh-1709)\n\t\t\t\t\t\t\tuniqueCache = outerCache[ node.uniqueID ] ||\n\t\t\t\t\t\t\t\t(outerCache[ node.uniqueID ] = {});\n\n\t\t\t\t\t\t\tcache = uniqueCache[ type ] || [];\n\t\t\t\t\t\t\tnodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];\n\t\t\t\t\t\t\tdiff = nodeIndex && cache[ 2 ];\n\t\t\t\t\t\t\tnode = nodeIndex && parent.childNodes[ nodeIndex ];\n\n\t\t\t\t\t\t\twhile ( (node = ++nodeIndex && node && node[ dir ] ||\n\n\t\t\t\t\t\t\t\t// Fallback to seeking `elem` from the start\n\t\t\t\t\t\t\t\t(diff = nodeIndex = 0) || start.pop()) ) {\n\n\t\t\t\t\t\t\t\t// When found, cache indexes on `parent` and break\n\t\t\t\t\t\t\t\tif ( node.nodeType === 1 && ++diff && node === elem ) {\n\t\t\t\t\t\t\t\t\tuniqueCache[ type ] = [ dirruns, nodeIndex, diff ];\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// Use previously-cached element index if available\n\t\t\t\t\t\t\tif ( useCache ) {\n\t\t\t\t\t\t\t\t// ...in a gzip-friendly way\n\t\t\t\t\t\t\t\tnode = elem;\n\t\t\t\t\t\t\t\touterCache = node[ expando ] || (node[ expando ] = {});\n\n\t\t\t\t\t\t\t\t// Support: IE <9 only\n\t\t\t\t\t\t\t\t// Defend against cloned attroperties (jQuery gh-1709)\n\t\t\t\t\t\t\t\tuniqueCache = outerCache[ node.uniqueID ] ||\n\t\t\t\t\t\t\t\t\t(outerCache[ node.uniqueID ] = {});\n\n\t\t\t\t\t\t\t\tcache = uniqueCache[ type ] || [];\n\t\t\t\t\t\t\t\tnodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];\n\t\t\t\t\t\t\t\tdiff = nodeIndex;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// xml :nth-child(...)\n\t\t\t\t\t\t\t// or :nth-last-child(...) or :nth(-last)?-of-type(...)\n\t\t\t\t\t\t\tif ( diff === false ) {\n\t\t\t\t\t\t\t\t// Use the same loop as above to seek `elem` from the start\n\t\t\t\t\t\t\t\twhile ( (node = ++nodeIndex && node && node[ dir ] ||\n\t\t\t\t\t\t\t\t\t(diff = nodeIndex = 0) || start.pop()) ) {\n\n\t\t\t\t\t\t\t\t\tif ( ( ofType ?\n\t\t\t\t\t\t\t\t\t\tnode.nodeName.toLowerCase() === name :\n\t\t\t\t\t\t\t\t\t\tnode.nodeType === 1 ) &&\n\t\t\t\t\t\t\t\t\t\t++diff ) {\n\n\t\t\t\t\t\t\t\t\t\t// Cache the index of each encountered element\n\t\t\t\t\t\t\t\t\t\tif ( useCache ) {\n\t\t\t\t\t\t\t\t\t\t\touterCache = node[ expando ] || (node[ expando ] = {});\n\n\t\t\t\t\t\t\t\t\t\t\t// Support: IE <9 only\n\t\t\t\t\t\t\t\t\t\t\t// Defend against cloned attroperties (jQuery gh-1709)\n\t\t\t\t\t\t\t\t\t\t\tuniqueCache = outerCache[ node.uniqueID ] ||\n\t\t\t\t\t\t\t\t\t\t\t\t(outerCache[ node.uniqueID ] = {});\n\n\t\t\t\t\t\t\t\t\t\t\tuniqueCache[ type ] = [ dirruns, diff ];\n\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\tif ( node === elem ) {\n\t\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Incorporate the offset, then check against cycle size\n\t\t\t\t\t\tdiff -= last;\n\t\t\t\t\t\treturn diff === first || ( diff % first === 0 && diff / first >= 0 );\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t},\n\n\t\t\"PSEUDO\": function( pseudo, argument ) {\n\t\t\t// pseudo-class names are case-insensitive\n\t\t\t// http://www.w3.org/TR/selectors/#pseudo-classes\n\t\t\t// Prioritize by case sensitivity in case custom pseudos are added with uppercase letters\n\t\t\t// Remember that setFilters inherits from pseudos\n\t\t\tvar args,\n\t\t\t\tfn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||\n\t\t\t\t\tSizzle.error( \"unsupported pseudo: \" + pseudo );\n\n\t\t\t// The user may use createPseudo to indicate that\n\t\t\t// arguments are needed to create the filter function\n\t\t\t// just as Sizzle does\n\t\t\tif ( fn[ expando ] ) {\n\t\t\t\treturn fn( argument );\n\t\t\t}\n\n\t\t\t// But maintain support for old signatures\n\t\t\tif ( fn.length > 1 ) {\n\t\t\t\targs = [ pseudo, pseudo, \"\", argument ];\n\t\t\t\treturn Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?\n\t\t\t\t\tmarkFunction(function( seed, matches ) {\n\t\t\t\t\t\tvar idx,\n\t\t\t\t\t\t\tmatched = fn( seed, argument ),\n\t\t\t\t\t\t\ti = matched.length;\n\t\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\t\tidx = indexOf( seed, matched[i] );\n\t\t\t\t\t\t\tseed[ idx ] = !( matches[ idx ] = matched[i] );\n\t\t\t\t\t\t}\n\t\t\t\t\t}) :\n\t\t\t\t\tfunction( elem ) {\n\t\t\t\t\t\treturn fn( elem, 0, args );\n\t\t\t\t\t};\n\t\t\t}\n\n\t\t\treturn fn;\n\t\t}\n\t},\n\n\tpseudos: {\n\t\t// Potentially complex pseudos\n\t\t\"not\": markFunction(function( selector ) {\n\t\t\t// Trim the selector passed to compile\n\t\t\t// to avoid treating leading and trailing\n\t\t\t// spaces as combinators\n\t\t\tvar input = [],\n\t\t\t\tresults = [],\n\t\t\t\tmatcher = compile( selector.replace( rtrim, \"$1\" ) );\n\n\t\t\treturn matcher[ expando ] ?\n\t\t\t\tmarkFunction(function( seed, matches, context, xml ) {\n\t\t\t\t\tvar elem,\n\t\t\t\t\t\tunmatched = matcher( seed, null, xml, [] ),\n\t\t\t\t\t\ti = seed.length;\n\n\t\t\t\t\t// Match elements unmatched by `matcher`\n\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\tif ( (elem = unmatched[i]) ) {\n\t\t\t\t\t\t\tseed[i] = !(matches[i] = elem);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}) :\n\t\t\t\tfunction( elem, context, xml ) {\n\t\t\t\t\tinput[0] = elem;\n\t\t\t\t\tmatcher( input, null, xml, results );\n\t\t\t\t\t// Don't keep the element (issue #299)\n\t\t\t\t\tinput[0] = null;\n\t\t\t\t\treturn !results.pop();\n\t\t\t\t};\n\t\t}),\n\n\t\t\"has\": markFunction(function( selector ) {\n\t\t\treturn function( elem ) {\n\t\t\t\treturn Sizzle( selector, elem ).length > 0;\n\t\t\t};\n\t\t}),\n\n\t\t\"contains\": markFunction(function( text ) {\n\t\t\ttext = text.replace( runescape, funescape );\n\t\t\treturn function( elem ) {\n\t\t\t\treturn ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;\n\t\t\t};\n\t\t}),\n\n\t\t// \"Whether an element is represented by a :lang() selector\n\t\t// is based solely on the element's language value\n\t\t// being equal to the identifier C,\n\t\t// or beginning with the identifier C immediately followed by \"-\".\n\t\t// The matching of C against the element's language value is performed case-insensitively.\n\t\t// The identifier C does not have to be a valid language name.\"\n\t\t// http://www.w3.org/TR/selectors/#lang-pseudo\n\t\t\"lang\": markFunction( function( lang ) {\n\t\t\t// lang value must be a valid identifier\n\t\t\tif ( !ridentifier.test(lang || \"\") ) {\n\t\t\t\tSizzle.error( \"unsupported lang: \" + lang );\n\t\t\t}\n\t\t\tlang = lang.replace( runescape, funescape ).toLowerCase();\n\t\t\treturn function( elem ) {\n\t\t\t\tvar elemLang;\n\t\t\t\tdo {\n\t\t\t\t\tif ( (elemLang = documentIsHTML ?\n\t\t\t\t\t\telem.lang :\n\t\t\t\t\t\telem.getAttribute(\"xml:lang\") || elem.getAttribute(\"lang\")) ) {\n\n\t\t\t\t\t\telemLang = elemLang.toLowerCase();\n\t\t\t\t\t\treturn elemLang === lang || elemLang.indexOf( lang + \"-\" ) === 0;\n\t\t\t\t\t}\n\t\t\t\t} while ( (elem = elem.parentNode) && elem.nodeType === 1 );\n\t\t\t\treturn false;\n\t\t\t};\n\t\t}),\n\n\t\t// Miscellaneous\n\t\t\"target\": function( elem ) {\n\t\t\tvar hash = window.location && window.location.hash;\n\t\t\treturn hash && hash.slice( 1 ) === elem.id;\n\t\t},\n\n\t\t\"root\": function( elem ) {\n\t\t\treturn elem === docElem;\n\t\t},\n\n\t\t\"focus\": function( elem ) {\n\t\t\treturn elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);\n\t\t},\n\n\t\t// Boolean properties\n\t\t\"enabled\": createDisabledPseudo( false ),\n\t\t\"disabled\": createDisabledPseudo( true ),\n\n\t\t\"checked\": function( elem ) {\n\t\t\t// In CSS3, :checked should return both checked and selected elements\n\t\t\t// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked\n\t\t\tvar nodeName = elem.nodeName.toLowerCase();\n\t\t\treturn (nodeName === \"input\" && !!elem.checked) || (nodeName === \"option\" && !!elem.selected);\n\t\t},\n\n\t\t\"selected\": function( elem ) {\n\t\t\t// Accessing this property makes selected-by-default\n\t\t\t// options in Safari work properly\n\t\t\tif ( elem.parentNode ) {\n\t\t\t\telem.parentNode.selectedIndex;\n\t\t\t}\n\n\t\t\treturn elem.selected === true;\n\t\t},\n\n\t\t// Contents\n\t\t\"empty\": function( elem ) {\n\t\t\t// http://www.w3.org/TR/selectors/#empty-pseudo\n\t\t\t// :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5),\n\t\t\t//   but not by others (comment: 8; processing instruction: 7; etc.)\n\t\t\t// nodeType < 6 works because attributes (2) do not appear as children\n\t\t\tfor ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {\n\t\t\t\tif ( elem.nodeType < 6 ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn true;\n\t\t},\n\n\t\t\"parent\": function( elem ) {\n\t\t\treturn !Expr.pseudos[\"empty\"]( elem );\n\t\t},\n\n\t\t// Element/input types\n\t\t\"header\": function( elem ) {\n\t\t\treturn rheader.test( elem.nodeName );\n\t\t},\n\n\t\t\"input\": function( elem ) {\n\t\t\treturn rinputs.test( elem.nodeName );\n\t\t},\n\n\t\t\"button\": function( elem ) {\n\t\t\tvar name = elem.nodeName.toLowerCase();\n\t\t\treturn name === \"input\" && elem.type === \"button\" || name === \"button\";\n\t\t},\n\n\t\t\"text\": function( elem ) {\n\t\t\tvar attr;\n\t\t\treturn elem.nodeName.toLowerCase() === \"input\" &&\n\t\t\t\telem.type === \"text\" &&\n\n\t\t\t\t// Support: IE<8\n\t\t\t\t// New HTML5 attribute values (e.g., \"search\") appear with elem.type === \"text\"\n\t\t\t\t( (attr = elem.getAttribute(\"type\")) == null || attr.toLowerCase() === \"text\" );\n\t\t},\n\n\t\t// Position-in-collection\n\t\t\"first\": createPositionalPseudo(function() {\n\t\t\treturn [ 0 ];\n\t\t}),\n\n\t\t\"last\": createPositionalPseudo(function( matchIndexes, length ) {\n\t\t\treturn [ length - 1 ];\n\t\t}),\n\n\t\t\"eq\": createPositionalPseudo(function( matchIndexes, length, argument ) {\n\t\t\treturn [ argument < 0 ? argument + length : argument ];\n\t\t}),\n\n\t\t\"even\": createPositionalPseudo(function( matchIndexes, length ) {\n\t\t\tvar i = 0;\n\t\t\tfor ( ; i < length; i += 2 ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t}),\n\n\t\t\"odd\": createPositionalPseudo(function( matchIndexes, length ) {\n\t\t\tvar i = 1;\n\t\t\tfor ( ; i < length; i += 2 ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t}),\n\n\t\t\"lt\": createPositionalPseudo(function( matchIndexes, length, argument ) {\n\t\t\tvar i = argument < 0 ? argument + length : argument;\n\t\t\tfor ( ; --i >= 0; ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t}),\n\n\t\t\"gt\": createPositionalPseudo(function( matchIndexes, length, argument ) {\n\t\t\tvar i = argument < 0 ? argument + length : argument;\n\t\t\tfor ( ; ++i < length; ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t})\n\t}\n};\n\nExpr.pseudos[\"nth\"] = Expr.pseudos[\"eq\"];\n\n// Add button/input type pseudos\nfor ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {\n\tExpr.pseudos[ i ] = createInputPseudo( i );\n}\nfor ( i in { submit: true, reset: true } ) {\n\tExpr.pseudos[ i ] = createButtonPseudo( i );\n}\n\n// Easy API for creating new setFilters\nfunction setFilters() {}\nsetFilters.prototype = Expr.filters = Expr.pseudos;\nExpr.setFilters = new setFilters();\n\ntokenize = Sizzle.tokenize = function( selector, parseOnly ) {\n\tvar matched, match, tokens, type,\n\t\tsoFar, groups, preFilters,\n\t\tcached = tokenCache[ selector + \" \" ];\n\n\tif ( cached ) {\n\t\treturn parseOnly ? 0 : cached.slice( 0 );\n\t}\n\n\tsoFar = selector;\n\tgroups = [];\n\tpreFilters = Expr.preFilter;\n\n\twhile ( soFar ) {\n\n\t\t// Comma and first run\n\t\tif ( !matched || (match = rcomma.exec( soFar )) ) {\n\t\t\tif ( match ) {\n\t\t\t\t// Don't consume trailing commas as valid\n\t\t\t\tsoFar = soFar.slice( match[0].length ) || soFar;\n\t\t\t}\n\t\t\tgroups.push( (tokens = []) );\n\t\t}\n\n\t\tmatched = false;\n\n\t\t// Combinators\n\t\tif ( (match = rcombinators.exec( soFar )) ) {\n\t\t\tmatched = match.shift();\n\t\t\ttokens.push({\n\t\t\t\tvalue: matched,\n\t\t\t\t// Cast descendant combinators to space\n\t\t\t\ttype: match[0].replace( rtrim, \" \" )\n\t\t\t});\n\t\t\tsoFar = soFar.slice( matched.length );\n\t\t}\n\n\t\t// Filters\n\t\tfor ( type in Expr.filter ) {\n\t\t\tif ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||\n\t\t\t\t(match = preFilters[ type ]( match ))) ) {\n\t\t\t\tmatched = match.shift();\n\t\t\t\ttokens.push({\n\t\t\t\t\tvalue: matched,\n\t\t\t\t\ttype: type,\n\t\t\t\t\tmatches: match\n\t\t\t\t});\n\t\t\t\tsoFar = soFar.slice( matched.length );\n\t\t\t}\n\t\t}\n\n\t\tif ( !matched ) {\n\t\t\tbreak;\n\t\t}\n\t}\n\n\t// Return the length of the invalid excess\n\t// if we're just parsing\n\t// Otherwise, throw an error or return tokens\n\treturn parseOnly ?\n\t\tsoFar.length :\n\t\tsoFar ?\n\t\t\tSizzle.error( selector ) :\n\t\t\t// Cache the tokens\n\t\t\ttokenCache( selector, groups ).slice( 0 );\n};\n\nfunction toSelector( tokens ) {\n\tvar i = 0,\n\t\tlen = tokens.length,\n\t\tselector = \"\";\n\tfor ( ; i < len; i++ ) {\n\t\tselector += tokens[i].value;\n\t}\n\treturn selector;\n}\n\nfunction addCombinator( matcher, combinator, base ) {\n\tvar dir = combinator.dir,\n\t\tskip = combinator.next,\n\t\tkey = skip || dir,\n\t\tcheckNonElements = base && key === \"parentNode\",\n\t\tdoneName = done++;\n\n\treturn combinator.first ?\n\t\t// Check against closest ancestor/preceding element\n\t\tfunction( elem, context, xml ) {\n\t\t\twhile ( (elem = elem[ dir ]) ) {\n\t\t\t\tif ( elem.nodeType === 1 || checkNonElements ) {\n\t\t\t\t\treturn matcher( elem, context, xml );\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t} :\n\n\t\t// Check against all ancestor/preceding elements\n\t\tfunction( elem, context, xml ) {\n\t\t\tvar oldCache, uniqueCache, outerCache,\n\t\t\t\tnewCache = [ dirruns, doneName ];\n\n\t\t\t// We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching\n\t\t\tif ( xml ) {\n\t\t\t\twhile ( (elem = elem[ dir ]) ) {\n\t\t\t\t\tif ( elem.nodeType === 1 || checkNonElements ) {\n\t\t\t\t\t\tif ( matcher( elem, context, xml ) ) {\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\twhile ( (elem = elem[ dir ]) ) {\n\t\t\t\t\tif ( elem.nodeType === 1 || checkNonElements ) {\n\t\t\t\t\t\touterCache = elem[ expando ] || (elem[ expando ] = {});\n\n\t\t\t\t\t\t// Support: IE <9 only\n\t\t\t\t\t\t// Defend against cloned attroperties (jQuery gh-1709)\n\t\t\t\t\t\tuniqueCache = outerCache[ elem.uniqueID ] || (outerCache[ elem.uniqueID ] = {});\n\n\t\t\t\t\t\tif ( skip && skip === elem.nodeName.toLowerCase() ) {\n\t\t\t\t\t\t\telem = elem[ dir ] || elem;\n\t\t\t\t\t\t} else if ( (oldCache = uniqueCache[ key ]) &&\n\t\t\t\t\t\t\toldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) {\n\n\t\t\t\t\t\t\t// Assign to newCache so results back-propagate to previous elements\n\t\t\t\t\t\t\treturn (newCache[ 2 ] = oldCache[ 2 ]);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// Reuse newcache so results back-propagate to previous elements\n\t\t\t\t\t\t\tuniqueCache[ key ] = newCache;\n\n\t\t\t\t\t\t\t// A match means we're done; a fail means we have to keep checking\n\t\t\t\t\t\t\tif ( (newCache[ 2 ] = matcher( elem, context, xml )) ) {\n\t\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t};\n}\n\nfunction elementMatcher( matchers ) {\n\treturn matchers.length > 1 ?\n\t\tfunction( elem, context, xml ) {\n\t\t\tvar i = matchers.length;\n\t\t\twhile ( i-- ) {\n\t\t\t\tif ( !matchers[i]( elem, context, xml ) ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn true;\n\t\t} :\n\t\tmatchers[0];\n}\n\nfunction multipleContexts( selector, contexts, results ) {\n\tvar i = 0,\n\t\tlen = contexts.length;\n\tfor ( ; i < len; i++ ) {\n\t\tSizzle( selector, contexts[i], results );\n\t}\n\treturn results;\n}\n\nfunction condense( unmatched, map, filter, context, xml ) {\n\tvar elem,\n\t\tnewUnmatched = [],\n\t\ti = 0,\n\t\tlen = unmatched.length,\n\t\tmapped = map != null;\n\n\tfor ( ; i < len; i++ ) {\n\t\tif ( (elem = unmatched[i]) ) {\n\t\t\tif ( !filter || filter( elem, context, xml ) ) {\n\t\t\t\tnewUnmatched.push( elem );\n\t\t\t\tif ( mapped ) {\n\t\t\t\t\tmap.push( i );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn newUnmatched;\n}\n\nfunction setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {\n\tif ( postFilter && !postFilter[ expando ] ) {\n\t\tpostFilter = setMatcher( postFilter );\n\t}\n\tif ( postFinder && !postFinder[ expando ] ) {\n\t\tpostFinder = setMatcher( postFinder, postSelector );\n\t}\n\treturn markFunction(function( seed, results, context, xml ) {\n\t\tvar temp, i, elem,\n\t\t\tpreMap = [],\n\t\t\tpostMap = [],\n\t\t\tpreexisting = results.length,\n\n\t\t\t// Get initial elements from seed or context\n\t\t\telems = seed || multipleContexts( selector || \"*\", context.nodeType ? [ context ] : context, [] ),\n\n\t\t\t// Prefilter to get matcher input, preserving a map for seed-results synchronization\n\t\t\tmatcherIn = preFilter && ( seed || !selector ) ?\n\t\t\t\tcondense( elems, preMap, preFilter, context, xml ) :\n\t\t\t\telems,\n\n\t\t\tmatcherOut = matcher ?\n\t\t\t\t// If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,\n\t\t\t\tpostFinder || ( seed ? preFilter : preexisting || postFilter ) ?\n\n\t\t\t\t\t// ...intermediate processing is necessary\n\t\t\t\t\t[] :\n\n\t\t\t\t\t// ...otherwise use results directly\n\t\t\t\t\tresults :\n\t\t\t\tmatcherIn;\n\n\t\t// Find primary matches\n\t\tif ( matcher ) {\n\t\t\tmatcher( matcherIn, matcherOut, context, xml );\n\t\t}\n\n\t\t// Apply postFilter\n\t\tif ( postFilter ) {\n\t\t\ttemp = condense( matcherOut, postMap );\n\t\t\tpostFilter( temp, [], context, xml );\n\n\t\t\t// Un-match failing elements by moving them back to matcherIn\n\t\t\ti = temp.length;\n\t\t\twhile ( i-- ) {\n\t\t\t\tif ( (elem = temp[i]) ) {\n\t\t\t\t\tmatcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif ( seed ) {\n\t\t\tif ( postFinder || preFilter ) {\n\t\t\t\tif ( postFinder ) {\n\t\t\t\t\t// Get the final matcherOut by condensing this intermediate into postFinder contexts\n\t\t\t\t\ttemp = [];\n\t\t\t\t\ti = matcherOut.length;\n\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\tif ( (elem = matcherOut[i]) ) {\n\t\t\t\t\t\t\t// Restore matcherIn since elem is not yet a final match\n\t\t\t\t\t\t\ttemp.push( (matcherIn[i] = elem) );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tpostFinder( null, (matcherOut = []), temp, xml );\n\t\t\t\t}\n\n\t\t\t\t// Move matched elements from seed to results to keep them synchronized\n\t\t\t\ti = matcherOut.length;\n\t\t\t\twhile ( i-- ) {\n\t\t\t\t\tif ( (elem = matcherOut[i]) &&\n\t\t\t\t\t\t(temp = postFinder ? indexOf( seed, elem ) : preMap[i]) > -1 ) {\n\n\t\t\t\t\t\tseed[temp] = !(results[temp] = elem);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t// Add elements to results, through postFinder if defined\n\t\t} else {\n\t\t\tmatcherOut = condense(\n\t\t\t\tmatcherOut === results ?\n\t\t\t\t\tmatcherOut.splice( preexisting, matcherOut.length ) :\n\t\t\t\t\tmatcherOut\n\t\t\t);\n\t\t\tif ( postFinder ) {\n\t\t\t\tpostFinder( null, results, matcherOut, xml );\n\t\t\t} else {\n\t\t\t\tpush.apply( results, matcherOut );\n\t\t\t}\n\t\t}\n\t});\n}\n\nfunction matcherFromTokens( tokens ) {\n\tvar checkContext, matcher, j,\n\t\tlen = tokens.length,\n\t\tleadingRelative = Expr.relative[ tokens[0].type ],\n\t\timplicitRelative = leadingRelative || Expr.relative[\" \"],\n\t\ti = leadingRelative ? 1 : 0,\n\n\t\t// The foundational matcher ensures that elements are reachable from top-level context(s)\n\t\tmatchContext = addCombinator( function( elem ) {\n\t\t\treturn elem === checkContext;\n\t\t}, implicitRelative, true ),\n\t\tmatchAnyContext = addCombinator( function( elem ) {\n\t\t\treturn indexOf( checkContext, elem ) > -1;\n\t\t}, implicitRelative, true ),\n\t\tmatchers = [ function( elem, context, xml ) {\n\t\t\tvar ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || (\n\t\t\t\t(checkContext = context).nodeType ?\n\t\t\t\t\tmatchContext( elem, context, xml ) :\n\t\t\t\t\tmatchAnyContext( elem, context, xml ) );\n\t\t\t// Avoid hanging onto element (issue #299)\n\t\t\tcheckContext = null;\n\t\t\treturn ret;\n\t\t} ];\n\n\tfor ( ; i < len; i++ ) {\n\t\tif ( (matcher = Expr.relative[ tokens[i].type ]) ) {\n\t\t\tmatchers = [ addCombinator(elementMatcher( matchers ), matcher) ];\n\t\t} else {\n\t\t\tmatcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches );\n\n\t\t\t// Return special upon seeing a positional matcher\n\t\t\tif ( matcher[ expando ] ) {\n\t\t\t\t// Find the next relative operator (if any) for proper handling\n\t\t\t\tj = ++i;\n\t\t\t\tfor ( ; j < len; j++ ) {\n\t\t\t\t\tif ( Expr.relative[ tokens[j].type ] ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn setMatcher(\n\t\t\t\t\ti > 1 && elementMatcher( matchers ),\n\t\t\t\t\ti > 1 && toSelector(\n\t\t\t\t\t\t// If the preceding token was a descendant combinator, insert an implicit any-element `*`\n\t\t\t\t\t\ttokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === \" \" ? \"*\" : \"\" })\n\t\t\t\t\t).replace( rtrim, \"$1\" ),\n\t\t\t\t\tmatcher,\n\t\t\t\t\ti < j && matcherFromTokens( tokens.slice( i, j ) ),\n\t\t\t\t\tj < len && matcherFromTokens( (tokens = tokens.slice( j )) ),\n\t\t\t\t\tj < len && toSelector( tokens )\n\t\t\t\t);\n\t\t\t}\n\t\t\tmatchers.push( matcher );\n\t\t}\n\t}\n\n\treturn elementMatcher( matchers );\n}\n\nfunction matcherFromGroupMatchers( elementMatchers, setMatchers ) {\n\tvar bySet = setMatchers.length > 0,\n\t\tbyElement = elementMatchers.length > 0,\n\t\tsuperMatcher = function( seed, context, xml, results, outermost ) {\n\t\t\tvar elem, j, matcher,\n\t\t\t\tmatchedCount = 0,\n\t\t\t\ti = \"0\",\n\t\t\t\tunmatched = seed && [],\n\t\t\t\tsetMatched = [],\n\t\t\t\tcontextBackup = outermostContext,\n\t\t\t\t// We must always have either seed elements or outermost context\n\t\t\t\telems = seed || byElement && Expr.find[\"TAG\"]( \"*\", outermost ),\n\t\t\t\t// Use integer dirruns iff this is the outermost matcher\n\t\t\t\tdirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1),\n\t\t\t\tlen = elems.length;\n\n\t\t\tif ( outermost ) {\n\t\t\t\toutermostContext = context === document || context || outermost;\n\t\t\t}\n\n\t\t\t// Add elements passing elementMatchers directly to results\n\t\t\t// Support: IE<9, Safari\n\t\t\t// Tolerate NodeList properties (IE: \"length\"; Safari: <number>) matching elements by id\n\t\t\tfor ( ; i !== len && (elem = elems[i]) != null; i++ ) {\n\t\t\t\tif ( byElement && elem ) {\n\t\t\t\t\tj = 0;\n\t\t\t\t\tif ( !context && elem.ownerDocument !== document ) {\n\t\t\t\t\t\tsetDocument( elem );\n\t\t\t\t\t\txml = !documentIsHTML;\n\t\t\t\t\t}\n\t\t\t\t\twhile ( (matcher = elementMatchers[j++]) ) {\n\t\t\t\t\t\tif ( matcher( elem, context || document, xml) ) {\n\t\t\t\t\t\t\tresults.push( elem );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif ( outermost ) {\n\t\t\t\t\t\tdirruns = dirrunsUnique;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Track unmatched elements for set filters\n\t\t\t\tif ( bySet ) {\n\t\t\t\t\t// They will have gone through all possible matchers\n\t\t\t\t\tif ( (elem = !matcher && elem) ) {\n\t\t\t\t\t\tmatchedCount--;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Lengthen the array for every element, matched or not\n\t\t\t\t\tif ( seed ) {\n\t\t\t\t\t\tunmatched.push( elem );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// `i` is now the count of elements visited above, and adding it to `matchedCount`\n\t\t\t// makes the latter nonnegative.\n\t\t\tmatchedCount += i;\n\n\t\t\t// Apply set filters to unmatched elements\n\t\t\t// NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount`\n\t\t\t// equals `i`), unless we didn't visit _any_ elements in the above loop because we have\n\t\t\t// no element matchers and no seed.\n\t\t\t// Incrementing an initially-string \"0\" `i` allows `i` to remain a string only in that\n\t\t\t// case, which will result in a \"00\" `matchedCount` that differs from `i` but is also\n\t\t\t// numerically zero.\n\t\t\tif ( bySet && i !== matchedCount ) {\n\t\t\t\tj = 0;\n\t\t\t\twhile ( (matcher = setMatchers[j++]) ) {\n\t\t\t\t\tmatcher( unmatched, setMatched, context, xml );\n\t\t\t\t}\n\n\t\t\t\tif ( seed ) {\n\t\t\t\t\t// Reintegrate element matches to eliminate the need for sorting\n\t\t\t\t\tif ( matchedCount > 0 ) {\n\t\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\t\tif ( !(unmatched[i] || setMatched[i]) ) {\n\t\t\t\t\t\t\t\tsetMatched[i] = pop.call( results );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Discard index placeholder values to get only actual matches\n\t\t\t\t\tsetMatched = condense( setMatched );\n\t\t\t\t}\n\n\t\t\t\t// Add matches to results\n\t\t\t\tpush.apply( results, setMatched );\n\n\t\t\t\t// Seedless set matches succeeding multiple successful matchers stipulate sorting\n\t\t\t\tif ( outermost && !seed && setMatched.length > 0 &&\n\t\t\t\t\t( matchedCount + setMatchers.length ) > 1 ) {\n\n\t\t\t\t\tSizzle.uniqueSort( results );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Override manipulation of globals by nested matchers\n\t\t\tif ( outermost ) {\n\t\t\t\tdirruns = dirrunsUnique;\n\t\t\t\toutermostContext = contextBackup;\n\t\t\t}\n\n\t\t\treturn unmatched;\n\t\t};\n\n\treturn bySet ?\n\t\tmarkFunction( superMatcher ) :\n\t\tsuperMatcher;\n}\n\ncompile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) {\n\tvar i,\n\t\tsetMatchers = [],\n\t\telementMatchers = [],\n\t\tcached = compilerCache[ selector + \" \" ];\n\n\tif ( !cached ) {\n\t\t// Generate a function of recursive functions that can be used to check each element\n\t\tif ( !match ) {\n\t\t\tmatch = tokenize( selector );\n\t\t}\n\t\ti = match.length;\n\t\twhile ( i-- ) {\n\t\t\tcached = matcherFromTokens( match[i] );\n\t\t\tif ( cached[ expando ] ) {\n\t\t\t\tsetMatchers.push( cached );\n\t\t\t} else {\n\t\t\t\telementMatchers.push( cached );\n\t\t\t}\n\t\t}\n\n\t\t// Cache the compiled function\n\t\tcached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) );\n\n\t\t// Save selector and tokenization\n\t\tcached.selector = selector;\n\t}\n\treturn cached;\n};\n\n/**\n * A low-level selection function that works with Sizzle's compiled\n *  selector functions\n * @param {String|Function} selector A selector or a pre-compiled\n *  selector function built with Sizzle.compile\n * @param {Element} context\n * @param {Array} [results]\n * @param {Array} [seed] A set of elements to match against\n */\nselect = Sizzle.select = function( selector, context, results, seed ) {\n\tvar i, tokens, token, type, find,\n\t\tcompiled = typeof selector === \"function\" && selector,\n\t\tmatch = !seed && tokenize( (selector = compiled.selector || selector) );\n\n\tresults = results || [];\n\n\t// Try to minimize operations if there is only one selector in the list and no seed\n\t// (the latter of which guarantees us context)\n\tif ( match.length === 1 ) {\n\n\t\t// Reduce context if the leading compound selector is an ID\n\t\ttokens = match[0] = match[0].slice( 0 );\n\t\tif ( tokens.length > 2 && (token = tokens[0]).type === \"ID\" &&\n\t\t\t\tcontext.nodeType === 9 && documentIsHTML && Expr.relative[ tokens[1].type ] ) {\n\n\t\t\tcontext = ( Expr.find[\"ID\"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0];\n\t\t\tif ( !context ) {\n\t\t\t\treturn results;\n\n\t\t\t// Precompiled matchers will still verify ancestry, so step up a level\n\t\t\t} else if ( compiled ) {\n\t\t\t\tcontext = context.parentNode;\n\t\t\t}\n\n\t\t\tselector = selector.slice( tokens.shift().value.length );\n\t\t}\n\n\t\t// Fetch a seed set for right-to-left matching\n\t\ti = matchExpr[\"needsContext\"].test( selector ) ? 0 : tokens.length;\n\t\twhile ( i-- ) {\n\t\t\ttoken = tokens[i];\n\n\t\t\t// Abort if we hit a combinator\n\t\t\tif ( Expr.relative[ (type = token.type) ] ) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif ( (find = Expr.find[ type ]) ) {\n\t\t\t\t// Search, expanding context for leading sibling combinators\n\t\t\t\tif ( (seed = find(\n\t\t\t\t\ttoken.matches[0].replace( runescape, funescape ),\n\t\t\t\t\trsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context\n\t\t\t\t)) ) {\n\n\t\t\t\t\t// If seed is empty or no tokens remain, we can return early\n\t\t\t\t\ttokens.splice( i, 1 );\n\t\t\t\t\tselector = seed.length && toSelector( tokens );\n\t\t\t\t\tif ( !selector ) {\n\t\t\t\t\t\tpush.apply( results, seed );\n\t\t\t\t\t\treturn results;\n\t\t\t\t\t}\n\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Compile and execute a filtering function if one is not provided\n\t// Provide `match` to avoid retokenization if we modified the selector above\n\t( compiled || compile( selector, match ) )(\n\t\tseed,\n\t\tcontext,\n\t\t!documentIsHTML,\n\t\tresults,\n\t\t!context || rsibling.test( selector ) && testContext( context.parentNode ) || context\n\t);\n\treturn results;\n};\n\n// One-time assignments\n\n// Sort stability\nsupport.sortStable = expando.split(\"\").sort( sortOrder ).join(\"\") === expando;\n\n// Support: Chrome 14-35+\n// Always assume duplicates if they aren't passed to the comparison function\nsupport.detectDuplicates = !!hasDuplicate;\n\n// Initialize against the default document\nsetDocument();\n\n// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)\n// Detached nodes confoundingly follow *each other*\nsupport.sortDetached = assert(function( el ) {\n\t// Should return 1, but returns 4 (following)\n\treturn el.compareDocumentPosition( document.createElement(\"fieldset\") ) & 1;\n});\n\n// Support: IE<8\n// Prevent attribute/property \"interpolation\"\n// https://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx\nif ( !assert(function( el ) {\n\tel.innerHTML = \"<a href='#'></a>\";\n\treturn el.firstChild.getAttribute(\"href\") === \"#\" ;\n}) ) {\n\taddHandle( \"type|href|height|width\", function( elem, name, isXML ) {\n\t\tif ( !isXML ) {\n\t\t\treturn elem.getAttribute( name, name.toLowerCase() === \"type\" ? 1 : 2 );\n\t\t}\n\t});\n}\n\n// Support: IE<9\n// Use defaultValue in place of getAttribute(\"value\")\nif ( !support.attributes || !assert(function( el ) {\n\tel.innerHTML = \"<input/>\";\n\tel.firstChild.setAttribute( \"value\", \"\" );\n\treturn el.firstChild.getAttribute( \"value\" ) === \"\";\n}) ) {\n\taddHandle( \"value\", function( elem, name, isXML ) {\n\t\tif ( !isXML && elem.nodeName.toLowerCase() === \"input\" ) {\n\t\t\treturn elem.defaultValue;\n\t\t}\n\t});\n}\n\n// Support: IE<9\n// Use getAttributeNode to fetch booleans when getAttribute lies\nif ( !assert(function( el ) {\n\treturn el.getAttribute(\"disabled\") == null;\n}) ) {\n\taddHandle( booleans, function( elem, name, isXML ) {\n\t\tvar val;\n\t\tif ( !isXML ) {\n\t\t\treturn elem[ name ] === true ? name.toLowerCase() :\n\t\t\t\t\t(val = elem.getAttributeNode( name )) && val.specified ?\n\t\t\t\t\tval.value :\n\t\t\t\tnull;\n\t\t}\n\t});\n}\n\nreturn Sizzle;\n\n})( window );\n\n\n\njQuery.find = Sizzle;\njQuery.expr = Sizzle.selectors;\n\n// Deprecated\njQuery.expr[ \":\" ] = jQuery.expr.pseudos;\njQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort;\njQuery.text = Sizzle.getText;\njQuery.isXMLDoc = Sizzle.isXML;\njQuery.contains = Sizzle.contains;\njQuery.escapeSelector = Sizzle.escape;\n\n\n\n\nvar dir = function( elem, dir, until ) {\n\tvar matched = [],\n\t\ttruncate = until !== undefined;\n\n\twhile ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) {\n\t\tif ( elem.nodeType === 1 ) {\n\t\t\tif ( truncate && jQuery( elem ).is( until ) ) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tmatched.push( elem );\n\t\t}\n\t}\n\treturn matched;\n};\n\n\nvar siblings = function( n, elem ) {\n\tvar matched = [];\n\n\tfor ( ; n; n = n.nextSibling ) {\n\t\tif ( n.nodeType === 1 && n !== elem ) {\n\t\t\tmatched.push( n );\n\t\t}\n\t}\n\n\treturn matched;\n};\n\n\nvar rneedsContext = jQuery.expr.match.needsContext;\n\n\n\nfunction nodeName( elem, name ) {\n\n  return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();\n\n};\nvar rsingleTag = ( /^<([a-z][^\\/\\0>:\\x20\\t\\r\\n\\f]*)[\\x20\\t\\r\\n\\f]*\\/?>(?:<\\/\\1>|)$/i );\n\n\n\n// Implement the identical functionality for filter and not\nfunction winnow( elements, qualifier, not ) {\n\tif ( isFunction( qualifier ) ) {\n\t\treturn jQuery.grep( elements, function( elem, i ) {\n\t\t\treturn !!qualifier.call( elem, i, elem ) !== not;\n\t\t} );\n\t}\n\n\t// Single element\n\tif ( qualifier.nodeType ) {\n\t\treturn jQuery.grep( elements, function( elem ) {\n\t\t\treturn ( elem === qualifier ) !== not;\n\t\t} );\n\t}\n\n\t// Arraylike of elements (jQuery, arguments, Array)\n\tif ( typeof qualifier !== \"string\" ) {\n\t\treturn jQuery.grep( elements, function( elem ) {\n\t\t\treturn ( indexOf.call( qualifier, elem ) > -1 ) !== not;\n\t\t} );\n\t}\n\n\t// Filtered directly for both simple and complex selectors\n\treturn jQuery.filter( qualifier, elements, not );\n}\n\njQuery.filter = function( expr, elems, not ) {\n\tvar elem = elems[ 0 ];\n\n\tif ( not ) {\n\t\texpr = \":not(\" + expr + \")\";\n\t}\n\n\tif ( elems.length === 1 && elem.nodeType === 1 ) {\n\t\treturn jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [];\n\t}\n\n\treturn jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {\n\t\treturn elem.nodeType === 1;\n\t} ) );\n};\n\njQuery.fn.extend( {\n\tfind: function( selector ) {\n\t\tvar i, ret,\n\t\t\tlen = this.length,\n\t\t\tself = this;\n\n\t\tif ( typeof selector !== \"string\" ) {\n\t\t\treturn this.pushStack( jQuery( selector ).filter( function() {\n\t\t\t\tfor ( i = 0; i < len; i++ ) {\n\t\t\t\t\tif ( jQuery.contains( self[ i ], this ) ) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} ) );\n\t\t}\n\n\t\tret = this.pushStack( [] );\n\n\t\tfor ( i = 0; i < len; i++ ) {\n\t\t\tjQuery.find( selector, self[ i ], ret );\n\t\t}\n\n\t\treturn len > 1 ? jQuery.uniqueSort( ret ) : ret;\n\t},\n\tfilter: function( selector ) {\n\t\treturn this.pushStack( winnow( this, selector || [], false ) );\n\t},\n\tnot: function( selector ) {\n\t\treturn this.pushStack( winnow( this, selector || [], true ) );\n\t},\n\tis: function( selector ) {\n\t\treturn !!winnow(\n\t\t\tthis,\n\n\t\t\t// If this is a positional/relative selector, check membership in the returned set\n\t\t\t// so $(\"p:first\").is(\"p:last\") won't return true for a doc with two \"p\".\n\t\t\ttypeof selector === \"string\" && rneedsContext.test( selector ) ?\n\t\t\t\tjQuery( selector ) :\n\t\t\t\tselector || [],\n\t\t\tfalse\n\t\t).length;\n\t}\n} );\n\n\n// Initialize a jQuery object\n\n\n// A central reference to the root jQuery(document)\nvar rootjQuery,\n\n\t// A simple way to check for HTML strings\n\t// Prioritize #id over <tag> to avoid XSS via location.hash (#9521)\n\t// Strict HTML recognition (#11290: must start with <)\n\t// Shortcut simple #id case for speed\n\trquickExpr = /^(?:\\s*(<[\\w\\W]+>)[^>]*|#([\\w-]+))$/,\n\n\tinit = jQuery.fn.init = function( selector, context, root ) {\n\t\tvar match, elem;\n\n\t\t// HANDLE: $(\"\"), $(null), $(undefined), $(false)\n\t\tif ( !selector ) {\n\t\t\treturn this;\n\t\t}\n\n\t\t// Method init() accepts an alternate rootjQuery\n\t\t// so migrate can support jQuery.sub (gh-2101)\n\t\troot = root || rootjQuery;\n\n\t\t// Handle HTML strings\n\t\tif ( typeof selector === \"string\" ) {\n\t\t\tif ( selector[ 0 ] === \"<\" &&\n\t\t\t\tselector[ selector.length - 1 ] === \">\" &&\n\t\t\t\tselector.length >= 3 ) {\n\n\t\t\t\t// Assume that strings that start and end with <> are HTML and skip the regex check\n\t\t\t\tmatch = [ null, selector, null ];\n\n\t\t\t} else {\n\t\t\t\tmatch = rquickExpr.exec( selector );\n\t\t\t}\n\n\t\t\t// Match html or make sure no context is specified for #id\n\t\t\tif ( match && ( match[ 1 ] || !context ) ) {\n\n\t\t\t\t// HANDLE: $(html) -> $(array)\n\t\t\t\tif ( match[ 1 ] ) {\n\t\t\t\t\tcontext = context instanceof jQuery ? context[ 0 ] : context;\n\n\t\t\t\t\t// Option to run scripts is true for back-compat\n\t\t\t\t\t// Intentionally let the error be thrown if parseHTML is not present\n\t\t\t\t\tjQuery.merge( this, jQuery.parseHTML(\n\t\t\t\t\t\tmatch[ 1 ],\n\t\t\t\t\t\tcontext && context.nodeType ? context.ownerDocument || context : document,\n\t\t\t\t\t\ttrue\n\t\t\t\t\t) );\n\n\t\t\t\t\t// HANDLE: $(html, props)\n\t\t\t\t\tif ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) {\n\t\t\t\t\t\tfor ( match in context ) {\n\n\t\t\t\t\t\t\t// Properties of context are called as methods if possible\n\t\t\t\t\t\t\tif ( isFunction( this[ match ] ) ) {\n\t\t\t\t\t\t\t\tthis[ match ]( context[ match ] );\n\n\t\t\t\t\t\t\t// ...and otherwise set as attributes\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tthis.attr( match, context[ match ] );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\treturn this;\n\n\t\t\t\t// HANDLE: $(#id)\n\t\t\t\t} else {\n\t\t\t\t\telem = document.getElementById( match[ 2 ] );\n\n\t\t\t\t\tif ( elem ) {\n\n\t\t\t\t\t\t// Inject the element directly into the jQuery object\n\t\t\t\t\t\tthis[ 0 ] = elem;\n\t\t\t\t\t\tthis.length = 1;\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t}\n\n\t\t\t// HANDLE: $(expr, $(...))\n\t\t\t} else if ( !context || context.jquery ) {\n\t\t\t\treturn ( context || root ).find( selector );\n\n\t\t\t// HANDLE: $(expr, context)\n\t\t\t// (which is just equivalent to: $(context).find(expr)\n\t\t\t} else {\n\t\t\t\treturn this.constructor( context ).find( selector );\n\t\t\t}\n\n\t\t// HANDLE: $(DOMElement)\n\t\t} else if ( selector.nodeType ) {\n\t\t\tthis[ 0 ] = selector;\n\t\t\tthis.length = 1;\n\t\t\treturn this;\n\n\t\t// HANDLE: $(function)\n\t\t// Shortcut for document ready\n\t\t} else if ( isFunction( selector ) ) {\n\t\t\treturn root.ready !== undefined ?\n\t\t\t\troot.ready( selector ) :\n\n\t\t\t\t// Execute immediately if ready is not present\n\t\t\t\tselector( jQuery );\n\t\t}\n\n\t\treturn jQuery.makeArray( selector, this );\n\t};\n\n// Give the init function the jQuery prototype for later instantiation\ninit.prototype = jQuery.fn;\n\n// Initialize central reference\nrootjQuery = jQuery( document );\n\n\nvar rparentsprev = /^(?:parents|prev(?:Until|All))/,\n\n\t// Methods guaranteed to produce a unique set when starting from a unique set\n\tguaranteedUnique = {\n\t\tchildren: true,\n\t\tcontents: true,\n\t\tnext: true,\n\t\tprev: true\n\t};\n\njQuery.fn.extend( {\n\thas: function( target ) {\n\t\tvar targets = jQuery( target, this ),\n\t\t\tl = targets.length;\n\n\t\treturn this.filter( function() {\n\t\t\tvar i = 0;\n\t\t\tfor ( ; i < l; i++ ) {\n\t\t\t\tif ( jQuery.contains( this, targets[ i ] ) ) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\t},\n\n\tclosest: function( selectors, context ) {\n\t\tvar cur,\n\t\t\ti = 0,\n\t\t\tl = this.length,\n\t\t\tmatched = [],\n\t\t\ttargets = typeof selectors !== \"string\" && jQuery( selectors );\n\n\t\t// Positional selectors never match, since there's no _selection_ context\n\t\tif ( !rneedsContext.test( selectors ) ) {\n\t\t\tfor ( ; i < l; i++ ) {\n\t\t\t\tfor ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) {\n\n\t\t\t\t\t// Always skip document fragments\n\t\t\t\t\tif ( cur.nodeType < 11 && ( targets ?\n\t\t\t\t\t\ttargets.index( cur ) > -1 :\n\n\t\t\t\t\t\t// Don't pass non-elements to Sizzle\n\t\t\t\t\t\tcur.nodeType === 1 &&\n\t\t\t\t\t\t\tjQuery.find.matchesSelector( cur, selectors ) ) ) {\n\n\t\t\t\t\t\tmatched.push( cur );\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched );\n\t},\n\n\t// Determine the position of an element within the set\n\tindex: function( elem ) {\n\n\t\t// No argument, return index in parent\n\t\tif ( !elem ) {\n\t\t\treturn ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1;\n\t\t}\n\n\t\t// Index in selector\n\t\tif ( typeof elem === \"string\" ) {\n\t\t\treturn indexOf.call( jQuery( elem ), this[ 0 ] );\n\t\t}\n\n\t\t// Locate the position of the desired element\n\t\treturn indexOf.call( this,\n\n\t\t\t// If it receives a jQuery object, the first element is used\n\t\t\telem.jquery ? elem[ 0 ] : elem\n\t\t);\n\t},\n\n\tadd: function( selector, context ) {\n\t\treturn this.pushStack(\n\t\t\tjQuery.uniqueSort(\n\t\t\t\tjQuery.merge( this.get(), jQuery( selector, context ) )\n\t\t\t)\n\t\t);\n\t},\n\n\taddBack: function( selector ) {\n\t\treturn this.add( selector == null ?\n\t\t\tthis.prevObject : this.prevObject.filter( selector )\n\t\t);\n\t}\n} );\n\nfunction sibling( cur, dir ) {\n\twhile ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {}\n\treturn cur;\n}\n\njQuery.each( {\n\tparent: function( elem ) {\n\t\tvar parent = elem.parentNode;\n\t\treturn parent && parent.nodeType !== 11 ? parent : null;\n\t},\n\tparents: function( elem ) {\n\t\treturn dir( elem, \"parentNode\" );\n\t},\n\tparentsUntil: function( elem, i, until ) {\n\t\treturn dir( elem, \"parentNode\", until );\n\t},\n\tnext: function( elem ) {\n\t\treturn sibling( elem, \"nextSibling\" );\n\t},\n\tprev: function( elem ) {\n\t\treturn sibling( elem, \"previousSibling\" );\n\t},\n\tnextAll: function( elem ) {\n\t\treturn dir( elem, \"nextSibling\" );\n\t},\n\tprevAll: function( elem ) {\n\t\treturn dir( elem, \"previousSibling\" );\n\t},\n\tnextUntil: function( elem, i, until ) {\n\t\treturn dir( elem, \"nextSibling\", until );\n\t},\n\tprevUntil: function( elem, i, until ) {\n\t\treturn dir( elem, \"previousSibling\", until );\n\t},\n\tsiblings: function( elem ) {\n\t\treturn siblings( ( elem.parentNode || {} ).firstChild, elem );\n\t},\n\tchildren: function( elem ) {\n\t\treturn siblings( elem.firstChild );\n\t},\n\tcontents: function( elem ) {\n        if ( nodeName( elem, \"iframe\" ) ) {\n            return elem.contentDocument;\n        }\n\n        // Support: IE 9 - 11 only, iOS 7 only, Android Browser <=4.3 only\n        // Treat the template element as a regular one in browsers that\n        // don't support it.\n        if ( nodeName( elem, \"template\" ) ) {\n            elem = elem.content || elem;\n        }\n\n        return jQuery.merge( [], elem.childNodes );\n\t}\n}, function( name, fn ) {\n\tjQuery.fn[ name ] = function( until, selector ) {\n\t\tvar matched = jQuery.map( this, fn, until );\n\n\t\tif ( name.slice( -5 ) !== \"Until\" ) {\n\t\t\tselector = until;\n\t\t}\n\n\t\tif ( selector && typeof selector === \"string\" ) {\n\t\t\tmatched = jQuery.filter( selector, matched );\n\t\t}\n\n\t\tif ( this.length > 1 ) {\n\n\t\t\t// Remove duplicates\n\t\t\tif ( !guaranteedUnique[ name ] ) {\n\t\t\t\tjQuery.uniqueSort( matched );\n\t\t\t}\n\n\t\t\t// Reverse order for parents* and prev-derivatives\n\t\t\tif ( rparentsprev.test( name ) ) {\n\t\t\t\tmatched.reverse();\n\t\t\t}\n\t\t}\n\n\t\treturn this.pushStack( matched );\n\t};\n} );\nvar rnothtmlwhite = ( /[^\\x20\\t\\r\\n\\f]+/g );\n\n\n\n// Convert String-formatted options into Object-formatted ones\nfunction createOptions( options ) {\n\tvar object = {};\n\tjQuery.each( options.match( rnothtmlwhite ) || [], function( _, flag ) {\n\t\tobject[ flag ] = true;\n\t} );\n\treturn object;\n}\n\n/*\n * Create a callback list using the following parameters:\n *\n *\toptions: an optional list of space-separated options that will change how\n *\t\t\tthe callback list behaves or a more traditional option object\n *\n * By default a callback list will act like an event callback list and can be\n * \"fired\" multiple times.\n *\n * Possible options:\n *\n *\tonce:\t\t\twill ensure the callback list can only be fired once (like a Deferred)\n *\n *\tmemory:\t\t\twill keep track of previous values and will call any callback added\n *\t\t\t\t\tafter the list has been fired right away with the latest \"memorized\"\n *\t\t\t\t\tvalues (like a Deferred)\n *\n *\tunique:\t\t\twill ensure a callback can only be added once (no duplicate in the list)\n *\n *\tstopOnFalse:\tinterrupt callings when a callback returns false\n *\n */\njQuery.Callbacks = function( options ) {\n\n\t// Convert options from String-formatted to Object-formatted if needed\n\t// (we check in cache first)\n\toptions = typeof options === \"string\" ?\n\t\tcreateOptions( options ) :\n\t\tjQuery.extend( {}, options );\n\n\tvar // Flag to know if list is currently firing\n\t\tfiring,\n\n\t\t// Last fire value for non-forgettable lists\n\t\tmemory,\n\n\t\t// Flag to know if list was already fired\n\t\tfired,\n\n\t\t// Flag to prevent firing\n\t\tlocked,\n\n\t\t// Actual callback list\n\t\tlist = [],\n\n\t\t// Queue of execution data for repeatable lists\n\t\tqueue = [],\n\n\t\t// Index of currently firing callback (modified by add/remove as needed)\n\t\tfiringIndex = -1,\n\n\t\t// Fire callbacks\n\t\tfire = function() {\n\n\t\t\t// Enforce single-firing\n\t\t\tlocked = locked || options.once;\n\n\t\t\t// Execute callbacks for all pending executions,\n\t\t\t// respecting firingIndex overrides and runtime changes\n\t\t\tfired = firing = true;\n\t\t\tfor ( ; queue.length; firingIndex = -1 ) {\n\t\t\t\tmemory = queue.shift();\n\t\t\t\twhile ( ++firingIndex < list.length ) {\n\n\t\t\t\t\t// Run callback and check for early termination\n\t\t\t\t\tif ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false &&\n\t\t\t\t\t\toptions.stopOnFalse ) {\n\n\t\t\t\t\t\t// Jump to end and forget the data so .add doesn't re-fire\n\t\t\t\t\t\tfiringIndex = list.length;\n\t\t\t\t\t\tmemory = false;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Forget the data if we're done with it\n\t\t\tif ( !options.memory ) {\n\t\t\t\tmemory = false;\n\t\t\t}\n\n\t\t\tfiring = false;\n\n\t\t\t// Clean up if we're done firing for good\n\t\t\tif ( locked ) {\n\n\t\t\t\t// Keep an empty list if we have data for future add calls\n\t\t\t\tif ( memory ) {\n\t\t\t\t\tlist = [];\n\n\t\t\t\t// Otherwise, this object is spent\n\t\t\t\t} else {\n\t\t\t\t\tlist = \"\";\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\t// Actual Callbacks object\n\t\tself = {\n\n\t\t\t// Add a callback or a collection of callbacks to the list\n\t\t\tadd: function() {\n\t\t\t\tif ( list ) {\n\n\t\t\t\t\t// If we have memory from a past run, we should fire after adding\n\t\t\t\t\tif ( memory && !firing ) {\n\t\t\t\t\t\tfiringIndex = list.length - 1;\n\t\t\t\t\t\tqueue.push( memory );\n\t\t\t\t\t}\n\n\t\t\t\t\t( function add( args ) {\n\t\t\t\t\t\tjQuery.each( args, function( _, arg ) {\n\t\t\t\t\t\t\tif ( isFunction( arg ) ) {\n\t\t\t\t\t\t\t\tif ( !options.unique || !self.has( arg ) ) {\n\t\t\t\t\t\t\t\t\tlist.push( arg );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else if ( arg && arg.length && toType( arg ) !== \"string\" ) {\n\n\t\t\t\t\t\t\t\t// Inspect recursively\n\t\t\t\t\t\t\t\tadd( arg );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} );\n\t\t\t\t\t} )( arguments );\n\n\t\t\t\t\tif ( memory && !firing ) {\n\t\t\t\t\t\tfire();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\n\t\t\t// Remove a callback from the list\n\t\t\tremove: function() {\n\t\t\t\tjQuery.each( arguments, function( _, arg ) {\n\t\t\t\t\tvar index;\n\t\t\t\t\twhile ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {\n\t\t\t\t\t\tlist.splice( index, 1 );\n\n\t\t\t\t\t\t// Handle firing indexes\n\t\t\t\t\t\tif ( index <= firingIndex ) {\n\t\t\t\t\t\t\tfiringIndex--;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} );\n\t\t\t\treturn this;\n\t\t\t},\n\n\t\t\t// Check if a given callback is in the list.\n\t\t\t// If no argument is given, return whether or not list has callbacks attached.\n\t\t\thas: function( fn ) {\n\t\t\t\treturn fn ?\n\t\t\t\t\tjQuery.inArray( fn, list ) > -1 :\n\t\t\t\t\tlist.length > 0;\n\t\t\t},\n\n\t\t\t// Remove all callbacks from the list\n\t\t\tempty: function() {\n\t\t\t\tif ( list ) {\n\t\t\t\t\tlist = [];\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\n\t\t\t// Disable .fire and .add\n\t\t\t// Abort any current/pending executions\n\t\t\t// Clear all callbacks and values\n\t\t\tdisable: function() {\n\t\t\t\tlocked = queue = [];\n\t\t\t\tlist = memory = \"\";\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\tdisabled: function() {\n\t\t\t\treturn !list;\n\t\t\t},\n\n\t\t\t// Disable .fire\n\t\t\t// Also disable .add unless we have memory (since it would have no effect)\n\t\t\t// Abort any pending executions\n\t\t\tlock: function() {\n\t\t\t\tlocked = queue = [];\n\t\t\t\tif ( !memory && !firing ) {\n\t\t\t\t\tlist = memory = \"\";\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\tlocked: function() {\n\t\t\t\treturn !!locked;\n\t\t\t},\n\n\t\t\t// Call all callbacks with the given context and arguments\n\t\t\tfireWith: function( context, args ) {\n\t\t\t\tif ( !locked ) {\n\t\t\t\t\targs = args || [];\n\t\t\t\t\targs = [ context, args.slice ? args.slice() : args ];\n\t\t\t\t\tqueue.push( args );\n\t\t\t\t\tif ( !firing ) {\n\t\t\t\t\t\tfire();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\n\t\t\t// Call all the callbacks with the given arguments\n\t\t\tfire: function() {\n\t\t\t\tself.fireWith( this, arguments );\n\t\t\t\treturn this;\n\t\t\t},\n\n\t\t\t// To know if the callbacks have already been called at least once\n\t\t\tfired: function() {\n\t\t\t\treturn !!fired;\n\t\t\t}\n\t\t};\n\n\treturn self;\n};\n\n\nfunction Identity( v ) {\n\treturn v;\n}\nfunction Thrower( ex ) {\n\tthrow ex;\n}\n\nfunction adoptValue( value, resolve, reject, noValue ) {\n\tvar method;\n\n\ttry {\n\n\t\t// Check for promise aspect first to privilege synchronous behavior\n\t\tif ( value && isFunction( ( method = value.promise ) ) ) {\n\t\t\tmethod.call( value ).done( resolve ).fail( reject );\n\n\t\t// Other thenables\n\t\t} else if ( value && isFunction( ( method = value.then ) ) ) {\n\t\t\tmethod.call( value, resolve, reject );\n\n\t\t// Other non-thenables\n\t\t} else {\n\n\t\t\t// Control `resolve` arguments by letting Array#slice cast boolean `noValue` to integer:\n\t\t\t// * false: [ value ].slice( 0 ) => resolve( value )\n\t\t\t// * true: [ value ].slice( 1 ) => resolve()\n\t\t\tresolve.apply( undefined, [ value ].slice( noValue ) );\n\t\t}\n\n\t// For Promises/A+, convert exceptions into rejections\n\t// Since jQuery.when doesn't unwrap thenables, we can skip the extra checks appearing in\n\t// Deferred#then to conditionally suppress rejection.\n\t} catch ( value ) {\n\n\t\t// Support: Android 4.0 only\n\t\t// Strict mode functions invoked without .call/.apply get global-object context\n\t\treject.apply( undefined, [ value ] );\n\t}\n}\n\njQuery.extend( {\n\n\tDeferred: function( func ) {\n\t\tvar tuples = [\n\n\t\t\t\t// action, add listener, callbacks,\n\t\t\t\t// ... .then handlers, argument index, [final state]\n\t\t\t\t[ \"notify\", \"progress\", jQuery.Callbacks( \"memory\" ),\n\t\t\t\t\tjQuery.Callbacks( \"memory\" ), 2 ],\n\t\t\t\t[ \"resolve\", \"done\", jQuery.Callbacks( \"once memory\" ),\n\t\t\t\t\tjQuery.Callbacks( \"once memory\" ), 0, \"resolved\" ],\n\t\t\t\t[ \"reject\", \"fail\", jQuery.Callbacks( \"once memory\" ),\n\t\t\t\t\tjQuery.Callbacks( \"once memory\" ), 1, \"rejected\" ]\n\t\t\t],\n\t\t\tstate = \"pending\",\n\t\t\tpromise = {\n\t\t\t\tstate: function() {\n\t\t\t\t\treturn state;\n\t\t\t\t},\n\t\t\t\talways: function() {\n\t\t\t\t\tdeferred.done( arguments ).fail( arguments );\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\t\t\t\t\"catch\": function( fn ) {\n\t\t\t\t\treturn promise.then( null, fn );\n\t\t\t\t},\n\n\t\t\t\t// Keep pipe for back-compat\n\t\t\t\tpipe: function( /* fnDone, fnFail, fnProgress */ ) {\n\t\t\t\t\tvar fns = arguments;\n\n\t\t\t\t\treturn jQuery.Deferred( function( newDefer ) {\n\t\t\t\t\t\tjQuery.each( tuples, function( i, tuple ) {\n\n\t\t\t\t\t\t\t// Map tuples (progress, done, fail) to arguments (done, fail, progress)\n\t\t\t\t\t\t\tvar fn = isFunction( fns[ tuple[ 4 ] ] ) && fns[ tuple[ 4 ] ];\n\n\t\t\t\t\t\t\t// deferred.progress(function() { bind to newDefer or newDefer.notify })\n\t\t\t\t\t\t\t// deferred.done(function() { bind to newDefer or newDefer.resolve })\n\t\t\t\t\t\t\t// deferred.fail(function() { bind to newDefer or newDefer.reject })\n\t\t\t\t\t\t\tdeferred[ tuple[ 1 ] ]( function() {\n\t\t\t\t\t\t\t\tvar returned = fn && fn.apply( this, arguments );\n\t\t\t\t\t\t\t\tif ( returned && isFunction( returned.promise ) ) {\n\t\t\t\t\t\t\t\t\treturned.promise()\n\t\t\t\t\t\t\t\t\t\t.progress( newDefer.notify )\n\t\t\t\t\t\t\t\t\t\t.done( newDefer.resolve )\n\t\t\t\t\t\t\t\t\t\t.fail( newDefer.reject );\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tnewDefer[ tuple[ 0 ] + \"With\" ](\n\t\t\t\t\t\t\t\t\t\tthis,\n\t\t\t\t\t\t\t\t\t\tfn ? [ returned ] : arguments\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} );\n\t\t\t\t\t\t} );\n\t\t\t\t\t\tfns = null;\n\t\t\t\t\t} ).promise();\n\t\t\t\t},\n\t\t\t\tthen: function( onFulfilled, onRejected, onProgress ) {\n\t\t\t\t\tvar maxDepth = 0;\n\t\t\t\t\tfunction resolve( depth, deferred, handler, special ) {\n\t\t\t\t\t\treturn function() {\n\t\t\t\t\t\t\tvar that = this,\n\t\t\t\t\t\t\t\targs = arguments,\n\t\t\t\t\t\t\t\tmightThrow = function() {\n\t\t\t\t\t\t\t\t\tvar returned, then;\n\n\t\t\t\t\t\t\t\t\t// Support: Promises/A+ section 2.3.3.3.3\n\t\t\t\t\t\t\t\t\t// https://promisesaplus.com/#point-59\n\t\t\t\t\t\t\t\t\t// Ignore double-resolution attempts\n\t\t\t\t\t\t\t\t\tif ( depth < maxDepth ) {\n\t\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\treturned = handler.apply( that, args );\n\n\t\t\t\t\t\t\t\t\t// Support: Promises/A+ section 2.3.1\n\t\t\t\t\t\t\t\t\t// https://promisesaplus.com/#point-48\n\t\t\t\t\t\t\t\t\tif ( returned === deferred.promise() ) {\n\t\t\t\t\t\t\t\t\t\tthrow new TypeError( \"Thenable self-resolution\" );\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t// Support: Promises/A+ sections 2.3.3.1, 3.5\n\t\t\t\t\t\t\t\t\t// https://promisesaplus.com/#point-54\n\t\t\t\t\t\t\t\t\t// https://promisesaplus.com/#point-75\n\t\t\t\t\t\t\t\t\t// Retrieve `then` only once\n\t\t\t\t\t\t\t\t\tthen = returned &&\n\n\t\t\t\t\t\t\t\t\t\t// Support: Promises/A+ section 2.3.4\n\t\t\t\t\t\t\t\t\t\t// https://promisesaplus.com/#point-64\n\t\t\t\t\t\t\t\t\t\t// Only check objects and functions for thenability\n\t\t\t\t\t\t\t\t\t\t( typeof returned === \"object\" ||\n\t\t\t\t\t\t\t\t\t\t\ttypeof returned === \"function\" ) &&\n\t\t\t\t\t\t\t\t\t\treturned.then;\n\n\t\t\t\t\t\t\t\t\t// Handle a returned thenable\n\t\t\t\t\t\t\t\t\tif ( isFunction( then ) ) {\n\n\t\t\t\t\t\t\t\t\t\t// Special processors (notify) just wait for resolution\n\t\t\t\t\t\t\t\t\t\tif ( special ) {\n\t\t\t\t\t\t\t\t\t\t\tthen.call(\n\t\t\t\t\t\t\t\t\t\t\t\treturned,\n\t\t\t\t\t\t\t\t\t\t\t\tresolve( maxDepth, deferred, Identity, special ),\n\t\t\t\t\t\t\t\t\t\t\t\tresolve( maxDepth, deferred, Thrower, special )\n\t\t\t\t\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\t\t\t\t// Normal processors (resolve) also hook into progress\n\t\t\t\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t\t\t\t// ...and disregard older resolution values\n\t\t\t\t\t\t\t\t\t\t\tmaxDepth++;\n\n\t\t\t\t\t\t\t\t\t\t\tthen.call(\n\t\t\t\t\t\t\t\t\t\t\t\treturned,\n\t\t\t\t\t\t\t\t\t\t\t\tresolve( maxDepth, deferred, Identity, special ),\n\t\t\t\t\t\t\t\t\t\t\t\tresolve( maxDepth, deferred, Thrower, special ),\n\t\t\t\t\t\t\t\t\t\t\t\tresolve( maxDepth, deferred, Identity,\n\t\t\t\t\t\t\t\t\t\t\t\t\tdeferred.notifyWith )\n\t\t\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t// Handle all other returned values\n\t\t\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t\t\t// Only substitute handlers pass on context\n\t\t\t\t\t\t\t\t\t\t// and multiple values (non-spec behavior)\n\t\t\t\t\t\t\t\t\t\tif ( handler !== Identity ) {\n\t\t\t\t\t\t\t\t\t\t\tthat = undefined;\n\t\t\t\t\t\t\t\t\t\t\targs = [ returned ];\n\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\t// Process the value(s)\n\t\t\t\t\t\t\t\t\t\t// Default process is resolve\n\t\t\t\t\t\t\t\t\t\t( special || deferred.resolveWith )( that, args );\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t},\n\n\t\t\t\t\t\t\t\t// Only normal processors (resolve) catch and reject exceptions\n\t\t\t\t\t\t\t\tprocess = special ?\n\t\t\t\t\t\t\t\t\tmightThrow :\n\t\t\t\t\t\t\t\t\tfunction() {\n\t\t\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\t\t\tmightThrow();\n\t\t\t\t\t\t\t\t\t\t} catch ( e ) {\n\n\t\t\t\t\t\t\t\t\t\t\tif ( jQuery.Deferred.exceptionHook ) {\n\t\t\t\t\t\t\t\t\t\t\t\tjQuery.Deferred.exceptionHook( e,\n\t\t\t\t\t\t\t\t\t\t\t\t\tprocess.stackTrace );\n\t\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\t\t// Support: Promises/A+ section 2.3.3.3.4.1\n\t\t\t\t\t\t\t\t\t\t\t// https://promisesaplus.com/#point-61\n\t\t\t\t\t\t\t\t\t\t\t// Ignore post-resolution exceptions\n\t\t\t\t\t\t\t\t\t\t\tif ( depth + 1 >= maxDepth ) {\n\n\t\t\t\t\t\t\t\t\t\t\t\t// Only substitute handlers pass on context\n\t\t\t\t\t\t\t\t\t\t\t\t// and multiple values (non-spec behavior)\n\t\t\t\t\t\t\t\t\t\t\t\tif ( handler !== Thrower ) {\n\t\t\t\t\t\t\t\t\t\t\t\t\tthat = undefined;\n\t\t\t\t\t\t\t\t\t\t\t\t\targs = [ e ];\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\t\t\tdeferred.rejectWith( that, args );\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t};\n\n\t\t\t\t\t\t\t// Support: Promises/A+ section 2.3.3.3.1\n\t\t\t\t\t\t\t// https://promisesaplus.com/#point-57\n\t\t\t\t\t\t\t// Re-resolve promises immediately to dodge false rejection from\n\t\t\t\t\t\t\t// subsequent errors\n\t\t\t\t\t\t\tif ( depth ) {\n\t\t\t\t\t\t\t\tprocess();\n\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t// Call an optional hook to record the stack, in case of exception\n\t\t\t\t\t\t\t\t// since it's otherwise lost when execution goes async\n\t\t\t\t\t\t\t\tif ( jQuery.Deferred.getStackHook ) {\n\t\t\t\t\t\t\t\t\tprocess.stackTrace = jQuery.Deferred.getStackHook();\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\twindow.setTimeout( process );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\n\t\t\t\t\treturn jQuery.Deferred( function( newDefer ) {\n\n\t\t\t\t\t\t// progress_handlers.add( ... )\n\t\t\t\t\t\ttuples[ 0 ][ 3 ].add(\n\t\t\t\t\t\t\tresolve(\n\t\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t\t\tnewDefer,\n\t\t\t\t\t\t\t\tisFunction( onProgress ) ?\n\t\t\t\t\t\t\t\t\tonProgress :\n\t\t\t\t\t\t\t\t\tIdentity,\n\t\t\t\t\t\t\t\tnewDefer.notifyWith\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t);\n\n\t\t\t\t\t\t// fulfilled_handlers.add( ... )\n\t\t\t\t\t\ttuples[ 1 ][ 3 ].add(\n\t\t\t\t\t\t\tresolve(\n\t\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t\t\tnewDefer,\n\t\t\t\t\t\t\t\tisFunction( onFulfilled ) ?\n\t\t\t\t\t\t\t\t\tonFulfilled :\n\t\t\t\t\t\t\t\t\tIdentity\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t);\n\n\t\t\t\t\t\t// rejected_handlers.add( ... )\n\t\t\t\t\t\ttuples[ 2 ][ 3 ].add(\n\t\t\t\t\t\t\tresolve(\n\t\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t\t\tnewDefer,\n\t\t\t\t\t\t\t\tisFunction( onRejected ) ?\n\t\t\t\t\t\t\t\t\tonRejected :\n\t\t\t\t\t\t\t\t\tThrower\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t);\n\t\t\t\t\t} ).promise();\n\t\t\t\t},\n\n\t\t\t\t// Get a promise for this deferred\n\t\t\t\t// If obj is provided, the promise aspect is added to the object\n\t\t\t\tpromise: function( obj ) {\n\t\t\t\t\treturn obj != null ? jQuery.extend( obj, promise ) : promise;\n\t\t\t\t}\n\t\t\t},\n\t\t\tdeferred = {};\n\n\t\t// Add list-specific methods\n\t\tjQuery.each( tuples, function( i, tuple ) {\n\t\t\tvar list = tuple[ 2 ],\n\t\t\t\tstateString = tuple[ 5 ];\n\n\t\t\t// promise.progress = list.add\n\t\t\t// promise.done = list.add\n\t\t\t// promise.fail = list.add\n\t\t\tpromise[ tuple[ 1 ] ] = list.add;\n\n\t\t\t// Handle state\n\t\t\tif ( stateString ) {\n\t\t\t\tlist.add(\n\t\t\t\t\tfunction() {\n\n\t\t\t\t\t\t// state = \"resolved\" (i.e., fulfilled)\n\t\t\t\t\t\t// state = \"rejected\"\n\t\t\t\t\t\tstate = stateString;\n\t\t\t\t\t},\n\n\t\t\t\t\t// rejected_callbacks.disable\n\t\t\t\t\t// fulfilled_callbacks.disable\n\t\t\t\t\ttuples[ 3 - i ][ 2 ].disable,\n\n\t\t\t\t\t// rejected_handlers.disable\n\t\t\t\t\t// fulfilled_handlers.disable\n\t\t\t\t\ttuples[ 3 - i ][ 3 ].disable,\n\n\t\t\t\t\t// progress_callbacks.lock\n\t\t\t\t\ttuples[ 0 ][ 2 ].lock,\n\n\t\t\t\t\t// progress_handlers.lock\n\t\t\t\t\ttuples[ 0 ][ 3 ].lock\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// progress_handlers.fire\n\t\t\t// fulfilled_handlers.fire\n\t\t\t// rejected_handlers.fire\n\t\t\tlist.add( tuple[ 3 ].fire );\n\n\t\t\t// deferred.notify = function() { deferred.notifyWith(...) }\n\t\t\t// deferred.resolve = function() { deferred.resolveWith(...) }\n\t\t\t// deferred.reject = function() { deferred.rejectWith(...) }\n\t\t\tdeferred[ tuple[ 0 ] ] = function() {\n\t\t\t\tdeferred[ tuple[ 0 ] + \"With\" ]( this === deferred ? undefined : this, arguments );\n\t\t\t\treturn this;\n\t\t\t};\n\n\t\t\t// deferred.notifyWith = list.fireWith\n\t\t\t// deferred.resolveWith = list.fireWith\n\t\t\t// deferred.rejectWith = list.fireWith\n\t\t\tdeferred[ tuple[ 0 ] + \"With\" ] = list.fireWith;\n\t\t} );\n\n\t\t// Make the deferred a promise\n\t\tpromise.promise( deferred );\n\n\t\t// Call given func if any\n\t\tif ( func ) {\n\t\t\tfunc.call( deferred, deferred );\n\t\t}\n\n\t\t// All done!\n\t\treturn deferred;\n\t},\n\n\t// Deferred helper\n\twhen: function( singleValue ) {\n\t\tvar\n\n\t\t\t// count of uncompleted subordinates\n\t\t\tremaining = arguments.length,\n\n\t\t\t// count of unprocessed arguments\n\t\t\ti = remaining,\n\n\t\t\t// subordinate fulfillment data\n\t\t\tresolveContexts = Array( i ),\n\t\t\tresolveValues = slice.call( arguments ),\n\n\t\t\t// the master Deferred\n\t\t\tmaster = jQuery.Deferred(),\n\n\t\t\t// subordinate callback factory\n\t\t\tupdateFunc = function( i ) {\n\t\t\t\treturn function( value ) {\n\t\t\t\t\tresolveContexts[ i ] = this;\n\t\t\t\t\tresolveValues[ i ] = arguments.length > 1 ? slice.call( arguments ) : value;\n\t\t\t\t\tif ( !( --remaining ) ) {\n\t\t\t\t\t\tmaster.resolveWith( resolveContexts, resolveValues );\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\t};\n\n\t\t// Single- and empty arguments are adopted like Promise.resolve\n\t\tif ( remaining <= 1 ) {\n\t\t\tadoptValue( singleValue, master.done( updateFunc( i ) ).resolve, master.reject,\n\t\t\t\t!remaining );\n\n\t\t\t// Use .then() to unwrap secondary thenables (cf. gh-3000)\n\t\t\tif ( master.state() === \"pending\" ||\n\t\t\t\tisFunction( resolveValues[ i ] && resolveValues[ i ].then ) ) {\n\n\t\t\t\treturn master.then();\n\t\t\t}\n\t\t}\n\n\t\t// Multiple arguments are aggregated like Promise.all array elements\n\t\twhile ( i-- ) {\n\t\t\tadoptValue( resolveValues[ i ], updateFunc( i ), master.reject );\n\t\t}\n\n\t\treturn master.promise();\n\t}\n} );\n\n\n// These usually indicate a programmer mistake during development,\n// warn about them ASAP rather than swallowing them by default.\nvar rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;\n\njQuery.Deferred.exceptionHook = function( error, stack ) {\n\n\t// Support: IE 8 - 9 only\n\t// Console exists when dev tools are open, which can happen at any time\n\tif ( window.console && window.console.warn && error && rerrorNames.test( error.name ) ) {\n\t\twindow.console.warn( \"jQuery.Deferred exception: \" + error.message, error.stack, stack );\n\t}\n};\n\n\n\n\njQuery.readyException = function( error ) {\n\twindow.setTimeout( function() {\n\t\tthrow error;\n\t} );\n};\n\n\n\n\n// The deferred used on DOM ready\nvar readyList = jQuery.Deferred();\n\njQuery.fn.ready = function( fn ) {\n\n\treadyList\n\t\t.then( fn )\n\n\t\t// Wrap jQuery.readyException in a function so that the lookup\n\t\t// happens at the time of error handling instead of callback\n\t\t// registration.\n\t\t.catch( function( error ) {\n\t\t\tjQuery.readyException( error );\n\t\t} );\n\n\treturn this;\n};\n\njQuery.extend( {\n\n\t// Is the DOM ready to be used? Set to true once it occurs.\n\tisReady: false,\n\n\t// A counter to track how many items to wait for before\n\t// the ready event fires. See #6781\n\treadyWait: 1,\n\n\t// Handle when the DOM is ready\n\tready: function( wait ) {\n\n\t\t// Abort if there are pending holds or we're already ready\n\t\tif ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Remember that the DOM is ready\n\t\tjQuery.isReady = true;\n\n\t\t// If a normal DOM Ready event fired, decrement, and wait if need be\n\t\tif ( wait !== true && --jQuery.readyWait > 0 ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// If there are functions bound, to execute\n\t\treadyList.resolveWith( document, [ jQuery ] );\n\t}\n} );\n\njQuery.ready.then = readyList.then;\n\n// The ready event handler and self cleanup method\nfunction completed() {\n\tdocument.removeEventListener( \"DOMContentLoaded\", completed );\n\twindow.removeEventListener( \"load\", completed );\n\tjQuery.ready();\n}\n\n// Catch cases where $(document).ready() is called\n// after the browser event has already occurred.\n// Support: IE <=9 - 10 only\n// Older IE sometimes signals \"interactive\" too soon\nif ( document.readyState === \"complete\" ||\n\t( document.readyState !== \"loading\" && !document.documentElement.doScroll ) ) {\n\n\t// Handle it asynchronously to allow scripts the opportunity to delay ready\n\twindow.setTimeout( jQuery.ready );\n\n} else {\n\n\t// Use the handy event callback\n\tdocument.addEventListener( \"DOMContentLoaded\", completed );\n\n\t// A fallback to window.onload, that will always work\n\twindow.addEventListener( \"load\", completed );\n}\n\n\n\n\n// Multifunctional method to get and set values of a collection\n// The value/s can optionally be executed if it's a function\nvar access = function( elems, fn, key, value, chainable, emptyGet, raw ) {\n\tvar i = 0,\n\t\tlen = elems.length,\n\t\tbulk = key == null;\n\n\t// Sets many values\n\tif ( toType( key ) === \"object\" ) {\n\t\tchainable = true;\n\t\tfor ( i in key ) {\n\t\t\taccess( elems, fn, i, key[ i ], true, emptyGet, raw );\n\t\t}\n\n\t// Sets one value\n\t} else if ( value !== undefined ) {\n\t\tchainable = true;\n\n\t\tif ( !isFunction( value ) ) {\n\t\t\traw = true;\n\t\t}\n\n\t\tif ( bulk ) {\n\n\t\t\t// Bulk operations run against the entire set\n\t\t\tif ( raw ) {\n\t\t\t\tfn.call( elems, value );\n\t\t\t\tfn = null;\n\n\t\t\t// ...except when executing function values\n\t\t\t} else {\n\t\t\t\tbulk = fn;\n\t\t\t\tfn = function( elem, key, value ) {\n\t\t\t\t\treturn bulk.call( jQuery( elem ), value );\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\tif ( fn ) {\n\t\t\tfor ( ; i < len; i++ ) {\n\t\t\t\tfn(\n\t\t\t\t\telems[ i ], key, raw ?\n\t\t\t\t\tvalue :\n\t\t\t\t\tvalue.call( elems[ i ], i, fn( elems[ i ], key ) )\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\tif ( chainable ) {\n\t\treturn elems;\n\t}\n\n\t// Gets\n\tif ( bulk ) {\n\t\treturn fn.call( elems );\n\t}\n\n\treturn len ? fn( elems[ 0 ], key ) : emptyGet;\n};\n\n\n// Matches dashed string for camelizing\nvar rmsPrefix = /^-ms-/,\n\trdashAlpha = /-([a-z])/g;\n\n// Used by camelCase as callback to replace()\nfunction fcamelCase( all, letter ) {\n\treturn letter.toUpperCase();\n}\n\n// Convert dashed to camelCase; used by the css and data modules\n// Support: IE <=9 - 11, Edge 12 - 15\n// Microsoft forgot to hump their vendor prefix (#9572)\nfunction camelCase( string ) {\n\treturn string.replace( rmsPrefix, \"ms-\" ).replace( rdashAlpha, fcamelCase );\n}\nvar acceptData = function( owner ) {\n\n\t// Accepts only:\n\t//  - Node\n\t//    - Node.ELEMENT_NODE\n\t//    - Node.DOCUMENT_NODE\n\t//  - Object\n\t//    - Any\n\treturn owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType );\n};\n\n\n\n\nfunction Data() {\n\tthis.expando = jQuery.expando + Data.uid++;\n}\n\nData.uid = 1;\n\nData.prototype = {\n\n\tcache: function( owner ) {\n\n\t\t// Check if the owner object already has a cache\n\t\tvar value = owner[ this.expando ];\n\n\t\t// If not, create one\n\t\tif ( !value ) {\n\t\t\tvalue = {};\n\n\t\t\t// We can accept data for non-element nodes in modern browsers,\n\t\t\t// but we should not, see #8335.\n\t\t\t// Always return an empty object.\n\t\t\tif ( acceptData( owner ) ) {\n\n\t\t\t\t// If it is a node unlikely to be stringify-ed or looped over\n\t\t\t\t// use plain assignment\n\t\t\t\tif ( owner.nodeType ) {\n\t\t\t\t\towner[ this.expando ] = value;\n\n\t\t\t\t// Otherwise secure it in a non-enumerable property\n\t\t\t\t// configurable must be true to allow the property to be\n\t\t\t\t// deleted when data is removed\n\t\t\t\t} else {\n\t\t\t\t\tObject.defineProperty( owner, this.expando, {\n\t\t\t\t\t\tvalue: value,\n\t\t\t\t\t\tconfigurable: true\n\t\t\t\t\t} );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn value;\n\t},\n\tset: function( owner, data, value ) {\n\t\tvar prop,\n\t\t\tcache = this.cache( owner );\n\n\t\t// Handle: [ owner, key, value ] args\n\t\t// Always use camelCase key (gh-2257)\n\t\tif ( typeof data === \"string\" ) {\n\t\t\tcache[ camelCase( data ) ] = value;\n\n\t\t// Handle: [ owner, { properties } ] args\n\t\t} else {\n\n\t\t\t// Copy the properties one-by-one to the cache object\n\t\t\tfor ( prop in data ) {\n\t\t\t\tcache[ camelCase( prop ) ] = data[ prop ];\n\t\t\t}\n\t\t}\n\t\treturn cache;\n\t},\n\tget: function( owner, key ) {\n\t\treturn key === undefined ?\n\t\t\tthis.cache( owner ) :\n\n\t\t\t// Always use camelCase key (gh-2257)\n\t\t\towner[ this.expando ] && owner[ this.expando ][ camelCase( key ) ];\n\t},\n\taccess: function( owner, key, value ) {\n\n\t\t// In cases where either:\n\t\t//\n\t\t//   1. No key was specified\n\t\t//   2. A string key was specified, but no value provided\n\t\t//\n\t\t// Take the \"read\" path and allow the get method to determine\n\t\t// which value to return, respectively either:\n\t\t//\n\t\t//   1. The entire cache object\n\t\t//   2. The data stored at the key\n\t\t//\n\t\tif ( key === undefined ||\n\t\t\t\t( ( key && typeof key === \"string\" ) && value === undefined ) ) {\n\n\t\t\treturn this.get( owner, key );\n\t\t}\n\n\t\t// When the key is not a string, or both a key and value\n\t\t// are specified, set or extend (existing objects) with either:\n\t\t//\n\t\t//   1. An object of properties\n\t\t//   2. A key and value\n\t\t//\n\t\tthis.set( owner, key, value );\n\n\t\t// Since the \"set\" path can have two possible entry points\n\t\t// return the expected data based on which path was taken[*]\n\t\treturn value !== undefined ? value : key;\n\t},\n\tremove: function( owner, key ) {\n\t\tvar i,\n\t\t\tcache = owner[ this.expando ];\n\n\t\tif ( cache === undefined ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( key !== undefined ) {\n\n\t\t\t// Support array or space separated string of keys\n\t\t\tif ( Array.isArray( key ) ) {\n\n\t\t\t\t// If key is an array of keys...\n\t\t\t\t// We always set camelCase keys, so remove that.\n\t\t\t\tkey = key.map( camelCase );\n\t\t\t} else {\n\t\t\t\tkey = camelCase( key );\n\n\t\t\t\t// If a key with the spaces exists, use it.\n\t\t\t\t// Otherwise, create an array by matching non-whitespace\n\t\t\t\tkey = key in cache ?\n\t\t\t\t\t[ key ] :\n\t\t\t\t\t( key.match( rnothtmlwhite ) || [] );\n\t\t\t}\n\n\t\t\ti = key.length;\n\n\t\t\twhile ( i-- ) {\n\t\t\t\tdelete cache[ key[ i ] ];\n\t\t\t}\n\t\t}\n\n\t\t// Remove the expando if there's no more data\n\t\tif ( key === undefined || jQuery.isEmptyObject( cache ) ) {\n\n\t\t\t// Support: Chrome <=35 - 45\n\t\t\t// Webkit & Blink performance suffers when deleting properties\n\t\t\t// from DOM nodes, so set to undefined instead\n\t\t\t// https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted)\n\t\t\tif ( owner.nodeType ) {\n\t\t\t\towner[ this.expando ] = undefined;\n\t\t\t} else {\n\t\t\t\tdelete owner[ this.expando ];\n\t\t\t}\n\t\t}\n\t},\n\thasData: function( owner ) {\n\t\tvar cache = owner[ this.expando ];\n\t\treturn cache !== undefined && !jQuery.isEmptyObject( cache );\n\t}\n};\nvar dataPriv = new Data();\n\nvar dataUser = new Data();\n\n\n\n//\tImplementation Summary\n//\n//\t1. Enforce API surface and semantic compatibility with 1.9.x branch\n//\t2. Improve the module's maintainability by reducing the storage\n//\t\tpaths to a single mechanism.\n//\t3. Use the same single mechanism to support \"private\" and \"user\" data.\n//\t4. _Never_ expose \"private\" data to user code (TODO: Drop _data, _removeData)\n//\t5. Avoid exposing implementation details on user objects (eg. expando properties)\n//\t6. Provide a clear path for implementation upgrade to WeakMap in 2014\n\nvar rbrace = /^(?:\\{[\\w\\W]*\\}|\\[[\\w\\W]*\\])$/,\n\trmultiDash = /[A-Z]/g;\n\nfunction getData( data ) {\n\tif ( data === \"true\" ) {\n\t\treturn true;\n\t}\n\n\tif ( data === \"false\" ) {\n\t\treturn false;\n\t}\n\n\tif ( data === \"null\" ) {\n\t\treturn null;\n\t}\n\n\t// Only convert to a number if it doesn't change the string\n\tif ( data === +data + \"\" ) {\n\t\treturn +data;\n\t}\n\n\tif ( rbrace.test( data ) ) {\n\t\treturn JSON.parse( data );\n\t}\n\n\treturn data;\n}\n\nfunction dataAttr( elem, key, data ) {\n\tvar name;\n\n\t// If nothing was found internally, try to fetch any\n\t// data from the HTML5 data-* attribute\n\tif ( data === undefined && elem.nodeType === 1 ) {\n\t\tname = \"data-\" + key.replace( rmultiDash, \"-$&\" ).toLowerCase();\n\t\tdata = elem.getAttribute( name );\n\n\t\tif ( typeof data === \"string\" ) {\n\t\t\ttry {\n\t\t\t\tdata = getData( data );\n\t\t\t} catch ( e ) {}\n\n\t\t\t// Make sure we set the data so it isn't changed later\n\t\t\tdataUser.set( elem, key, data );\n\t\t} else {\n\t\t\tdata = undefined;\n\t\t}\n\t}\n\treturn data;\n}\n\njQuery.extend( {\n\thasData: function( elem ) {\n\t\treturn dataUser.hasData( elem ) || dataPriv.hasData( elem );\n\t},\n\n\tdata: function( elem, name, data ) {\n\t\treturn dataUser.access( elem, name, data );\n\t},\n\n\tremoveData: function( elem, name ) {\n\t\tdataUser.remove( elem, name );\n\t},\n\n\t// TODO: Now that all calls to _data and _removeData have been replaced\n\t// with direct calls to dataPriv methods, these can be deprecated.\n\t_data: function( elem, name, data ) {\n\t\treturn dataPriv.access( elem, name, data );\n\t},\n\n\t_removeData: function( elem, name ) {\n\t\tdataPriv.remove( elem, name );\n\t}\n} );\n\njQuery.fn.extend( {\n\tdata: function( key, value ) {\n\t\tvar i, name, data,\n\t\t\telem = this[ 0 ],\n\t\t\tattrs = elem && elem.attributes;\n\n\t\t// Gets all values\n\t\tif ( key === undefined ) {\n\t\t\tif ( this.length ) {\n\t\t\t\tdata = dataUser.get( elem );\n\n\t\t\t\tif ( elem.nodeType === 1 && !dataPriv.get( elem, \"hasDataAttrs\" ) ) {\n\t\t\t\t\ti = attrs.length;\n\t\t\t\t\twhile ( i-- ) {\n\n\t\t\t\t\t\t// Support: IE 11 only\n\t\t\t\t\t\t// The attrs elements can be null (#14894)\n\t\t\t\t\t\tif ( attrs[ i ] ) {\n\t\t\t\t\t\t\tname = attrs[ i ].name;\n\t\t\t\t\t\t\tif ( name.indexOf( \"data-\" ) === 0 ) {\n\t\t\t\t\t\t\t\tname = camelCase( name.slice( 5 ) );\n\t\t\t\t\t\t\t\tdataAttr( elem, name, data[ name ] );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tdataPriv.set( elem, \"hasDataAttrs\", true );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn data;\n\t\t}\n\n\t\t// Sets multiple values\n\t\tif ( typeof key === \"object\" ) {\n\t\t\treturn this.each( function() {\n\t\t\t\tdataUser.set( this, key );\n\t\t\t} );\n\t\t}\n\n\t\treturn access( this, function( value ) {\n\t\t\tvar data;\n\n\t\t\t// The calling jQuery object (element matches) is not empty\n\t\t\t// (and therefore has an element appears at this[ 0 ]) and the\n\t\t\t// `value` parameter was not undefined. An empty jQuery object\n\t\t\t// will result in `undefined` for elem = this[ 0 ] which will\n\t\t\t// throw an exception if an attempt to read a data cache is made.\n\t\t\tif ( elem && value === undefined ) {\n\n\t\t\t\t// Attempt to get data from the cache\n\t\t\t\t// The key will always be camelCased in Data\n\t\t\t\tdata = dataUser.get( elem, key );\n\t\t\t\tif ( data !== undefined ) {\n\t\t\t\t\treturn data;\n\t\t\t\t}\n\n\t\t\t\t// Attempt to \"discover\" the data in\n\t\t\t\t// HTML5 custom data-* attrs\n\t\t\t\tdata = dataAttr( elem, key );\n\t\t\t\tif ( data !== undefined ) {\n\t\t\t\t\treturn data;\n\t\t\t\t}\n\n\t\t\t\t// We tried really hard, but the data doesn't exist.\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Set the data...\n\t\t\tthis.each( function() {\n\n\t\t\t\t// We always store the camelCased key\n\t\t\t\tdataUser.set( this, key, value );\n\t\t\t} );\n\t\t}, null, value, arguments.length > 1, null, true );\n\t},\n\n\tremoveData: function( key ) {\n\t\treturn this.each( function() {\n\t\t\tdataUser.remove( this, key );\n\t\t} );\n\t}\n} );\n\n\njQuery.extend( {\n\tqueue: function( elem, type, data ) {\n\t\tvar queue;\n\n\t\tif ( elem ) {\n\t\t\ttype = ( type || \"fx\" ) + \"queue\";\n\t\t\tqueue = dataPriv.get( elem, type );\n\n\t\t\t// Speed up dequeue by getting out quickly if this is just a lookup\n\t\t\tif ( data ) {\n\t\t\t\tif ( !queue || Array.isArray( data ) ) {\n\t\t\t\t\tqueue = dataPriv.access( elem, type, jQuery.makeArray( data ) );\n\t\t\t\t} else {\n\t\t\t\t\tqueue.push( data );\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn queue || [];\n\t\t}\n\t},\n\n\tdequeue: function( elem, type ) {\n\t\ttype = type || \"fx\";\n\n\t\tvar queue = jQuery.queue( elem, type ),\n\t\t\tstartLength = queue.length,\n\t\t\tfn = queue.shift(),\n\t\t\thooks = jQuery._queueHooks( elem, type ),\n\t\t\tnext = function() {\n\t\t\t\tjQuery.dequeue( elem, type );\n\t\t\t};\n\n\t\t// If the fx queue is dequeued, always remove the progress sentinel\n\t\tif ( fn === \"inprogress\" ) {\n\t\t\tfn = queue.shift();\n\t\t\tstartLength--;\n\t\t}\n\n\t\tif ( fn ) {\n\n\t\t\t// Add a progress sentinel to prevent the fx queue from being\n\t\t\t// automatically dequeued\n\t\t\tif ( type === \"fx\" ) {\n\t\t\t\tqueue.unshift( \"inprogress\" );\n\t\t\t}\n\n\t\t\t// Clear up the last queue stop function\n\t\t\tdelete hooks.stop;\n\t\t\tfn.call( elem, next, hooks );\n\t\t}\n\n\t\tif ( !startLength && hooks ) {\n\t\t\thooks.empty.fire();\n\t\t}\n\t},\n\n\t// Not public - generate a queueHooks object, or return the current one\n\t_queueHooks: function( elem, type ) {\n\t\tvar key = type + \"queueHooks\";\n\t\treturn dataPriv.get( elem, key ) || dataPriv.access( elem, key, {\n\t\t\tempty: jQuery.Callbacks( \"once memory\" ).add( function() {\n\t\t\t\tdataPriv.remove( elem, [ type + \"queue\", key ] );\n\t\t\t} )\n\t\t} );\n\t}\n} );\n\njQuery.fn.extend( {\n\tqueue: function( type, data ) {\n\t\tvar setter = 2;\n\n\t\tif ( typeof type !== \"string\" ) {\n\t\t\tdata = type;\n\t\t\ttype = \"fx\";\n\t\t\tsetter--;\n\t\t}\n\n\t\tif ( arguments.length < setter ) {\n\t\t\treturn jQuery.queue( this[ 0 ], type );\n\t\t}\n\n\t\treturn data === undefined ?\n\t\t\tthis :\n\t\t\tthis.each( function() {\n\t\t\t\tvar queue = jQuery.queue( this, type, data );\n\n\t\t\t\t// Ensure a hooks for this queue\n\t\t\t\tjQuery._queueHooks( this, type );\n\n\t\t\t\tif ( type === \"fx\" && queue[ 0 ] !== \"inprogress\" ) {\n\t\t\t\t\tjQuery.dequeue( this, type );\n\t\t\t\t}\n\t\t\t} );\n\t},\n\tdequeue: function( type ) {\n\t\treturn this.each( function() {\n\t\t\tjQuery.dequeue( this, type );\n\t\t} );\n\t},\n\tclearQueue: function( type ) {\n\t\treturn this.queue( type || \"fx\", [] );\n\t},\n\n\t// Get a promise resolved when queues of a certain type\n\t// are emptied (fx is the type by default)\n\tpromise: function( type, obj ) {\n\t\tvar tmp,\n\t\t\tcount = 1,\n\t\t\tdefer = jQuery.Deferred(),\n\t\t\telements = this,\n\t\t\ti = this.length,\n\t\t\tresolve = function() {\n\t\t\t\tif ( !( --count ) ) {\n\t\t\t\t\tdefer.resolveWith( elements, [ elements ] );\n\t\t\t\t}\n\t\t\t};\n\n\t\tif ( typeof type !== \"string\" ) {\n\t\t\tobj = type;\n\t\t\ttype = undefined;\n\t\t}\n\t\ttype = type || \"fx\";\n\n\t\twhile ( i-- ) {\n\t\t\ttmp = dataPriv.get( elements[ i ], type + \"queueHooks\" );\n\t\t\tif ( tmp && tmp.empty ) {\n\t\t\t\tcount++;\n\t\t\t\ttmp.empty.add( resolve );\n\t\t\t}\n\t\t}\n\t\tresolve();\n\t\treturn defer.promise( obj );\n\t}\n} );\nvar pnum = ( /[+-]?(?:\\d*\\.|)\\d+(?:[eE][+-]?\\d+|)/ ).source;\n\nvar rcssNum = new RegExp( \"^(?:([+-])=|)(\" + pnum + \")([a-z%]*)$\", \"i\" );\n\n\nvar cssExpand = [ \"Top\", \"Right\", \"Bottom\", \"Left\" ];\n\nvar isHiddenWithinTree = function( elem, el ) {\n\n\t\t// isHiddenWithinTree might be called from jQuery#filter function;\n\t\t// in that case, element will be second argument\n\t\telem = el || elem;\n\n\t\t// Inline style trumps all\n\t\treturn elem.style.display === \"none\" ||\n\t\t\telem.style.display === \"\" &&\n\n\t\t\t// Otherwise, check computed style\n\t\t\t// Support: Firefox <=43 - 45\n\t\t\t// Disconnected elements can have computed display: none, so first confirm that elem is\n\t\t\t// in the document.\n\t\t\tjQuery.contains( elem.ownerDocument, elem ) &&\n\n\t\t\tjQuery.css( elem, \"display\" ) === \"none\";\n\t};\n\nvar swap = function( elem, options, callback, args ) {\n\tvar ret, name,\n\t\told = {};\n\n\t// Remember the old values, and insert the new ones\n\tfor ( name in options ) {\n\t\told[ name ] = elem.style[ name ];\n\t\telem.style[ name ] = options[ name ];\n\t}\n\n\tret = callback.apply( elem, args || [] );\n\n\t// Revert the old values\n\tfor ( name in options ) {\n\t\telem.style[ name ] = old[ name ];\n\t}\n\n\treturn ret;\n};\n\n\n\n\nfunction adjustCSS( elem, prop, valueParts, tween ) {\n\tvar adjusted, scale,\n\t\tmaxIterations = 20,\n\t\tcurrentValue = tween ?\n\t\t\tfunction() {\n\t\t\t\treturn tween.cur();\n\t\t\t} :\n\t\t\tfunction() {\n\t\t\t\treturn jQuery.css( elem, prop, \"\" );\n\t\t\t},\n\t\tinitial = currentValue(),\n\t\tunit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? \"\" : \"px\" ),\n\n\t\t// Starting value computation is required for potential unit mismatches\n\t\tinitialInUnit = ( jQuery.cssNumber[ prop ] || unit !== \"px\" && +initial ) &&\n\t\t\trcssNum.exec( jQuery.css( elem, prop ) );\n\n\tif ( initialInUnit && initialInUnit[ 3 ] !== unit ) {\n\n\t\t// Support: Firefox <=54\n\t\t// Halve the iteration target value to prevent interference from CSS upper bounds (gh-2144)\n\t\tinitial = initial / 2;\n\n\t\t// Trust units reported by jQuery.css\n\t\tunit = unit || initialInUnit[ 3 ];\n\n\t\t// Iteratively approximate from a nonzero starting point\n\t\tinitialInUnit = +initial || 1;\n\n\t\twhile ( maxIterations-- ) {\n\n\t\t\t// Evaluate and update our best guess (doubling guesses that zero out).\n\t\t\t// Finish if the scale equals or crosses 1 (making the old*new product non-positive).\n\t\t\tjQuery.style( elem, prop, initialInUnit + unit );\n\t\t\tif ( ( 1 - scale ) * ( 1 - ( scale = currentValue() / initial || 0.5 ) ) <= 0 ) {\n\t\t\t\tmaxIterations = 0;\n\t\t\t}\n\t\t\tinitialInUnit = initialInUnit / scale;\n\n\t\t}\n\n\t\tinitialInUnit = initialInUnit * 2;\n\t\tjQuery.style( elem, prop, initialInUnit + unit );\n\n\t\t// Make sure we update the tween properties later on\n\t\tvalueParts = valueParts || [];\n\t}\n\n\tif ( valueParts ) {\n\t\tinitialInUnit = +initialInUnit || +initial || 0;\n\n\t\t// Apply relative offset (+=/-=) if specified\n\t\tadjusted = valueParts[ 1 ] ?\n\t\t\tinitialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] :\n\t\t\t+valueParts[ 2 ];\n\t\tif ( tween ) {\n\t\t\ttween.unit = unit;\n\t\t\ttween.start = initialInUnit;\n\t\t\ttween.end = adjusted;\n\t\t}\n\t}\n\treturn adjusted;\n}\n\n\nvar defaultDisplayMap = {};\n\nfunction getDefaultDisplay( elem ) {\n\tvar temp,\n\t\tdoc = elem.ownerDocument,\n\t\tnodeName = elem.nodeName,\n\t\tdisplay = defaultDisplayMap[ nodeName ];\n\n\tif ( display ) {\n\t\treturn display;\n\t}\n\n\ttemp = doc.body.appendChild( doc.createElement( nodeName ) );\n\tdisplay = jQuery.css( temp, \"display\" );\n\n\ttemp.parentNode.removeChild( temp );\n\n\tif ( display === \"none\" ) {\n\t\tdisplay = \"block\";\n\t}\n\tdefaultDisplayMap[ nodeName ] = display;\n\n\treturn display;\n}\n\nfunction showHide( elements, show ) {\n\tvar display, elem,\n\t\tvalues = [],\n\t\tindex = 0,\n\t\tlength = elements.length;\n\n\t// Determine new display value for elements that need to change\n\tfor ( ; index < length; index++ ) {\n\t\telem = elements[ index ];\n\t\tif ( !elem.style ) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tdisplay = elem.style.display;\n\t\tif ( show ) {\n\n\t\t\t// Since we force visibility upon cascade-hidden elements, an immediate (and slow)\n\t\t\t// check is required in this first loop unless we have a nonempty display value (either\n\t\t\t// inline or about-to-be-restored)\n\t\t\tif ( display === \"none\" ) {\n\t\t\t\tvalues[ index ] = dataPriv.get( elem, \"display\" ) || null;\n\t\t\t\tif ( !values[ index ] ) {\n\t\t\t\t\telem.style.display = \"\";\n\t\t\t\t}\n\t\t\t}\n\t\t\tif ( elem.style.display === \"\" && isHiddenWithinTree( elem ) ) {\n\t\t\t\tvalues[ index ] = getDefaultDisplay( elem );\n\t\t\t}\n\t\t} else {\n\t\t\tif ( display !== \"none\" ) {\n\t\t\t\tvalues[ index ] = \"none\";\n\n\t\t\t\t// Remember what we're overwriting\n\t\t\t\tdataPriv.set( elem, \"display\", display );\n\t\t\t}\n\t\t}\n\t}\n\n\t// Set the display of the elements in a second loop to avoid constant reflow\n\tfor ( index = 0; index < length; index++ ) {\n\t\tif ( values[ index ] != null ) {\n\t\t\telements[ index ].style.display = values[ index ];\n\t\t}\n\t}\n\n\treturn elements;\n}\n\njQuery.fn.extend( {\n\tshow: function() {\n\t\treturn showHide( this, true );\n\t},\n\thide: function() {\n\t\treturn showHide( this );\n\t},\n\ttoggle: function( state ) {\n\t\tif ( typeof state === \"boolean\" ) {\n\t\t\treturn state ? this.show() : this.hide();\n\t\t}\n\n\t\treturn this.each( function() {\n\t\t\tif ( isHiddenWithinTree( this ) ) {\n\t\t\t\tjQuery( this ).show();\n\t\t\t} else {\n\t\t\t\tjQuery( this ).hide();\n\t\t\t}\n\t\t} );\n\t}\n} );\nvar rcheckableType = ( /^(?:checkbox|radio)$/i );\n\nvar rtagName = ( /<([a-z][^\\/\\0>\\x20\\t\\r\\n\\f]+)/i );\n\nvar rscriptType = ( /^$|^module$|\\/(?:java|ecma)script/i );\n\n\n\n// We have to close these tags to support XHTML (#13200)\nvar wrapMap = {\n\n\t// Support: IE <=9 only\n\toption: [ 1, \"<select multiple='multiple'>\", \"</select>\" ],\n\n\t// XHTML parsers do not magically insert elements in the\n\t// same way that tag soup parsers do. So we cannot shorten\n\t// this by omitting <tbody> or other required elements.\n\tthead: [ 1, \"<table>\", \"</table>\" ],\n\tcol: [ 2, \"<table><colgroup>\", \"</colgroup></table>\" ],\n\ttr: [ 2, \"<table><tbody>\", \"</tbody></table>\" ],\n\ttd: [ 3, \"<table><tbody><tr>\", \"</tr></tbody></table>\" ],\n\n\t_default: [ 0, \"\", \"\" ]\n};\n\n// Support: IE <=9 only\nwrapMap.optgroup = wrapMap.option;\n\nwrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;\nwrapMap.th = wrapMap.td;\n\n\nfunction getAll( context, tag ) {\n\n\t// Support: IE <=9 - 11 only\n\t// Use typeof to avoid zero-argument method invocation on host objects (#15151)\n\tvar ret;\n\n\tif ( typeof context.getElementsByTagName !== \"undefined\" ) {\n\t\tret = context.getElementsByTagName( tag || \"*\" );\n\n\t} else if ( typeof context.querySelectorAll !== \"undefined\" ) {\n\t\tret = context.querySelectorAll( tag || \"*\" );\n\n\t} else {\n\t\tret = [];\n\t}\n\n\tif ( tag === undefined || tag && nodeName( context, tag ) ) {\n\t\treturn jQuery.merge( [ context ], ret );\n\t}\n\n\treturn ret;\n}\n\n\n// Mark scripts as having already been evaluated\nfunction setGlobalEval( elems, refElements ) {\n\tvar i = 0,\n\t\tl = elems.length;\n\n\tfor ( ; i < l; i++ ) {\n\t\tdataPriv.set(\n\t\t\telems[ i ],\n\t\t\t\"globalEval\",\n\t\t\t!refElements || dataPriv.get( refElements[ i ], \"globalEval\" )\n\t\t);\n\t}\n}\n\n\nvar rhtml = /<|&#?\\w+;/;\n\nfunction buildFragment( elems, context, scripts, selection, ignored ) {\n\tvar elem, tmp, tag, wrap, contains, j,\n\t\tfragment = context.createDocumentFragment(),\n\t\tnodes = [],\n\t\ti = 0,\n\t\tl = elems.length;\n\n\tfor ( ; i < l; i++ ) {\n\t\telem = elems[ i ];\n\n\t\tif ( elem || elem === 0 ) {\n\n\t\t\t// Add nodes directly\n\t\t\tif ( toType( elem ) === \"object\" ) {\n\n\t\t\t\t// Support: Android <=4.0 only, PhantomJS 1 only\n\t\t\t\t// push.apply(_, arraylike) throws on ancient WebKit\n\t\t\t\tjQuery.merge( nodes, elem.nodeType ? [ elem ] : elem );\n\n\t\t\t// Convert non-html into a text node\n\t\t\t} else if ( !rhtml.test( elem ) ) {\n\t\t\t\tnodes.push( context.createTextNode( elem ) );\n\n\t\t\t// Convert html into DOM nodes\n\t\t\t} else {\n\t\t\t\ttmp = tmp || fragment.appendChild( context.createElement( \"div\" ) );\n\n\t\t\t\t// Deserialize a standard representation\n\t\t\t\ttag = ( rtagName.exec( elem ) || [ \"\", \"\" ] )[ 1 ].toLowerCase();\n\t\t\t\twrap = wrapMap[ tag ] || wrapMap._default;\n\t\t\t\ttmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ];\n\n\t\t\t\t// Descend through wrappers to the right content\n\t\t\t\tj = wrap[ 0 ];\n\t\t\t\twhile ( j-- ) {\n\t\t\t\t\ttmp = tmp.lastChild;\n\t\t\t\t}\n\n\t\t\t\t// Support: Android <=4.0 only, PhantomJS 1 only\n\t\t\t\t// push.apply(_, arraylike) throws on ancient WebKit\n\t\t\t\tjQuery.merge( nodes, tmp.childNodes );\n\n\t\t\t\t// Remember the top-level container\n\t\t\t\ttmp = fragment.firstChild;\n\n\t\t\t\t// Ensure the created nodes are orphaned (#12392)\n\t\t\t\ttmp.textContent = \"\";\n\t\t\t}\n\t\t}\n\t}\n\n\t// Remove wrapper from fragment\n\tfragment.textContent = \"\";\n\n\ti = 0;\n\twhile ( ( elem = nodes[ i++ ] ) ) {\n\n\t\t// Skip elements already in the context collection (trac-4087)\n\t\tif ( selection && jQuery.inArray( elem, selection ) > -1 ) {\n\t\t\tif ( ignored ) {\n\t\t\t\tignored.push( elem );\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tcontains = jQuery.contains( elem.ownerDocument, elem );\n\n\t\t// Append to fragment\n\t\ttmp = getAll( fragment.appendChild( elem ), \"script\" );\n\n\t\t// Preserve script evaluation history\n\t\tif ( contains ) {\n\t\t\tsetGlobalEval( tmp );\n\t\t}\n\n\t\t// Capture executables\n\t\tif ( scripts ) {\n\t\t\tj = 0;\n\t\t\twhile ( ( elem = tmp[ j++ ] ) ) {\n\t\t\t\tif ( rscriptType.test( elem.type || \"\" ) ) {\n\t\t\t\t\tscripts.push( elem );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn fragment;\n}\n\n\n( function() {\n\tvar fragment = document.createDocumentFragment(),\n\t\tdiv = fragment.appendChild( document.createElement( \"div\" ) ),\n\t\tinput = document.createElement( \"input\" );\n\n\t// Support: Android 4.0 - 4.3 only\n\t// Check state lost if the name is set (#11217)\n\t// Support: Windows Web Apps (WWA)\n\t// `name` and `type` must use .setAttribute for WWA (#14901)\n\tinput.setAttribute( \"type\", \"radio\" );\n\tinput.setAttribute( \"checked\", \"checked\" );\n\tinput.setAttribute( \"name\", \"t\" );\n\n\tdiv.appendChild( input );\n\n\t// Support: Android <=4.1 only\n\t// Older WebKit doesn't clone checked state correctly in fragments\n\tsupport.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked;\n\n\t// Support: IE <=11 only\n\t// Make sure textarea (and checkbox) defaultValue is properly cloned\n\tdiv.innerHTML = \"<textarea>x</textarea>\";\n\tsupport.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue;\n} )();\nvar documentElement = document.documentElement;\n\n\n\nvar\n\trkeyEvent = /^key/,\n\trmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/,\n\trtypenamespace = /^([^.]*)(?:\\.(.+)|)/;\n\nfunction returnTrue() {\n\treturn true;\n}\n\nfunction returnFalse() {\n\treturn false;\n}\n\n// Support: IE <=9 only\n// See #13393 for more info\nfunction safeActiveElement() {\n\ttry {\n\t\treturn document.activeElement;\n\t} catch ( err ) { }\n}\n\nfunction on( elem, types, selector, data, fn, one ) {\n\tvar origFn, type;\n\n\t// Types can be a map of types/handlers\n\tif ( typeof types === \"object\" ) {\n\n\t\t// ( types-Object, selector, data )\n\t\tif ( typeof selector !== \"string\" ) {\n\n\t\t\t// ( types-Object, data )\n\t\t\tdata = data || selector;\n\t\t\tselector = undefined;\n\t\t}\n\t\tfor ( type in types ) {\n\t\t\ton( elem, type, selector, data, types[ type ], one );\n\t\t}\n\t\treturn elem;\n\t}\n\n\tif ( data == null && fn == null ) {\n\n\t\t// ( types, fn )\n\t\tfn = selector;\n\t\tdata = selector = undefined;\n\t} else if ( fn == null ) {\n\t\tif ( typeof selector === \"string\" ) {\n\n\t\t\t// ( types, selector, fn )\n\t\t\tfn = data;\n\t\t\tdata = undefined;\n\t\t} else {\n\n\t\t\t// ( types, data, fn )\n\t\t\tfn = data;\n\t\t\tdata = selector;\n\t\t\tselector = undefined;\n\t\t}\n\t}\n\tif ( fn === false ) {\n\t\tfn = returnFalse;\n\t} else if ( !fn ) {\n\t\treturn elem;\n\t}\n\n\tif ( one === 1 ) {\n\t\torigFn = fn;\n\t\tfn = function( event ) {\n\n\t\t\t// Can use an empty set, since event contains the info\n\t\t\tjQuery().off( event );\n\t\t\treturn origFn.apply( this, arguments );\n\t\t};\n\n\t\t// Use same guid so caller can remove using origFn\n\t\tfn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );\n\t}\n\treturn elem.each( function() {\n\t\tjQuery.event.add( this, types, fn, data, selector );\n\t} );\n}\n\n/*\n * Helper functions for managing events -- not part of the public interface.\n * Props to Dean Edwards' addEvent library for many of the ideas.\n */\njQuery.event = {\n\n\tglobal: {},\n\n\tadd: function( elem, types, handler, data, selector ) {\n\n\t\tvar handleObjIn, eventHandle, tmp,\n\t\t\tevents, t, handleObj,\n\t\t\tspecial, handlers, type, namespaces, origType,\n\t\t\telemData = dataPriv.get( elem );\n\n\t\t// Don't attach events to noData or text/comment nodes (but allow plain objects)\n\t\tif ( !elemData ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Caller can pass in an object of custom data in lieu of the handler\n\t\tif ( handler.handler ) {\n\t\t\thandleObjIn = handler;\n\t\t\thandler = handleObjIn.handler;\n\t\t\tselector = handleObjIn.selector;\n\t\t}\n\n\t\t// Ensure that invalid selectors throw exceptions at attach time\n\t\t// Evaluate against documentElement in case elem is a non-element node (e.g., document)\n\t\tif ( selector ) {\n\t\t\tjQuery.find.matchesSelector( documentElement, selector );\n\t\t}\n\n\t\t// Make sure that the handler has a unique ID, used to find/remove it later\n\t\tif ( !handler.guid ) {\n\t\t\thandler.guid = jQuery.guid++;\n\t\t}\n\n\t\t// Init the element's event structure and main handler, if this is the first\n\t\tif ( !( events = elemData.events ) ) {\n\t\t\tevents = elemData.events = {};\n\t\t}\n\t\tif ( !( eventHandle = elemData.handle ) ) {\n\t\t\teventHandle = elemData.handle = function( e ) {\n\n\t\t\t\t// Discard the second event of a jQuery.event.trigger() and\n\t\t\t\t// when an event is called after a page has unloaded\n\t\t\t\treturn typeof jQuery !== \"undefined\" && jQuery.event.triggered !== e.type ?\n\t\t\t\t\tjQuery.event.dispatch.apply( elem, arguments ) : undefined;\n\t\t\t};\n\t\t}\n\n\t\t// Handle multiple events separated by a space\n\t\ttypes = ( types || \"\" ).match( rnothtmlwhite ) || [ \"\" ];\n\t\tt = types.length;\n\t\twhile ( t-- ) {\n\t\t\ttmp = rtypenamespace.exec( types[ t ] ) || [];\n\t\t\ttype = origType = tmp[ 1 ];\n\t\t\tnamespaces = ( tmp[ 2 ] || \"\" ).split( \".\" ).sort();\n\n\t\t\t// There *must* be a type, no attaching namespace-only handlers\n\t\t\tif ( !type ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// If event changes its type, use the special event handlers for the changed type\n\t\t\tspecial = jQuery.event.special[ type ] || {};\n\n\t\t\t// If selector defined, determine special event api type, otherwise given type\n\t\t\ttype = ( selector ? special.delegateType : special.bindType ) || type;\n\n\t\t\t// Update special based on newly reset type\n\t\t\tspecial = jQuery.event.special[ type ] || {};\n\n\t\t\t// handleObj is passed to all event handlers\n\t\t\thandleObj = jQuery.extend( {\n\t\t\t\ttype: type,\n\t\t\t\torigType: origType,\n\t\t\t\tdata: data,\n\t\t\t\thandler: handler,\n\t\t\t\tguid: handler.guid,\n\t\t\t\tselector: selector,\n\t\t\t\tneedsContext: selector && jQuery.expr.match.needsContext.test( selector ),\n\t\t\t\tnamespace: namespaces.join( \".\" )\n\t\t\t}, handleObjIn );\n\n\t\t\t// Init the event handler queue if we're the first\n\t\t\tif ( !( handlers = events[ type ] ) ) {\n\t\t\t\thandlers = events[ type ] = [];\n\t\t\t\thandlers.delegateCount = 0;\n\n\t\t\t\t// Only use addEventListener if the special events handler returns false\n\t\t\t\tif ( !special.setup ||\n\t\t\t\t\tspecial.setup.call( elem, data, namespaces, eventHandle ) === false ) {\n\n\t\t\t\t\tif ( elem.addEventListener ) {\n\t\t\t\t\t\telem.addEventListener( type, eventHandle );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( special.add ) {\n\t\t\t\tspecial.add.call( elem, handleObj );\n\n\t\t\t\tif ( !handleObj.handler.guid ) {\n\t\t\t\t\thandleObj.handler.guid = handler.guid;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Add to the element's handler list, delegates in front\n\t\t\tif ( selector ) {\n\t\t\t\thandlers.splice( handlers.delegateCount++, 0, handleObj );\n\t\t\t} else {\n\t\t\t\thandlers.push( handleObj );\n\t\t\t}\n\n\t\t\t// Keep track of which events have ever been used, for event optimization\n\t\t\tjQuery.event.global[ type ] = true;\n\t\t}\n\n\t},\n\n\t// Detach an event or set of events from an element\n\tremove: function( elem, types, handler, selector, mappedTypes ) {\n\n\t\tvar j, origCount, tmp,\n\t\t\tevents, t, handleObj,\n\t\t\tspecial, handlers, type, namespaces, origType,\n\t\t\telemData = dataPriv.hasData( elem ) && dataPriv.get( elem );\n\n\t\tif ( !elemData || !( events = elemData.events ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Once for each type.namespace in types; type may be omitted\n\t\ttypes = ( types || \"\" ).match( rnothtmlwhite ) || [ \"\" ];\n\t\tt = types.length;\n\t\twhile ( t-- ) {\n\t\t\ttmp = rtypenamespace.exec( types[ t ] ) || [];\n\t\t\ttype = origType = tmp[ 1 ];\n\t\t\tnamespaces = ( tmp[ 2 ] || \"\" ).split( \".\" ).sort();\n\n\t\t\t// Unbind all events (on this namespace, if provided) for the element\n\t\t\tif ( !type ) {\n\t\t\t\tfor ( type in events ) {\n\t\t\t\t\tjQuery.event.remove( elem, type + types[ t ], handler, selector, true );\n\t\t\t\t}\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tspecial = jQuery.event.special[ type ] || {};\n\t\t\ttype = ( selector ? special.delegateType : special.bindType ) || type;\n\t\t\thandlers = events[ type ] || [];\n\t\t\ttmp = tmp[ 2 ] &&\n\t\t\t\tnew RegExp( \"(^|\\\\.)\" + namespaces.join( \"\\\\.(?:.*\\\\.|)\" ) + \"(\\\\.|$)\" );\n\n\t\t\t// Remove matching events\n\t\t\torigCount = j = handlers.length;\n\t\t\twhile ( j-- ) {\n\t\t\t\thandleObj = handlers[ j ];\n\n\t\t\t\tif ( ( mappedTypes || origType === handleObj.origType ) &&\n\t\t\t\t\t( !handler || handler.guid === handleObj.guid ) &&\n\t\t\t\t\t( !tmp || tmp.test( handleObj.namespace ) ) &&\n\t\t\t\t\t( !selector || selector === handleObj.selector ||\n\t\t\t\t\t\tselector === \"**\" && handleObj.selector ) ) {\n\t\t\t\t\thandlers.splice( j, 1 );\n\n\t\t\t\t\tif ( handleObj.selector ) {\n\t\t\t\t\t\thandlers.delegateCount--;\n\t\t\t\t\t}\n\t\t\t\t\tif ( special.remove ) {\n\t\t\t\t\t\tspecial.remove.call( elem, handleObj );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Remove generic event handler if we removed something and no more handlers exist\n\t\t\t// (avoids potential for endless recursion during removal of special event handlers)\n\t\t\tif ( origCount && !handlers.length ) {\n\t\t\t\tif ( !special.teardown ||\n\t\t\t\t\tspecial.teardown.call( elem, namespaces, elemData.handle ) === false ) {\n\n\t\t\t\t\tjQuery.removeEvent( elem, type, elemData.handle );\n\t\t\t\t}\n\n\t\t\t\tdelete events[ type ];\n\t\t\t}\n\t\t}\n\n\t\t// Remove data and the expando if it's no longer used\n\t\tif ( jQuery.isEmptyObject( events ) ) {\n\t\t\tdataPriv.remove( elem, \"handle events\" );\n\t\t}\n\t},\n\n\tdispatch: function( nativeEvent ) {\n\n\t\t// Make a writable jQuery.Event from the native event object\n\t\tvar event = jQuery.event.fix( nativeEvent );\n\n\t\tvar i, j, ret, matched, handleObj, handlerQueue,\n\t\t\targs = new Array( arguments.length ),\n\t\t\thandlers = ( dataPriv.get( this, \"events\" ) || {} )[ event.type ] || [],\n\t\t\tspecial = jQuery.event.special[ event.type ] || {};\n\n\t\t// Use the fix-ed jQuery.Event rather than the (read-only) native event\n\t\targs[ 0 ] = event;\n\n\t\tfor ( i = 1; i < arguments.length; i++ ) {\n\t\t\targs[ i ] = arguments[ i ];\n\t\t}\n\n\t\tevent.delegateTarget = this;\n\n\t\t// Call the preDispatch hook for the mapped type, and let it bail if desired\n\t\tif ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Determine handlers\n\t\thandlerQueue = jQuery.event.handlers.call( this, event, handlers );\n\n\t\t// Run delegates first; they may want to stop propagation beneath us\n\t\ti = 0;\n\t\twhile ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) {\n\t\t\tevent.currentTarget = matched.elem;\n\n\t\t\tj = 0;\n\t\t\twhile ( ( handleObj = matched.handlers[ j++ ] ) &&\n\t\t\t\t!event.isImmediatePropagationStopped() ) {\n\n\t\t\t\t// Triggered event must either 1) have no namespace, or 2) have namespace(s)\n\t\t\t\t// a subset or equal to those in the bound event (both can have no namespace).\n\t\t\t\tif ( !event.rnamespace || event.rnamespace.test( handleObj.namespace ) ) {\n\n\t\t\t\t\tevent.handleObj = handleObj;\n\t\t\t\t\tevent.data = handleObj.data;\n\n\t\t\t\t\tret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle ||\n\t\t\t\t\t\thandleObj.handler ).apply( matched.elem, args );\n\n\t\t\t\t\tif ( ret !== undefined ) {\n\t\t\t\t\t\tif ( ( event.result = ret ) === false ) {\n\t\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\t\tevent.stopPropagation();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Call the postDispatch hook for the mapped type\n\t\tif ( special.postDispatch ) {\n\t\t\tspecial.postDispatch.call( this, event );\n\t\t}\n\n\t\treturn event.result;\n\t},\n\n\thandlers: function( event, handlers ) {\n\t\tvar i, handleObj, sel, matchedHandlers, matchedSelectors,\n\t\t\thandlerQueue = [],\n\t\t\tdelegateCount = handlers.delegateCount,\n\t\t\tcur = event.target;\n\n\t\t// Find delegate handlers\n\t\tif ( delegateCount &&\n\n\t\t\t// Support: IE <=9\n\t\t\t// Black-hole SVG <use> instance trees (trac-13180)\n\t\t\tcur.nodeType &&\n\n\t\t\t// Support: Firefox <=42\n\t\t\t// Suppress spec-violating clicks indicating a non-primary pointer button (trac-3861)\n\t\t\t// https://www.w3.org/TR/DOM-Level-3-Events/#event-type-click\n\t\t\t// Support: IE 11 only\n\t\t\t// ...but not arrow key \"clicks\" of radio inputs, which can have `button` -1 (gh-2343)\n\t\t\t!( event.type === \"click\" && event.button >= 1 ) ) {\n\n\t\t\tfor ( ; cur !== this; cur = cur.parentNode || this ) {\n\n\t\t\t\t// Don't check non-elements (#13208)\n\t\t\t\t// Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)\n\t\t\t\tif ( cur.nodeType === 1 && !( event.type === \"click\" && cur.disabled === true ) ) {\n\t\t\t\t\tmatchedHandlers = [];\n\t\t\t\t\tmatchedSelectors = {};\n\t\t\t\t\tfor ( i = 0; i < delegateCount; i++ ) {\n\t\t\t\t\t\thandleObj = handlers[ i ];\n\n\t\t\t\t\t\t// Don't conflict with Object.prototype properties (#13203)\n\t\t\t\t\t\tsel = handleObj.selector + \" \";\n\n\t\t\t\t\t\tif ( matchedSelectors[ sel ] === undefined ) {\n\t\t\t\t\t\t\tmatchedSelectors[ sel ] = handleObj.needsContext ?\n\t\t\t\t\t\t\t\tjQuery( sel, this ).index( cur ) > -1 :\n\t\t\t\t\t\t\t\tjQuery.find( sel, this, null, [ cur ] ).length;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( matchedSelectors[ sel ] ) {\n\t\t\t\t\t\t\tmatchedHandlers.push( handleObj );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif ( matchedHandlers.length ) {\n\t\t\t\t\t\thandlerQueue.push( { elem: cur, handlers: matchedHandlers } );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Add the remaining (directly-bound) handlers\n\t\tcur = this;\n\t\tif ( delegateCount < handlers.length ) {\n\t\t\thandlerQueue.push( { elem: cur, handlers: handlers.slice( delegateCount ) } );\n\t\t}\n\n\t\treturn handlerQueue;\n\t},\n\n\taddProp: function( name, hook ) {\n\t\tObject.defineProperty( jQuery.Event.prototype, name, {\n\t\t\tenumerable: true,\n\t\t\tconfigurable: true,\n\n\t\t\tget: isFunction( hook ) ?\n\t\t\t\tfunction() {\n\t\t\t\t\tif ( this.originalEvent ) {\n\t\t\t\t\t\t\treturn hook( this.originalEvent );\n\t\t\t\t\t}\n\t\t\t\t} :\n\t\t\t\tfunction() {\n\t\t\t\t\tif ( this.originalEvent ) {\n\t\t\t\t\t\t\treturn this.originalEvent[ name ];\n\t\t\t\t\t}\n\t\t\t\t},\n\n\t\t\tset: function( value ) {\n\t\t\t\tObject.defineProperty( this, name, {\n\t\t\t\t\tenumerable: true,\n\t\t\t\t\tconfigurable: true,\n\t\t\t\t\twritable: true,\n\t\t\t\t\tvalue: value\n\t\t\t\t} );\n\t\t\t}\n\t\t} );\n\t},\n\n\tfix: function( originalEvent ) {\n\t\treturn originalEvent[ jQuery.expando ] ?\n\t\t\toriginalEvent :\n\t\t\tnew jQuery.Event( originalEvent );\n\t},\n\n\tspecial: {\n\t\tload: {\n\n\t\t\t// Prevent triggered image.load events from bubbling to window.load\n\t\t\tnoBubble: true\n\t\t},\n\t\tfocus: {\n\n\t\t\t// Fire native event if possible so blur/focus sequence is correct\n\t\t\ttrigger: function() {\n\t\t\t\tif ( this !== safeActiveElement() && this.focus ) {\n\t\t\t\t\tthis.focus();\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t},\n\t\t\tdelegateType: \"focusin\"\n\t\t},\n\t\tblur: {\n\t\t\ttrigger: function() {\n\t\t\t\tif ( this === safeActiveElement() && this.blur ) {\n\t\t\t\t\tthis.blur();\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t},\n\t\t\tdelegateType: \"focusout\"\n\t\t},\n\t\tclick: {\n\n\t\t\t// For checkbox, fire native event so checked state will be right\n\t\t\ttrigger: function() {\n\t\t\t\tif ( this.type === \"checkbox\" && this.click && nodeName( this, \"input\" ) ) {\n\t\t\t\t\tthis.click();\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t},\n\n\t\t\t// For cross-browser consistency, don't fire native .click() on links\n\t\t\t_default: function( event ) {\n\t\t\t\treturn nodeName( event.target, \"a\" );\n\t\t\t}\n\t\t},\n\n\t\tbeforeunload: {\n\t\t\tpostDispatch: function( event ) {\n\n\t\t\t\t// Support: Firefox 20+\n\t\t\t\t// Firefox doesn't alert if the returnValue field is not set.\n\t\t\t\tif ( event.result !== undefined && event.originalEvent ) {\n\t\t\t\t\tevent.originalEvent.returnValue = event.result;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n};\n\njQuery.removeEvent = function( elem, type, handle ) {\n\n\t// This \"if\" is needed for plain objects\n\tif ( elem.removeEventListener ) {\n\t\telem.removeEventListener( type, handle );\n\t}\n};\n\njQuery.Event = function( src, props ) {\n\n\t// Allow instantiation without the 'new' keyword\n\tif ( !( this instanceof jQuery.Event ) ) {\n\t\treturn new jQuery.Event( src, props );\n\t}\n\n\t// Event object\n\tif ( src && src.type ) {\n\t\tthis.originalEvent = src;\n\t\tthis.type = src.type;\n\n\t\t// Events bubbling up the document may have been marked as prevented\n\t\t// by a handler lower down the tree; reflect the correct value.\n\t\tthis.isDefaultPrevented = src.defaultPrevented ||\n\t\t\t\tsrc.defaultPrevented === undefined &&\n\n\t\t\t\t// Support: Android <=2.3 only\n\t\t\t\tsrc.returnValue === false ?\n\t\t\treturnTrue :\n\t\t\treturnFalse;\n\n\t\t// Create target properties\n\t\t// Support: Safari <=6 - 7 only\n\t\t// Target should not be a text node (#504, #13143)\n\t\tthis.target = ( src.target && src.target.nodeType === 3 ) ?\n\t\t\tsrc.target.parentNode :\n\t\t\tsrc.target;\n\n\t\tthis.currentTarget = src.currentTarget;\n\t\tthis.relatedTarget = src.relatedTarget;\n\n\t// Event type\n\t} else {\n\t\tthis.type = src;\n\t}\n\n\t// Put explicitly provided properties onto the event object\n\tif ( props ) {\n\t\tjQuery.extend( this, props );\n\t}\n\n\t// Create a timestamp if incoming event doesn't have one\n\tthis.timeStamp = src && src.timeStamp || Date.now();\n\n\t// Mark it as fixed\n\tthis[ jQuery.expando ] = true;\n};\n\n// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding\n// https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html\njQuery.Event.prototype = {\n\tconstructor: jQuery.Event,\n\tisDefaultPrevented: returnFalse,\n\tisPropagationStopped: returnFalse,\n\tisImmediatePropagationStopped: returnFalse,\n\tisSimulated: false,\n\n\tpreventDefault: function() {\n\t\tvar e = this.originalEvent;\n\n\t\tthis.isDefaultPrevented = returnTrue;\n\n\t\tif ( e && !this.isSimulated ) {\n\t\t\te.preventDefault();\n\t\t}\n\t},\n\tstopPropagation: function() {\n\t\tvar e = this.originalEvent;\n\n\t\tthis.isPropagationStopped = returnTrue;\n\n\t\tif ( e && !this.isSimulated ) {\n\t\t\te.stopPropagation();\n\t\t}\n\t},\n\tstopImmediatePropagation: function() {\n\t\tvar e = this.originalEvent;\n\n\t\tthis.isImmediatePropagationStopped = returnTrue;\n\n\t\tif ( e && !this.isSimulated ) {\n\t\t\te.stopImmediatePropagation();\n\t\t}\n\n\t\tthis.stopPropagation();\n\t}\n};\n\n// Includes all common event props including KeyEvent and MouseEvent specific props\njQuery.each( {\n\taltKey: true,\n\tbubbles: true,\n\tcancelable: true,\n\tchangedTouches: true,\n\tctrlKey: true,\n\tdetail: true,\n\teventPhase: true,\n\tmetaKey: true,\n\tpageX: true,\n\tpageY: true,\n\tshiftKey: true,\n\tview: true,\n\t\"char\": true,\n\tcharCode: true,\n\tkey: true,\n\tkeyCode: true,\n\tbutton: true,\n\tbuttons: true,\n\tclientX: true,\n\tclientY: true,\n\toffsetX: true,\n\toffsetY: true,\n\tpointerId: true,\n\tpointerType: true,\n\tscreenX: true,\n\tscreenY: true,\n\ttargetTouches: true,\n\ttoElement: true,\n\ttouches: true,\n\n\twhich: function( event ) {\n\t\tvar button = event.button;\n\n\t\t// Add which for key events\n\t\tif ( event.which == null && rkeyEvent.test( event.type ) ) {\n\t\t\treturn event.charCode != null ? event.charCode : event.keyCode;\n\t\t}\n\n\t\t// Add which for click: 1 === left; 2 === middle; 3 === right\n\t\tif ( !event.which && button !== undefined && rmouseEvent.test( event.type ) ) {\n\t\t\tif ( button & 1 ) {\n\t\t\t\treturn 1;\n\t\t\t}\n\n\t\t\tif ( button & 2 ) {\n\t\t\t\treturn 3;\n\t\t\t}\n\n\t\t\tif ( button & 4 ) {\n\t\t\t\treturn 2;\n\t\t\t}\n\n\t\t\treturn 0;\n\t\t}\n\n\t\treturn event.which;\n\t}\n}, jQuery.event.addProp );\n\n// Create mouseenter/leave events using mouseover/out and event-time checks\n// so that event delegation works in jQuery.\n// Do the same for pointerenter/pointerleave and pointerover/pointerout\n//\n// Support: Safari 7 only\n// Safari sends mouseenter too often; see:\n// https://bugs.chromium.org/p/chromium/issues/detail?id=470258\n// for the description of the bug (it existed in older Chrome versions as well).\njQuery.each( {\n\tmouseenter: \"mouseover\",\n\tmouseleave: \"mouseout\",\n\tpointerenter: \"pointerover\",\n\tpointerleave: \"pointerout\"\n}, function( orig, fix ) {\n\tjQuery.event.special[ orig ] = {\n\t\tdelegateType: fix,\n\t\tbindType: fix,\n\n\t\thandle: function( event ) {\n\t\t\tvar ret,\n\t\t\t\ttarget = this,\n\t\t\t\trelated = event.relatedTarget,\n\t\t\t\thandleObj = event.handleObj;\n\n\t\t\t// For mouseenter/leave call the handler if related is outside the target.\n\t\t\t// NB: No relatedTarget if the mouse left/entered the browser window\n\t\t\tif ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) {\n\t\t\t\tevent.type = handleObj.origType;\n\t\t\t\tret = handleObj.handler.apply( this, arguments );\n\t\t\t\tevent.type = fix;\n\t\t\t}\n\t\t\treturn ret;\n\t\t}\n\t};\n} );\n\njQuery.fn.extend( {\n\n\ton: function( types, selector, data, fn ) {\n\t\treturn on( this, types, selector, data, fn );\n\t},\n\tone: function( types, selector, data, fn ) {\n\t\treturn on( this, types, selector, data, fn, 1 );\n\t},\n\toff: function( types, selector, fn ) {\n\t\tvar handleObj, type;\n\t\tif ( types && types.preventDefault && types.handleObj ) {\n\n\t\t\t// ( event )  dispatched jQuery.Event\n\t\t\thandleObj = types.handleObj;\n\t\t\tjQuery( types.delegateTarget ).off(\n\t\t\t\thandleObj.namespace ?\n\t\t\t\t\thandleObj.origType + \".\" + handleObj.namespace :\n\t\t\t\t\thandleObj.origType,\n\t\t\t\thandleObj.selector,\n\t\t\t\thandleObj.handler\n\t\t\t);\n\t\t\treturn this;\n\t\t}\n\t\tif ( typeof types === \"object\" ) {\n\n\t\t\t// ( types-object [, selector] )\n\t\t\tfor ( type in types ) {\n\t\t\t\tthis.off( type, selector, types[ type ] );\n\t\t\t}\n\t\t\treturn this;\n\t\t}\n\t\tif ( selector === false || typeof selector === \"function\" ) {\n\n\t\t\t// ( types [, fn] )\n\t\t\tfn = selector;\n\t\t\tselector = undefined;\n\t\t}\n\t\tif ( fn === false ) {\n\t\t\tfn = returnFalse;\n\t\t}\n\t\treturn this.each( function() {\n\t\t\tjQuery.event.remove( this, types, fn, selector );\n\t\t} );\n\t}\n} );\n\n\nvar\n\n\t/* eslint-disable max-len */\n\n\t// See https://github.com/eslint/eslint/issues/3229\n\trxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\\/\\0>\\x20\\t\\r\\n\\f]*)[^>]*)\\/>/gi,\n\n\t/* eslint-enable */\n\n\t// Support: IE <=10 - 11, Edge 12 - 13 only\n\t// In IE/Edge using regex groups here causes severe slowdowns.\n\t// See https://connect.microsoft.com/IE/feedback/details/1736512/\n\trnoInnerhtml = /<script|<style|<link/i,\n\n\t// checked=\"checked\" or checked\n\trchecked = /checked\\s*(?:[^=]|=\\s*.checked.)/i,\n\trcleanScript = /^\\s*<!(?:\\[CDATA\\[|--)|(?:\\]\\]|--)>\\s*$/g;\n\n// Prefer a tbody over its parent table for containing new rows\nfunction manipulationTarget( elem, content ) {\n\tif ( nodeName( elem, \"table\" ) &&\n\t\tnodeName( content.nodeType !== 11 ? content : content.firstChild, \"tr\" ) ) {\n\n\t\treturn jQuery( elem ).children( \"tbody\" )[ 0 ] || elem;\n\t}\n\n\treturn elem;\n}\n\n// Replace/restore the type attribute of script elements for safe DOM manipulation\nfunction disableScript( elem ) {\n\telem.type = ( elem.getAttribute( \"type\" ) !== null ) + \"/\" + elem.type;\n\treturn elem;\n}\nfunction restoreScript( elem ) {\n\tif ( ( elem.type || \"\" ).slice( 0, 5 ) === \"true/\" ) {\n\t\telem.type = elem.type.slice( 5 );\n\t} else {\n\t\telem.removeAttribute( \"type\" );\n\t}\n\n\treturn elem;\n}\n\nfunction cloneCopyEvent( src, dest ) {\n\tvar i, l, type, pdataOld, pdataCur, udataOld, udataCur, events;\n\n\tif ( dest.nodeType !== 1 ) {\n\t\treturn;\n\t}\n\n\t// 1. Copy private data: events, handlers, etc.\n\tif ( dataPriv.hasData( src ) ) {\n\t\tpdataOld = dataPriv.access( src );\n\t\tpdataCur = dataPriv.set( dest, pdataOld );\n\t\tevents = pdataOld.events;\n\n\t\tif ( events ) {\n\t\t\tdelete pdataCur.handle;\n\t\t\tpdataCur.events = {};\n\n\t\t\tfor ( type in events ) {\n\t\t\t\tfor ( i = 0, l = events[ type ].length; i < l; i++ ) {\n\t\t\t\t\tjQuery.event.add( dest, type, events[ type ][ i ] );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// 2. Copy user data\n\tif ( dataUser.hasData( src ) ) {\n\t\tudataOld = dataUser.access( src );\n\t\tudataCur = jQuery.extend( {}, udataOld );\n\n\t\tdataUser.set( dest, udataCur );\n\t}\n}\n\n// Fix IE bugs, see support tests\nfunction fixInput( src, dest ) {\n\tvar nodeName = dest.nodeName.toLowerCase();\n\n\t// Fails to persist the checked state of a cloned checkbox or radio button.\n\tif ( nodeName === \"input\" && rcheckableType.test( src.type ) ) {\n\t\tdest.checked = src.checked;\n\n\t// Fails to return the selected option to the default selected state when cloning options\n\t} else if ( nodeName === \"input\" || nodeName === \"textarea\" ) {\n\t\tdest.defaultValue = src.defaultValue;\n\t}\n}\n\nfunction domManip( collection, args, callback, ignored ) {\n\n\t// Flatten any nested arrays\n\targs = concat.apply( [], args );\n\n\tvar fragment, first, scripts, hasScripts, node, doc,\n\t\ti = 0,\n\t\tl = collection.length,\n\t\tiNoClone = l - 1,\n\t\tvalue = args[ 0 ],\n\t\tvalueIsFunction = isFunction( value );\n\n\t// We can't cloneNode fragments that contain checked, in WebKit\n\tif ( valueIsFunction ||\n\t\t\t( l > 1 && typeof value === \"string\" &&\n\t\t\t\t!support.checkClone && rchecked.test( value ) ) ) {\n\t\treturn collection.each( function( index ) {\n\t\t\tvar self = collection.eq( index );\n\t\t\tif ( valueIsFunction ) {\n\t\t\t\targs[ 0 ] = value.call( this, index, self.html() );\n\t\t\t}\n\t\t\tdomManip( self, args, callback, ignored );\n\t\t} );\n\t}\n\n\tif ( l ) {\n\t\tfragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored );\n\t\tfirst = fragment.firstChild;\n\n\t\tif ( fragment.childNodes.length === 1 ) {\n\t\t\tfragment = first;\n\t\t}\n\n\t\t// Require either new content or an interest in ignored elements to invoke the callback\n\t\tif ( first || ignored ) {\n\t\t\tscripts = jQuery.map( getAll( fragment, \"script\" ), disableScript );\n\t\t\thasScripts = scripts.length;\n\n\t\t\t// Use the original fragment for the last item\n\t\t\t// instead of the first because it can end up\n\t\t\t// being emptied incorrectly in certain situations (#8070).\n\t\t\tfor ( ; i < l; i++ ) {\n\t\t\t\tnode = fragment;\n\n\t\t\t\tif ( i !== iNoClone ) {\n\t\t\t\t\tnode = jQuery.clone( node, true, true );\n\n\t\t\t\t\t// Keep references to cloned scripts for later restoration\n\t\t\t\t\tif ( hasScripts ) {\n\n\t\t\t\t\t\t// Support: Android <=4.0 only, PhantomJS 1 only\n\t\t\t\t\t\t// push.apply(_, arraylike) throws on ancient WebKit\n\t\t\t\t\t\tjQuery.merge( scripts, getAll( node, \"script\" ) );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tcallback.call( collection[ i ], node, i );\n\t\t\t}\n\n\t\t\tif ( hasScripts ) {\n\t\t\t\tdoc = scripts[ scripts.length - 1 ].ownerDocument;\n\n\t\t\t\t// Reenable scripts\n\t\t\t\tjQuery.map( scripts, restoreScript );\n\n\t\t\t\t// Evaluate executable scripts on first document insertion\n\t\t\t\tfor ( i = 0; i < hasScripts; i++ ) {\n\t\t\t\t\tnode = scripts[ i ];\n\t\t\t\t\tif ( rscriptType.test( node.type || \"\" ) &&\n\t\t\t\t\t\t!dataPriv.access( node, \"globalEval\" ) &&\n\t\t\t\t\t\tjQuery.contains( doc, node ) ) {\n\n\t\t\t\t\t\tif ( node.src && ( node.type || \"\" ).toLowerCase()  !== \"module\" ) {\n\n\t\t\t\t\t\t\t// Optional AJAX dependency, but won't run scripts if not present\n\t\t\t\t\t\t\tif ( jQuery._evalUrl ) {\n\t\t\t\t\t\t\t\tjQuery._evalUrl( node.src );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tDOMEval( node.textContent.replace( rcleanScript, \"\" ), doc, node );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn collection;\n}\n\nfunction remove( elem, selector, keepData ) {\n\tvar node,\n\t\tnodes = selector ? jQuery.filter( selector, elem ) : elem,\n\t\ti = 0;\n\n\tfor ( ; ( node = nodes[ i ] ) != null; i++ ) {\n\t\tif ( !keepData && node.nodeType === 1 ) {\n\t\t\tjQuery.cleanData( getAll( node ) );\n\t\t}\n\n\t\tif ( node.parentNode ) {\n\t\t\tif ( keepData && jQuery.contains( node.ownerDocument, node ) ) {\n\t\t\t\tsetGlobalEval( getAll( node, \"script\" ) );\n\t\t\t}\n\t\t\tnode.parentNode.removeChild( node );\n\t\t}\n\t}\n\n\treturn elem;\n}\n\njQuery.extend( {\n\thtmlPrefilter: function( html ) {\n\t\treturn html.replace( rxhtmlTag, \"<$1></$2>\" );\n\t},\n\n\tclone: function( elem, dataAndEvents, deepDataAndEvents ) {\n\t\tvar i, l, srcElements, destElements,\n\t\t\tclone = elem.cloneNode( true ),\n\t\t\tinPage = jQuery.contains( elem.ownerDocument, elem );\n\n\t\t// Fix IE cloning issues\n\t\tif ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) &&\n\t\t\t\t!jQuery.isXMLDoc( elem ) ) {\n\n\t\t\t// We eschew Sizzle here for performance reasons: https://jsperf.com/getall-vs-sizzle/2\n\t\t\tdestElements = getAll( clone );\n\t\t\tsrcElements = getAll( elem );\n\n\t\t\tfor ( i = 0, l = srcElements.length; i < l; i++ ) {\n\t\t\t\tfixInput( srcElements[ i ], destElements[ i ] );\n\t\t\t}\n\t\t}\n\n\t\t// Copy the events from the original to the clone\n\t\tif ( dataAndEvents ) {\n\t\t\tif ( deepDataAndEvents ) {\n\t\t\t\tsrcElements = srcElements || getAll( elem );\n\t\t\t\tdestElements = destElements || getAll( clone );\n\n\t\t\t\tfor ( i = 0, l = srcElements.length; i < l; i++ ) {\n\t\t\t\t\tcloneCopyEvent( srcElements[ i ], destElements[ i ] );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tcloneCopyEvent( elem, clone );\n\t\t\t}\n\t\t}\n\n\t\t// Preserve script evaluation history\n\t\tdestElements = getAll( clone, \"script\" );\n\t\tif ( destElements.length > 0 ) {\n\t\t\tsetGlobalEval( destElements, !inPage && getAll( elem, \"script\" ) );\n\t\t}\n\n\t\t// Return the cloned set\n\t\treturn clone;\n\t},\n\n\tcleanData: function( elems ) {\n\t\tvar data, elem, type,\n\t\t\tspecial = jQuery.event.special,\n\t\t\ti = 0;\n\n\t\tfor ( ; ( elem = elems[ i ] ) !== undefined; i++ ) {\n\t\t\tif ( acceptData( elem ) ) {\n\t\t\t\tif ( ( data = elem[ dataPriv.expando ] ) ) {\n\t\t\t\t\tif ( data.events ) {\n\t\t\t\t\t\tfor ( type in data.events ) {\n\t\t\t\t\t\t\tif ( special[ type ] ) {\n\t\t\t\t\t\t\t\tjQuery.event.remove( elem, type );\n\n\t\t\t\t\t\t\t// This is a shortcut to avoid jQuery.event.remove's overhead\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tjQuery.removeEvent( elem, type, data.handle );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Support: Chrome <=35 - 45+\n\t\t\t\t\t// Assign undefined instead of using delete, see Data#remove\n\t\t\t\t\telem[ dataPriv.expando ] = undefined;\n\t\t\t\t}\n\t\t\t\tif ( elem[ dataUser.expando ] ) {\n\n\t\t\t\t\t// Support: Chrome <=35 - 45+\n\t\t\t\t\t// Assign undefined instead of using delete, see Data#remove\n\t\t\t\t\telem[ dataUser.expando ] = undefined;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n} );\n\njQuery.fn.extend( {\n\tdetach: function( selector ) {\n\t\treturn remove( this, selector, true );\n\t},\n\n\tremove: function( selector ) {\n\t\treturn remove( this, selector );\n\t},\n\n\ttext: function( value ) {\n\t\treturn access( this, function( value ) {\n\t\t\treturn value === undefined ?\n\t\t\t\tjQuery.text( this ) :\n\t\t\t\tthis.empty().each( function() {\n\t\t\t\t\tif ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {\n\t\t\t\t\t\tthis.textContent = value;\n\t\t\t\t\t}\n\t\t\t\t} );\n\t\t}, null, value, arguments.length );\n\t},\n\n\tappend: function() {\n\t\treturn domManip( this, arguments, function( elem ) {\n\t\t\tif ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {\n\t\t\t\tvar target = manipulationTarget( this, elem );\n\t\t\t\ttarget.appendChild( elem );\n\t\t\t}\n\t\t} );\n\t},\n\n\tprepend: function() {\n\t\treturn domManip( this, arguments, function( elem ) {\n\t\t\tif ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {\n\t\t\t\tvar target = manipulationTarget( this, elem );\n\t\t\t\ttarget.insertBefore( elem, target.firstChild );\n\t\t\t}\n\t\t} );\n\t},\n\n\tbefore: function() {\n\t\treturn domManip( this, arguments, function( elem ) {\n\t\t\tif ( this.parentNode ) {\n\t\t\t\tthis.parentNode.insertBefore( elem, this );\n\t\t\t}\n\t\t} );\n\t},\n\n\tafter: function() {\n\t\treturn domManip( this, arguments, function( elem ) {\n\t\t\tif ( this.parentNode ) {\n\t\t\t\tthis.parentNode.insertBefore( elem, this.nextSibling );\n\t\t\t}\n\t\t} );\n\t},\n\n\tempty: function() {\n\t\tvar elem,\n\t\t\ti = 0;\n\n\t\tfor ( ; ( elem = this[ i ] ) != null; i++ ) {\n\t\t\tif ( elem.nodeType === 1 ) {\n\n\t\t\t\t// Prevent memory leaks\n\t\t\t\tjQuery.cleanData( getAll( elem, false ) );\n\n\t\t\t\t// Remove any remaining nodes\n\t\t\t\telem.textContent = \"\";\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\tclone: function( dataAndEvents, deepDataAndEvents ) {\n\t\tdataAndEvents = dataAndEvents == null ? false : dataAndEvents;\n\t\tdeepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;\n\n\t\treturn this.map( function() {\n\t\t\treturn jQuery.clone( this, dataAndEvents, deepDataAndEvents );\n\t\t} );\n\t},\n\n\thtml: function( value ) {\n\t\treturn access( this, function( value ) {\n\t\t\tvar elem = this[ 0 ] || {},\n\t\t\t\ti = 0,\n\t\t\t\tl = this.length;\n\n\t\t\tif ( value === undefined && elem.nodeType === 1 ) {\n\t\t\t\treturn elem.innerHTML;\n\t\t\t}\n\n\t\t\t// See if we can take a shortcut and just use innerHTML\n\t\t\tif ( typeof value === \"string\" && !rnoInnerhtml.test( value ) &&\n\t\t\t\t!wrapMap[ ( rtagName.exec( value ) || [ \"\", \"\" ] )[ 1 ].toLowerCase() ] ) {\n\n\t\t\t\tvalue = jQuery.htmlPrefilter( value );\n\n\t\t\t\ttry {\n\t\t\t\t\tfor ( ; i < l; i++ ) {\n\t\t\t\t\t\telem = this[ i ] || {};\n\n\t\t\t\t\t\t// Remove element nodes and prevent memory leaks\n\t\t\t\t\t\tif ( elem.nodeType === 1 ) {\n\t\t\t\t\t\t\tjQuery.cleanData( getAll( elem, false ) );\n\t\t\t\t\t\t\telem.innerHTML = value;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\telem = 0;\n\n\t\t\t\t// If using innerHTML throws an exception, use the fallback method\n\t\t\t\t} catch ( e ) {}\n\t\t\t}\n\n\t\t\tif ( elem ) {\n\t\t\t\tthis.empty().append( value );\n\t\t\t}\n\t\t}, null, value, arguments.length );\n\t},\n\n\treplaceWith: function() {\n\t\tvar ignored = [];\n\n\t\t// Make the changes, replacing each non-ignored context element with the new content\n\t\treturn domManip( this, arguments, function( elem ) {\n\t\t\tvar parent = this.parentNode;\n\n\t\t\tif ( jQuery.inArray( this, ignored ) < 0 ) {\n\t\t\t\tjQuery.cleanData( getAll( this ) );\n\t\t\t\tif ( parent ) {\n\t\t\t\t\tparent.replaceChild( elem, this );\n\t\t\t\t}\n\t\t\t}\n\n\t\t// Force callback invocation\n\t\t}, ignored );\n\t}\n} );\n\njQuery.each( {\n\tappendTo: \"append\",\n\tprependTo: \"prepend\",\n\tinsertBefore: \"before\",\n\tinsertAfter: \"after\",\n\treplaceAll: \"replaceWith\"\n}, function( name, original ) {\n\tjQuery.fn[ name ] = function( selector ) {\n\t\tvar elems,\n\t\t\tret = [],\n\t\t\tinsert = jQuery( selector ),\n\t\t\tlast = insert.length - 1,\n\t\t\ti = 0;\n\n\t\tfor ( ; i <= last; i++ ) {\n\t\t\telems = i === last ? this : this.clone( true );\n\t\t\tjQuery( insert[ i ] )[ original ]( elems );\n\n\t\t\t// Support: Android <=4.0 only, PhantomJS 1 only\n\t\t\t// .get() because push.apply(_, arraylike) throws on ancient WebKit\n\t\t\tpush.apply( ret, elems.get() );\n\t\t}\n\n\t\treturn this.pushStack( ret );\n\t};\n} );\nvar rnumnonpx = new RegExp( \"^(\" + pnum + \")(?!px)[a-z%]+$\", \"i\" );\n\nvar getStyles = function( elem ) {\n\n\t\t// Support: IE <=11 only, Firefox <=30 (#15098, #14150)\n\t\t// IE throws on elements created in popups\n\t\t// FF meanwhile throws on frame elements through \"defaultView.getComputedStyle\"\n\t\tvar view = elem.ownerDocument.defaultView;\n\n\t\tif ( !view || !view.opener ) {\n\t\t\tview = window;\n\t\t}\n\n\t\treturn view.getComputedStyle( elem );\n\t};\n\nvar rboxStyle = new RegExp( cssExpand.join( \"|\" ), \"i\" );\n\n\n\n( function() {\n\n\t// Executing both pixelPosition & boxSizingReliable tests require only one layout\n\t// so they're executed at the same time to save the second computation.\n\tfunction computeStyleTests() {\n\n\t\t// This is a singleton, we need to execute it only once\n\t\tif ( !div ) {\n\t\t\treturn;\n\t\t}\n\n\t\tcontainer.style.cssText = \"position:absolute;left:-11111px;width:60px;\" +\n\t\t\t\"margin-top:1px;padding:0;border:0\";\n\t\tdiv.style.cssText =\n\t\t\t\"position:relative;display:block;box-sizing:border-box;overflow:scroll;\" +\n\t\t\t\"margin:auto;border:1px;padding:1px;\" +\n\t\t\t\"width:60%;top:1%\";\n\t\tdocumentElement.appendChild( container ).appendChild( div );\n\n\t\tvar divStyle = window.getComputedStyle( div );\n\t\tpixelPositionVal = divStyle.top !== \"1%\";\n\n\t\t// Support: Android 4.0 - 4.3 only, Firefox <=3 - 44\n\t\treliableMarginLeftVal = roundPixelMeasures( divStyle.marginLeft ) === 12;\n\n\t\t// Support: Android 4.0 - 4.3 only, Safari <=9.1 - 10.1, iOS <=7.0 - 9.3\n\t\t// Some styles come back with percentage values, even though they shouldn't\n\t\tdiv.style.right = \"60%\";\n\t\tpixelBoxStylesVal = roundPixelMeasures( divStyle.right ) === 36;\n\n\t\t// Support: IE 9 - 11 only\n\t\t// Detect misreporting of content dimensions for box-sizing:border-box elements\n\t\tboxSizingReliableVal = roundPixelMeasures( divStyle.width ) === 36;\n\n\t\t// Support: IE 9 only\n\t\t// Detect overflow:scroll screwiness (gh-3699)\n\t\tdiv.style.position = \"absolute\";\n\t\tscrollboxSizeVal = div.offsetWidth === 36 || \"absolute\";\n\n\t\tdocumentElement.removeChild( container );\n\n\t\t// Nullify the div so it wouldn't be stored in the memory and\n\t\t// it will also be a sign that checks already performed\n\t\tdiv = null;\n\t}\n\n\tfunction roundPixelMeasures( measure ) {\n\t\treturn Math.round( parseFloat( measure ) );\n\t}\n\n\tvar pixelPositionVal, boxSizingReliableVal, scrollboxSizeVal, pixelBoxStylesVal,\n\t\treliableMarginLeftVal,\n\t\tcontainer = document.createElement( \"div\" ),\n\t\tdiv = document.createElement( \"div\" );\n\n\t// Finish early in limited (non-browser) environments\n\tif ( !div.style ) {\n\t\treturn;\n\t}\n\n\t// Support: IE <=9 - 11 only\n\t// Style of cloned element affects source element cloned (#8908)\n\tdiv.style.backgroundClip = \"content-box\";\n\tdiv.cloneNode( true ).style.backgroundClip = \"\";\n\tsupport.clearCloneStyle = div.style.backgroundClip === \"content-box\";\n\n\tjQuery.extend( support, {\n\t\tboxSizingReliable: function() {\n\t\t\tcomputeStyleTests();\n\t\t\treturn boxSizingReliableVal;\n\t\t},\n\t\tpixelBoxStyles: function() {\n\t\t\tcomputeStyleTests();\n\t\t\treturn pixelBoxStylesVal;\n\t\t},\n\t\tpixelPosition: function() {\n\t\t\tcomputeStyleTests();\n\t\t\treturn pixelPositionVal;\n\t\t},\n\t\treliableMarginLeft: function() {\n\t\t\tcomputeStyleTests();\n\t\t\treturn reliableMarginLeftVal;\n\t\t},\n\t\tscrollboxSize: function() {\n\t\t\tcomputeStyleTests();\n\t\t\treturn scrollboxSizeVal;\n\t\t}\n\t} );\n} )();\n\n\nfunction curCSS( elem, name, computed ) {\n\tvar width, minWidth, maxWidth, ret,\n\n\t\t// Support: Firefox 51+\n\t\t// Retrieving style before computed somehow\n\t\t// fixes an issue with getting wrong values\n\t\t// on detached elements\n\t\tstyle = elem.style;\n\n\tcomputed = computed || getStyles( elem );\n\n\t// getPropertyValue is needed for:\n\t//   .css('filter') (IE 9 only, #12537)\n\t//   .css('--customProperty) (#3144)\n\tif ( computed ) {\n\t\tret = computed.getPropertyValue( name ) || computed[ name ];\n\n\t\tif ( ret === \"\" && !jQuery.contains( elem.ownerDocument, elem ) ) {\n\t\t\tret = jQuery.style( elem, name );\n\t\t}\n\n\t\t// A tribute to the \"awesome hack by Dean Edwards\"\n\t\t// Android Browser returns percentage for some values,\n\t\t// but width seems to be reliably pixels.\n\t\t// This is against the CSSOM draft spec:\n\t\t// https://drafts.csswg.org/cssom/#resolved-values\n\t\tif ( !support.pixelBoxStyles() && rnumnonpx.test( ret ) && rboxStyle.test( name ) ) {\n\n\t\t\t// Remember the original values\n\t\t\twidth = style.width;\n\t\t\tminWidth = style.minWidth;\n\t\t\tmaxWidth = style.maxWidth;\n\n\t\t\t// Put in the new values to get a computed value out\n\t\t\tstyle.minWidth = style.maxWidth = style.width = ret;\n\t\t\tret = computed.width;\n\n\t\t\t// Revert the changed values\n\t\t\tstyle.width = width;\n\t\t\tstyle.minWidth = minWidth;\n\t\t\tstyle.maxWidth = maxWidth;\n\t\t}\n\t}\n\n\treturn ret !== undefined ?\n\n\t\t// Support: IE <=9 - 11 only\n\t\t// IE returns zIndex value as an integer.\n\t\tret + \"\" :\n\t\tret;\n}\n\n\nfunction addGetHookIf( conditionFn, hookFn ) {\n\n\t// Define the hook, we'll check on the first run if it's really needed.\n\treturn {\n\t\tget: function() {\n\t\t\tif ( conditionFn() ) {\n\n\t\t\t\t// Hook not needed (or it's not possible to use it due\n\t\t\t\t// to missing dependency), remove it.\n\t\t\t\tdelete this.get;\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Hook needed; redefine it so that the support test is not executed again.\n\t\t\treturn ( this.get = hookFn ).apply( this, arguments );\n\t\t}\n\t};\n}\n\n\nvar\n\n\t// Swappable if display is none or starts with table\n\t// except \"table\", \"table-cell\", or \"table-caption\"\n\t// See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display\n\trdisplayswap = /^(none|table(?!-c[ea]).+)/,\n\trcustomProp = /^--/,\n\tcssShow = { position: \"absolute\", visibility: \"hidden\", display: \"block\" },\n\tcssNormalTransform = {\n\t\tletterSpacing: \"0\",\n\t\tfontWeight: \"400\"\n\t},\n\n\tcssPrefixes = [ \"Webkit\", \"Moz\", \"ms\" ],\n\temptyStyle = document.createElement( \"div\" ).style;\n\n// Return a css property mapped to a potentially vendor prefixed property\nfunction vendorPropName( name ) {\n\n\t// Shortcut for names that are not vendor prefixed\n\tif ( name in emptyStyle ) {\n\t\treturn name;\n\t}\n\n\t// Check for vendor prefixed names\n\tvar capName = name[ 0 ].toUpperCase() + name.slice( 1 ),\n\t\ti = cssPrefixes.length;\n\n\twhile ( i-- ) {\n\t\tname = cssPrefixes[ i ] + capName;\n\t\tif ( name in emptyStyle ) {\n\t\t\treturn name;\n\t\t}\n\t}\n}\n\n// Return a property mapped along what jQuery.cssProps suggests or to\n// a vendor prefixed property.\nfunction finalPropName( name ) {\n\tvar ret = jQuery.cssProps[ name ];\n\tif ( !ret ) {\n\t\tret = jQuery.cssProps[ name ] = vendorPropName( name ) || name;\n\t}\n\treturn ret;\n}\n\nfunction setPositiveNumber( elem, value, subtract ) {\n\n\t// Any relative (+/-) values have already been\n\t// normalized at this point\n\tvar matches = rcssNum.exec( value );\n\treturn matches ?\n\n\t\t// Guard against undefined \"subtract\", e.g., when used as in cssHooks\n\t\tMath.max( 0, matches[ 2 ] - ( subtract || 0 ) ) + ( matches[ 3 ] || \"px\" ) :\n\t\tvalue;\n}\n\nfunction boxModelAdjustment( elem, dimension, box, isBorderBox, styles, computedVal ) {\n\tvar i = dimension === \"width\" ? 1 : 0,\n\t\textra = 0,\n\t\tdelta = 0;\n\n\t// Adjustment may not be necessary\n\tif ( box === ( isBorderBox ? \"border\" : \"content\" ) ) {\n\t\treturn 0;\n\t}\n\n\tfor ( ; i < 4; i += 2 ) {\n\n\t\t// Both box models exclude margin\n\t\tif ( box === \"margin\" ) {\n\t\t\tdelta += jQuery.css( elem, box + cssExpand[ i ], true, styles );\n\t\t}\n\n\t\t// If we get here with a content-box, we're seeking \"padding\" or \"border\" or \"margin\"\n\t\tif ( !isBorderBox ) {\n\n\t\t\t// Add padding\n\t\t\tdelta += jQuery.css( elem, \"padding\" + cssExpand[ i ], true, styles );\n\n\t\t\t// For \"border\" or \"margin\", add border\n\t\t\tif ( box !== \"padding\" ) {\n\t\t\t\tdelta += jQuery.css( elem, \"border\" + cssExpand[ i ] + \"Width\", true, styles );\n\n\t\t\t// But still keep track of it otherwise\n\t\t\t} else {\n\t\t\t\textra += jQuery.css( elem, \"border\" + cssExpand[ i ] + \"Width\", true, styles );\n\t\t\t}\n\n\t\t// If we get here with a border-box (content + padding + border), we're seeking \"content\" or\n\t\t// \"padding\" or \"margin\"\n\t\t} else {\n\n\t\t\t// For \"content\", subtract padding\n\t\t\tif ( box === \"content\" ) {\n\t\t\t\tdelta -= jQuery.css( elem, \"padding\" + cssExpand[ i ], true, styles );\n\t\t\t}\n\n\t\t\t// For \"content\" or \"padding\", subtract border\n\t\t\tif ( box !== \"margin\" ) {\n\t\t\t\tdelta -= jQuery.css( elem, \"border\" + cssExpand[ i ] + \"Width\", true, styles );\n\t\t\t}\n\t\t}\n\t}\n\n\t// Account for positive content-box scroll gutter when requested by providing computedVal\n\tif ( !isBorderBox && computedVal >= 0 ) {\n\n\t\t// offsetWidth/offsetHeight is a rounded sum of content, padding, scroll gutter, and border\n\t\t// Assuming integer scroll gutter, subtract the rest and round down\n\t\tdelta += Math.max( 0, Math.ceil(\n\t\t\telem[ \"offset\" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] -\n\t\t\tcomputedVal -\n\t\t\tdelta -\n\t\t\textra -\n\t\t\t0.5\n\t\t) );\n\t}\n\n\treturn delta;\n}\n\nfunction getWidthOrHeight( elem, dimension, extra ) {\n\n\t// Start with computed style\n\tvar styles = getStyles( elem ),\n\t\tval = curCSS( elem, dimension, styles ),\n\t\tisBorderBox = jQuery.css( elem, \"boxSizing\", false, styles ) === \"border-box\",\n\t\tvalueIsBorderBox = isBorderBox;\n\n\t// Support: Firefox <=54\n\t// Return a confounding non-pixel value or feign ignorance, as appropriate.\n\tif ( rnumnonpx.test( val ) ) {\n\t\tif ( !extra ) {\n\t\t\treturn val;\n\t\t}\n\t\tval = \"auto\";\n\t}\n\n\t// Check for style in case a browser which returns unreliable values\n\t// for getComputedStyle silently falls back to the reliable elem.style\n\tvalueIsBorderBox = valueIsBorderBox &&\n\t\t( support.boxSizingReliable() || val === elem.style[ dimension ] );\n\n\t// Fall back to offsetWidth/offsetHeight when value is \"auto\"\n\t// This happens for inline elements with no explicit setting (gh-3571)\n\t// Support: Android <=4.1 - 4.3 only\n\t// Also use offsetWidth/offsetHeight for misreported inline dimensions (gh-3602)\n\tif ( val === \"auto\" ||\n\t\t!parseFloat( val ) && jQuery.css( elem, \"display\", false, styles ) === \"inline\" ) {\n\n\t\tval = elem[ \"offset\" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ];\n\n\t\t// offsetWidth/offsetHeight provide border-box values\n\t\tvalueIsBorderBox = true;\n\t}\n\n\t// Normalize \"\" and auto\n\tval = parseFloat( val ) || 0;\n\n\t// Adjust for the element's box model\n\treturn ( val +\n\t\tboxModelAdjustment(\n\t\t\telem,\n\t\t\tdimension,\n\t\t\textra || ( isBorderBox ? \"border\" : \"content\" ),\n\t\t\tvalueIsBorderBox,\n\t\t\tstyles,\n\n\t\t\t// Provide the current computed size to request scroll gutter calculation (gh-3589)\n\t\t\tval\n\t\t)\n\t) + \"px\";\n}\n\njQuery.extend( {\n\n\t// Add in style property hooks for overriding the default\n\t// behavior of getting and setting a style property\n\tcssHooks: {\n\t\topacity: {\n\t\t\tget: function( elem, computed ) {\n\t\t\t\tif ( computed ) {\n\n\t\t\t\t\t// We should always get a number back from opacity\n\t\t\t\t\tvar ret = curCSS( elem, \"opacity\" );\n\t\t\t\t\treturn ret === \"\" ? \"1\" : ret;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n\n\t// Don't automatically add \"px\" to these possibly-unitless properties\n\tcssNumber: {\n\t\t\"animationIterationCount\": true,\n\t\t\"columnCount\": true,\n\t\t\"fillOpacity\": true,\n\t\t\"flexGrow\": true,\n\t\t\"flexShrink\": true,\n\t\t\"fontWeight\": true,\n\t\t\"lineHeight\": true,\n\t\t\"opacity\": true,\n\t\t\"order\": true,\n\t\t\"orphans\": true,\n\t\t\"widows\": true,\n\t\t\"zIndex\": true,\n\t\t\"zoom\": true\n\t},\n\n\t// Add in properties whose names you wish to fix before\n\t// setting or getting the value\n\tcssProps: {},\n\n\t// Get and set the style property on a DOM Node\n\tstyle: function( elem, name, value, extra ) {\n\n\t\t// Don't set styles on text and comment nodes\n\t\tif ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Make sure that we're working with the right name\n\t\tvar ret, type, hooks,\n\t\t\torigName = camelCase( name ),\n\t\t\tisCustomProp = rcustomProp.test( name ),\n\t\t\tstyle = elem.style;\n\n\t\t// Make sure that we're working with the right name. We don't\n\t\t// want to query the value if it is a CSS custom property\n\t\t// since they are user-defined.\n\t\tif ( !isCustomProp ) {\n\t\t\tname = finalPropName( origName );\n\t\t}\n\n\t\t// Gets hook for the prefixed version, then unprefixed version\n\t\thooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];\n\n\t\t// Check if we're setting a value\n\t\tif ( value !== undefined ) {\n\t\t\ttype = typeof value;\n\n\t\t\t// Convert \"+=\" or \"-=\" to relative numbers (#7345)\n\t\t\tif ( type === \"string\" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) {\n\t\t\t\tvalue = adjustCSS( elem, name, ret );\n\n\t\t\t\t// Fixes bug #9237\n\t\t\t\ttype = \"number\";\n\t\t\t}\n\n\t\t\t// Make sure that null and NaN values aren't set (#7116)\n\t\t\tif ( value == null || value !== value ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// If a number was passed in, add the unit (except for certain CSS properties)\n\t\t\tif ( type === \"number\" ) {\n\t\t\t\tvalue += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? \"\" : \"px\" );\n\t\t\t}\n\n\t\t\t// background-* props affect original clone's values\n\t\t\tif ( !support.clearCloneStyle && value === \"\" && name.indexOf( \"background\" ) === 0 ) {\n\t\t\t\tstyle[ name ] = \"inherit\";\n\t\t\t}\n\n\t\t\t// If a hook was provided, use that value, otherwise just set the specified value\n\t\t\tif ( !hooks || !( \"set\" in hooks ) ||\n\t\t\t\t( value = hooks.set( elem, value, extra ) ) !== undefined ) {\n\n\t\t\t\tif ( isCustomProp ) {\n\t\t\t\t\tstyle.setProperty( name, value );\n\t\t\t\t} else {\n\t\t\t\t\tstyle[ name ] = value;\n\t\t\t\t}\n\t\t\t}\n\n\t\t} else {\n\n\t\t\t// If a hook was provided get the non-computed value from there\n\t\t\tif ( hooks && \"get\" in hooks &&\n\t\t\t\t( ret = hooks.get( elem, false, extra ) ) !== undefined ) {\n\n\t\t\t\treturn ret;\n\t\t\t}\n\n\t\t\t// Otherwise just get the value from the style object\n\t\t\treturn style[ name ];\n\t\t}\n\t},\n\n\tcss: function( elem, name, extra, styles ) {\n\t\tvar val, num, hooks,\n\t\t\torigName = camelCase( name ),\n\t\t\tisCustomProp = rcustomProp.test( name );\n\n\t\t// Make sure that we're working with the right name. We don't\n\t\t// want to modify the value if it is a CSS custom property\n\t\t// since they are user-defined.\n\t\tif ( !isCustomProp ) {\n\t\t\tname = finalPropName( origName );\n\t\t}\n\n\t\t// Try prefixed name followed by the unprefixed name\n\t\thooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];\n\n\t\t// If a hook was provided get the computed value from there\n\t\tif ( hooks && \"get\" in hooks ) {\n\t\t\tval = hooks.get( elem, true, extra );\n\t\t}\n\n\t\t// Otherwise, if a way to get the computed value exists, use that\n\t\tif ( val === undefined ) {\n\t\t\tval = curCSS( elem, name, styles );\n\t\t}\n\n\t\t// Convert \"normal\" to computed value\n\t\tif ( val === \"normal\" && name in cssNormalTransform ) {\n\t\t\tval = cssNormalTransform[ name ];\n\t\t}\n\n\t\t// Make numeric if forced or a qualifier was provided and val looks numeric\n\t\tif ( extra === \"\" || extra ) {\n\t\t\tnum = parseFloat( val );\n\t\t\treturn extra === true || isFinite( num ) ? num || 0 : val;\n\t\t}\n\n\t\treturn val;\n\t}\n} );\n\njQuery.each( [ \"height\", \"width\" ], function( i, dimension ) {\n\tjQuery.cssHooks[ dimension ] = {\n\t\tget: function( elem, computed, extra ) {\n\t\t\tif ( computed ) {\n\n\t\t\t\t// Certain elements can have dimension info if we invisibly show them\n\t\t\t\t// but it must have a current display style that would benefit\n\t\t\t\treturn rdisplayswap.test( jQuery.css( elem, \"display\" ) ) &&\n\n\t\t\t\t\t// Support: Safari 8+\n\t\t\t\t\t// Table columns in Safari have non-zero offsetWidth & zero\n\t\t\t\t\t// getBoundingClientRect().width unless display is changed.\n\t\t\t\t\t// Support: IE <=11 only\n\t\t\t\t\t// Running getBoundingClientRect on a disconnected node\n\t\t\t\t\t// in IE throws an error.\n\t\t\t\t\t( !elem.getClientRects().length || !elem.getBoundingClientRect().width ) ?\n\t\t\t\t\t\tswap( elem, cssShow, function() {\n\t\t\t\t\t\t\treturn getWidthOrHeight( elem, dimension, extra );\n\t\t\t\t\t\t} ) :\n\t\t\t\t\t\tgetWidthOrHeight( elem, dimension, extra );\n\t\t\t}\n\t\t},\n\n\t\tset: function( elem, value, extra ) {\n\t\t\tvar matches,\n\t\t\t\tstyles = getStyles( elem ),\n\t\t\t\tisBorderBox = jQuery.css( elem, \"boxSizing\", false, styles ) === \"border-box\",\n\t\t\t\tsubtract = extra && boxModelAdjustment(\n\t\t\t\t\telem,\n\t\t\t\t\tdimension,\n\t\t\t\t\textra,\n\t\t\t\t\tisBorderBox,\n\t\t\t\t\tstyles\n\t\t\t\t);\n\n\t\t\t// Account for unreliable border-box dimensions by comparing offset* to computed and\n\t\t\t// faking a content-box to get border and padding (gh-3699)\n\t\t\tif ( isBorderBox && support.scrollboxSize() === styles.position ) {\n\t\t\t\tsubtract -= Math.ceil(\n\t\t\t\t\telem[ \"offset\" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] -\n\t\t\t\t\tparseFloat( styles[ dimension ] ) -\n\t\t\t\t\tboxModelAdjustment( elem, dimension, \"border\", false, styles ) -\n\t\t\t\t\t0.5\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// Convert to pixels if value adjustment is needed\n\t\t\tif ( subtract && ( matches = rcssNum.exec( value ) ) &&\n\t\t\t\t( matches[ 3 ] || \"px\" ) !== \"px\" ) {\n\n\t\t\t\telem.style[ dimension ] = value;\n\t\t\t\tvalue = jQuery.css( elem, dimension );\n\t\t\t}\n\n\t\t\treturn setPositiveNumber( elem, value, subtract );\n\t\t}\n\t};\n} );\n\njQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft,\n\tfunction( elem, computed ) {\n\t\tif ( computed ) {\n\t\t\treturn ( parseFloat( curCSS( elem, \"marginLeft\" ) ) ||\n\t\t\t\telem.getBoundingClientRect().left -\n\t\t\t\t\tswap( elem, { marginLeft: 0 }, function() {\n\t\t\t\t\t\treturn elem.getBoundingClientRect().left;\n\t\t\t\t\t} )\n\t\t\t\t) + \"px\";\n\t\t}\n\t}\n);\n\n// These hooks are used by animate to expand properties\njQuery.each( {\n\tmargin: \"\",\n\tpadding: \"\",\n\tborder: \"Width\"\n}, function( prefix, suffix ) {\n\tjQuery.cssHooks[ prefix + suffix ] = {\n\t\texpand: function( value ) {\n\t\t\tvar i = 0,\n\t\t\t\texpanded = {},\n\n\t\t\t\t// Assumes a single number if not a string\n\t\t\t\tparts = typeof value === \"string\" ? value.split( \" \" ) : [ value ];\n\n\t\t\tfor ( ; i < 4; i++ ) {\n\t\t\t\texpanded[ prefix + cssExpand[ i ] + suffix ] =\n\t\t\t\t\tparts[ i ] || parts[ i - 2 ] || parts[ 0 ];\n\t\t\t}\n\n\t\t\treturn expanded;\n\t\t}\n\t};\n\n\tif ( prefix !== \"margin\" ) {\n\t\tjQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;\n\t}\n} );\n\njQuery.fn.extend( {\n\tcss: function( name, value ) {\n\t\treturn access( this, function( elem, name, value ) {\n\t\t\tvar styles, len,\n\t\t\t\tmap = {},\n\t\t\t\ti = 0;\n\n\t\t\tif ( Array.isArray( name ) ) {\n\t\t\t\tstyles = getStyles( elem );\n\t\t\t\tlen = name.length;\n\n\t\t\t\tfor ( ; i < len; i++ ) {\n\t\t\t\t\tmap[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );\n\t\t\t\t}\n\n\t\t\t\treturn map;\n\t\t\t}\n\n\t\t\treturn value !== undefined ?\n\t\t\t\tjQuery.style( elem, name, value ) :\n\t\t\t\tjQuery.css( elem, name );\n\t\t}, name, value, arguments.length > 1 );\n\t}\n} );\n\n\nfunction Tween( elem, options, prop, end, easing ) {\n\treturn new Tween.prototype.init( elem, options, prop, end, easing );\n}\njQuery.Tween = Tween;\n\nTween.prototype = {\n\tconstructor: Tween,\n\tinit: function( elem, options, prop, end, easing, unit ) {\n\t\tthis.elem = elem;\n\t\tthis.prop = prop;\n\t\tthis.easing = easing || jQuery.easing._default;\n\t\tthis.options = options;\n\t\tthis.start = this.now = this.cur();\n\t\tthis.end = end;\n\t\tthis.unit = unit || ( jQuery.cssNumber[ prop ] ? \"\" : \"px\" );\n\t},\n\tcur: function() {\n\t\tvar hooks = Tween.propHooks[ this.prop ];\n\n\t\treturn hooks && hooks.get ?\n\t\t\thooks.get( this ) :\n\t\t\tTween.propHooks._default.get( this );\n\t},\n\trun: function( percent ) {\n\t\tvar eased,\n\t\t\thooks = Tween.propHooks[ this.prop ];\n\n\t\tif ( this.options.duration ) {\n\t\t\tthis.pos = eased = jQuery.easing[ this.easing ](\n\t\t\t\tpercent, this.options.duration * percent, 0, 1, this.options.duration\n\t\t\t);\n\t\t} else {\n\t\t\tthis.pos = eased = percent;\n\t\t}\n\t\tthis.now = ( this.end - this.start ) * eased + this.start;\n\n\t\tif ( this.options.step ) {\n\t\t\tthis.options.step.call( this.elem, this.now, this );\n\t\t}\n\n\t\tif ( hooks && hooks.set ) {\n\t\t\thooks.set( this );\n\t\t} else {\n\t\t\tTween.propHooks._default.set( this );\n\t\t}\n\t\treturn this;\n\t}\n};\n\nTween.prototype.init.prototype = Tween.prototype;\n\nTween.propHooks = {\n\t_default: {\n\t\tget: function( tween ) {\n\t\t\tvar result;\n\n\t\t\t// Use a property on the element directly when it is not a DOM element,\n\t\t\t// or when there is no matching style property that exists.\n\t\t\tif ( tween.elem.nodeType !== 1 ||\n\t\t\t\ttween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) {\n\t\t\t\treturn tween.elem[ tween.prop ];\n\t\t\t}\n\n\t\t\t// Passing an empty string as a 3rd parameter to .css will automatically\n\t\t\t// attempt a parseFloat and fallback to a string if the parse fails.\n\t\t\t// Simple values such as \"10px\" are parsed to Float;\n\t\t\t// complex values such as \"rotate(1rad)\" are returned as-is.\n\t\t\tresult = jQuery.css( tween.elem, tween.prop, \"\" );\n\n\t\t\t// Empty strings, null, undefined and \"auto\" are converted to 0.\n\t\t\treturn !result || result === \"auto\" ? 0 : result;\n\t\t},\n\t\tset: function( tween ) {\n\n\t\t\t// Use step hook for back compat.\n\t\t\t// Use cssHook if its there.\n\t\t\t// Use .style if available and use plain properties where available.\n\t\t\tif ( jQuery.fx.step[ tween.prop ] ) {\n\t\t\t\tjQuery.fx.step[ tween.prop ]( tween );\n\t\t\t} else if ( tween.elem.nodeType === 1 &&\n\t\t\t\t( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null ||\n\t\t\t\t\tjQuery.cssHooks[ tween.prop ] ) ) {\n\t\t\t\tjQuery.style( tween.elem, tween.prop, tween.now + tween.unit );\n\t\t\t} else {\n\t\t\t\ttween.elem[ tween.prop ] = tween.now;\n\t\t\t}\n\t\t}\n\t}\n};\n\n// Support: IE <=9 only\n// Panic based approach to setting things on disconnected nodes\nTween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {\n\tset: function( tween ) {\n\t\tif ( tween.elem.nodeType && tween.elem.parentNode ) {\n\t\t\ttween.elem[ tween.prop ] = tween.now;\n\t\t}\n\t}\n};\n\njQuery.easing = {\n\tlinear: function( p ) {\n\t\treturn p;\n\t},\n\tswing: function( p ) {\n\t\treturn 0.5 - Math.cos( p * Math.PI ) / 2;\n\t},\n\t_default: \"swing\"\n};\n\njQuery.fx = Tween.prototype.init;\n\n// Back compat <1.8 extension point\njQuery.fx.step = {};\n\n\n\n\nvar\n\tfxNow, inProgress,\n\trfxtypes = /^(?:toggle|show|hide)$/,\n\trrun = /queueHooks$/;\n\nfunction schedule() {\n\tif ( inProgress ) {\n\t\tif ( document.hidden === false && window.requestAnimationFrame ) {\n\t\t\twindow.requestAnimationFrame( schedule );\n\t\t} else {\n\t\t\twindow.setTimeout( schedule, jQuery.fx.interval );\n\t\t}\n\n\t\tjQuery.fx.tick();\n\t}\n}\n\n// Animations created synchronously will run synchronously\nfunction createFxNow() {\n\twindow.setTimeout( function() {\n\t\tfxNow = undefined;\n\t} );\n\treturn ( fxNow = Date.now() );\n}\n\n// Generate parameters to create a standard animation\nfunction genFx( type, includeWidth ) {\n\tvar which,\n\t\ti = 0,\n\t\tattrs = { height: type };\n\n\t// If we include width, step value is 1 to do all cssExpand values,\n\t// otherwise step value is 2 to skip over Left and Right\n\tincludeWidth = includeWidth ? 1 : 0;\n\tfor ( ; i < 4; i += 2 - includeWidth ) {\n\t\twhich = cssExpand[ i ];\n\t\tattrs[ \"margin\" + which ] = attrs[ \"padding\" + which ] = type;\n\t}\n\n\tif ( includeWidth ) {\n\t\tattrs.opacity = attrs.width = type;\n\t}\n\n\treturn attrs;\n}\n\nfunction createTween( value, prop, animation ) {\n\tvar tween,\n\t\tcollection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ \"*\" ] ),\n\t\tindex = 0,\n\t\tlength = collection.length;\n\tfor ( ; index < length; index++ ) {\n\t\tif ( ( tween = collection[ index ].call( animation, prop, value ) ) ) {\n\n\t\t\t// We're done with this property\n\t\t\treturn tween;\n\t\t}\n\t}\n}\n\nfunction defaultPrefilter( elem, props, opts ) {\n\tvar prop, value, toggle, hooks, oldfire, propTween, restoreDisplay, display,\n\t\tisBox = \"width\" in props || \"height\" in props,\n\t\tanim = this,\n\t\torig = {},\n\t\tstyle = elem.style,\n\t\thidden = elem.nodeType && isHiddenWithinTree( elem ),\n\t\tdataShow = dataPriv.get( elem, \"fxshow\" );\n\n\t// Queue-skipping animations hijack the fx hooks\n\tif ( !opts.queue ) {\n\t\thooks = jQuery._queueHooks( elem, \"fx\" );\n\t\tif ( hooks.unqueued == null ) {\n\t\t\thooks.unqueued = 0;\n\t\t\toldfire = hooks.empty.fire;\n\t\t\thooks.empty.fire = function() {\n\t\t\t\tif ( !hooks.unqueued ) {\n\t\t\t\t\toldfire();\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\t\thooks.unqueued++;\n\n\t\tanim.always( function() {\n\n\t\t\t// Ensure the complete handler is called before this completes\n\t\t\tanim.always( function() {\n\t\t\t\thooks.unqueued--;\n\t\t\t\tif ( !jQuery.queue( elem, \"fx\" ).length ) {\n\t\t\t\t\thooks.empty.fire();\n\t\t\t\t}\n\t\t\t} );\n\t\t} );\n\t}\n\n\t// Detect show/hide animations\n\tfor ( prop in props ) {\n\t\tvalue = props[ prop ];\n\t\tif ( rfxtypes.test( value ) ) {\n\t\t\tdelete props[ prop ];\n\t\t\ttoggle = toggle || value === \"toggle\";\n\t\t\tif ( value === ( hidden ? \"hide\" : \"show\" ) ) {\n\n\t\t\t\t// Pretend to be hidden if this is a \"show\" and\n\t\t\t\t// there is still data from a stopped show/hide\n\t\t\t\tif ( value === \"show\" && dataShow && dataShow[ prop ] !== undefined ) {\n\t\t\t\t\thidden = true;\n\n\t\t\t\t// Ignore all other no-op show/hide data\n\t\t\t\t} else {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\t\t\torig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop );\n\t\t}\n\t}\n\n\t// Bail out if this is a no-op like .hide().hide()\n\tpropTween = !jQuery.isEmptyObject( props );\n\tif ( !propTween && jQuery.isEmptyObject( orig ) ) {\n\t\treturn;\n\t}\n\n\t// Restrict \"overflow\" and \"display\" styles during box animations\n\tif ( isBox && elem.nodeType === 1 ) {\n\n\t\t// Support: IE <=9 - 11, Edge 12 - 15\n\t\t// Record all 3 overflow attributes because IE does not infer the shorthand\n\t\t// from identically-valued overflowX and overflowY and Edge just mirrors\n\t\t// the overflowX value there.\n\t\topts.overflow = [ style.overflow, style.overflowX, style.overflowY ];\n\n\t\t// Identify a display type, preferring old show/hide data over the CSS cascade\n\t\trestoreDisplay = dataShow && dataShow.display;\n\t\tif ( restoreDisplay == null ) {\n\t\t\trestoreDisplay = dataPriv.get( elem, \"display\" );\n\t\t}\n\t\tdisplay = jQuery.css( elem, \"display\" );\n\t\tif ( display === \"none\" ) {\n\t\t\tif ( restoreDisplay ) {\n\t\t\t\tdisplay = restoreDisplay;\n\t\t\t} else {\n\n\t\t\t\t// Get nonempty value(s) by temporarily forcing visibility\n\t\t\t\tshowHide( [ elem ], true );\n\t\t\t\trestoreDisplay = elem.style.display || restoreDisplay;\n\t\t\t\tdisplay = jQuery.css( elem, \"display\" );\n\t\t\t\tshowHide( [ elem ] );\n\t\t\t}\n\t\t}\n\n\t\t// Animate inline elements as inline-block\n\t\tif ( display === \"inline\" || display === \"inline-block\" && restoreDisplay != null ) {\n\t\t\tif ( jQuery.css( elem, \"float\" ) === \"none\" ) {\n\n\t\t\t\t// Restore the original display value at the end of pure show/hide animations\n\t\t\t\tif ( !propTween ) {\n\t\t\t\t\tanim.done( function() {\n\t\t\t\t\t\tstyle.display = restoreDisplay;\n\t\t\t\t\t} );\n\t\t\t\t\tif ( restoreDisplay == null ) {\n\t\t\t\t\t\tdisplay = style.display;\n\t\t\t\t\t\trestoreDisplay = display === \"none\" ? \"\" : display;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tstyle.display = \"inline-block\";\n\t\t\t}\n\t\t}\n\t}\n\n\tif ( opts.overflow ) {\n\t\tstyle.overflow = \"hidden\";\n\t\tanim.always( function() {\n\t\t\tstyle.overflow = opts.overflow[ 0 ];\n\t\t\tstyle.overflowX = opts.overflow[ 1 ];\n\t\t\tstyle.overflowY = opts.overflow[ 2 ];\n\t\t} );\n\t}\n\n\t// Implement show/hide animations\n\tpropTween = false;\n\tfor ( prop in orig ) {\n\n\t\t// General show/hide setup for this element animation\n\t\tif ( !propTween ) {\n\t\t\tif ( dataShow ) {\n\t\t\t\tif ( \"hidden\" in dataShow ) {\n\t\t\t\t\thidden = dataShow.hidden;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tdataShow = dataPriv.access( elem, \"fxshow\", { display: restoreDisplay } );\n\t\t\t}\n\n\t\t\t// Store hidden/visible for toggle so `.stop().toggle()` \"reverses\"\n\t\t\tif ( toggle ) {\n\t\t\t\tdataShow.hidden = !hidden;\n\t\t\t}\n\n\t\t\t// Show elements before animating them\n\t\t\tif ( hidden ) {\n\t\t\t\tshowHide( [ elem ], true );\n\t\t\t}\n\n\t\t\t/* eslint-disable no-loop-func */\n\n\t\t\tanim.done( function() {\n\n\t\t\t/* eslint-enable no-loop-func */\n\n\t\t\t\t// The final step of a \"hide\" animation is actually hiding the element\n\t\t\t\tif ( !hidden ) {\n\t\t\t\t\tshowHide( [ elem ] );\n\t\t\t\t}\n\t\t\t\tdataPriv.remove( elem, \"fxshow\" );\n\t\t\t\tfor ( prop in orig ) {\n\t\t\t\t\tjQuery.style( elem, prop, orig[ prop ] );\n\t\t\t\t}\n\t\t\t} );\n\t\t}\n\n\t\t// Per-property setup\n\t\tpropTween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim );\n\t\tif ( !( prop in dataShow ) ) {\n\t\t\tdataShow[ prop ] = propTween.start;\n\t\t\tif ( hidden ) {\n\t\t\t\tpropTween.end = propTween.start;\n\t\t\t\tpropTween.start = 0;\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunction propFilter( props, specialEasing ) {\n\tvar index, name, easing, value, hooks;\n\n\t// camelCase, specialEasing and expand cssHook pass\n\tfor ( index in props ) {\n\t\tname = camelCase( index );\n\t\teasing = specialEasing[ name ];\n\t\tvalue = props[ index ];\n\t\tif ( Array.isArray( value ) ) {\n\t\t\teasing = value[ 1 ];\n\t\t\tvalue = props[ index ] = value[ 0 ];\n\t\t}\n\n\t\tif ( index !== name ) {\n\t\t\tprops[ name ] = value;\n\t\t\tdelete props[ index ];\n\t\t}\n\n\t\thooks = jQuery.cssHooks[ name ];\n\t\tif ( hooks && \"expand\" in hooks ) {\n\t\t\tvalue = hooks.expand( value );\n\t\t\tdelete props[ name ];\n\n\t\t\t// Not quite $.extend, this won't overwrite existing keys.\n\t\t\t// Reusing 'index' because we have the correct \"name\"\n\t\t\tfor ( index in value ) {\n\t\t\t\tif ( !( index in props ) ) {\n\t\t\t\t\tprops[ index ] = value[ index ];\n\t\t\t\t\tspecialEasing[ index ] = easing;\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tspecialEasing[ name ] = easing;\n\t\t}\n\t}\n}\n\nfunction Animation( elem, properties, options ) {\n\tvar result,\n\t\tstopped,\n\t\tindex = 0,\n\t\tlength = Animation.prefilters.length,\n\t\tdeferred = jQuery.Deferred().always( function() {\n\n\t\t\t// Don't match elem in the :animated selector\n\t\t\tdelete tick.elem;\n\t\t} ),\n\t\ttick = function() {\n\t\t\tif ( stopped ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tvar currentTime = fxNow || createFxNow(),\n\t\t\t\tremaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),\n\n\t\t\t\t// Support: Android 2.3 only\n\t\t\t\t// Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497)\n\t\t\t\ttemp = remaining / animation.duration || 0,\n\t\t\t\tpercent = 1 - temp,\n\t\t\t\tindex = 0,\n\t\t\t\tlength = animation.tweens.length;\n\n\t\t\tfor ( ; index < length; index++ ) {\n\t\t\t\tanimation.tweens[ index ].run( percent );\n\t\t\t}\n\n\t\t\tdeferred.notifyWith( elem, [ animation, percent, remaining ] );\n\n\t\t\t// If there's more to do, yield\n\t\t\tif ( percent < 1 && length ) {\n\t\t\t\treturn remaining;\n\t\t\t}\n\n\t\t\t// If this was an empty animation, synthesize a final progress notification\n\t\t\tif ( !length ) {\n\t\t\t\tdeferred.notifyWith( elem, [ animation, 1, 0 ] );\n\t\t\t}\n\n\t\t\t// Resolve the animation and report its conclusion\n\t\t\tdeferred.resolveWith( elem, [ animation ] );\n\t\t\treturn false;\n\t\t},\n\t\tanimation = deferred.promise( {\n\t\t\telem: elem,\n\t\t\tprops: jQuery.extend( {}, properties ),\n\t\t\topts: jQuery.extend( true, {\n\t\t\t\tspecialEasing: {},\n\t\t\t\teasing: jQuery.easing._default\n\t\t\t}, options ),\n\t\t\toriginalProperties: properties,\n\t\t\toriginalOptions: options,\n\t\t\tstartTime: fxNow || createFxNow(),\n\t\t\tduration: options.duration,\n\t\t\ttweens: [],\n\t\t\tcreateTween: function( prop, end ) {\n\t\t\t\tvar tween = jQuery.Tween( elem, animation.opts, prop, end,\n\t\t\t\t\t\tanimation.opts.specialEasing[ prop ] || animation.opts.easing );\n\t\t\t\tanimation.tweens.push( tween );\n\t\t\t\treturn tween;\n\t\t\t},\n\t\t\tstop: function( gotoEnd ) {\n\t\t\t\tvar index = 0,\n\n\t\t\t\t\t// If we are going to the end, we want to run all the tweens\n\t\t\t\t\t// otherwise we skip this part\n\t\t\t\t\tlength = gotoEnd ? animation.tweens.length : 0;\n\t\t\t\tif ( stopped ) {\n\t\t\t\t\treturn this;\n\t\t\t\t}\n\t\t\t\tstopped = true;\n\t\t\t\tfor ( ; index < length; index++ ) {\n\t\t\t\t\tanimation.tweens[ index ].run( 1 );\n\t\t\t\t}\n\n\t\t\t\t// Resolve when we played the last frame; otherwise, reject\n\t\t\t\tif ( gotoEnd ) {\n\t\t\t\t\tdeferred.notifyWith( elem, [ animation, 1, 0 ] );\n\t\t\t\t\tdeferred.resolveWith( elem, [ animation, gotoEnd ] );\n\t\t\t\t} else {\n\t\t\t\t\tdeferred.rejectWith( elem, [ animation, gotoEnd ] );\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t}\n\t\t} ),\n\t\tprops = animation.props;\n\n\tpropFilter( props, animation.opts.specialEasing );\n\n\tfor ( ; index < length; index++ ) {\n\t\tresult = Animation.prefilters[ index ].call( animation, elem, props, animation.opts );\n\t\tif ( result ) {\n\t\t\tif ( isFunction( result.stop ) ) {\n\t\t\t\tjQuery._queueHooks( animation.elem, animation.opts.queue ).stop =\n\t\t\t\t\tresult.stop.bind( result );\n\t\t\t}\n\t\t\treturn result;\n\t\t}\n\t}\n\n\tjQuery.map( props, createTween, animation );\n\n\tif ( isFunction( animation.opts.start ) ) {\n\t\tanimation.opts.start.call( elem, animation );\n\t}\n\n\t// Attach callbacks from options\n\tanimation\n\t\t.progress( animation.opts.progress )\n\t\t.done( animation.opts.done, animation.opts.complete )\n\t\t.fail( animation.opts.fail )\n\t\t.always( animation.opts.always );\n\n\tjQuery.fx.timer(\n\t\tjQuery.extend( tick, {\n\t\t\telem: elem,\n\t\t\tanim: animation,\n\t\t\tqueue: animation.opts.queue\n\t\t} )\n\t);\n\n\treturn animation;\n}\n\njQuery.Animation = jQuery.extend( Animation, {\n\n\ttweeners: {\n\t\t\"*\": [ function( prop, value ) {\n\t\t\tvar tween = this.createTween( prop, value );\n\t\t\tadjustCSS( tween.elem, prop, rcssNum.exec( value ), tween );\n\t\t\treturn tween;\n\t\t} ]\n\t},\n\n\ttweener: function( props, callback ) {\n\t\tif ( isFunction( props ) ) {\n\t\t\tcallback = props;\n\t\t\tprops = [ \"*\" ];\n\t\t} else {\n\t\t\tprops = props.match( rnothtmlwhite );\n\t\t}\n\n\t\tvar prop,\n\t\t\tindex = 0,\n\t\t\tlength = props.length;\n\n\t\tfor ( ; index < length; index++ ) {\n\t\t\tprop = props[ index ];\n\t\t\tAnimation.tweeners[ prop ] = Animation.tweeners[ prop ] || [];\n\t\t\tAnimation.tweeners[ prop ].unshift( callback );\n\t\t}\n\t},\n\n\tprefilters: [ defaultPrefilter ],\n\n\tprefilter: function( callback, prepend ) {\n\t\tif ( prepend ) {\n\t\t\tAnimation.prefilters.unshift( callback );\n\t\t} else {\n\t\t\tAnimation.prefilters.push( callback );\n\t\t}\n\t}\n} );\n\njQuery.speed = function( speed, easing, fn ) {\n\tvar opt = speed && typeof speed === \"object\" ? jQuery.extend( {}, speed ) : {\n\t\tcomplete: fn || !fn && easing ||\n\t\t\tisFunction( speed ) && speed,\n\t\tduration: speed,\n\t\teasing: fn && easing || easing && !isFunction( easing ) && easing\n\t};\n\n\t// Go to the end state if fx are off\n\tif ( jQuery.fx.off ) {\n\t\topt.duration = 0;\n\n\t} else {\n\t\tif ( typeof opt.duration !== \"number\" ) {\n\t\t\tif ( opt.duration in jQuery.fx.speeds ) {\n\t\t\t\topt.duration = jQuery.fx.speeds[ opt.duration ];\n\n\t\t\t} else {\n\t\t\t\topt.duration = jQuery.fx.speeds._default;\n\t\t\t}\n\t\t}\n\t}\n\n\t// Normalize opt.queue - true/undefined/null -> \"fx\"\n\tif ( opt.queue == null || opt.queue === true ) {\n\t\topt.queue = \"fx\";\n\t}\n\n\t// Queueing\n\topt.old = opt.complete;\n\n\topt.complete = function() {\n\t\tif ( isFunction( opt.old ) ) {\n\t\t\topt.old.call( this );\n\t\t}\n\n\t\tif ( opt.queue ) {\n\t\t\tjQuery.dequeue( this, opt.queue );\n\t\t}\n\t};\n\n\treturn opt;\n};\n\njQuery.fn.extend( {\n\tfadeTo: function( speed, to, easing, callback ) {\n\n\t\t// Show any hidden elements after setting opacity to 0\n\t\treturn this.filter( isHiddenWithinTree ).css( \"opacity\", 0 ).show()\n\n\t\t\t// Animate to the value specified\n\t\t\t.end().animate( { opacity: to }, speed, easing, callback );\n\t},\n\tanimate: function( prop, speed, easing, callback ) {\n\t\tvar empty = jQuery.isEmptyObject( prop ),\n\t\t\toptall = jQuery.speed( speed, easing, callback ),\n\t\t\tdoAnimation = function() {\n\n\t\t\t\t// Operate on a copy of prop so per-property easing won't be lost\n\t\t\t\tvar anim = Animation( this, jQuery.extend( {}, prop ), optall );\n\n\t\t\t\t// Empty animations, or finishing resolves immediately\n\t\t\t\tif ( empty || dataPriv.get( this, \"finish\" ) ) {\n\t\t\t\t\tanim.stop( true );\n\t\t\t\t}\n\t\t\t};\n\t\t\tdoAnimation.finish = doAnimation;\n\n\t\treturn empty || optall.queue === false ?\n\t\t\tthis.each( doAnimation ) :\n\t\t\tthis.queue( optall.queue, doAnimation );\n\t},\n\tstop: function( type, clearQueue, gotoEnd ) {\n\t\tvar stopQueue = function( hooks ) {\n\t\t\tvar stop = hooks.stop;\n\t\t\tdelete hooks.stop;\n\t\t\tstop( gotoEnd );\n\t\t};\n\n\t\tif ( typeof type !== \"string\" ) {\n\t\t\tgotoEnd = clearQueue;\n\t\t\tclearQueue = type;\n\t\t\ttype = undefined;\n\t\t}\n\t\tif ( clearQueue && type !== false ) {\n\t\t\tthis.queue( type || \"fx\", [] );\n\t\t}\n\n\t\treturn this.each( function() {\n\t\t\tvar dequeue = true,\n\t\t\t\tindex = type != null && type + \"queueHooks\",\n\t\t\t\ttimers = jQuery.timers,\n\t\t\t\tdata = dataPriv.get( this );\n\n\t\t\tif ( index ) {\n\t\t\t\tif ( data[ index ] && data[ index ].stop ) {\n\t\t\t\t\tstopQueue( data[ index ] );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tfor ( index in data ) {\n\t\t\t\t\tif ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {\n\t\t\t\t\t\tstopQueue( data[ index ] );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor ( index = timers.length; index--; ) {\n\t\t\t\tif ( timers[ index ].elem === this &&\n\t\t\t\t\t( type == null || timers[ index ].queue === type ) ) {\n\n\t\t\t\t\ttimers[ index ].anim.stop( gotoEnd );\n\t\t\t\t\tdequeue = false;\n\t\t\t\t\ttimers.splice( index, 1 );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Start the next in the queue if the last step wasn't forced.\n\t\t\t// Timers currently will call their complete callbacks, which\n\t\t\t// will dequeue but only if they were gotoEnd.\n\t\t\tif ( dequeue || !gotoEnd ) {\n\t\t\t\tjQuery.dequeue( this, type );\n\t\t\t}\n\t\t} );\n\t},\n\tfinish: function( type ) {\n\t\tif ( type !== false ) {\n\t\t\ttype = type || \"fx\";\n\t\t}\n\t\treturn this.each( function() {\n\t\t\tvar index,\n\t\t\t\tdata = dataPriv.get( this ),\n\t\t\t\tqueue = data[ type + \"queue\" ],\n\t\t\t\thooks = data[ type + \"queueHooks\" ],\n\t\t\t\ttimers = jQuery.timers,\n\t\t\t\tlength = queue ? queue.length : 0;\n\n\t\t\t// Enable finishing flag on private data\n\t\t\tdata.finish = true;\n\n\t\t\t// Empty the queue first\n\t\t\tjQuery.queue( this, type, [] );\n\n\t\t\tif ( hooks && hooks.stop ) {\n\t\t\t\thooks.stop.call( this, true );\n\t\t\t}\n\n\t\t\t// Look for any active animations, and finish them\n\t\t\tfor ( index = timers.length; index--; ) {\n\t\t\t\tif ( timers[ index ].elem === this && timers[ index ].queue === type ) {\n\t\t\t\t\ttimers[ index ].anim.stop( true );\n\t\t\t\t\ttimers.splice( index, 1 );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Look for any animations in the old queue and finish them\n\t\t\tfor ( index = 0; index < length; index++ ) {\n\t\t\t\tif ( queue[ index ] && queue[ index ].finish ) {\n\t\t\t\t\tqueue[ index ].finish.call( this );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Turn off finishing flag\n\t\t\tdelete data.finish;\n\t\t} );\n\t}\n} );\n\njQuery.each( [ \"toggle\", \"show\", \"hide\" ], function( i, name ) {\n\tvar cssFn = jQuery.fn[ name ];\n\tjQuery.fn[ name ] = function( speed, easing, callback ) {\n\t\treturn speed == null || typeof speed === \"boolean\" ?\n\t\t\tcssFn.apply( this, arguments ) :\n\t\t\tthis.animate( genFx( name, true ), speed, easing, callback );\n\t};\n} );\n\n// Generate shortcuts for custom animations\njQuery.each( {\n\tslideDown: genFx( \"show\" ),\n\tslideUp: genFx( \"hide\" ),\n\tslideToggle: genFx( \"toggle\" ),\n\tfadeIn: { opacity: \"show\" },\n\tfadeOut: { opacity: \"hide\" },\n\tfadeToggle: { opacity: \"toggle\" }\n}, function( name, props ) {\n\tjQuery.fn[ name ] = function( speed, easing, callback ) {\n\t\treturn this.animate( props, speed, easing, callback );\n\t};\n} );\n\njQuery.timers = [];\njQuery.fx.tick = function() {\n\tvar timer,\n\t\ti = 0,\n\t\ttimers = jQuery.timers;\n\n\tfxNow = Date.now();\n\n\tfor ( ; i < timers.length; i++ ) {\n\t\ttimer = timers[ i ];\n\n\t\t// Run the timer and safely remove it when done (allowing for external removal)\n\t\tif ( !timer() && timers[ i ] === timer ) {\n\t\t\ttimers.splice( i--, 1 );\n\t\t}\n\t}\n\n\tif ( !timers.length ) {\n\t\tjQuery.fx.stop();\n\t}\n\tfxNow = undefined;\n};\n\njQuery.fx.timer = function( timer ) {\n\tjQuery.timers.push( timer );\n\tjQuery.fx.start();\n};\n\njQuery.fx.interval = 13;\njQuery.fx.start = function() {\n\tif ( inProgress ) {\n\t\treturn;\n\t}\n\n\tinProgress = true;\n\tschedule();\n};\n\njQuery.fx.stop = function() {\n\tinProgress = null;\n};\n\njQuery.fx.speeds = {\n\tslow: 600,\n\tfast: 200,\n\n\t// Default speed\n\t_default: 400\n};\n\n\n// Based off of the plugin by Clint Helfers, with permission.\n// https://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/\njQuery.fn.delay = function( time, type ) {\n\ttime = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;\n\ttype = type || \"fx\";\n\n\treturn this.queue( type, function( next, hooks ) {\n\t\tvar timeout = window.setTimeout( next, time );\n\t\thooks.stop = function() {\n\t\t\twindow.clearTimeout( timeout );\n\t\t};\n\t} );\n};\n\n\n( function() {\n\tvar input = document.createElement( \"input\" ),\n\t\tselect = document.createElement( \"select\" ),\n\t\topt = select.appendChild( document.createElement( \"option\" ) );\n\n\tinput.type = \"checkbox\";\n\n\t// Support: Android <=4.3 only\n\t// Default value for a checkbox should be \"on\"\n\tsupport.checkOn = input.value !== \"\";\n\n\t// Support: IE <=11 only\n\t// Must access selectedIndex to make default options select\n\tsupport.optSelected = opt.selected;\n\n\t// Support: IE <=11 only\n\t// An input loses its value after becoming a radio\n\tinput = document.createElement( \"input\" );\n\tinput.value = \"t\";\n\tinput.type = \"radio\";\n\tsupport.radioValue = input.value === \"t\";\n} )();\n\n\nvar boolHook,\n\tattrHandle = jQuery.expr.attrHandle;\n\njQuery.fn.extend( {\n\tattr: function( name, value ) {\n\t\treturn access( this, jQuery.attr, name, value, arguments.length > 1 );\n\t},\n\n\tremoveAttr: function( name ) {\n\t\treturn this.each( function() {\n\t\t\tjQuery.removeAttr( this, name );\n\t\t} );\n\t}\n} );\n\njQuery.extend( {\n\tattr: function( elem, name, value ) {\n\t\tvar ret, hooks,\n\t\t\tnType = elem.nodeType;\n\n\t\t// Don't get/set attributes on text, comment and attribute nodes\n\t\tif ( nType === 3 || nType === 8 || nType === 2 ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Fallback to prop when attributes are not supported\n\t\tif ( typeof elem.getAttribute === \"undefined\" ) {\n\t\t\treturn jQuery.prop( elem, name, value );\n\t\t}\n\n\t\t// Attribute hooks are determined by the lowercase version\n\t\t// Grab necessary hook if one is defined\n\t\tif ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {\n\t\t\thooks = jQuery.attrHooks[ name.toLowerCase() ] ||\n\t\t\t\t( jQuery.expr.match.bool.test( name ) ? boolHook : undefined );\n\t\t}\n\n\t\tif ( value !== undefined ) {\n\t\t\tif ( value === null ) {\n\t\t\t\tjQuery.removeAttr( elem, name );\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( hooks && \"set\" in hooks &&\n\t\t\t\t( ret = hooks.set( elem, value, name ) ) !== undefined ) {\n\t\t\t\treturn ret;\n\t\t\t}\n\n\t\t\telem.setAttribute( name, value + \"\" );\n\t\t\treturn value;\n\t\t}\n\n\t\tif ( hooks && \"get\" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {\n\t\t\treturn ret;\n\t\t}\n\n\t\tret = jQuery.find.attr( elem, name );\n\n\t\t// Non-existent attributes return null, we normalize to undefined\n\t\treturn ret == null ? undefined : ret;\n\t},\n\n\tattrHooks: {\n\t\ttype: {\n\t\t\tset: function( elem, value ) {\n\t\t\t\tif ( !support.radioValue && value === \"radio\" &&\n\t\t\t\t\tnodeName( elem, \"input\" ) ) {\n\t\t\t\t\tvar val = elem.value;\n\t\t\t\t\telem.setAttribute( \"type\", value );\n\t\t\t\t\tif ( val ) {\n\t\t\t\t\t\telem.value = val;\n\t\t\t\t\t}\n\t\t\t\t\treturn value;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n\n\tremoveAttr: function( elem, value ) {\n\t\tvar name,\n\t\t\ti = 0,\n\n\t\t\t// Attribute names can contain non-HTML whitespace characters\n\t\t\t// https://html.spec.whatwg.org/multipage/syntax.html#attributes-2\n\t\t\tattrNames = value && value.match( rnothtmlwhite );\n\n\t\tif ( attrNames && elem.nodeType === 1 ) {\n\t\t\twhile ( ( name = attrNames[ i++ ] ) ) {\n\t\t\t\telem.removeAttribute( name );\n\t\t\t}\n\t\t}\n\t}\n} );\n\n// Hooks for boolean attributes\nboolHook = {\n\tset: function( elem, value, name ) {\n\t\tif ( value === false ) {\n\n\t\t\t// Remove boolean attributes when set to false\n\t\t\tjQuery.removeAttr( elem, name );\n\t\t} else {\n\t\t\telem.setAttribute( name, name );\n\t\t}\n\t\treturn name;\n\t}\n};\n\njQuery.each( jQuery.expr.match.bool.source.match( /\\w+/g ), function( i, name ) {\n\tvar getter = attrHandle[ name ] || jQuery.find.attr;\n\n\tattrHandle[ name ] = function( elem, name, isXML ) {\n\t\tvar ret, handle,\n\t\t\tlowercaseName = name.toLowerCase();\n\n\t\tif ( !isXML ) {\n\n\t\t\t// Avoid an infinite loop by temporarily removing this function from the getter\n\t\t\thandle = attrHandle[ lowercaseName ];\n\t\t\tattrHandle[ lowercaseName ] = ret;\n\t\t\tret = getter( elem, name, isXML ) != null ?\n\t\t\t\tlowercaseName :\n\t\t\t\tnull;\n\t\t\tattrHandle[ lowercaseName ] = handle;\n\t\t}\n\t\treturn ret;\n\t};\n} );\n\n\n\n\nvar rfocusable = /^(?:input|select|textarea|button)$/i,\n\trclickable = /^(?:a|area)$/i;\n\njQuery.fn.extend( {\n\tprop: function( name, value ) {\n\t\treturn access( this, jQuery.prop, name, value, arguments.length > 1 );\n\t},\n\n\tremoveProp: function( name ) {\n\t\treturn this.each( function() {\n\t\t\tdelete this[ jQuery.propFix[ name ] || name ];\n\t\t} );\n\t}\n} );\n\njQuery.extend( {\n\tprop: function( elem, name, value ) {\n\t\tvar ret, hooks,\n\t\t\tnType = elem.nodeType;\n\n\t\t// Don't get/set properties on text, comment and attribute nodes\n\t\tif ( nType === 3 || nType === 8 || nType === 2 ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {\n\n\t\t\t// Fix name and attach hooks\n\t\t\tname = jQuery.propFix[ name ] || name;\n\t\t\thooks = jQuery.propHooks[ name ];\n\t\t}\n\n\t\tif ( value !== undefined ) {\n\t\t\tif ( hooks && \"set\" in hooks &&\n\t\t\t\t( ret = hooks.set( elem, value, name ) ) !== undefined ) {\n\t\t\t\treturn ret;\n\t\t\t}\n\n\t\t\treturn ( elem[ name ] = value );\n\t\t}\n\n\t\tif ( hooks && \"get\" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {\n\t\t\treturn ret;\n\t\t}\n\n\t\treturn elem[ name ];\n\t},\n\n\tpropHooks: {\n\t\ttabIndex: {\n\t\t\tget: function( elem ) {\n\n\t\t\t\t// Support: IE <=9 - 11 only\n\t\t\t\t// elem.tabIndex doesn't always return the\n\t\t\t\t// correct value when it hasn't been explicitly set\n\t\t\t\t// https://web.archive.org/web/20141116233347/http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/\n\t\t\t\t// Use proper attribute retrieval(#12072)\n\t\t\t\tvar tabindex = jQuery.find.attr( elem, \"tabindex\" );\n\n\t\t\t\tif ( tabindex ) {\n\t\t\t\t\treturn parseInt( tabindex, 10 );\n\t\t\t\t}\n\n\t\t\t\tif (\n\t\t\t\t\trfocusable.test( elem.nodeName ) ||\n\t\t\t\t\trclickable.test( elem.nodeName ) &&\n\t\t\t\t\telem.href\n\t\t\t\t) {\n\t\t\t\t\treturn 0;\n\t\t\t\t}\n\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t}\n\t},\n\n\tpropFix: {\n\t\t\"for\": \"htmlFor\",\n\t\t\"class\": \"className\"\n\t}\n} );\n\n// Support: IE <=11 only\n// Accessing the selectedIndex property\n// forces the browser to respect setting selected\n// on the option\n// The getter ensures a default option is selected\n// when in an optgroup\n// eslint rule \"no-unused-expressions\" is disabled for this code\n// since it considers such accessions noop\nif ( !support.optSelected ) {\n\tjQuery.propHooks.selected = {\n\t\tget: function( elem ) {\n\n\t\t\t/* eslint no-unused-expressions: \"off\" */\n\n\t\t\tvar parent = elem.parentNode;\n\t\t\tif ( parent && parent.parentNode ) {\n\t\t\t\tparent.parentNode.selectedIndex;\n\t\t\t}\n\t\t\treturn null;\n\t\t},\n\t\tset: function( elem ) {\n\n\t\t\t/* eslint no-unused-expressions: \"off\" */\n\n\t\t\tvar parent = elem.parentNode;\n\t\t\tif ( parent ) {\n\t\t\t\tparent.selectedIndex;\n\n\t\t\t\tif ( parent.parentNode ) {\n\t\t\t\t\tparent.parentNode.selectedIndex;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n}\n\njQuery.each( [\n\t\"tabIndex\",\n\t\"readOnly\",\n\t\"maxLength\",\n\t\"cellSpacing\",\n\t\"cellPadding\",\n\t\"rowSpan\",\n\t\"colSpan\",\n\t\"useMap\",\n\t\"frameBorder\",\n\t\"contentEditable\"\n], function() {\n\tjQuery.propFix[ this.toLowerCase() ] = this;\n} );\n\n\n\n\n\t// Strip and collapse whitespace according to HTML spec\n\t// https://infra.spec.whatwg.org/#strip-and-collapse-ascii-whitespace\n\tfunction stripAndCollapse( value ) {\n\t\tvar tokens = value.match( rnothtmlwhite ) || [];\n\t\treturn tokens.join( \" \" );\n\t}\n\n\nfunction getClass( elem ) {\n\treturn elem.getAttribute && elem.getAttribute( \"class\" ) || \"\";\n}\n\nfunction classesToArray( value ) {\n\tif ( Array.isArray( value ) ) {\n\t\treturn value;\n\t}\n\tif ( typeof value === \"string\" ) {\n\t\treturn value.match( rnothtmlwhite ) || [];\n\t}\n\treturn [];\n}\n\njQuery.fn.extend( {\n\taddClass: function( value ) {\n\t\tvar classes, elem, cur, curValue, clazz, j, finalValue,\n\t\t\ti = 0;\n\n\t\tif ( isFunction( value ) ) {\n\t\t\treturn this.each( function( j ) {\n\t\t\t\tjQuery( this ).addClass( value.call( this, j, getClass( this ) ) );\n\t\t\t} );\n\t\t}\n\n\t\tclasses = classesToArray( value );\n\n\t\tif ( classes.length ) {\n\t\t\twhile ( ( elem = this[ i++ ] ) ) {\n\t\t\t\tcurValue = getClass( elem );\n\t\t\t\tcur = elem.nodeType === 1 && ( \" \" + stripAndCollapse( curValue ) + \" \" );\n\n\t\t\t\tif ( cur ) {\n\t\t\t\t\tj = 0;\n\t\t\t\t\twhile ( ( clazz = classes[ j++ ] ) ) {\n\t\t\t\t\t\tif ( cur.indexOf( \" \" + clazz + \" \" ) < 0 ) {\n\t\t\t\t\t\t\tcur += clazz + \" \";\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Only assign if different to avoid unneeded rendering.\n\t\t\t\t\tfinalValue = stripAndCollapse( cur );\n\t\t\t\t\tif ( curValue !== finalValue ) {\n\t\t\t\t\t\telem.setAttribute( \"class\", finalValue );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\tremoveClass: function( value ) {\n\t\tvar classes, elem, cur, curValue, clazz, j, finalValue,\n\t\t\ti = 0;\n\n\t\tif ( isFunction( value ) ) {\n\t\t\treturn this.each( function( j ) {\n\t\t\t\tjQuery( this ).removeClass( value.call( this, j, getClass( this ) ) );\n\t\t\t} );\n\t\t}\n\n\t\tif ( !arguments.length ) {\n\t\t\treturn this.attr( \"class\", \"\" );\n\t\t}\n\n\t\tclasses = classesToArray( value );\n\n\t\tif ( classes.length ) {\n\t\t\twhile ( ( elem = this[ i++ ] ) ) {\n\t\t\t\tcurValue = getClass( elem );\n\n\t\t\t\t// This expression is here for better compressibility (see addClass)\n\t\t\t\tcur = elem.nodeType === 1 && ( \" \" + stripAndCollapse( curValue ) + \" \" );\n\n\t\t\t\tif ( cur ) {\n\t\t\t\t\tj = 0;\n\t\t\t\t\twhile ( ( clazz = classes[ j++ ] ) ) {\n\n\t\t\t\t\t\t// Remove *all* instances\n\t\t\t\t\t\twhile ( cur.indexOf( \" \" + clazz + \" \" ) > -1 ) {\n\t\t\t\t\t\t\tcur = cur.replace( \" \" + clazz + \" \", \" \" );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Only assign if different to avoid unneeded rendering.\n\t\t\t\t\tfinalValue = stripAndCollapse( cur );\n\t\t\t\t\tif ( curValue !== finalValue ) {\n\t\t\t\t\t\telem.setAttribute( \"class\", finalValue );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\ttoggleClass: function( value, stateVal ) {\n\t\tvar type = typeof value,\n\t\t\tisValidValue = type === \"string\" || Array.isArray( value );\n\n\t\tif ( typeof stateVal === \"boolean\" && isValidValue ) {\n\t\t\treturn stateVal ? this.addClass( value ) : this.removeClass( value );\n\t\t}\n\n\t\tif ( isFunction( value ) ) {\n\t\t\treturn this.each( function( i ) {\n\t\t\t\tjQuery( this ).toggleClass(\n\t\t\t\t\tvalue.call( this, i, getClass( this ), stateVal ),\n\t\t\t\t\tstateVal\n\t\t\t\t);\n\t\t\t} );\n\t\t}\n\n\t\treturn this.each( function() {\n\t\t\tvar className, i, self, classNames;\n\n\t\t\tif ( isValidValue ) {\n\n\t\t\t\t// Toggle individual class names\n\t\t\t\ti = 0;\n\t\t\t\tself = jQuery( this );\n\t\t\t\tclassNames = classesToArray( value );\n\n\t\t\t\twhile ( ( className = classNames[ i++ ] ) ) {\n\n\t\t\t\t\t// Check each className given, space separated list\n\t\t\t\t\tif ( self.hasClass( className ) ) {\n\t\t\t\t\t\tself.removeClass( className );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tself.addClass( className );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t// Toggle whole class name\n\t\t\t} else if ( value === undefined || type === \"boolean\" ) {\n\t\t\t\tclassName = getClass( this );\n\t\t\t\tif ( className ) {\n\n\t\t\t\t\t// Store className if set\n\t\t\t\t\tdataPriv.set( this, \"__className__\", className );\n\t\t\t\t}\n\n\t\t\t\t// If the element has a class name or if we're passed `false`,\n\t\t\t\t// then remove the whole classname (if there was one, the above saved it).\n\t\t\t\t// Otherwise bring back whatever was previously saved (if anything),\n\t\t\t\t// falling back to the empty string if nothing was stored.\n\t\t\t\tif ( this.setAttribute ) {\n\t\t\t\t\tthis.setAttribute( \"class\",\n\t\t\t\t\t\tclassName || value === false ?\n\t\t\t\t\t\t\"\" :\n\t\t\t\t\t\tdataPriv.get( this, \"__className__\" ) || \"\"\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\t},\n\n\thasClass: function( selector ) {\n\t\tvar className, elem,\n\t\t\ti = 0;\n\n\t\tclassName = \" \" + selector + \" \";\n\t\twhile ( ( elem = this[ i++ ] ) ) {\n\t\t\tif ( elem.nodeType === 1 &&\n\t\t\t\t( \" \" + stripAndCollapse( getClass( elem ) ) + \" \" ).indexOf( className ) > -1 ) {\n\t\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t\treturn false;\n\t}\n} );\n\n\n\n\nvar rreturn = /\\r/g;\n\njQuery.fn.extend( {\n\tval: function( value ) {\n\t\tvar hooks, ret, valueIsFunction,\n\t\t\telem = this[ 0 ];\n\n\t\tif ( !arguments.length ) {\n\t\t\tif ( elem ) {\n\t\t\t\thooks = jQuery.valHooks[ elem.type ] ||\n\t\t\t\t\tjQuery.valHooks[ elem.nodeName.toLowerCase() ];\n\n\t\t\t\tif ( hooks &&\n\t\t\t\t\t\"get\" in hooks &&\n\t\t\t\t\t( ret = hooks.get( elem, \"value\" ) ) !== undefined\n\t\t\t\t) {\n\t\t\t\t\treturn ret;\n\t\t\t\t}\n\n\t\t\t\tret = elem.value;\n\n\t\t\t\t// Handle most common string cases\n\t\t\t\tif ( typeof ret === \"string\" ) {\n\t\t\t\t\treturn ret.replace( rreturn, \"\" );\n\t\t\t\t}\n\n\t\t\t\t// Handle cases where value is null/undef or number\n\t\t\t\treturn ret == null ? \"\" : ret;\n\t\t\t}\n\n\t\t\treturn;\n\t\t}\n\n\t\tvalueIsFunction = isFunction( value );\n\n\t\treturn this.each( function( i ) {\n\t\t\tvar val;\n\n\t\t\tif ( this.nodeType !== 1 ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( valueIsFunction ) {\n\t\t\t\tval = value.call( this, i, jQuery( this ).val() );\n\t\t\t} else {\n\t\t\t\tval = value;\n\t\t\t}\n\n\t\t\t// Treat null/undefined as \"\"; convert numbers to string\n\t\t\tif ( val == null ) {\n\t\t\t\tval = \"\";\n\n\t\t\t} else if ( typeof val === \"number\" ) {\n\t\t\t\tval += \"\";\n\n\t\t\t} else if ( Array.isArray( val ) ) {\n\t\t\t\tval = jQuery.map( val, function( value ) {\n\t\t\t\t\treturn value == null ? \"\" : value + \"\";\n\t\t\t\t} );\n\t\t\t}\n\n\t\t\thooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];\n\n\t\t\t// If set returns undefined, fall back to normal setting\n\t\t\tif ( !hooks || !( \"set\" in hooks ) || hooks.set( this, val, \"value\" ) === undefined ) {\n\t\t\t\tthis.value = val;\n\t\t\t}\n\t\t} );\n\t}\n} );\n\njQuery.extend( {\n\tvalHooks: {\n\t\toption: {\n\t\t\tget: function( elem ) {\n\n\t\t\t\tvar val = jQuery.find.attr( elem, \"value\" );\n\t\t\t\treturn val != null ?\n\t\t\t\t\tval :\n\n\t\t\t\t\t// Support: IE <=10 - 11 only\n\t\t\t\t\t// option.text throws exceptions (#14686, #14858)\n\t\t\t\t\t// Strip and collapse whitespace\n\t\t\t\t\t// https://html.spec.whatwg.org/#strip-and-collapse-whitespace\n\t\t\t\t\tstripAndCollapse( jQuery.text( elem ) );\n\t\t\t}\n\t\t},\n\t\tselect: {\n\t\t\tget: function( elem ) {\n\t\t\t\tvar value, option, i,\n\t\t\t\t\toptions = elem.options,\n\t\t\t\t\tindex = elem.selectedIndex,\n\t\t\t\t\tone = elem.type === \"select-one\",\n\t\t\t\t\tvalues = one ? null : [],\n\t\t\t\t\tmax = one ? index + 1 : options.length;\n\n\t\t\t\tif ( index < 0 ) {\n\t\t\t\t\ti = max;\n\n\t\t\t\t} else {\n\t\t\t\t\ti = one ? index : 0;\n\t\t\t\t}\n\n\t\t\t\t// Loop through all the selected options\n\t\t\t\tfor ( ; i < max; i++ ) {\n\t\t\t\t\toption = options[ i ];\n\n\t\t\t\t\t// Support: IE <=9 only\n\t\t\t\t\t// IE8-9 doesn't update selected after form reset (#2551)\n\t\t\t\t\tif ( ( option.selected || i === index ) &&\n\n\t\t\t\t\t\t\t// Don't return options that are disabled or in a disabled optgroup\n\t\t\t\t\t\t\t!option.disabled &&\n\t\t\t\t\t\t\t( !option.parentNode.disabled ||\n\t\t\t\t\t\t\t\t!nodeName( option.parentNode, \"optgroup\" ) ) ) {\n\n\t\t\t\t\t\t// Get the specific value for the option\n\t\t\t\t\t\tvalue = jQuery( option ).val();\n\n\t\t\t\t\t\t// We don't need an array for one selects\n\t\t\t\t\t\tif ( one ) {\n\t\t\t\t\t\t\treturn value;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Multi-Selects return an array\n\t\t\t\t\t\tvalues.push( value );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn values;\n\t\t\t},\n\n\t\t\tset: function( elem, value ) {\n\t\t\t\tvar optionSet, option,\n\t\t\t\t\toptions = elem.options,\n\t\t\t\t\tvalues = jQuery.makeArray( value ),\n\t\t\t\t\ti = options.length;\n\n\t\t\t\twhile ( i-- ) {\n\t\t\t\t\toption = options[ i ];\n\n\t\t\t\t\t/* eslint-disable no-cond-assign */\n\n\t\t\t\t\tif ( option.selected =\n\t\t\t\t\t\tjQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1\n\t\t\t\t\t) {\n\t\t\t\t\t\toptionSet = true;\n\t\t\t\t\t}\n\n\t\t\t\t\t/* eslint-enable no-cond-assign */\n\t\t\t\t}\n\n\t\t\t\t// Force browsers to behave consistently when non-matching value is set\n\t\t\t\tif ( !optionSet ) {\n\t\t\t\t\telem.selectedIndex = -1;\n\t\t\t\t}\n\t\t\t\treturn values;\n\t\t\t}\n\t\t}\n\t}\n} );\n\n// Radios and checkboxes getter/setter\njQuery.each( [ \"radio\", \"checkbox\" ], function() {\n\tjQuery.valHooks[ this ] = {\n\t\tset: function( elem, value ) {\n\t\t\tif ( Array.isArray( value ) ) {\n\t\t\t\treturn ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 );\n\t\t\t}\n\t\t}\n\t};\n\tif ( !support.checkOn ) {\n\t\tjQuery.valHooks[ this ].get = function( elem ) {\n\t\t\treturn elem.getAttribute( \"value\" ) === null ? \"on\" : elem.value;\n\t\t};\n\t}\n} );\n\n\n\n\n// Return jQuery for attributes-only inclusion\n\n\nsupport.focusin = \"onfocusin\" in window;\n\n\nvar rfocusMorph = /^(?:focusinfocus|focusoutblur)$/,\n\tstopPropagationCallback = function( e ) {\n\t\te.stopPropagation();\n\t};\n\njQuery.extend( jQuery.event, {\n\n\ttrigger: function( event, data, elem, onlyHandlers ) {\n\n\t\tvar i, cur, tmp, bubbleType, ontype, handle, special, lastElement,\n\t\t\teventPath = [ elem || document ],\n\t\t\ttype = hasOwn.call( event, \"type\" ) ? event.type : event,\n\t\t\tnamespaces = hasOwn.call( event, \"namespace\" ) ? event.namespace.split( \".\" ) : [];\n\n\t\tcur = lastElement = tmp = elem = elem || document;\n\n\t\t// Don't do events on text and comment nodes\n\t\tif ( elem.nodeType === 3 || elem.nodeType === 8 ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// focus/blur morphs to focusin/out; ensure we're not firing them right now\n\t\tif ( rfocusMorph.test( type + jQuery.event.triggered ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( type.indexOf( \".\" ) > -1 ) {\n\n\t\t\t// Namespaced trigger; create a regexp to match event type in handle()\n\t\t\tnamespaces = type.split( \".\" );\n\t\t\ttype = namespaces.shift();\n\t\t\tnamespaces.sort();\n\t\t}\n\t\tontype = type.indexOf( \":\" ) < 0 && \"on\" + type;\n\n\t\t// Caller can pass in a jQuery.Event object, Object, or just an event type string\n\t\tevent = event[ jQuery.expando ] ?\n\t\t\tevent :\n\t\t\tnew jQuery.Event( type, typeof event === \"object\" && event );\n\n\t\t// Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)\n\t\tevent.isTrigger = onlyHandlers ? 2 : 3;\n\t\tevent.namespace = namespaces.join( \".\" );\n\t\tevent.rnamespace = event.namespace ?\n\t\t\tnew RegExp( \"(^|\\\\.)\" + namespaces.join( \"\\\\.(?:.*\\\\.|)\" ) + \"(\\\\.|$)\" ) :\n\t\t\tnull;\n\n\t\t// Clean up the event in case it is being reused\n\t\tevent.result = undefined;\n\t\tif ( !event.target ) {\n\t\t\tevent.target = elem;\n\t\t}\n\n\t\t// Clone any incoming data and prepend the event, creating the handler arg list\n\t\tdata = data == null ?\n\t\t\t[ event ] :\n\t\t\tjQuery.makeArray( data, [ event ] );\n\n\t\t// Allow special events to draw outside the lines\n\t\tspecial = jQuery.event.special[ type ] || {};\n\t\tif ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Determine event propagation path in advance, per W3C events spec (#9951)\n\t\t// Bubble up to document, then to window; watch for a global ownerDocument var (#9724)\n\t\tif ( !onlyHandlers && !special.noBubble && !isWindow( elem ) ) {\n\n\t\t\tbubbleType = special.delegateType || type;\n\t\t\tif ( !rfocusMorph.test( bubbleType + type ) ) {\n\t\t\t\tcur = cur.parentNode;\n\t\t\t}\n\t\t\tfor ( ; cur; cur = cur.parentNode ) {\n\t\t\t\teventPath.push( cur );\n\t\t\t\ttmp = cur;\n\t\t\t}\n\n\t\t\t// Only add window if we got to document (e.g., not plain obj or detached DOM)\n\t\t\tif ( tmp === ( elem.ownerDocument || document ) ) {\n\t\t\t\teventPath.push( tmp.defaultView || tmp.parentWindow || window );\n\t\t\t}\n\t\t}\n\n\t\t// Fire handlers on the event path\n\t\ti = 0;\n\t\twhile ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) {\n\t\t\tlastElement = cur;\n\t\t\tevent.type = i > 1 ?\n\t\t\t\tbubbleType :\n\t\t\t\tspecial.bindType || type;\n\n\t\t\t// jQuery handler\n\t\t\thandle = ( dataPriv.get( cur, \"events\" ) || {} )[ event.type ] &&\n\t\t\t\tdataPriv.get( cur, \"handle\" );\n\t\t\tif ( handle ) {\n\t\t\t\thandle.apply( cur, data );\n\t\t\t}\n\n\t\t\t// Native handler\n\t\t\thandle = ontype && cur[ ontype ];\n\t\t\tif ( handle && handle.apply && acceptData( cur ) ) {\n\t\t\t\tevent.result = handle.apply( cur, data );\n\t\t\t\tif ( event.result === false ) {\n\t\t\t\t\tevent.preventDefault();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tevent.type = type;\n\n\t\t// If nobody prevented the default action, do it now\n\t\tif ( !onlyHandlers && !event.isDefaultPrevented() ) {\n\n\t\t\tif ( ( !special._default ||\n\t\t\t\tspecial._default.apply( eventPath.pop(), data ) === false ) &&\n\t\t\t\tacceptData( elem ) ) {\n\n\t\t\t\t// Call a native DOM method on the target with the same name as the event.\n\t\t\t\t// Don't do default actions on window, that's where global variables be (#6170)\n\t\t\t\tif ( ontype && isFunction( elem[ type ] ) && !isWindow( elem ) ) {\n\n\t\t\t\t\t// Don't re-trigger an onFOO event when we call its FOO() method\n\t\t\t\t\ttmp = elem[ ontype ];\n\n\t\t\t\t\tif ( tmp ) {\n\t\t\t\t\t\telem[ ontype ] = null;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Prevent re-triggering of the same event, since we already bubbled it above\n\t\t\t\t\tjQuery.event.triggered = type;\n\n\t\t\t\t\tif ( event.isPropagationStopped() ) {\n\t\t\t\t\t\tlastElement.addEventListener( type, stopPropagationCallback );\n\t\t\t\t\t}\n\n\t\t\t\t\telem[ type ]();\n\n\t\t\t\t\tif ( event.isPropagationStopped() ) {\n\t\t\t\t\t\tlastElement.removeEventListener( type, stopPropagationCallback );\n\t\t\t\t\t}\n\n\t\t\t\t\tjQuery.event.triggered = undefined;\n\n\t\t\t\t\tif ( tmp ) {\n\t\t\t\t\t\telem[ ontype ] = tmp;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn event.result;\n\t},\n\n\t// Piggyback on a donor event to simulate a different one\n\t// Used only for `focus(in | out)` events\n\tsimulate: function( type, elem, event ) {\n\t\tvar e = jQuery.extend(\n\t\t\tnew jQuery.Event(),\n\t\t\tevent,\n\t\t\t{\n\t\t\t\ttype: type,\n\t\t\t\tisSimulated: true\n\t\t\t}\n\t\t);\n\n\t\tjQuery.event.trigger( e, null, elem );\n\t}\n\n} );\n\njQuery.fn.extend( {\n\n\ttrigger: function( type, data ) {\n\t\treturn this.each( function() {\n\t\t\tjQuery.event.trigger( type, data, this );\n\t\t} );\n\t},\n\ttriggerHandler: function( type, data ) {\n\t\tvar elem = this[ 0 ];\n\t\tif ( elem ) {\n\t\t\treturn jQuery.event.trigger( type, data, elem, true );\n\t\t}\n\t}\n} );\n\n\n// Support: Firefox <=44\n// Firefox doesn't have focus(in | out) events\n// Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787\n//\n// Support: Chrome <=48 - 49, Safari <=9.0 - 9.1\n// focus(in | out) events fire after focus & blur events,\n// which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order\n// Related ticket - https://bugs.chromium.org/p/chromium/issues/detail?id=449857\nif ( !support.focusin ) {\n\tjQuery.each( { focus: \"focusin\", blur: \"focusout\" }, function( orig, fix ) {\n\n\t\t// Attach a single capturing handler on the document while someone wants focusin/focusout\n\t\tvar handler = function( event ) {\n\t\t\tjQuery.event.simulate( fix, event.target, jQuery.event.fix( event ) );\n\t\t};\n\n\t\tjQuery.event.special[ fix ] = {\n\t\t\tsetup: function() {\n\t\t\t\tvar doc = this.ownerDocument || this,\n\t\t\t\t\tattaches = dataPriv.access( doc, fix );\n\n\t\t\t\tif ( !attaches ) {\n\t\t\t\t\tdoc.addEventListener( orig, handler, true );\n\t\t\t\t}\n\t\t\t\tdataPriv.access( doc, fix, ( attaches || 0 ) + 1 );\n\t\t\t},\n\t\t\tteardown: function() {\n\t\t\t\tvar doc = this.ownerDocument || this,\n\t\t\t\t\tattaches = dataPriv.access( doc, fix ) - 1;\n\n\t\t\t\tif ( !attaches ) {\n\t\t\t\t\tdoc.removeEventListener( orig, handler, true );\n\t\t\t\t\tdataPriv.remove( doc, fix );\n\n\t\t\t\t} else {\n\t\t\t\t\tdataPriv.access( doc, fix, attaches );\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t} );\n}\nvar location = window.location;\n\nvar nonce = Date.now();\n\nvar rquery = ( /\\?/ );\n\n\n\n// Cross-browser xml parsing\njQuery.parseXML = function( data ) {\n\tvar xml;\n\tif ( !data || typeof data !== \"string\" ) {\n\t\treturn null;\n\t}\n\n\t// Support: IE 9 - 11 only\n\t// IE throws on parseFromString with invalid input.\n\ttry {\n\t\txml = ( new window.DOMParser() ).parseFromString( data, \"text/xml\" );\n\t} catch ( e ) {\n\t\txml = undefined;\n\t}\n\n\tif ( !xml || xml.getElementsByTagName( \"parsererror\" ).length ) {\n\t\tjQuery.error( \"Invalid XML: \" + data );\n\t}\n\treturn xml;\n};\n\n\nvar\n\trbracket = /\\[\\]$/,\n\trCRLF = /\\r?\\n/g,\n\trsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,\n\trsubmittable = /^(?:input|select|textarea|keygen)/i;\n\nfunction buildParams( prefix, obj, traditional, add ) {\n\tvar name;\n\n\tif ( Array.isArray( obj ) ) {\n\n\t\t// Serialize array item.\n\t\tjQuery.each( obj, function( i, v ) {\n\t\t\tif ( traditional || rbracket.test( prefix ) ) {\n\n\t\t\t\t// Treat each array item as a scalar.\n\t\t\t\tadd( prefix, v );\n\n\t\t\t} else {\n\n\t\t\t\t// Item is non-scalar (array or object), encode its numeric index.\n\t\t\t\tbuildParams(\n\t\t\t\t\tprefix + \"[\" + ( typeof v === \"object\" && v != null ? i : \"\" ) + \"]\",\n\t\t\t\t\tv,\n\t\t\t\t\ttraditional,\n\t\t\t\t\tadd\n\t\t\t\t);\n\t\t\t}\n\t\t} );\n\n\t} else if ( !traditional && toType( obj ) === \"object\" ) {\n\n\t\t// Serialize object item.\n\t\tfor ( name in obj ) {\n\t\t\tbuildParams( prefix + \"[\" + name + \"]\", obj[ name ], traditional, add );\n\t\t}\n\n\t} else {\n\n\t\t// Serialize scalar item.\n\t\tadd( prefix, obj );\n\t}\n}\n\n// Serialize an array of form elements or a set of\n// key/values into a query string\njQuery.param = function( a, traditional ) {\n\tvar prefix,\n\t\ts = [],\n\t\tadd = function( key, valueOrFunction ) {\n\n\t\t\t// If value is a function, invoke it and use its return value\n\t\t\tvar value = isFunction( valueOrFunction ) ?\n\t\t\t\tvalueOrFunction() :\n\t\t\t\tvalueOrFunction;\n\n\t\t\ts[ s.length ] = encodeURIComponent( key ) + \"=\" +\n\t\t\t\tencodeURIComponent( value == null ? \"\" : value );\n\t\t};\n\n\t// If an array was passed in, assume that it is an array of form elements.\n\tif ( Array.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {\n\n\t\t// Serialize the form elements\n\t\tjQuery.each( a, function() {\n\t\t\tadd( this.name, this.value );\n\t\t} );\n\n\t} else {\n\n\t\t// If traditional, encode the \"old\" way (the way 1.3.2 or older\n\t\t// did it), otherwise encode params recursively.\n\t\tfor ( prefix in a ) {\n\t\t\tbuildParams( prefix, a[ prefix ], traditional, add );\n\t\t}\n\t}\n\n\t// Return the resulting serialization\n\treturn s.join( \"&\" );\n};\n\njQuery.fn.extend( {\n\tserialize: function() {\n\t\treturn jQuery.param( this.serializeArray() );\n\t},\n\tserializeArray: function() {\n\t\treturn this.map( function() {\n\n\t\t\t// Can add propHook for \"elements\" to filter or add form elements\n\t\t\tvar elements = jQuery.prop( this, \"elements\" );\n\t\t\treturn elements ? jQuery.makeArray( elements ) : this;\n\t\t} )\n\t\t.filter( function() {\n\t\t\tvar type = this.type;\n\n\t\t\t// Use .is( \":disabled\" ) so that fieldset[disabled] works\n\t\t\treturn this.name && !jQuery( this ).is( \":disabled\" ) &&\n\t\t\t\trsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) &&\n\t\t\t\t( this.checked || !rcheckableType.test( type ) );\n\t\t} )\n\t\t.map( function( i, elem ) {\n\t\t\tvar val = jQuery( this ).val();\n\n\t\t\tif ( val == null ) {\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\tif ( Array.isArray( val ) ) {\n\t\t\t\treturn jQuery.map( val, function( val ) {\n\t\t\t\t\treturn { name: elem.name, value: val.replace( rCRLF, \"\\r\\n\" ) };\n\t\t\t\t} );\n\t\t\t}\n\n\t\t\treturn { name: elem.name, value: val.replace( rCRLF, \"\\r\\n\" ) };\n\t\t} ).get();\n\t}\n} );\n\n\nvar\n\tr20 = /%20/g,\n\trhash = /#.*$/,\n\trantiCache = /([?&])_=[^&]*/,\n\trheaders = /^(.*?):[ \\t]*([^\\r\\n]*)$/mg,\n\n\t// #7653, #8125, #8152: local protocol detection\n\trlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,\n\trnoContent = /^(?:GET|HEAD)$/,\n\trprotocol = /^\\/\\//,\n\n\t/* Prefilters\n\t * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)\n\t * 2) These are called:\n\t *    - BEFORE asking for a transport\n\t *    - AFTER param serialization (s.data is a string if s.processData is true)\n\t * 3) key is the dataType\n\t * 4) the catchall symbol \"*\" can be used\n\t * 5) execution will start with transport dataType and THEN continue down to \"*\" if needed\n\t */\n\tprefilters = {},\n\n\t/* Transports bindings\n\t * 1) key is the dataType\n\t * 2) the catchall symbol \"*\" can be used\n\t * 3) selection will start with transport dataType and THEN go to \"*\" if needed\n\t */\n\ttransports = {},\n\n\t// Avoid comment-prolog char sequence (#10098); must appease lint and evade compression\n\tallTypes = \"*/\".concat( \"*\" ),\n\n\t// Anchor tag for parsing the document origin\n\toriginAnchor = document.createElement( \"a\" );\n\toriginAnchor.href = location.href;\n\n// Base \"constructor\" for jQuery.ajaxPrefilter and jQuery.ajaxTransport\nfunction addToPrefiltersOrTransports( structure ) {\n\n\t// dataTypeExpression is optional and defaults to \"*\"\n\treturn function( dataTypeExpression, func ) {\n\n\t\tif ( typeof dataTypeExpression !== \"string\" ) {\n\t\t\tfunc = dataTypeExpression;\n\t\t\tdataTypeExpression = \"*\";\n\t\t}\n\n\t\tvar dataType,\n\t\t\ti = 0,\n\t\t\tdataTypes = dataTypeExpression.toLowerCase().match( rnothtmlwhite ) || [];\n\n\t\tif ( isFunction( func ) ) {\n\n\t\t\t// For each dataType in the dataTypeExpression\n\t\t\twhile ( ( dataType = dataTypes[ i++ ] ) ) {\n\n\t\t\t\t// Prepend if requested\n\t\t\t\tif ( dataType[ 0 ] === \"+\" ) {\n\t\t\t\t\tdataType = dataType.slice( 1 ) || \"*\";\n\t\t\t\t\t( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func );\n\n\t\t\t\t// Otherwise append\n\t\t\t\t} else {\n\t\t\t\t\t( structure[ dataType ] = structure[ dataType ] || [] ).push( func );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n}\n\n// Base inspection function for prefilters and transports\nfunction inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) {\n\n\tvar inspected = {},\n\t\tseekingTransport = ( structure === transports );\n\n\tfunction inspect( dataType ) {\n\t\tvar selected;\n\t\tinspected[ dataType ] = true;\n\t\tjQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) {\n\t\t\tvar dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR );\n\t\t\tif ( typeof dataTypeOrTransport === \"string\" &&\n\t\t\t\t!seekingTransport && !inspected[ dataTypeOrTransport ] ) {\n\n\t\t\t\toptions.dataTypes.unshift( dataTypeOrTransport );\n\t\t\t\tinspect( dataTypeOrTransport );\n\t\t\t\treturn false;\n\t\t\t} else if ( seekingTransport ) {\n\t\t\t\treturn !( selected = dataTypeOrTransport );\n\t\t\t}\n\t\t} );\n\t\treturn selected;\n\t}\n\n\treturn inspect( options.dataTypes[ 0 ] ) || !inspected[ \"*\" ] && inspect( \"*\" );\n}\n\n// A special extend for ajax options\n// that takes \"flat\" options (not to be deep extended)\n// Fixes #9887\nfunction ajaxExtend( target, src ) {\n\tvar key, deep,\n\t\tflatOptions = jQuery.ajaxSettings.flatOptions || {};\n\n\tfor ( key in src ) {\n\t\tif ( src[ key ] !== undefined ) {\n\t\t\t( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ];\n\t\t}\n\t}\n\tif ( deep ) {\n\t\tjQuery.extend( true, target, deep );\n\t}\n\n\treturn target;\n}\n\n/* Handles responses to an ajax request:\n * - finds the right dataType (mediates between content-type and expected dataType)\n * - returns the corresponding response\n */\nfunction ajaxHandleResponses( s, jqXHR, responses ) {\n\n\tvar ct, type, finalDataType, firstDataType,\n\t\tcontents = s.contents,\n\t\tdataTypes = s.dataTypes;\n\n\t// Remove auto dataType and get content-type in the process\n\twhile ( dataTypes[ 0 ] === \"*\" ) {\n\t\tdataTypes.shift();\n\t\tif ( ct === undefined ) {\n\t\t\tct = s.mimeType || jqXHR.getResponseHeader( \"Content-Type\" );\n\t\t}\n\t}\n\n\t// Check if we're dealing with a known content-type\n\tif ( ct ) {\n\t\tfor ( type in contents ) {\n\t\t\tif ( contents[ type ] && contents[ type ].test( ct ) ) {\n\t\t\t\tdataTypes.unshift( type );\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\t// Check to see if we have a response for the expected dataType\n\tif ( dataTypes[ 0 ] in responses ) {\n\t\tfinalDataType = dataTypes[ 0 ];\n\t} else {\n\n\t\t// Try convertible dataTypes\n\t\tfor ( type in responses ) {\n\t\t\tif ( !dataTypes[ 0 ] || s.converters[ type + \" \" + dataTypes[ 0 ] ] ) {\n\t\t\t\tfinalDataType = type;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif ( !firstDataType ) {\n\t\t\t\tfirstDataType = type;\n\t\t\t}\n\t\t}\n\n\t\t// Or just use first one\n\t\tfinalDataType = finalDataType || firstDataType;\n\t}\n\n\t// If we found a dataType\n\t// We add the dataType to the list if needed\n\t// and return the corresponding response\n\tif ( finalDataType ) {\n\t\tif ( finalDataType !== dataTypes[ 0 ] ) {\n\t\t\tdataTypes.unshift( finalDataType );\n\t\t}\n\t\treturn responses[ finalDataType ];\n\t}\n}\n\n/* Chain conversions given the request and the original response\n * Also sets the responseXXX fields on the jqXHR instance\n */\nfunction ajaxConvert( s, response, jqXHR, isSuccess ) {\n\tvar conv2, current, conv, tmp, prev,\n\t\tconverters = {},\n\n\t\t// Work with a copy of dataTypes in case we need to modify it for conversion\n\t\tdataTypes = s.dataTypes.slice();\n\n\t// Create converters map with lowercased keys\n\tif ( dataTypes[ 1 ] ) {\n\t\tfor ( conv in s.converters ) {\n\t\t\tconverters[ conv.toLowerCase() ] = s.converters[ conv ];\n\t\t}\n\t}\n\n\tcurrent = dataTypes.shift();\n\n\t// Convert to each sequential dataType\n\twhile ( current ) {\n\n\t\tif ( s.responseFields[ current ] ) {\n\t\t\tjqXHR[ s.responseFields[ current ] ] = response;\n\t\t}\n\n\t\t// Apply the dataFilter if provided\n\t\tif ( !prev && isSuccess && s.dataFilter ) {\n\t\t\tresponse = s.dataFilter( response, s.dataType );\n\t\t}\n\n\t\tprev = current;\n\t\tcurrent = dataTypes.shift();\n\n\t\tif ( current ) {\n\n\t\t\t// There's only work to do if current dataType is non-auto\n\t\t\tif ( current === \"*\" ) {\n\n\t\t\t\tcurrent = prev;\n\n\t\t\t// Convert response if prev dataType is non-auto and differs from current\n\t\t\t} else if ( prev !== \"*\" && prev !== current ) {\n\n\t\t\t\t// Seek a direct converter\n\t\t\t\tconv = converters[ prev + \" \" + current ] || converters[ \"* \" + current ];\n\n\t\t\t\t// If none found, seek a pair\n\t\t\t\tif ( !conv ) {\n\t\t\t\t\tfor ( conv2 in converters ) {\n\n\t\t\t\t\t\t// If conv2 outputs current\n\t\t\t\t\t\ttmp = conv2.split( \" \" );\n\t\t\t\t\t\tif ( tmp[ 1 ] === current ) {\n\n\t\t\t\t\t\t\t// If prev can be converted to accepted input\n\t\t\t\t\t\t\tconv = converters[ prev + \" \" + tmp[ 0 ] ] ||\n\t\t\t\t\t\t\t\tconverters[ \"* \" + tmp[ 0 ] ];\n\t\t\t\t\t\t\tif ( conv ) {\n\n\t\t\t\t\t\t\t\t// Condense equivalence converters\n\t\t\t\t\t\t\t\tif ( conv === true ) {\n\t\t\t\t\t\t\t\t\tconv = converters[ conv2 ];\n\n\t\t\t\t\t\t\t\t// Otherwise, insert the intermediate dataType\n\t\t\t\t\t\t\t\t} else if ( converters[ conv2 ] !== true ) {\n\t\t\t\t\t\t\t\t\tcurrent = tmp[ 0 ];\n\t\t\t\t\t\t\t\t\tdataTypes.unshift( tmp[ 1 ] );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Apply converter (if not an equivalence)\n\t\t\t\tif ( conv !== true ) {\n\n\t\t\t\t\t// Unless errors are allowed to bubble, catch and return them\n\t\t\t\t\tif ( conv && s.throws ) {\n\t\t\t\t\t\tresponse = conv( response );\n\t\t\t\t\t} else {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tresponse = conv( response );\n\t\t\t\t\t\t} catch ( e ) {\n\t\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t\tstate: \"parsererror\",\n\t\t\t\t\t\t\t\terror: conv ? e : \"No conversion from \" + prev + \" to \" + current\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn { state: \"success\", data: response };\n}\n\njQuery.extend( {\n\n\t// Counter for holding the number of active queries\n\tactive: 0,\n\n\t// Last-Modified header cache for next request\n\tlastModified: {},\n\tetag: {},\n\n\tajaxSettings: {\n\t\turl: location.href,\n\t\ttype: \"GET\",\n\t\tisLocal: rlocalProtocol.test( location.protocol ),\n\t\tglobal: true,\n\t\tprocessData: true,\n\t\tasync: true,\n\t\tcontentType: \"application/x-www-form-urlencoded; charset=UTF-8\",\n\n\t\t/*\n\t\ttimeout: 0,\n\t\tdata: null,\n\t\tdataType: null,\n\t\tusername: null,\n\t\tpassword: null,\n\t\tcache: null,\n\t\tthrows: false,\n\t\ttraditional: false,\n\t\theaders: {},\n\t\t*/\n\n\t\taccepts: {\n\t\t\t\"*\": allTypes,\n\t\t\ttext: \"text/plain\",\n\t\t\thtml: \"text/html\",\n\t\t\txml: \"application/xml, text/xml\",\n\t\t\tjson: \"application/json, text/javascript\"\n\t\t},\n\n\t\tcontents: {\n\t\t\txml: /\\bxml\\b/,\n\t\t\thtml: /\\bhtml/,\n\t\t\tjson: /\\bjson\\b/\n\t\t},\n\n\t\tresponseFields: {\n\t\t\txml: \"responseXML\",\n\t\t\ttext: \"responseText\",\n\t\t\tjson: \"responseJSON\"\n\t\t},\n\n\t\t// Data converters\n\t\t// Keys separate source (or catchall \"*\") and destination types with a single space\n\t\tconverters: {\n\n\t\t\t// Convert anything to text\n\t\t\t\"* text\": String,\n\n\t\t\t// Text to html (true = no transformation)\n\t\t\t\"text html\": true,\n\n\t\t\t// Evaluate text as a json expression\n\t\t\t\"text json\": JSON.parse,\n\n\t\t\t// Parse text as xml\n\t\t\t\"text xml\": jQuery.parseXML\n\t\t},\n\n\t\t// For options that shouldn't be deep extended:\n\t\t// you can add your own custom options here if\n\t\t// and when you create one that shouldn't be\n\t\t// deep extended (see ajaxExtend)\n\t\tflatOptions: {\n\t\t\turl: true,\n\t\t\tcontext: true\n\t\t}\n\t},\n\n\t// Creates a full fledged settings object into target\n\t// with both ajaxSettings and settings fields.\n\t// If target is omitted, writes into ajaxSettings.\n\tajaxSetup: function( target, settings ) {\n\t\treturn settings ?\n\n\t\t\t// Building a settings object\n\t\t\tajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) :\n\n\t\t\t// Extending ajaxSettings\n\t\t\tajaxExtend( jQuery.ajaxSettings, target );\n\t},\n\n\tajaxPrefilter: addToPrefiltersOrTransports( prefilters ),\n\tajaxTransport: addToPrefiltersOrTransports( transports ),\n\n\t// Main method\n\tajax: function( url, options ) {\n\n\t\t// If url is an object, simulate pre-1.5 signature\n\t\tif ( typeof url === \"object\" ) {\n\t\t\toptions = url;\n\t\t\turl = undefined;\n\t\t}\n\n\t\t// Force options to be an object\n\t\toptions = options || {};\n\n\t\tvar transport,\n\n\t\t\t// URL without anti-cache param\n\t\t\tcacheURL,\n\n\t\t\t// Response headers\n\t\t\tresponseHeadersString,\n\t\t\tresponseHeaders,\n\n\t\t\t// timeout handle\n\t\t\ttimeoutTimer,\n\n\t\t\t// Url cleanup var\n\t\t\turlAnchor,\n\n\t\t\t// Request state (becomes false upon send and true upon completion)\n\t\t\tcompleted,\n\n\t\t\t// To know if global events are to be dispatched\n\t\t\tfireGlobals,\n\n\t\t\t// Loop variable\n\t\t\ti,\n\n\t\t\t// uncached part of the url\n\t\t\tuncached,\n\n\t\t\t// Create the final options object\n\t\t\ts = jQuery.ajaxSetup( {}, options ),\n\n\t\t\t// Callbacks context\n\t\t\tcallbackContext = s.context || s,\n\n\t\t\t// Context for global events is callbackContext if it is a DOM node or jQuery collection\n\t\t\tglobalEventContext = s.context &&\n\t\t\t\t( callbackContext.nodeType || callbackContext.jquery ) ?\n\t\t\t\t\tjQuery( callbackContext ) :\n\t\t\t\t\tjQuery.event,\n\n\t\t\t// Deferreds\n\t\t\tdeferred = jQuery.Deferred(),\n\t\t\tcompleteDeferred = jQuery.Callbacks( \"once memory\" ),\n\n\t\t\t// Status-dependent callbacks\n\t\t\tstatusCode = s.statusCode || {},\n\n\t\t\t// Headers (they are sent all at once)\n\t\t\trequestHeaders = {},\n\t\t\trequestHeadersNames = {},\n\n\t\t\t// Default abort message\n\t\t\tstrAbort = \"canceled\",\n\n\t\t\t// Fake xhr\n\t\t\tjqXHR = {\n\t\t\t\treadyState: 0,\n\n\t\t\t\t// Builds headers hashtable if needed\n\t\t\t\tgetResponseHeader: function( key ) {\n\t\t\t\t\tvar match;\n\t\t\t\t\tif ( completed ) {\n\t\t\t\t\t\tif ( !responseHeaders ) {\n\t\t\t\t\t\t\tresponseHeaders = {};\n\t\t\t\t\t\t\twhile ( ( match = rheaders.exec( responseHeadersString ) ) ) {\n\t\t\t\t\t\t\t\tresponseHeaders[ match[ 1 ].toLowerCase() ] = match[ 2 ];\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tmatch = responseHeaders[ key.toLowerCase() ];\n\t\t\t\t\t}\n\t\t\t\t\treturn match == null ? null : match;\n\t\t\t\t},\n\n\t\t\t\t// Raw string\n\t\t\t\tgetAllResponseHeaders: function() {\n\t\t\t\t\treturn completed ? responseHeadersString : null;\n\t\t\t\t},\n\n\t\t\t\t// Caches the header\n\t\t\t\tsetRequestHeader: function( name, value ) {\n\t\t\t\t\tif ( completed == null ) {\n\t\t\t\t\t\tname = requestHeadersNames[ name.toLowerCase() ] =\n\t\t\t\t\t\t\trequestHeadersNames[ name.toLowerCase() ] || name;\n\t\t\t\t\t\trequestHeaders[ name ] = value;\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\n\t\t\t\t// Overrides response content-type header\n\t\t\t\toverrideMimeType: function( type ) {\n\t\t\t\t\tif ( completed == null ) {\n\t\t\t\t\t\ts.mimeType = type;\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\n\t\t\t\t// Status-dependent callbacks\n\t\t\t\tstatusCode: function( map ) {\n\t\t\t\t\tvar code;\n\t\t\t\t\tif ( map ) {\n\t\t\t\t\t\tif ( completed ) {\n\n\t\t\t\t\t\t\t// Execute the appropriate callbacks\n\t\t\t\t\t\t\tjqXHR.always( map[ jqXHR.status ] );\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t// Lazy-add the new callbacks in a way that preserves old ones\n\t\t\t\t\t\t\tfor ( code in map ) {\n\t\t\t\t\t\t\t\tstatusCode[ code ] = [ statusCode[ code ], map[ code ] ];\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\n\t\t\t\t// Cancel the request\n\t\t\t\tabort: function( statusText ) {\n\t\t\t\t\tvar finalText = statusText || strAbort;\n\t\t\t\t\tif ( transport ) {\n\t\t\t\t\t\ttransport.abort( finalText );\n\t\t\t\t\t}\n\t\t\t\t\tdone( 0, finalText );\n\t\t\t\t\treturn this;\n\t\t\t\t}\n\t\t\t};\n\n\t\t// Attach deferreds\n\t\tdeferred.promise( jqXHR );\n\n\t\t// Add protocol if not provided (prefilters might expect it)\n\t\t// Handle falsy url in the settings object (#10093: consistency with old signature)\n\t\t// We also use the url parameter if available\n\t\ts.url = ( ( url || s.url || location.href ) + \"\" )\n\t\t\t.replace( rprotocol, location.protocol + \"//\" );\n\n\t\t// Alias method option to type as per ticket #12004\n\t\ts.type = options.method || options.type || s.method || s.type;\n\n\t\t// Extract dataTypes list\n\t\ts.dataTypes = ( s.dataType || \"*\" ).toLowerCase().match( rnothtmlwhite ) || [ \"\" ];\n\n\t\t// A cross-domain request is in order when the origin doesn't match the current origin.\n\t\tif ( s.crossDomain == null ) {\n\t\t\turlAnchor = document.createElement( \"a\" );\n\n\t\t\t// Support: IE <=8 - 11, Edge 12 - 15\n\t\t\t// IE throws exception on accessing the href property if url is malformed,\n\t\t\t// e.g. http://example.com:80x/\n\t\t\ttry {\n\t\t\t\turlAnchor.href = s.url;\n\n\t\t\t\t// Support: IE <=8 - 11 only\n\t\t\t\t// Anchor's host property isn't correctly set when s.url is relative\n\t\t\t\turlAnchor.href = urlAnchor.href;\n\t\t\t\ts.crossDomain = originAnchor.protocol + \"//\" + originAnchor.host !==\n\t\t\t\t\turlAnchor.protocol + \"//\" + urlAnchor.host;\n\t\t\t} catch ( e ) {\n\n\t\t\t\t// If there is an error parsing the URL, assume it is crossDomain,\n\t\t\t\t// it can be rejected by the transport if it is invalid\n\t\t\t\ts.crossDomain = true;\n\t\t\t}\n\t\t}\n\n\t\t// Convert data if not already a string\n\t\tif ( s.data && s.processData && typeof s.data !== \"string\" ) {\n\t\t\ts.data = jQuery.param( s.data, s.traditional );\n\t\t}\n\n\t\t// Apply prefilters\n\t\tinspectPrefiltersOrTransports( prefilters, s, options, jqXHR );\n\n\t\t// If request was aborted inside a prefilter, stop there\n\t\tif ( completed ) {\n\t\t\treturn jqXHR;\n\t\t}\n\n\t\t// We can fire global events as of now if asked to\n\t\t// Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118)\n\t\tfireGlobals = jQuery.event && s.global;\n\n\t\t// Watch for a new set of requests\n\t\tif ( fireGlobals && jQuery.active++ === 0 ) {\n\t\t\tjQuery.event.trigger( \"ajaxStart\" );\n\t\t}\n\n\t\t// Uppercase the type\n\t\ts.type = s.type.toUpperCase();\n\n\t\t// Determine if request has content\n\t\ts.hasContent = !rnoContent.test( s.type );\n\n\t\t// Save the URL in case we're toying with the If-Modified-Since\n\t\t// and/or If-None-Match header later on\n\t\t// Remove hash to simplify url manipulation\n\t\tcacheURL = s.url.replace( rhash, \"\" );\n\n\t\t// More options handling for requests with no content\n\t\tif ( !s.hasContent ) {\n\n\t\t\t// Remember the hash so we can put it back\n\t\t\tuncached = s.url.slice( cacheURL.length );\n\n\t\t\t// If data is available and should be processed, append data to url\n\t\t\tif ( s.data && ( s.processData || typeof s.data === \"string\" ) ) {\n\t\t\t\tcacheURL += ( rquery.test( cacheURL ) ? \"&\" : \"?\" ) + s.data;\n\n\t\t\t\t// #9682: remove data so that it's not used in an eventual retry\n\t\t\t\tdelete s.data;\n\t\t\t}\n\n\t\t\t// Add or update anti-cache param if needed\n\t\t\tif ( s.cache === false ) {\n\t\t\t\tcacheURL = cacheURL.replace( rantiCache, \"$1\" );\n\t\t\t\tuncached = ( rquery.test( cacheURL ) ? \"&\" : \"?\" ) + \"_=\" + ( nonce++ ) + uncached;\n\t\t\t}\n\n\t\t\t// Put hash and anti-cache on the URL that will be requested (gh-1732)\n\t\t\ts.url = cacheURL + uncached;\n\n\t\t// Change '%20' to '+' if this is encoded form body content (gh-2658)\n\t\t} else if ( s.data && s.processData &&\n\t\t\t( s.contentType || \"\" ).indexOf( \"application/x-www-form-urlencoded\" ) === 0 ) {\n\t\t\ts.data = s.data.replace( r20, \"+\" );\n\t\t}\n\n\t\t// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.\n\t\tif ( s.ifModified ) {\n\t\t\tif ( jQuery.lastModified[ cacheURL ] ) {\n\t\t\t\tjqXHR.setRequestHeader( \"If-Modified-Since\", jQuery.lastModified[ cacheURL ] );\n\t\t\t}\n\t\t\tif ( jQuery.etag[ cacheURL ] ) {\n\t\t\t\tjqXHR.setRequestHeader( \"If-None-Match\", jQuery.etag[ cacheURL ] );\n\t\t\t}\n\t\t}\n\n\t\t// Set the correct header, if data is being sent\n\t\tif ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {\n\t\t\tjqXHR.setRequestHeader( \"Content-Type\", s.contentType );\n\t\t}\n\n\t\t// Set the Accepts header for the server, depending on the dataType\n\t\tjqXHR.setRequestHeader(\n\t\t\t\"Accept\",\n\t\t\ts.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ?\n\t\t\t\ts.accepts[ s.dataTypes[ 0 ] ] +\n\t\t\t\t\t( s.dataTypes[ 0 ] !== \"*\" ? \", \" + allTypes + \"; q=0.01\" : \"\" ) :\n\t\t\t\ts.accepts[ \"*\" ]\n\t\t);\n\n\t\t// Check for headers option\n\t\tfor ( i in s.headers ) {\n\t\t\tjqXHR.setRequestHeader( i, s.headers[ i ] );\n\t\t}\n\n\t\t// Allow custom headers/mimetypes and early abort\n\t\tif ( s.beforeSend &&\n\t\t\t( s.beforeSend.call( callbackContext, jqXHR, s ) === false || completed ) ) {\n\n\t\t\t// Abort if not done already and return\n\t\t\treturn jqXHR.abort();\n\t\t}\n\n\t\t// Aborting is no longer a cancellation\n\t\tstrAbort = \"abort\";\n\n\t\t// Install callbacks on deferreds\n\t\tcompleteDeferred.add( s.complete );\n\t\tjqXHR.done( s.success );\n\t\tjqXHR.fail( s.error );\n\n\t\t// Get transport\n\t\ttransport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );\n\n\t\t// If no transport, we auto-abort\n\t\tif ( !transport ) {\n\t\t\tdone( -1, \"No Transport\" );\n\t\t} else {\n\t\t\tjqXHR.readyState = 1;\n\n\t\t\t// Send global event\n\t\t\tif ( fireGlobals ) {\n\t\t\t\tglobalEventContext.trigger( \"ajaxSend\", [ jqXHR, s ] );\n\t\t\t}\n\n\t\t\t// If request was aborted inside ajaxSend, stop there\n\t\t\tif ( completed ) {\n\t\t\t\treturn jqXHR;\n\t\t\t}\n\n\t\t\t// Timeout\n\t\t\tif ( s.async && s.timeout > 0 ) {\n\t\t\t\ttimeoutTimer = window.setTimeout( function() {\n\t\t\t\t\tjqXHR.abort( \"timeout\" );\n\t\t\t\t}, s.timeout );\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tcompleted = false;\n\t\t\t\ttransport.send( requestHeaders, done );\n\t\t\t} catch ( e ) {\n\n\t\t\t\t// Rethrow post-completion exceptions\n\t\t\t\tif ( completed ) {\n\t\t\t\t\tthrow e;\n\t\t\t\t}\n\n\t\t\t\t// Propagate others as results\n\t\t\t\tdone( -1, e );\n\t\t\t}\n\t\t}\n\n\t\t// Callback for when everything is done\n\t\tfunction done( status, nativeStatusText, responses, headers ) {\n\t\t\tvar isSuccess, success, error, response, modified,\n\t\t\t\tstatusText = nativeStatusText;\n\n\t\t\t// Ignore repeat invocations\n\t\t\tif ( completed ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tcompleted = true;\n\n\t\t\t// Clear timeout if it exists\n\t\t\tif ( timeoutTimer ) {\n\t\t\t\twindow.clearTimeout( timeoutTimer );\n\t\t\t}\n\n\t\t\t// Dereference transport for early garbage collection\n\t\t\t// (no matter how long the jqXHR object will be used)\n\t\t\ttransport = undefined;\n\n\t\t\t// Cache response headers\n\t\t\tresponseHeadersString = headers || \"\";\n\n\t\t\t// Set readyState\n\t\t\tjqXHR.readyState = status > 0 ? 4 : 0;\n\n\t\t\t// Determine if successful\n\t\t\tisSuccess = status >= 200 && status < 300 || status === 304;\n\n\t\t\t// Get response data\n\t\t\tif ( responses ) {\n\t\t\t\tresponse = ajaxHandleResponses( s, jqXHR, responses );\n\t\t\t}\n\n\t\t\t// Convert no matter what (that way responseXXX fields are always set)\n\t\t\tresponse = ajaxConvert( s, response, jqXHR, isSuccess );\n\n\t\t\t// If successful, handle type chaining\n\t\t\tif ( isSuccess ) {\n\n\t\t\t\t// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.\n\t\t\t\tif ( s.ifModified ) {\n\t\t\t\t\tmodified = jqXHR.getResponseHeader( \"Last-Modified\" );\n\t\t\t\t\tif ( modified ) {\n\t\t\t\t\t\tjQuery.lastModified[ cacheURL ] = modified;\n\t\t\t\t\t}\n\t\t\t\t\tmodified = jqXHR.getResponseHeader( \"etag\" );\n\t\t\t\t\tif ( modified ) {\n\t\t\t\t\t\tjQuery.etag[ cacheURL ] = modified;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// if no content\n\t\t\t\tif ( status === 204 || s.type === \"HEAD\" ) {\n\t\t\t\t\tstatusText = \"nocontent\";\n\n\t\t\t\t// if not modified\n\t\t\t\t} else if ( status === 304 ) {\n\t\t\t\t\tstatusText = \"notmodified\";\n\n\t\t\t\t// If we have data, let's convert it\n\t\t\t\t} else {\n\t\t\t\t\tstatusText = response.state;\n\t\t\t\t\tsuccess = response.data;\n\t\t\t\t\terror = response.error;\n\t\t\t\t\tisSuccess = !error;\n\t\t\t\t}\n\t\t\t} else {\n\n\t\t\t\t// Extract error from statusText and normalize for non-aborts\n\t\t\t\terror = statusText;\n\t\t\t\tif ( status || !statusText ) {\n\t\t\t\t\tstatusText = \"error\";\n\t\t\t\t\tif ( status < 0 ) {\n\t\t\t\t\t\tstatus = 0;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Set data for the fake xhr object\n\t\t\tjqXHR.status = status;\n\t\t\tjqXHR.statusText = ( nativeStatusText || statusText ) + \"\";\n\n\t\t\t// Success/Error\n\t\t\tif ( isSuccess ) {\n\t\t\t\tdeferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );\n\t\t\t} else {\n\t\t\t\tdeferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );\n\t\t\t}\n\n\t\t\t// Status-dependent callbacks\n\t\t\tjqXHR.statusCode( statusCode );\n\t\t\tstatusCode = undefined;\n\n\t\t\tif ( fireGlobals ) {\n\t\t\t\tglobalEventContext.trigger( isSuccess ? \"ajaxSuccess\" : \"ajaxError\",\n\t\t\t\t\t[ jqXHR, s, isSuccess ? success : error ] );\n\t\t\t}\n\n\t\t\t// Complete\n\t\t\tcompleteDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );\n\n\t\t\tif ( fireGlobals ) {\n\t\t\t\tglobalEventContext.trigger( \"ajaxComplete\", [ jqXHR, s ] );\n\n\t\t\t\t// Handle the global AJAX counter\n\t\t\t\tif ( !( --jQuery.active ) ) {\n\t\t\t\t\tjQuery.event.trigger( \"ajaxStop\" );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn jqXHR;\n\t},\n\n\tgetJSON: function( url, data, callback ) {\n\t\treturn jQuery.get( url, data, callback, \"json\" );\n\t},\n\n\tgetScript: function( url, callback ) {\n\t\treturn jQuery.get( url, undefined, callback, \"script\" );\n\t}\n} );\n\njQuery.each( [ \"get\", \"post\" ], function( i, method ) {\n\tjQuery[ method ] = function( url, data, callback, type ) {\n\n\t\t// Shift arguments if data argument was omitted\n\t\tif ( isFunction( data ) ) {\n\t\t\ttype = type || callback;\n\t\t\tcallback = data;\n\t\t\tdata = undefined;\n\t\t}\n\n\t\t// The url can be an options object (which then must have .url)\n\t\treturn jQuery.ajax( jQuery.extend( {\n\t\t\turl: url,\n\t\t\ttype: method,\n\t\t\tdataType: type,\n\t\t\tdata: data,\n\t\t\tsuccess: callback\n\t\t}, jQuery.isPlainObject( url ) && url ) );\n\t};\n} );\n\n\njQuery._evalUrl = function( url ) {\n\treturn jQuery.ajax( {\n\t\turl: url,\n\n\t\t// Make this explicit, since user can override this through ajaxSetup (#11264)\n\t\ttype: \"GET\",\n\t\tdataType: \"script\",\n\t\tcache: true,\n\t\tasync: false,\n\t\tglobal: false,\n\t\t\"throws\": true\n\t} );\n};\n\n\njQuery.fn.extend( {\n\twrapAll: function( html ) {\n\t\tvar wrap;\n\n\t\tif ( this[ 0 ] ) {\n\t\t\tif ( isFunction( html ) ) {\n\t\t\t\thtml = html.call( this[ 0 ] );\n\t\t\t}\n\n\t\t\t// The elements to wrap the target around\n\t\t\twrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true );\n\n\t\t\tif ( this[ 0 ].parentNode ) {\n\t\t\t\twrap.insertBefore( this[ 0 ] );\n\t\t\t}\n\n\t\t\twrap.map( function() {\n\t\t\t\tvar elem = this;\n\n\t\t\t\twhile ( elem.firstElementChild ) {\n\t\t\t\t\telem = elem.firstElementChild;\n\t\t\t\t}\n\n\t\t\t\treturn elem;\n\t\t\t} ).append( this );\n\t\t}\n\n\t\treturn this;\n\t},\n\n\twrapInner: function( html ) {\n\t\tif ( isFunction( html ) ) {\n\t\t\treturn this.each( function( i ) {\n\t\t\t\tjQuery( this ).wrapInner( html.call( this, i ) );\n\t\t\t} );\n\t\t}\n\n\t\treturn this.each( function() {\n\t\t\tvar self = jQuery( this ),\n\t\t\t\tcontents = self.contents();\n\n\t\t\tif ( contents.length ) {\n\t\t\t\tcontents.wrapAll( html );\n\n\t\t\t} else {\n\t\t\t\tself.append( html );\n\t\t\t}\n\t\t} );\n\t},\n\n\twrap: function( html ) {\n\t\tvar htmlIsFunction = isFunction( html );\n\n\t\treturn this.each( function( i ) {\n\t\t\tjQuery( this ).wrapAll( htmlIsFunction ? html.call( this, i ) : html );\n\t\t} );\n\t},\n\n\tunwrap: function( selector ) {\n\t\tthis.parent( selector ).not( \"body\" ).each( function() {\n\t\t\tjQuery( this ).replaceWith( this.childNodes );\n\t\t} );\n\t\treturn this;\n\t}\n} );\n\n\njQuery.expr.pseudos.hidden = function( elem ) {\n\treturn !jQuery.expr.pseudos.visible( elem );\n};\njQuery.expr.pseudos.visible = function( elem ) {\n\treturn !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length );\n};\n\n\n\n\njQuery.ajaxSettings.xhr = function() {\n\ttry {\n\t\treturn new window.XMLHttpRequest();\n\t} catch ( e ) {}\n};\n\nvar xhrSuccessStatus = {\n\n\t\t// File protocol always yields status code 0, assume 200\n\t\t0: 200,\n\n\t\t// Support: IE <=9 only\n\t\t// #1450: sometimes IE returns 1223 when it should be 204\n\t\t1223: 204\n\t},\n\txhrSupported = jQuery.ajaxSettings.xhr();\n\nsupport.cors = !!xhrSupported && ( \"withCredentials\" in xhrSupported );\nsupport.ajax = xhrSupported = !!xhrSupported;\n\njQuery.ajaxTransport( function( options ) {\n\tvar callback, errorCallback;\n\n\t// Cross domain only allowed if supported through XMLHttpRequest\n\tif ( support.cors || xhrSupported && !options.crossDomain ) {\n\t\treturn {\n\t\t\tsend: function( headers, complete ) {\n\t\t\t\tvar i,\n\t\t\t\t\txhr = options.xhr();\n\n\t\t\t\txhr.open(\n\t\t\t\t\toptions.type,\n\t\t\t\t\toptions.url,\n\t\t\t\t\toptions.async,\n\t\t\t\t\toptions.username,\n\t\t\t\t\toptions.password\n\t\t\t\t);\n\n\t\t\t\t// Apply custom fields if provided\n\t\t\t\tif ( options.xhrFields ) {\n\t\t\t\t\tfor ( i in options.xhrFields ) {\n\t\t\t\t\t\txhr[ i ] = options.xhrFields[ i ];\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Override mime type if needed\n\t\t\t\tif ( options.mimeType && xhr.overrideMimeType ) {\n\t\t\t\t\txhr.overrideMimeType( options.mimeType );\n\t\t\t\t}\n\n\t\t\t\t// X-Requested-With header\n\t\t\t\t// For cross-domain requests, seeing as conditions for a preflight are\n\t\t\t\t// akin to a jigsaw puzzle, we simply never set it to be sure.\n\t\t\t\t// (it can always be set on a per-request basis or even using ajaxSetup)\n\t\t\t\t// For same-domain requests, won't change header if already provided.\n\t\t\t\tif ( !options.crossDomain && !headers[ \"X-Requested-With\" ] ) {\n\t\t\t\t\theaders[ \"X-Requested-With\" ] = \"XMLHttpRequest\";\n\t\t\t\t}\n\n\t\t\t\t// Set headers\n\t\t\t\tfor ( i in headers ) {\n\t\t\t\t\txhr.setRequestHeader( i, headers[ i ] );\n\t\t\t\t}\n\n\t\t\t\t// Callback\n\t\t\t\tcallback = function( type ) {\n\t\t\t\t\treturn function() {\n\t\t\t\t\t\tif ( callback ) {\n\t\t\t\t\t\t\tcallback = errorCallback = xhr.onload =\n\t\t\t\t\t\t\t\txhr.onerror = xhr.onabort = xhr.ontimeout =\n\t\t\t\t\t\t\t\t\txhr.onreadystatechange = null;\n\n\t\t\t\t\t\t\tif ( type === \"abort\" ) {\n\t\t\t\t\t\t\t\txhr.abort();\n\t\t\t\t\t\t\t} else if ( type === \"error\" ) {\n\n\t\t\t\t\t\t\t\t// Support: IE <=9 only\n\t\t\t\t\t\t\t\t// On a manual native abort, IE9 throws\n\t\t\t\t\t\t\t\t// errors on any property access that is not readyState\n\t\t\t\t\t\t\t\tif ( typeof xhr.status !== \"number\" ) {\n\t\t\t\t\t\t\t\t\tcomplete( 0, \"error\" );\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tcomplete(\n\n\t\t\t\t\t\t\t\t\t\t// File: protocol always yields status 0; see #8605, #14207\n\t\t\t\t\t\t\t\t\t\txhr.status,\n\t\t\t\t\t\t\t\t\t\txhr.statusText\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tcomplete(\n\t\t\t\t\t\t\t\t\txhrSuccessStatus[ xhr.status ] || xhr.status,\n\t\t\t\t\t\t\t\t\txhr.statusText,\n\n\t\t\t\t\t\t\t\t\t// Support: IE <=9 only\n\t\t\t\t\t\t\t\t\t// IE9 has no XHR2 but throws on binary (trac-11426)\n\t\t\t\t\t\t\t\t\t// For XHR2 non-text, let the caller handle it (gh-2498)\n\t\t\t\t\t\t\t\t\t( xhr.responseType || \"text\" ) !== \"text\"  ||\n\t\t\t\t\t\t\t\t\ttypeof xhr.responseText !== \"string\" ?\n\t\t\t\t\t\t\t\t\t\t{ binary: xhr.response } :\n\t\t\t\t\t\t\t\t\t\t{ text: xhr.responseText },\n\t\t\t\t\t\t\t\t\txhr.getAllResponseHeaders()\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t};\n\t\t\t\t};\n\n\t\t\t\t// Listen to events\n\t\t\t\txhr.onload = callback();\n\t\t\t\terrorCallback = xhr.onerror = xhr.ontimeout = callback( \"error\" );\n\n\t\t\t\t// Support: IE 9 only\n\t\t\t\t// Use onreadystatechange to replace onabort\n\t\t\t\t// to handle uncaught aborts\n\t\t\t\tif ( xhr.onabort !== undefined ) {\n\t\t\t\t\txhr.onabort = errorCallback;\n\t\t\t\t} else {\n\t\t\t\t\txhr.onreadystatechange = function() {\n\n\t\t\t\t\t\t// Check readyState before timeout as it changes\n\t\t\t\t\t\tif ( xhr.readyState === 4 ) {\n\n\t\t\t\t\t\t\t// Allow onerror to be called first,\n\t\t\t\t\t\t\t// but that will not handle a native abort\n\t\t\t\t\t\t\t// Also, save errorCallback to a variable\n\t\t\t\t\t\t\t// as xhr.onerror cannot be accessed\n\t\t\t\t\t\t\twindow.setTimeout( function() {\n\t\t\t\t\t\t\t\tif ( callback ) {\n\t\t\t\t\t\t\t\t\terrorCallback();\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} );\n\t\t\t\t\t\t}\n\t\t\t\t\t};\n\t\t\t\t}\n\n\t\t\t\t// Create the abort callback\n\t\t\t\tcallback = callback( \"abort\" );\n\n\t\t\t\ttry {\n\n\t\t\t\t\t// Do send the request (this may raise an exception)\n\t\t\t\t\txhr.send( options.hasContent && options.data || null );\n\t\t\t\t} catch ( e ) {\n\n\t\t\t\t\t// #14683: Only rethrow if this hasn't been notified as an error yet\n\t\t\t\t\tif ( callback ) {\n\t\t\t\t\t\tthrow e;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\n\t\t\tabort: function() {\n\t\t\t\tif ( callback ) {\n\t\t\t\t\tcallback();\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t}\n} );\n\n\n\n\n// Prevent auto-execution of scripts when no explicit dataType was provided (See gh-2432)\njQuery.ajaxPrefilter( function( s ) {\n\tif ( s.crossDomain ) {\n\t\ts.contents.script = false;\n\t}\n} );\n\n// Install script dataType\njQuery.ajaxSetup( {\n\taccepts: {\n\t\tscript: \"text/javascript, application/javascript, \" +\n\t\t\t\"application/ecmascript, application/x-ecmascript\"\n\t},\n\tcontents: {\n\t\tscript: /\\b(?:java|ecma)script\\b/\n\t},\n\tconverters: {\n\t\t\"text script\": function( text ) {\n\t\t\tjQuery.globalEval( text );\n\t\t\treturn text;\n\t\t}\n\t}\n} );\n\n// Handle cache's special case and crossDomain\njQuery.ajaxPrefilter( \"script\", function( s ) {\n\tif ( s.cache === undefined ) {\n\t\ts.cache = false;\n\t}\n\tif ( s.crossDomain ) {\n\t\ts.type = \"GET\";\n\t}\n} );\n\n// Bind script tag hack transport\njQuery.ajaxTransport( \"script\", function( s ) {\n\n\t// This transport only deals with cross domain requests\n\tif ( s.crossDomain ) {\n\t\tvar script, callback;\n\t\treturn {\n\t\t\tsend: function( _, complete ) {\n\t\t\t\tscript = jQuery( \"<script>\" ).prop( {\n\t\t\t\t\tcharset: s.scriptCharset,\n\t\t\t\t\tsrc: s.url\n\t\t\t\t} ).on(\n\t\t\t\t\t\"load error\",\n\t\t\t\t\tcallback = function( evt ) {\n\t\t\t\t\t\tscript.remove();\n\t\t\t\t\t\tcallback = null;\n\t\t\t\t\t\tif ( evt ) {\n\t\t\t\t\t\t\tcomplete( evt.type === \"error\" ? 404 : 200, evt.type );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t);\n\n\t\t\t\t// Use native DOM manipulation to avoid our domManip AJAX trickery\n\t\t\t\tdocument.head.appendChild( script[ 0 ] );\n\t\t\t},\n\t\t\tabort: function() {\n\t\t\t\tif ( callback ) {\n\t\t\t\t\tcallback();\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t}\n} );\n\n\n\n\nvar oldCallbacks = [],\n\trjsonp = /(=)\\?(?=&|$)|\\?\\?/;\n\n// Default jsonp settings\njQuery.ajaxSetup( {\n\tjsonp: \"callback\",\n\tjsonpCallback: function() {\n\t\tvar callback = oldCallbacks.pop() || ( jQuery.expando + \"_\" + ( nonce++ ) );\n\t\tthis[ callback ] = true;\n\t\treturn callback;\n\t}\n} );\n\n// Detect, normalize options and install callbacks for jsonp requests\njQuery.ajaxPrefilter( \"json jsonp\", function( s, originalSettings, jqXHR ) {\n\n\tvar callbackName, overwritten, responseContainer,\n\t\tjsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ?\n\t\t\t\"url\" :\n\t\t\ttypeof s.data === \"string\" &&\n\t\t\t\t( s.contentType || \"\" )\n\t\t\t\t\t.indexOf( \"application/x-www-form-urlencoded\" ) === 0 &&\n\t\t\t\trjsonp.test( s.data ) && \"data\"\n\t\t);\n\n\t// Handle iff the expected data type is \"jsonp\" or we have a parameter to set\n\tif ( jsonProp || s.dataTypes[ 0 ] === \"jsonp\" ) {\n\n\t\t// Get callback name, remembering preexisting value associated with it\n\t\tcallbackName = s.jsonpCallback = isFunction( s.jsonpCallback ) ?\n\t\t\ts.jsonpCallback() :\n\t\t\ts.jsonpCallback;\n\n\t\t// Insert callback into url or form data\n\t\tif ( jsonProp ) {\n\t\t\ts[ jsonProp ] = s[ jsonProp ].replace( rjsonp, \"$1\" + callbackName );\n\t\t} else if ( s.jsonp !== false ) {\n\t\t\ts.url += ( rquery.test( s.url ) ? \"&\" : \"?\" ) + s.jsonp + \"=\" + callbackName;\n\t\t}\n\n\t\t// Use data converter to retrieve json after script execution\n\t\ts.converters[ \"script json\" ] = function() {\n\t\t\tif ( !responseContainer ) {\n\t\t\t\tjQuery.error( callbackName + \" was not called\" );\n\t\t\t}\n\t\t\treturn responseContainer[ 0 ];\n\t\t};\n\n\t\t// Force json dataType\n\t\ts.dataTypes[ 0 ] = \"json\";\n\n\t\t// Install callback\n\t\toverwritten = window[ callbackName ];\n\t\twindow[ callbackName ] = function() {\n\t\t\tresponseContainer = arguments;\n\t\t};\n\n\t\t// Clean-up function (fires after converters)\n\t\tjqXHR.always( function() {\n\n\t\t\t// If previous value didn't exist - remove it\n\t\t\tif ( overwritten === undefined ) {\n\t\t\t\tjQuery( window ).removeProp( callbackName );\n\n\t\t\t// Otherwise restore preexisting value\n\t\t\t} else {\n\t\t\t\twindow[ callbackName ] = overwritten;\n\t\t\t}\n\n\t\t\t// Save back as free\n\t\t\tif ( s[ callbackName ] ) {\n\n\t\t\t\t// Make sure that re-using the options doesn't screw things around\n\t\t\t\ts.jsonpCallback = originalSettings.jsonpCallback;\n\n\t\t\t\t// Save the callback name for future use\n\t\t\t\toldCallbacks.push( callbackName );\n\t\t\t}\n\n\t\t\t// Call if it was a function and we have a response\n\t\t\tif ( responseContainer && isFunction( overwritten ) ) {\n\t\t\t\toverwritten( responseContainer[ 0 ] );\n\t\t\t}\n\n\t\t\tresponseContainer = overwritten = undefined;\n\t\t} );\n\n\t\t// Delegate to script\n\t\treturn \"script\";\n\t}\n} );\n\n\n\n\n// Support: Safari 8 only\n// In Safari 8 documents created via document.implementation.createHTMLDocument\n// collapse sibling forms: the second one becomes a child of the first one.\n// Because of that, this security measure has to be disabled in Safari 8.\n// https://bugs.webkit.org/show_bug.cgi?id=137337\nsupport.createHTMLDocument = ( function() {\n\tvar body = document.implementation.createHTMLDocument( \"\" ).body;\n\tbody.innerHTML = \"<form></form><form></form>\";\n\treturn body.childNodes.length === 2;\n} )();\n\n\n// Argument \"data\" should be string of html\n// context (optional): If specified, the fragment will be created in this context,\n// defaults to document\n// keepScripts (optional): If true, will include scripts passed in the html string\njQuery.parseHTML = function( data, context, keepScripts ) {\n\tif ( typeof data !== \"string\" ) {\n\t\treturn [];\n\t}\n\tif ( typeof context === \"boolean\" ) {\n\t\tkeepScripts = context;\n\t\tcontext = false;\n\t}\n\n\tvar base, parsed, scripts;\n\n\tif ( !context ) {\n\n\t\t// Stop scripts or inline event handlers from being executed immediately\n\t\t// by using document.implementation\n\t\tif ( support.createHTMLDocument ) {\n\t\t\tcontext = document.implementation.createHTMLDocument( \"\" );\n\n\t\t\t// Set the base href for the created document\n\t\t\t// so any parsed elements with URLs\n\t\t\t// are based on the document's URL (gh-2965)\n\t\t\tbase = context.createElement( \"base\" );\n\t\t\tbase.href = document.location.href;\n\t\t\tcontext.head.appendChild( base );\n\t\t} else {\n\t\t\tcontext = document;\n\t\t}\n\t}\n\n\tparsed = rsingleTag.exec( data );\n\tscripts = !keepScripts && [];\n\n\t// Single tag\n\tif ( parsed ) {\n\t\treturn [ context.createElement( parsed[ 1 ] ) ];\n\t}\n\n\tparsed = buildFragment( [ data ], context, scripts );\n\n\tif ( scripts && scripts.length ) {\n\t\tjQuery( scripts ).remove();\n\t}\n\n\treturn jQuery.merge( [], parsed.childNodes );\n};\n\n\n/**\n * Load a url into a page\n */\njQuery.fn.load = function( url, params, callback ) {\n\tvar selector, type, response,\n\t\tself = this,\n\t\toff = url.indexOf( \" \" );\n\n\tif ( off > -1 ) {\n\t\tselector = stripAndCollapse( url.slice( off ) );\n\t\turl = url.slice( 0, off );\n\t}\n\n\t// If it's a function\n\tif ( isFunction( params ) ) {\n\n\t\t// We assume that it's the callback\n\t\tcallback = params;\n\t\tparams = undefined;\n\n\t// Otherwise, build a param string\n\t} else if ( params && typeof params === \"object\" ) {\n\t\ttype = \"POST\";\n\t}\n\n\t// If we have elements to modify, make the request\n\tif ( self.length > 0 ) {\n\t\tjQuery.ajax( {\n\t\t\turl: url,\n\n\t\t\t// If \"type\" variable is undefined, then \"GET\" method will be used.\n\t\t\t// Make value of this field explicit since\n\t\t\t// user can override it through ajaxSetup method\n\t\t\ttype: type || \"GET\",\n\t\t\tdataType: \"html\",\n\t\t\tdata: params\n\t\t} ).done( function( responseText ) {\n\n\t\t\t// Save response for use in complete callback\n\t\t\tresponse = arguments;\n\n\t\t\tself.html( selector ?\n\n\t\t\t\t// If a selector was specified, locate the right elements in a dummy div\n\t\t\t\t// Exclude scripts to avoid IE 'Permission Denied' errors\n\t\t\t\tjQuery( \"<div>\" ).append( jQuery.parseHTML( responseText ) ).find( selector ) :\n\n\t\t\t\t// Otherwise use the full result\n\t\t\t\tresponseText );\n\n\t\t// If the request succeeds, this function gets \"data\", \"status\", \"jqXHR\"\n\t\t// but they are ignored because response was set above.\n\t\t// If it fails, this function gets \"jqXHR\", \"status\", \"error\"\n\t\t} ).always( callback && function( jqXHR, status ) {\n\t\t\tself.each( function() {\n\t\t\t\tcallback.apply( this, response || [ jqXHR.responseText, status, jqXHR ] );\n\t\t\t} );\n\t\t} );\n\t}\n\n\treturn this;\n};\n\n\n\n\n// Attach a bunch of functions for handling common AJAX events\njQuery.each( [\n\t\"ajaxStart\",\n\t\"ajaxStop\",\n\t\"ajaxComplete\",\n\t\"ajaxError\",\n\t\"ajaxSuccess\",\n\t\"ajaxSend\"\n], function( i, type ) {\n\tjQuery.fn[ type ] = function( fn ) {\n\t\treturn this.on( type, fn );\n\t};\n} );\n\n\n\n\njQuery.expr.pseudos.animated = function( elem ) {\n\treturn jQuery.grep( jQuery.timers, function( fn ) {\n\t\treturn elem === fn.elem;\n\t} ).length;\n};\n\n\n\n\njQuery.offset = {\n\tsetOffset: function( elem, options, i ) {\n\t\tvar curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition,\n\t\t\tposition = jQuery.css( elem, \"position\" ),\n\t\t\tcurElem = jQuery( elem ),\n\t\t\tprops = {};\n\n\t\t// Set position first, in-case top/left are set even on static elem\n\t\tif ( position === \"static\" ) {\n\t\t\telem.style.position = \"relative\";\n\t\t}\n\n\t\tcurOffset = curElem.offset();\n\t\tcurCSSTop = jQuery.css( elem, \"top\" );\n\t\tcurCSSLeft = jQuery.css( elem, \"left\" );\n\t\tcalculatePosition = ( position === \"absolute\" || position === \"fixed\" ) &&\n\t\t\t( curCSSTop + curCSSLeft ).indexOf( \"auto\" ) > -1;\n\n\t\t// Need to be able to calculate position if either\n\t\t// top or left is auto and position is either absolute or fixed\n\t\tif ( calculatePosition ) {\n\t\t\tcurPosition = curElem.position();\n\t\t\tcurTop = curPosition.top;\n\t\t\tcurLeft = curPosition.left;\n\n\t\t} else {\n\t\t\tcurTop = parseFloat( curCSSTop ) || 0;\n\t\t\tcurLeft = parseFloat( curCSSLeft ) || 0;\n\t\t}\n\n\t\tif ( isFunction( options ) ) {\n\n\t\t\t// Use jQuery.extend here to allow modification of coordinates argument (gh-1848)\n\t\t\toptions = options.call( elem, i, jQuery.extend( {}, curOffset ) );\n\t\t}\n\n\t\tif ( options.top != null ) {\n\t\t\tprops.top = ( options.top - curOffset.top ) + curTop;\n\t\t}\n\t\tif ( options.left != null ) {\n\t\t\tprops.left = ( options.left - curOffset.left ) + curLeft;\n\t\t}\n\n\t\tif ( \"using\" in options ) {\n\t\t\toptions.using.call( elem, props );\n\n\t\t} else {\n\t\t\tcurElem.css( props );\n\t\t}\n\t}\n};\n\njQuery.fn.extend( {\n\n\t// offset() relates an element's border box to the document origin\n\toffset: function( options ) {\n\n\t\t// Preserve chaining for setter\n\t\tif ( arguments.length ) {\n\t\t\treturn options === undefined ?\n\t\t\t\tthis :\n\t\t\t\tthis.each( function( i ) {\n\t\t\t\t\tjQuery.offset.setOffset( this, options, i );\n\t\t\t\t} );\n\t\t}\n\n\t\tvar rect, win,\n\t\t\telem = this[ 0 ];\n\n\t\tif ( !elem ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Return zeros for disconnected and hidden (display: none) elements (gh-2310)\n\t\t// Support: IE <=11 only\n\t\t// Running getBoundingClientRect on a\n\t\t// disconnected node in IE throws an error\n\t\tif ( !elem.getClientRects().length ) {\n\t\t\treturn { top: 0, left: 0 };\n\t\t}\n\n\t\t// Get document-relative position by adding viewport scroll to viewport-relative gBCR\n\t\trect = elem.getBoundingClientRect();\n\t\twin = elem.ownerDocument.defaultView;\n\t\treturn {\n\t\t\ttop: rect.top + win.pageYOffset,\n\t\t\tleft: rect.left + win.pageXOffset\n\t\t};\n\t},\n\n\t// position() relates an element's margin box to its offset parent's padding box\n\t// This corresponds to the behavior of CSS absolute positioning\n\tposition: function() {\n\t\tif ( !this[ 0 ] ) {\n\t\t\treturn;\n\t\t}\n\n\t\tvar offsetParent, offset, doc,\n\t\t\telem = this[ 0 ],\n\t\t\tparentOffset = { top: 0, left: 0 };\n\n\t\t// position:fixed elements are offset from the viewport, which itself always has zero offset\n\t\tif ( jQuery.css( elem, \"position\" ) === \"fixed\" ) {\n\n\t\t\t// Assume position:fixed implies availability of getBoundingClientRect\n\t\t\toffset = elem.getBoundingClientRect();\n\n\t\t} else {\n\t\t\toffset = this.offset();\n\n\t\t\t// Account for the *real* offset parent, which can be the document or its root element\n\t\t\t// when a statically positioned element is identified\n\t\t\tdoc = elem.ownerDocument;\n\t\t\toffsetParent = elem.offsetParent || doc.documentElement;\n\t\t\twhile ( offsetParent &&\n\t\t\t\t( offsetParent === doc.body || offsetParent === doc.documentElement ) &&\n\t\t\t\tjQuery.css( offsetParent, \"position\" ) === \"static\" ) {\n\n\t\t\t\toffsetParent = offsetParent.parentNode;\n\t\t\t}\n\t\t\tif ( offsetParent && offsetParent !== elem && offsetParent.nodeType === 1 ) {\n\n\t\t\t\t// Incorporate borders into its offset, since they are outside its content origin\n\t\t\t\tparentOffset = jQuery( offsetParent ).offset();\n\t\t\t\tparentOffset.top += jQuery.css( offsetParent, \"borderTopWidth\", true );\n\t\t\t\tparentOffset.left += jQuery.css( offsetParent, \"borderLeftWidth\", true );\n\t\t\t}\n\t\t}\n\n\t\t// Subtract parent offsets and element margins\n\t\treturn {\n\t\t\ttop: offset.top - parentOffset.top - jQuery.css( elem, \"marginTop\", true ),\n\t\t\tleft: offset.left - parentOffset.left - jQuery.css( elem, \"marginLeft\", true )\n\t\t};\n\t},\n\n\t// This method will return documentElement in the following cases:\n\t// 1) For the element inside the iframe without offsetParent, this method will return\n\t//    documentElement of the parent window\n\t// 2) For the hidden or detached element\n\t// 3) For body or html element, i.e. in case of the html node - it will return itself\n\t//\n\t// but those exceptions were never presented as a real life use-cases\n\t// and might be considered as more preferable results.\n\t//\n\t// This logic, however, is not guaranteed and can change at any point in the future\n\toffsetParent: function() {\n\t\treturn this.map( function() {\n\t\t\tvar offsetParent = this.offsetParent;\n\n\t\t\twhile ( offsetParent && jQuery.css( offsetParent, \"position\" ) === \"static\" ) {\n\t\t\t\toffsetParent = offsetParent.offsetParent;\n\t\t\t}\n\n\t\t\treturn offsetParent || documentElement;\n\t\t} );\n\t}\n} );\n\n// Create scrollLeft and scrollTop methods\njQuery.each( { scrollLeft: \"pageXOffset\", scrollTop: \"pageYOffset\" }, function( method, prop ) {\n\tvar top = \"pageYOffset\" === prop;\n\n\tjQuery.fn[ method ] = function( val ) {\n\t\treturn access( this, function( elem, method, val ) {\n\n\t\t\t// Coalesce documents and windows\n\t\t\tvar win;\n\t\t\tif ( isWindow( elem ) ) {\n\t\t\t\twin = elem;\n\t\t\t} else if ( elem.nodeType === 9 ) {\n\t\t\t\twin = elem.defaultView;\n\t\t\t}\n\n\t\t\tif ( val === undefined ) {\n\t\t\t\treturn win ? win[ prop ] : elem[ method ];\n\t\t\t}\n\n\t\t\tif ( win ) {\n\t\t\t\twin.scrollTo(\n\t\t\t\t\t!top ? val : win.pageXOffset,\n\t\t\t\t\ttop ? val : win.pageYOffset\n\t\t\t\t);\n\n\t\t\t} else {\n\t\t\t\telem[ method ] = val;\n\t\t\t}\n\t\t}, method, val, arguments.length );\n\t};\n} );\n\n// Support: Safari <=7 - 9.1, Chrome <=37 - 49\n// Add the top/left cssHooks using jQuery.fn.position\n// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084\n// Blink bug: https://bugs.chromium.org/p/chromium/issues/detail?id=589347\n// getComputedStyle returns percent when specified for top/left/bottom/right;\n// rather than make the css module depend on the offset module, just check for it here\njQuery.each( [ \"top\", \"left\" ], function( i, prop ) {\n\tjQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition,\n\t\tfunction( elem, computed ) {\n\t\t\tif ( computed ) {\n\t\t\t\tcomputed = curCSS( elem, prop );\n\n\t\t\t\t// If curCSS returns percentage, fallback to offset\n\t\t\t\treturn rnumnonpx.test( computed ) ?\n\t\t\t\t\tjQuery( elem ).position()[ prop ] + \"px\" :\n\t\t\t\t\tcomputed;\n\t\t\t}\n\t\t}\n\t);\n} );\n\n\n// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods\njQuery.each( { Height: \"height\", Width: \"width\" }, function( name, type ) {\n\tjQuery.each( { padding: \"inner\" + name, content: type, \"\": \"outer\" + name },\n\t\tfunction( defaultExtra, funcName ) {\n\n\t\t// Margin is only for outerHeight, outerWidth\n\t\tjQuery.fn[ funcName ] = function( margin, value ) {\n\t\t\tvar chainable = arguments.length && ( defaultExtra || typeof margin !== \"boolean\" ),\n\t\t\t\textra = defaultExtra || ( margin === true || value === true ? \"margin\" : \"border\" );\n\n\t\t\treturn access( this, function( elem, type, value ) {\n\t\t\t\tvar doc;\n\n\t\t\t\tif ( isWindow( elem ) ) {\n\n\t\t\t\t\t// $( window ).outerWidth/Height return w/h including scrollbars (gh-1729)\n\t\t\t\t\treturn funcName.indexOf( \"outer\" ) === 0 ?\n\t\t\t\t\t\telem[ \"inner\" + name ] :\n\t\t\t\t\t\telem.document.documentElement[ \"client\" + name ];\n\t\t\t\t}\n\n\t\t\t\t// Get document width or height\n\t\t\t\tif ( elem.nodeType === 9 ) {\n\t\t\t\t\tdoc = elem.documentElement;\n\n\t\t\t\t\t// Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height],\n\t\t\t\t\t// whichever is greatest\n\t\t\t\t\treturn Math.max(\n\t\t\t\t\t\telem.body[ \"scroll\" + name ], doc[ \"scroll\" + name ],\n\t\t\t\t\t\telem.body[ \"offset\" + name ], doc[ \"offset\" + name ],\n\t\t\t\t\t\tdoc[ \"client\" + name ]\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\treturn value === undefined ?\n\n\t\t\t\t\t// Get width or height on the element, requesting but not forcing parseFloat\n\t\t\t\t\tjQuery.css( elem, type, extra ) :\n\n\t\t\t\t\t// Set width or height on the element\n\t\t\t\t\tjQuery.style( elem, type, value, extra );\n\t\t\t}, type, chainable ? margin : undefined, chainable );\n\t\t};\n\t} );\n} );\n\n\njQuery.each( ( \"blur focus focusin focusout resize scroll click dblclick \" +\n\t\"mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave \" +\n\t\"change select submit keydown keypress keyup contextmenu\" ).split( \" \" ),\n\tfunction( i, name ) {\n\n\t// Handle event binding\n\tjQuery.fn[ name ] = function( data, fn ) {\n\t\treturn arguments.length > 0 ?\n\t\t\tthis.on( name, null, data, fn ) :\n\t\t\tthis.trigger( name );\n\t};\n} );\n\njQuery.fn.extend( {\n\thover: function( fnOver, fnOut ) {\n\t\treturn this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );\n\t}\n} );\n\n\n\n\njQuery.fn.extend( {\n\n\tbind: function( types, data, fn ) {\n\t\treturn this.on( types, null, data, fn );\n\t},\n\tunbind: function( types, fn ) {\n\t\treturn this.off( types, null, fn );\n\t},\n\n\tdelegate: function( selector, types, data, fn ) {\n\t\treturn this.on( types, selector, data, fn );\n\t},\n\tundelegate: function( selector, types, fn ) {\n\n\t\t// ( namespace ) or ( selector, types [, fn] )\n\t\treturn arguments.length === 1 ?\n\t\t\tthis.off( selector, \"**\" ) :\n\t\t\tthis.off( types, selector || \"**\", fn );\n\t}\n} );\n\n// Bind a function to a context, optionally partially applying any\n// arguments.\n// jQuery.proxy is deprecated to promote standards (specifically Function#bind)\n// However, it is not slated for removal any time soon\njQuery.proxy = function( fn, context ) {\n\tvar tmp, args, proxy;\n\n\tif ( typeof context === \"string\" ) {\n\t\ttmp = fn[ context ];\n\t\tcontext = fn;\n\t\tfn = tmp;\n\t}\n\n\t// Quick check to determine if target is callable, in the spec\n\t// this throws a TypeError, but we will just return undefined.\n\tif ( !isFunction( fn ) ) {\n\t\treturn undefined;\n\t}\n\n\t// Simulated bind\n\targs = slice.call( arguments, 2 );\n\tproxy = function() {\n\t\treturn fn.apply( context || this, args.concat( slice.call( arguments ) ) );\n\t};\n\n\t// Set the guid of unique handler to the same of original handler, so it can be removed\n\tproxy.guid = fn.guid = fn.guid || jQuery.guid++;\n\n\treturn proxy;\n};\n\njQuery.holdReady = function( hold ) {\n\tif ( hold ) {\n\t\tjQuery.readyWait++;\n\t} else {\n\t\tjQuery.ready( true );\n\t}\n};\njQuery.isArray = Array.isArray;\njQuery.parseJSON = JSON.parse;\njQuery.nodeName = nodeName;\njQuery.isFunction = isFunction;\njQuery.isWindow = isWindow;\njQuery.camelCase = camelCase;\njQuery.type = toType;\n\njQuery.now = Date.now;\n\njQuery.isNumeric = function( obj ) {\n\n\t// As of jQuery 3.0, isNumeric is limited to\n\t// strings and numbers (primitives or objects)\n\t// that can be coerced to finite numbers (gh-2662)\n\tvar type = jQuery.type( obj );\n\treturn ( type === \"number\" || type === \"string\" ) &&\n\n\t\t// parseFloat NaNs numeric-cast false positives (\"\")\n\t\t// ...but misinterprets leading-number strings, particularly hex literals (\"0x...\")\n\t\t// subtraction forces infinities to NaN\n\t\t!isNaN( obj - parseFloat( obj ) );\n};\n\n\n\n\n// Register as a named AMD module, since jQuery can be concatenated with other\n// files that may use define, but not via a proper concatenation script that\n// understands anonymous AMD modules. A named AMD is safest and most robust\n// way to register. Lowercase jquery is used because AMD module names are\n// derived from file names, and jQuery is normally delivered in a lowercase\n// file name. Do this after creating the global so that if an AMD module wants\n// to call noConflict to hide this version of jQuery, it will work.\n\n// Note that for maximum portability, libraries that are not jQuery should\n// declare themselves as anonymous modules, and avoid setting a global if an\n// AMD loader is present. jQuery is a special case. For more information, see\n// https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon\n\nif ( typeof define === \"function\" && define.amd ) {\n\tdefine( \"jquery\", [], function() {\n\t\treturn jQuery;\n\t} );\n}\n\n\n\n\nvar\n\n\t// Map over jQuery in case of overwrite\n\t_jQuery = window.jQuery,\n\n\t// Map over the $ in case of overwrite\n\t_$ = window.$;\n\njQuery.noConflict = function( deep ) {\n\tif ( window.$ === jQuery ) {\n\t\twindow.$ = _$;\n\t}\n\n\tif ( deep && window.jQuery === jQuery ) {\n\t\twindow.jQuery = _jQuery;\n\t}\n\n\treturn jQuery;\n};\n\n// Expose jQuery and $ identifiers, even in AMD\n// (#7102#comment:10, https://github.com/jquery/jquery/pull/557)\n// and CommonJS for browser emulators (#13566)\nif ( !noGlobal ) {\n\twindow.jQuery = window.$ = jQuery;\n}\n\n\n\n\nreturn jQuery;\n} );\n"
  },
  {
    "path": "src/static_cdn/admin/js/vendor/select2/LICENSE.md",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2012-2015 Kevin Brown, Igor Vaynberg, and Select2 contributors\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n"
  },
  {
    "path": "src/static_cdn/admin/js/vendor/select2/i18n/ar.js",
    "content": "/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */\n\n(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define(\"select2/i18n/ar\",[],function(){return{errorLoading:function(){return\"لا يمكن تحميل النتائج\"},inputTooLong:function(e){var t=e.input.length-e.maximum,n=\"الرجاء حذف \"+t+\" عناصر\";return n},inputTooShort:function(e){var t=e.minimum-e.input.length,n=\"الرجاء إضافة \"+t+\" عناصر\";return n},loadingMore:function(){return\"جاري تحميل نتائج إضافية...\"},maximumSelected:function(e){var t=\"تستطيع إختيار \"+e.maximum+\" بنود فقط\";return t},noResults:function(){return\"لم يتم العثور على أي نتائج\"},searching:function(){return\"جاري البحث…\"}}}),{define:e.define,require:e.require}})();"
  },
  {
    "path": "src/static_cdn/admin/js/vendor/select2/i18n/az.js",
    "content": "/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */\n\n(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define(\"select2/i18n/az\",[],function(){return{inputTooLong:function(e){var t=e.input.length-e.maximum;return t+\" simvol silin\"},inputTooShort:function(e){var t=e.minimum-e.input.length;return t+\" simvol daxil edin\"},loadingMore:function(){return\"Daha çox nəticə yüklənir…\"},maximumSelected:function(e){return\"Sadəcə \"+e.maximum+\" element seçə bilərsiniz\"},noResults:function(){return\"Nəticə tapılmadı\"},searching:function(){return\"Axtarılır…\"}}}),{define:e.define,require:e.require}})();"
  },
  {
    "path": "src/static_cdn/admin/js/vendor/select2/i18n/bg.js",
    "content": "/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */\n\n(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define(\"select2/i18n/bg\",[],function(){return{inputTooLong:function(e){var t=e.input.length-e.maximum,n=\"Моля въведете с \"+t+\" по-малко символ\";return t>1&&(n+=\"a\"),n},inputTooShort:function(e){var t=e.minimum-e.input.length,n=\"Моля въведете още \"+t+\" символ\";return t>1&&(n+=\"a\"),n},loadingMore:function(){return\"Зареждат се още…\"},maximumSelected:function(e){var t=\"Можете да направите до \"+e.maximum+\" \";return e.maximum>1?t+=\"избора\":t+=\"избор\",t},noResults:function(){return\"Няма намерени съвпадения\"},searching:function(){return\"Търсене…\"}}}),{define:e.define,require:e.require}})();"
  },
  {
    "path": "src/static_cdn/admin/js/vendor/select2/i18n/ca.js",
    "content": "/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */\n\n(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define(\"select2/i18n/ca\",[],function(){return{errorLoading:function(){return\"La càrrega ha fallat\"},inputTooLong:function(e){var t=e.input.length-e.maximum,n=\"Si us plau, elimina \"+t+\" car\";return t==1?n+=\"àcter\":n+=\"àcters\",n},inputTooShort:function(e){var t=e.minimum-e.input.length,n=\"Si us plau, introdueix \"+t+\" car\";return t==1?n+=\"àcter\":n+=\"àcters\",n},loadingMore:function(){return\"Carregant més resultats…\"},maximumSelected:function(e){var t=\"Només es pot seleccionar \"+e.maximum+\" element\";return e.maximum!=1&&(t+=\"s\"),t},noResults:function(){return\"No s'han trobat resultats\"},searching:function(){return\"Cercant…\"}}}),{define:e.define,require:e.require}})();"
  },
  {
    "path": "src/static_cdn/admin/js/vendor/select2/i18n/cs.js",
    "content": "/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */\n\n(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define(\"select2/i18n/cs\",[],function(){function e(e,t){switch(e){case 2:return t?\"dva\":\"dvě\";case 3:return\"tři\";case 4:return\"čtyři\"}return\"\"}return{errorLoading:function(){return\"Výsledky nemohly být načteny.\"},inputTooLong:function(t){var n=t.input.length-t.maximum;return n==1?\"Prosím zadejte o jeden znak méně\":n<=4?\"Prosím zadejte o \"+e(n,!0)+\" znaky méně\":\"Prosím zadejte o \"+n+\" znaků méně\"},inputTooShort:function(t){var n=t.minimum-t.input.length;return n==1?\"Prosím zadejte ještě jeden znak\":n<=4?\"Prosím zadejte ještě další \"+e(n,!0)+\" znaky\":\"Prosím zadejte ještě dalších \"+n+\" znaků\"},loadingMore:function(){return\"Načítají se další výsledky…\"},maximumSelected:function(t){var n=t.maximum;return n==1?\"Můžete zvolit jen jednu položku\":n<=4?\"Můžete zvolit maximálně \"+e(n,!1)+\" položky\":\"Můžete zvolit maximálně \"+n+\" položek\"},noResults:function(){return\"Nenalezeny žádné položky\"},searching:function(){return\"Vyhledávání…\"}}}),{define:e.define,require:e.require}})();"
  },
  {
    "path": "src/static_cdn/admin/js/vendor/select2/i18n/da.js",
    "content": "/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */\n\n(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define(\"select2/i18n/da\",[],function(){return{errorLoading:function(){return\"Resultaterne kunne ikke indlæses.\"},inputTooLong:function(e){var t=e.input.length-e.maximum,n=\"Angiv venligst \"+t+\" tegn mindre\";return n},inputTooShort:function(e){var t=e.minimum-e.input.length,n=\"Angiv venligst \"+t+\" tegn mere\";return n},loadingMore:function(){return\"Indlæser flere resultater…\"},maximumSelected:function(e){var t=\"Du kan kun vælge \"+e.maximum+\" emne\";return e.maximum!=1&&(t+=\"r\"),t},noResults:function(){return\"Ingen resultater fundet\"},searching:function(){return\"Søger…\"}}}),{define:e.define,require:e.require}})();"
  },
  {
    "path": "src/static_cdn/admin/js/vendor/select2/i18n/de.js",
    "content": "/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */\n\n(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define(\"select2/i18n/de\",[],function(){return{inputTooLong:function(e){var t=e.input.length-e.maximum;return\"Bitte \"+t+\" Zeichen weniger eingeben\"},inputTooShort:function(e){var t=e.minimum-e.input.length;return\"Bitte \"+t+\" Zeichen mehr eingeben\"},loadingMore:function(){return\"Lade mehr Ergebnisse…\"},maximumSelected:function(e){var t=\"Sie können nur \"+e.maximum+\" Eintr\";return e.maximum===1?t+=\"ag\":t+=\"äge\",t+=\" auswählen\",t},noResults:function(){return\"Keine Übereinstimmungen gefunden\"},searching:function(){return\"Suche…\"}}}),{define:e.define,require:e.require}})();"
  },
  {
    "path": "src/static_cdn/admin/js/vendor/select2/i18n/el.js",
    "content": "/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */\n\n(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define(\"select2/i18n/el\",[],function(){return{errorLoading:function(){return\"Τα αποτελέσματα δεν μπόρεσαν να φορτώσουν.\"},inputTooLong:function(e){var t=e.input.length-e.maximum,n=\"Παρακαλώ διαγράψτε \"+t+\" χαρακτήρ\";return t==1&&(n+=\"α\"),t!=1&&(n+=\"ες\"),n},inputTooShort:function(e){var t=e.minimum-e.input.length,n=\"Παρακαλώ συμπληρώστε \"+t+\" ή περισσότερους χαρακτήρες\";return n},loadingMore:function(){return\"Φόρτωση περισσότερων αποτελεσμάτων…\"},maximumSelected:function(e){var t=\"Μπορείτε να επιλέξετε μόνο \"+e.maximum+\" επιλογ\";return e.maximum==1&&(t+=\"ή\"),e.maximum!=1&&(t+=\"ές\"),t},noResults:function(){return\"Δεν βρέθηκαν αποτελέσματα\"},searching:function(){return\"Αναζήτηση…\"}}}),{define:e.define,require:e.require}})();"
  },
  {
    "path": "src/static_cdn/admin/js/vendor/select2/i18n/en.js",
    "content": "/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */\n\n(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define(\"select2/i18n/en\",[],function(){return{errorLoading:function(){return\"The results could not be loaded.\"},inputTooLong:function(e){var t=e.input.length-e.maximum,n=\"Please delete \"+t+\" character\";return t!=1&&(n+=\"s\"),n},inputTooShort:function(e){var t=e.minimum-e.input.length,n=\"Please enter \"+t+\" or more characters\";return n},loadingMore:function(){return\"Loading more results…\"},maximumSelected:function(e){var t=\"You can only select \"+e.maximum+\" item\";return e.maximum!=1&&(t+=\"s\"),t},noResults:function(){return\"No results found\"},searching:function(){return\"Searching…\"}}}),{define:e.define,require:e.require}})();"
  },
  {
    "path": "src/static_cdn/admin/js/vendor/select2/i18n/es.js",
    "content": "/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */\n\n(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define(\"select2/i18n/es\",[],function(){return{errorLoading:function(){return\"La carga falló\"},inputTooLong:function(e){var t=e.input.length-e.maximum,n=\"Por favor, elimine \"+t+\" car\";return t==1?n+=\"ácter\":n+=\"acteres\",n},inputTooShort:function(e){var t=e.minimum-e.input.length,n=\"Por favor, introduzca \"+t+\" car\";return t==1?n+=\"ácter\":n+=\"acteres\",n},loadingMore:function(){return\"Cargando más resultados…\"},maximumSelected:function(e){var t=\"Sólo puede seleccionar \"+e.maximum+\" elemento\";return e.maximum!=1&&(t+=\"s\"),t},noResults:function(){return\"No se encontraron resultados\"},searching:function(){return\"Buscando…\"}}}),{define:e.define,require:e.require}})();"
  },
  {
    "path": "src/static_cdn/admin/js/vendor/select2/i18n/et.js",
    "content": "/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */\n\n(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define(\"select2/i18n/et\",[],function(){return{inputTooLong:function(e){var t=e.input.length-e.maximum,n=\"Sisesta \"+t+\" täht\";return t!=1&&(n+=\"e\"),n+=\" vähem\",n},inputTooShort:function(e){var t=e.minimum-e.input.length,n=\"Sisesta \"+t+\" täht\";return t!=1&&(n+=\"e\"),n+=\" rohkem\",n},loadingMore:function(){return\"Laen tulemusi…\"},maximumSelected:function(e){var t=\"Saad vaid \"+e.maximum+\" tulemus\";return e.maximum==1?t+=\"e\":t+=\"t\",t+=\" valida\",t},noResults:function(){return\"Tulemused puuduvad\"},searching:function(){return\"Otsin…\"}}}),{define:e.define,require:e.require}})();"
  },
  {
    "path": "src/static_cdn/admin/js/vendor/select2/i18n/eu.js",
    "content": "/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */\n\n(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define(\"select2/i18n/eu\",[],function(){return{inputTooLong:function(e){var t=e.input.length-e.maximum,n=\"Idatzi \";return t==1?n+=\"karaktere bat\":n+=t+\" karaktere\",n+=\" gutxiago\",n},inputTooShort:function(e){var t=e.minimum-e.input.length,n=\"Idatzi \";return t==1?n+=\"karaktere bat\":n+=t+\" karaktere\",n+=\" gehiago\",n},loadingMore:function(){return\"Emaitza gehiago kargatzen…\"},maximumSelected:function(e){return e.maximum===1?\"Elementu bakarra hauta dezakezu\":e.maximum+\" elementu hauta ditzakezu soilik\"},noResults:function(){return\"Ez da bat datorrenik aurkitu\"},searching:function(){return\"Bilatzen…\"}}}),{define:e.define,require:e.require}})();"
  },
  {
    "path": "src/static_cdn/admin/js/vendor/select2/i18n/fa.js",
    "content": "/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */\n\n(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define(\"select2/i18n/fa\",[],function(){return{errorLoading:function(){return\"امکان بارگذاری نتایج وجود ندارد.\"},inputTooLong:function(e){var t=e.input.length-e.maximum,n=\"لطفاً \"+t+\" کاراکتر را حذف نمایید\";return n},inputTooShort:function(e){var t=e.minimum-e.input.length,n=\"لطفاً تعداد \"+t+\" کاراکتر یا بیشتر وارد نمایید\";return n},loadingMore:function(){return\"در حال بارگذاری نتایج بیشتر...\"},maximumSelected:function(e){var t=\"شما تنها می‌توانید \"+e.maximum+\" آیتم را انتخاب نمایید\";return t},noResults:function(){return\"هیچ نتیجه‌ای یافت نشد\"},searching:function(){return\"در حال جستجو...\"}}}),{define:e.define,require:e.require}})();"
  },
  {
    "path": "src/static_cdn/admin/js/vendor/select2/i18n/fi.js",
    "content": "/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */\n\n(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define(\"select2/i18n/fi\",[],function(){return{inputTooLong:function(e){var t=e.input.length-e.maximum;return\"Ole hyvä ja anna \"+t+\" merkkiä vähemmän\"},inputTooShort:function(e){var t=e.minimum-e.input.length;return\"Ole hyvä ja anna \"+t+\" merkkiä lisää\"},loadingMore:function(){return\"Ladataan lisää tuloksia…\"},maximumSelected:function(e){return\"Voit valita ainoastaan \"+e.maximum+\" kpl\"},noResults:function(){return\"Ei tuloksia\"},searching:function(){}}}),{define:e.define,require:e.require}})();"
  },
  {
    "path": "src/static_cdn/admin/js/vendor/select2/i18n/fr.js",
    "content": "/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */\n\n(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define(\"select2/i18n/fr\",[],function(){return{errorLoading:function(){return\"Les résultats ne peuvent pas être chargés.\"},inputTooLong:function(e){var t=e.input.length-e.maximum,n=\"Supprimez \"+t+\" caractère\";return t!==1&&(n+=\"s\"),n},inputTooShort:function(e){var t=e.minimum-e.input.length,n=\"Saisissez \"+t+\" caractère\";return t!==1&&(n+=\"s\"),n},loadingMore:function(){return\"Chargement de résultats supplémentaires…\"},maximumSelected:function(e){var t=\"Vous pouvez seulement sélectionner \"+e.maximum+\" élément\";return e.maximum!==1&&(t+=\"s\"),t},noResults:function(){return\"Aucun résultat trouvé\"},searching:function(){return\"Recherche en cours…\"}}}),{define:e.define,require:e.require}})();"
  },
  {
    "path": "src/static_cdn/admin/js/vendor/select2/i18n/gl.js",
    "content": "/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */\n\n(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define(\"select2/i18n/gl\",[],function(){return{inputTooLong:function(e){var t=e.input.length-e.maximum,n=\"Elimine \";return t===1?n+=\"un carácter\":n+=t+\" caracteres\",n},inputTooShort:function(e){var t=e.minimum-e.input.length,n=\"Engada \";return t===1?n+=\"un carácter\":n+=t+\" caracteres\",n},loadingMore:function(){return\"Cargando máis resultados…\"},maximumSelected:function(e){var t=\"Só pode \";return e.maximum===1?t+=\"un elemento\":t+=e.maximum+\" elementos\",t},noResults:function(){return\"Non se atoparon resultados\"},searching:function(){return\"Buscando…\"}}}),{define:e.define,require:e.require}})();"
  },
  {
    "path": "src/static_cdn/admin/js/vendor/select2/i18n/he.js",
    "content": "/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */\n\n(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define(\"select2/i18n/he\",[],function(){return{errorLoading:function(){return\"שגיאה בטעינת התוצאות\"},inputTooLong:function(e){var t=e.input.length-e.maximum,n=\"נא למחוק \";return t===1?n+=\"תו אחד\":n+=t+\" תווים\",n},inputTooShort:function(e){var t=e.minimum-e.input.length,n=\"נא להכניס \";return t===1?n+=\"תו אחד\":n+=t+\" תווים\",n+=\" או יותר\",n},loadingMore:function(){return\"טוען תוצאות נוספות…\"},maximumSelected:function(e){var t=\"באפשרותך לבחור עד \";return e.maximum===1?t+=\"פריט אחד\":t+=e.maximum+\" פריטים\",t},noResults:function(){return\"לא נמצאו תוצאות\"},searching:function(){return\"מחפש…\"}}}),{define:e.define,require:e.require}})();"
  },
  {
    "path": "src/static_cdn/admin/js/vendor/select2/i18n/hi.js",
    "content": "/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */\n\n(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define(\"select2/i18n/hi\",[],function(){return{errorLoading:function(){return\"परिणामों को लोड नहीं किया जा सका।\"},inputTooLong:function(e){var t=e.input.length-e.maximum,n=t+\" अक्षर को हटा दें\";return t>1&&(n=t+\" अक्षरों को हटा दें \"),n},inputTooShort:function(e){var t=e.minimum-e.input.length,n=\"कृपया \"+t+\" या अधिक अक्षर दर्ज करें\";return n},loadingMore:function(){return\"अधिक परिणाम लोड हो रहे है...\"},maximumSelected:function(e){var t=\"आप केवल \"+e.maximum+\" आइटम का चयन कर सकते हैं\";return t},noResults:function(){return\"कोई परिणाम नहीं मिला\"},searching:function(){return\"खोज रहा है...\"}}}),{define:e.define,require:e.require}})();"
  },
  {
    "path": "src/static_cdn/admin/js/vendor/select2/i18n/hr.js",
    "content": "/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */\n\n(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define(\"select2/i18n/hr\",[],function(){function e(e){var t=\" \"+e+\" znak\";return e%10<5&&e%10>0&&(e%100<5||e%100>19)?e%10>1&&(t+=\"a\"):t+=\"ova\",t}return{errorLoading:function(){return\"Preuzimanje nije uspjelo.\"},inputTooLong:function(t){var n=t.input.length-t.maximum;return\"Unesite \"+e(n)},inputTooShort:function(t){var n=t.minimum-t.input.length;return\"Unesite još \"+e(n)},loadingMore:function(){return\"Učitavanje rezultata…\"},maximumSelected:function(e){return\"Maksimalan broj odabranih stavki je \"+e.maximum},noResults:function(){return\"Nema rezultata\"},searching:function(){return\"Pretraga…\"}}}),{define:e.define,require:e.require}})();"
  },
  {
    "path": "src/static_cdn/admin/js/vendor/select2/i18n/hu.js",
    "content": "/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */\n\n(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define(\"select2/i18n/hu\",[],function(){return{inputTooLong:function(e){var t=e.input.length-e.maximum;return\"Túl hosszú. \"+t+\" karakterrel több, mint kellene.\"},inputTooShort:function(e){var t=e.minimum-e.input.length;return\"Túl rövid. Még \"+t+\" karakter hiányzik.\"},loadingMore:function(){return\"Töltés…\"},maximumSelected:function(e){return\"Csak \"+e.maximum+\" elemet lehet kiválasztani.\"},noResults:function(){return\"Nincs találat.\"},searching:function(){return\"Keresés…\"}}}),{define:e.define,require:e.require}})();"
  },
  {
    "path": "src/static_cdn/admin/js/vendor/select2/i18n/id.js",
    "content": "/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */\n\n(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define(\"select2/i18n/id\",[],function(){return{errorLoading:function(){return\"Data tidak boleh diambil.\"},inputTooLong:function(e){var t=e.input.length-e.maximum;return\"Hapuskan \"+t+\" huruf\"},inputTooShort:function(e){var t=e.minimum-e.input.length;return\"Masukkan \"+t+\" huruf lagi\"},loadingMore:function(){return\"Mengambil data…\"},maximumSelected:function(e){return\"Anda hanya dapat memilih \"+e.maximum+\" pilihan\"},noResults:function(){return\"Tidak ada data yang sesuai\"},searching:function(){return\"Mencari…\"}}}),{define:e.define,require:e.require}})();"
  },
  {
    "path": "src/static_cdn/admin/js/vendor/select2/i18n/is.js",
    "content": "/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */\n\n(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define(\"select2/i18n/is\",[],function(){return{inputTooLong:function(e){var t=e.input.length-e.maximum,n=\"Vinsamlegast styttið texta um \"+t+\" staf\";return t<=1?n:n+\"i\"},inputTooShort:function(e){var t=e.minimum-e.input.length,n=\"Vinsamlegast skrifið \"+t+\" staf\";return t>1&&(n+=\"i\"),n+=\" í viðbót\",n},loadingMore:function(){return\"Sæki fleiri niðurstöður…\"},maximumSelected:function(e){return\"Þú getur aðeins valið \"+e.maximum+\" atriði\"},noResults:function(){return\"Ekkert fannst\"},searching:function(){return\"Leita…\"}}}),{define:e.define,require:e.require}})();"
  },
  {
    "path": "src/static_cdn/admin/js/vendor/select2/i18n/it.js",
    "content": "/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */\n\n(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define(\"select2/i18n/it\",[],function(){return{errorLoading:function(){return\"I risultati non possono essere caricati.\"},inputTooLong:function(e){var t=e.input.length-e.maximum,n=\"Per favore cancella \"+t+\" caratter\";return t!==1?n+=\"i\":n+=\"e\",n},inputTooShort:function(e){var t=e.minimum-e.input.length,n=\"Per favore inserisci \"+t+\" o più caratteri\";return n},loadingMore:function(){return\"Caricando più risultati…\"},maximumSelected:function(e){var t=\"Puoi selezionare solo \"+e.maximum+\" element\";return e.maximum!==1?t+=\"i\":t+=\"o\",t},noResults:function(){return\"Nessun risultato trovato\"},searching:function(){return\"Sto cercando…\"}}}),{define:e.define,require:e.require}})();"
  },
  {
    "path": "src/static_cdn/admin/js/vendor/select2/i18n/ja.js",
    "content": "/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */\n\n(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define(\"select2/i18n/ja\",[],function(){return{errorLoading:function(){return\"結果が読み込まれませんでした\"},inputTooLong:function(e){var t=e.input.length-e.maximum,n=t+\" 文字を削除してください\";return n},inputTooShort:function(e){var t=e.minimum-e.input.length,n=\"少なくとも \"+t+\" 文字を入力してください\";return n},loadingMore:function(){return\"読み込み中…\"},maximumSelected:function(e){var t=e.maximum+\" 件しか選択できません\";return t},noResults:function(){return\"対象が見つかりません\"},searching:function(){return\"検索しています…\"}}}),{define:e.define,require:e.require}})();"
  },
  {
    "path": "src/static_cdn/admin/js/vendor/select2/i18n/km.js",
    "content": "/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */\n\n(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define(\"select2/i18n/km\",[],function(){return{errorLoading:function(){return\"មិនអាចទាញយកទិន្នន័យ\"},inputTooLong:function(e){var t=e.input.length-e.maximum,n=\"សូមលុបចេញ  \"+t+\" អក្សរ\";return n},inputTooShort:function(e){var t=e.minimum-e.input.length,n=\"សូមបញ្ចូល\"+t+\" អក្សរ រឺ ច្រើនជាងនេះ\";return n},loadingMore:function(){return\"កំពុងទាញយកទិន្នន័យបន្ថែម...\"},maximumSelected:function(e){var t=\"អ្នកអាចជ្រើសរើសបានតែ \"+e.maximum+\" ជម្រើសប៉ុណ្ណោះ\";return t},noResults:function(){return\"មិនមានលទ្ធផល\"},searching:function(){return\"កំពុងស្វែងរក...\"}}}),{define:e.define,require:e.require}})();"
  },
  {
    "path": "src/static_cdn/admin/js/vendor/select2/i18n/ko.js",
    "content": "/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */\n\n(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define(\"select2/i18n/ko\",[],function(){return{errorLoading:function(){return\"결과를 불러올 수 없습니다.\"},inputTooLong:function(e){var t=e.input.length-e.maximum,n=\"너무 깁니다. \"+t+\" 글자 지워주세요.\";return n},inputTooShort:function(e){var t=e.minimum-e.input.length,n=\"너무 짧습니다. \"+t+\" 글자 더 입력해주세요.\";return n},loadingMore:function(){return\"불러오는 중…\"},maximumSelected:function(e){var t=\"최대 \"+e.maximum+\"개까지만 선택 가능합니다.\";return t},noResults:function(){return\"결과가 없습니다.\"},searching:function(){return\"검색 중…\"}}}),{define:e.define,require:e.require}})();"
  },
  {
    "path": "src/static_cdn/admin/js/vendor/select2/i18n/lt.js",
    "content": "/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */\n\n(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define(\"select2/i18n/lt\",[],function(){function e(e,t,n,r){return e%10===1&&(e%100<11||e%100>19)?t:e%10>=2&&e%10<=9&&(e%100<11||e%100>19)?n:r}return{inputTooLong:function(t){var n=t.input.length-t.maximum,r=\"Pašalinkite \"+n+\" simbol\";return r+=e(n,\"į\",\"ius\",\"ių\"),r},inputTooShort:function(t){var n=t.minimum-t.input.length,r=\"Įrašykite dar \"+n+\" simbol\";return r+=e(n,\"į\",\"ius\",\"ių\"),r},loadingMore:function(){return\"Kraunama daugiau rezultatų…\"},maximumSelected:function(t){var n=\"Jūs galite pasirinkti tik \"+t.maximum+\" element\";return n+=e(t.maximum,\"ą\",\"us\",\"ų\"),n},noResults:function(){return\"Atitikmenų nerasta\"},searching:function(){return\"Ieškoma…\"}}}),{define:e.define,require:e.require}})();"
  },
  {
    "path": "src/static_cdn/admin/js/vendor/select2/i18n/lv.js",
    "content": "/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */\n\n(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define(\"select2/i18n/lv\",[],function(){function e(e,t,n,r){return e===11?t:e%10===1?n:r}return{inputTooLong:function(t){var n=t.input.length-t.maximum,r=\"Lūdzu ievadiet par  \"+n;return r+=\" simbol\"+e(n,\"iem\",\"u\",\"iem\"),r+\" mazāk\"},inputTooShort:function(t){var n=t.minimum-t.input.length,r=\"Lūdzu ievadiet vēl \"+n;return r+=\" simbol\"+e(n,\"us\",\"u\",\"us\"),r},loadingMore:function(){return\"Datu ielāde…\"},maximumSelected:function(t){var n=\"Jūs varat izvēlēties ne vairāk kā \"+t.maximum;return n+=\" element\"+e(t.maximum,\"us\",\"u\",\"us\"),n},noResults:function(){return\"Sakritību nav\"},searching:function(){return\"Meklēšana…\"}}}),{define:e.define,require:e.require}})();"
  },
  {
    "path": "src/static_cdn/admin/js/vendor/select2/i18n/mk.js",
    "content": "/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */\n\n(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define(\"select2/i18n/mk\",[],function(){return{inputTooLong:function(e){var t=e.input.length-e.maximum,n=\"Ве молиме внесете \"+e.maximum+\" помалку карактер\";return e.maximum!==1&&(n+=\"и\"),n},inputTooShort:function(e){var t=e.minimum-e.input.length,n=\"Ве молиме внесете уште \"+e.maximum+\" карактер\";return e.maximum!==1&&(n+=\"и\"),n},loadingMore:function(){return\"Вчитување резултати…\"},maximumSelected:function(e){var t=\"Можете да изберете само \"+e.maximum+\" ставк\";return e.maximum===1?t+=\"а\":t+=\"и\",t},noResults:function(){return\"Нема пронајдено совпаѓања\"},searching:function(){return\"Пребарување…\"}}}),{define:e.define,require:e.require}})();"
  },
  {
    "path": "src/static_cdn/admin/js/vendor/select2/i18n/ms.js",
    "content": "/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */\n\n(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define(\"select2/i18n/ms\",[],function(){return{errorLoading:function(){return\"Keputusan tidak berjaya dimuatkan.\"},inputTooLong:function(e){var t=e.input.length-e.maximum;return\"Sila hapuskan \"+t+\" aksara\"},inputTooShort:function(e){var t=e.minimum-e.input.length;return\"Sila masukkan \"+t+\" atau lebih aksara\"},loadingMore:function(){return\"Sedang memuatkan keputusan…\"},maximumSelected:function(e){return\"Anda hanya boleh memilih \"+e.maximum+\" pilihan\"},noResults:function(){return\"Tiada padanan yang ditemui\"},searching:function(){return\"Mencari…\"}}}),{define:e.define,require:e.require}})();"
  },
  {
    "path": "src/static_cdn/admin/js/vendor/select2/i18n/nb.js",
    "content": "/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */\n\n(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define(\"select2/i18n/nb\",[],function(){return{errorLoading:function(){return\"Kunne ikke hente resultater.\"},inputTooLong:function(e){var t=e.input.length-e.maximum;return\"Vennligst fjern \"+t+\" tegn\"},inputTooShort:function(e){var t=e.minimum-e.input.length,n=\"Vennligst skriv inn \";return t>1?n+=\" flere tegn\":n+=\" tegn til\",n},loadingMore:function(){return\"Laster flere resultater…\"},maximumSelected:function(e){return\"Du kan velge maks \"+e.maximum+\" elementer\"},noResults:function(){return\"Ingen treff\"},searching:function(){return\"Søker…\"}}}),{define:e.define,require:e.require}})();"
  },
  {
    "path": "src/static_cdn/admin/js/vendor/select2/i18n/nl.js",
    "content": "/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */\n\n(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define(\"select2/i18n/nl\",[],function(){return{errorLoading:function(){return\"De resultaten konden niet worden geladen.\"},inputTooLong:function(e){var t=e.input.length-e.maximum,n=\"Gelieve \"+t+\" karakters te verwijderen\";return n},inputTooShort:function(e){var t=e.minimum-e.input.length,n=\"Gelieve \"+t+\" of meer karakters in te voeren\";return n},loadingMore:function(){return\"Meer resultaten laden…\"},maximumSelected:function(e){var t=e.maximum==1?\"kan\":\"kunnen\",n=\"Er \"+t+\" maar \"+e.maximum+\" item\";return e.maximum!=1&&(n+=\"s\"),n+=\" worden geselecteerd\",n},noResults:function(){return\"Geen resultaten gevonden…\"},searching:function(){return\"Zoeken…\"}}}),{define:e.define,require:e.require}})();"
  },
  {
    "path": "src/static_cdn/admin/js/vendor/select2/i18n/pl.js",
    "content": "/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */\n\n(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define(\"select2/i18n/pl\",[],function(){var e=[\"znak\",\"znaki\",\"znaków\"],t=[\"element\",\"elementy\",\"elementów\"],n=function(t,n){if(t===1)return n[0];if(t>1&&t<=4)return n[1];if(t>=5)return n[2]};return{errorLoading:function(){return\"Nie można załadować wyników.\"},inputTooLong:function(t){var r=t.input.length-t.maximum;return\"Usuń \"+r+\" \"+n(r,e)},inputTooShort:function(t){var r=t.minimum-t.input.length;return\"Podaj przynajmniej \"+r+\" \"+n(r,e)},loadingMore:function(){return\"Trwa ładowanie…\"},maximumSelected:function(e){return\"Możesz zaznaczyć tylko \"+e.maximum+\" \"+n(e.maximum,t)},noResults:function(){return\"Brak wyników\"},searching:function(){return\"Trwa wyszukiwanie…\"}}}),{define:e.define,require:e.require}})();"
  },
  {
    "path": "src/static_cdn/admin/js/vendor/select2/i18n/pt-BR.js",
    "content": "/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */\n\n(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define(\"select2/i18n/pt-BR\",[],function(){return{errorLoading:function(){return\"Os resultados não puderam ser carregados.\"},inputTooLong:function(e){var t=e.input.length-e.maximum,n=\"Apague \"+t+\" caracter\";return t!=1&&(n+=\"es\"),n},inputTooShort:function(e){var t=e.minimum-e.input.length,n=\"Digite \"+t+\" ou mais caracteres\";return n},loadingMore:function(){return\"Carregando mais resultados…\"},maximumSelected:function(e){var t=\"Você só pode selecionar \"+e.maximum+\" ite\";return e.maximum==1?t+=\"m\":t+=\"ns\",t},noResults:function(){return\"Nenhum resultado encontrado\"},searching:function(){return\"Buscando…\"}}}),{define:e.define,require:e.require}})();"
  },
  {
    "path": "src/static_cdn/admin/js/vendor/select2/i18n/pt.js",
    "content": "/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */\n\n(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define(\"select2/i18n/pt\",[],function(){return{errorLoading:function(){return\"Os resultados não puderam ser carregados.\"},inputTooLong:function(e){var t=e.input.length-e.maximum,n=\"Por favor apague \"+t+\" \";return n+=t!=1?\"caracteres\":\"carácter\",n},inputTooShort:function(e){var t=e.minimum-e.input.length,n=\"Introduza \"+t+\" ou mais caracteres\";return n},loadingMore:function(){return\"A carregar mais resultados…\"},maximumSelected:function(e){var t=\"Apenas pode seleccionar \"+e.maximum+\" \";return t+=e.maximum!=1?\"itens\":\"item\",t},noResults:function(){return\"Sem resultados\"},searching:function(){return\"A procurar…\"}}}),{define:e.define,require:e.require}})();"
  },
  {
    "path": "src/static_cdn/admin/js/vendor/select2/i18n/ro.js",
    "content": "/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */\n\n(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define(\"select2/i18n/ro\",[],function(){return{errorLoading:function(){return\"Rezultatele nu au putut fi incărcate.\"},inputTooLong:function(e){var t=e.input.length-e.maximum,n=\"Vă rugăm să ștergeți\"+t+\" caracter\";return t!==1&&(n+=\"e\"),n},inputTooShort:function(e){var t=e.minimum-e.input.length,n=\"Vă rugăm să introduceți \"+t+\"sau mai multe caractere\";return n},loadingMore:function(){return\"Se încarcă mai multe rezultate…\"},maximumSelected:function(e){var t=\"Aveți voie să selectați cel mult \"+e.maximum;return t+=\" element\",e.maximum!==1&&(t+=\"e\"),t},noResults:function(){return\"Nu au fost găsite rezultate\"},searching:function(){return\"Căutare…\"}}}),{define:e.define,require:e.require}})();"
  },
  {
    "path": "src/static_cdn/admin/js/vendor/select2/i18n/ru.js",
    "content": "/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */\n\n(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define(\"select2/i18n/ru\",[],function(){function e(e,t,n,r){return e%10<5&&e%10>0&&e%100<5||e%100>20?e%10>1?n:t:r}return{errorLoading:function(){return\"Невозможно загрузить результаты\"},inputTooLong:function(t){var n=t.input.length-t.maximum,r=\"Пожалуйста, введите на \"+n+\" символ\";return r+=e(n,\"\",\"a\",\"ов\"),r+=\" меньше\",r},inputTooShort:function(t){var n=t.minimum-t.input.length,r=\"Пожалуйста, введите еще хотя бы \"+n+\" символ\";return r+=e(n,\"\",\"a\",\"ов\"),r},loadingMore:function(){return\"Загрузка данных…\"},maximumSelected:function(t){var n=\"Вы можете выбрать не более \"+t.maximum+\" элемент\";return n+=e(t.maximum,\"\",\"a\",\"ов\"),n},noResults:function(){return\"Совпадений не найдено\"},searching:function(){return\"Поиск…\"}}}),{define:e.define,require:e.require}})();"
  },
  {
    "path": "src/static_cdn/admin/js/vendor/select2/i18n/sk.js",
    "content": "/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */\n\n(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define(\"select2/i18n/sk\",[],function(){var e={2:function(e){return e?\"dva\":\"dve\"},3:function(){return\"tri\"},4:function(){return\"štyri\"}};return{inputTooLong:function(t){var n=t.input.length-t.maximum;return n==1?\"Prosím, zadajte o jeden znak menej\":n>=2&&n<=4?\"Prosím, zadajte o \"+e[n](!0)+\" znaky menej\":\"Prosím, zadajte o \"+n+\" znakov menej\"},inputTooShort:function(t){var n=t.minimum-t.input.length;return n==1?\"Prosím, zadajte ešte jeden znak\":n<=4?\"Prosím, zadajte ešte ďalšie \"+e[n](!0)+\" znaky\":\"Prosím, zadajte ešte ďalších \"+n+\" znakov\"},loadingMore:function(){return\"Loading more results…\"},maximumSelected:function(t){return t.maximum==1?\"Môžete zvoliť len jednu položku\":t.maximum>=2&&t.maximum<=4?\"Môžete zvoliť najviac \"+e[t.maximum](!1)+\" položky\":\"Môžete zvoliť najviac \"+t.maximum+\" položiek\"},noResults:function(){return\"Nenašli sa žiadne položky\"},searching:function(){return\"Vyhľadávanie…\"}}}),{define:e.define,require:e.require}})();"
  },
  {
    "path": "src/static_cdn/admin/js/vendor/select2/i18n/sr-Cyrl.js",
    "content": "/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */\n\n(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define(\"select2/i18n/sr-Cyrl\",[],function(){function e(e,t,n,r){return e%10==1&&e%100!=11?t:e%10>=2&&e%10<=4&&(e%100<12||e%100>14)?n:r}return{errorLoading:function(){return\"Преузимање није успело.\"},inputTooLong:function(t){var n=t.input.length-t.maximum,r=\"Обришите \"+n+\" симбол\";return r+=e(n,\"\",\"а\",\"а\"),r},inputTooShort:function(t){var n=t.minimum-t.input.length,r=\"Укуцајте бар још \"+n+\" симбол\";return r+=e(n,\"\",\"а\",\"а\"),r},loadingMore:function(){return\"Преузимање још резултата…\"},maximumSelected:function(t){var n=\"Можете изабрати само \"+t.maximum+\" ставк\";return n+=e(t.maximum,\"у\",\"е\",\"и\"),n},noResults:function(){return\"Ништа није пронађено\"},searching:function(){return\"Претрага…\"}}}),{define:e.define,require:e.require}})();"
  },
  {
    "path": "src/static_cdn/admin/js/vendor/select2/i18n/sr.js",
    "content": "/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */\n\n(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define(\"select2/i18n/sr\",[],function(){function e(e,t,n,r){return e%10==1&&e%100!=11?t:e%10>=2&&e%10<=4&&(e%100<12||e%100>14)?n:r}return{errorLoading:function(){return\"Preuzimanje nije uspelo.\"},inputTooLong:function(t){var n=t.input.length-t.maximum,r=\"Obrišite \"+n+\" simbol\";return r+=e(n,\"\",\"a\",\"a\"),r},inputTooShort:function(t){var n=t.minimum-t.input.length,r=\"Ukucajte bar još \"+n+\" simbol\";return r+=e(n,\"\",\"a\",\"a\"),r},loadingMore:function(){return\"Preuzimanje još rezultata…\"},maximumSelected:function(t){var n=\"Možete izabrati samo \"+t.maximum+\" stavk\";return n+=e(t.maximum,\"u\",\"e\",\"i\"),n},noResults:function(){return\"Ništa nije pronađeno\"},searching:function(){return\"Pretraga…\"}}}),{define:e.define,require:e.require}})();"
  },
  {
    "path": "src/static_cdn/admin/js/vendor/select2/i18n/sv.js",
    "content": "/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */\n\n(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define(\"select2/i18n/sv\",[],function(){return{errorLoading:function(){return\"Resultat kunde inte laddas.\"},inputTooLong:function(e){var t=e.input.length-e.maximum,n=\"Vänligen sudda ut \"+t+\" tecken\";return n},inputTooShort:function(e){var t=e.minimum-e.input.length,n=\"Vänligen skriv in \"+t+\" eller fler tecken\";return n},loadingMore:function(){return\"Laddar fler resultat…\"},maximumSelected:function(e){var t=\"Du kan max välja \"+e.maximum+\" element\";return t},noResults:function(){return\"Inga träffar\"},searching:function(){return\"Söker…\"}}}),{define:e.define,require:e.require}})();"
  },
  {
    "path": "src/static_cdn/admin/js/vendor/select2/i18n/th.js",
    "content": "/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */\n\n(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define(\"select2/i18n/th\",[],function(){return{inputTooLong:function(e){var t=e.input.length-e.maximum,n=\"โปรดลบออก \"+t+\" ตัวอักษร\";return n},inputTooShort:function(e){var t=e.minimum-e.input.length,n=\"โปรดพิมพ์เพิ่มอีก \"+t+\" ตัวอักษร\";return n},loadingMore:function(){return\"กำลังค้นข้อมูลเพิ่ม…\"},maximumSelected:function(e){var t=\"คุณสามารถเลือกได้ไม่เกิน \"+e.maximum+\" รายการ\";return t},noResults:function(){return\"ไม่พบข้อมูล\"},searching:function(){return\"กำลังค้นข้อมูล…\"}}}),{define:e.define,require:e.require}})();"
  },
  {
    "path": "src/static_cdn/admin/js/vendor/select2/i18n/tr.js",
    "content": "/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */\n\n(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define(\"select2/i18n/tr\",[],function(){return{inputTooLong:function(e){var t=e.input.length-e.maximum,n=t+\" karakter daha girmelisiniz\";return n},inputTooShort:function(e){var t=e.minimum-e.input.length,n=\"En az \"+t+\" karakter daha girmelisiniz\";return n},loadingMore:function(){return\"Daha fazla…\"},maximumSelected:function(e){var t=\"Sadece \"+e.maximum+\" seçim yapabilirsiniz\";return t},noResults:function(){return\"Sonuç bulunamadı\"},searching:function(){return\"Aranıyor…\"}}}),{define:e.define,require:e.require}})();"
  },
  {
    "path": "src/static_cdn/admin/js/vendor/select2/i18n/uk.js",
    "content": "/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */\n\n(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define(\"select2/i18n/uk\",[],function(){function e(e,t,n,r){return e%100>10&&e%100<15?r:e%10===1?t:e%10>1&&e%10<5?n:r}return{errorLoading:function(){return\"Неможливо завантажити результати\"},inputTooLong:function(t){var n=t.input.length-t.maximum;return\"Будь ласка, видаліть \"+n+\" \"+e(t.maximum,\"літеру\",\"літери\",\"літер\")},inputTooShort:function(e){var t=e.minimum-e.input.length;return\"Будь ласка, введіть \"+t+\" або більше літер\"},loadingMore:function(){return\"Завантаження інших результатів…\"},maximumSelected:function(t){return\"Ви можете вибрати лише \"+t.maximum+\" \"+e(t.maximum,\"пункт\",\"пункти\",\"пунктів\")},noResults:function(){return\"Нічого не знайдено\"},searching:function(){return\"Пошук…\"}}}),{define:e.define,require:e.require}})();"
  },
  {
    "path": "src/static_cdn/admin/js/vendor/select2/i18n/vi.js",
    "content": "/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */\n\n(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define(\"select2/i18n/vi\",[],function(){return{inputTooLong:function(e){var t=e.input.length-e.maximum,n=\"Vui lòng nhập ít hơn \"+t+\" ký tự\";return t!=1&&(n+=\"s\"),n},inputTooShort:function(e){var t=e.minimum-e.input.length,n=\"Vui lòng nhập nhiều hơn \"+t+' ký tự\"';return n},loadingMore:function(){return\"Đang lấy thêm kết quả…\"},maximumSelected:function(e){var t=\"Chỉ có thể chọn được \"+e.maximum+\" lựa chọn\";return t},noResults:function(){return\"Không tìm thấy kết quả\"},searching:function(){return\"Đang tìm…\"}}}),{define:e.define,require:e.require}})();"
  },
  {
    "path": "src/static_cdn/admin/js/vendor/select2/i18n/zh-CN.js",
    "content": "/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */\n\n(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define(\"select2/i18n/zh-CN\",[],function(){return{errorLoading:function(){return\"无法载入结果。\"},inputTooLong:function(e){var t=e.input.length-e.maximum,n=\"请删除\"+t+\"个字符\";return n},inputTooShort:function(e){var t=e.minimum-e.input.length,n=\"请再输入至少\"+t+\"个字符\";return n},loadingMore:function(){return\"载入更多结果…\"},maximumSelected:function(e){var t=\"最多只能选择\"+e.maximum+\"个项目\";return t},noResults:function(){return\"未找到结果\"},searching:function(){return\"搜索中…\"}}}),{define:e.define,require:e.require}})();"
  },
  {
    "path": "src/static_cdn/admin/js/vendor/select2/i18n/zh-TW.js",
    "content": "/*! Select2 4.0.3 | https://github.com/select2/select2/blob/master/LICENSE.md */\n\n(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define(\"select2/i18n/zh-TW\",[],function(){return{inputTooLong:function(e){var t=e.input.length-e.maximum,n=\"請刪掉\"+t+\"個字元\";return n},inputTooShort:function(e){var t=e.minimum-e.input.length,n=\"請再輸入\"+t+\"個字元\";return n},loadingMore:function(){return\"載入中…\"},maximumSelected:function(e){var t=\"你只能選擇最多\"+e.maximum+\"項\";return t},noResults:function(){return\"沒有找到相符的項目\"},searching:function(){return\"搜尋中…\"}}}),{define:e.define,require:e.require}})();"
  },
  {
    "path": "src/static_cdn/admin/js/vendor/select2/select2.full.js",
    "content": "/*!\n * Select2 4.0.3\n * https://select2.github.io\n *\n * Released under the MIT license\n * https://github.com/select2/select2/blob/master/LICENSE.md\n */\n(function (factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module.\n    define(['jquery'], factory);\n  } else if (typeof exports === 'object') {\n    // Node/CommonJS\n    factory(require('jquery'));\n  } else {\n    // Browser globals\n    factory(jQuery);\n  }\n}(function (jQuery) {\n  // This is needed so we can catch the AMD loader configuration and use it\n  // The inner file should be wrapped (by `banner.start.js`) in a function that\n  // returns the AMD loader references.\n  var S2 =\n(function () {\n  // Restore the Select2 AMD loader so it can be used\n  // Needed mostly in the language files, where the loader is not inserted\n  if (jQuery && jQuery.fn && jQuery.fn.select2 && jQuery.fn.select2.amd) {\n    var S2 = jQuery.fn.select2.amd;\n  }\nvar S2;(function () { if (!S2 || !S2.requirejs) {\nif (!S2) { S2 = {}; } else { require = S2; }\n/**\n * @license almond 0.3.1 Copyright (c) 2011-2014, The Dojo Foundation All Rights Reserved.\n * Available via the MIT or new BSD license.\n * see: http://github.com/jrburke/almond for details\n */\n//Going sloppy to avoid 'use strict' string cost, but strict practices should\n//be followed.\n/*jslint sloppy: true */\n/*global setTimeout: false */\n\nvar requirejs, require, define;\n(function (undef) {\n    var main, req, makeMap, handlers,\n        defined = {},\n        waiting = {},\n        config = {},\n        defining = {},\n        hasOwn = Object.prototype.hasOwnProperty,\n        aps = [].slice,\n        jsSuffixRegExp = /\\.js$/;\n\n    function hasProp(obj, prop) {\n        return hasOwn.call(obj, prop);\n    }\n\n    /**\n     * Given a relative module name, like ./something, normalize it to\n     * a real name that can be mapped to a path.\n     * @param {String} name the relative name\n     * @param {String} baseName a real name that the name arg is relative\n     * to.\n     * @returns {String} normalized name\n     */\n    function normalize(name, baseName) {\n        var nameParts, nameSegment, mapValue, foundMap, lastIndex,\n            foundI, foundStarMap, starI, i, j, part,\n            baseParts = baseName && baseName.split(\"/\"),\n            map = config.map,\n            starMap = (map && map['*']) || {};\n\n        //Adjust any relative paths.\n        if (name && name.charAt(0) === \".\") {\n            //If have a base name, try to normalize against it,\n            //otherwise, assume it is a top-level require that will\n            //be relative to baseUrl in the end.\n            if (baseName) {\n                name = name.split('/');\n                lastIndex = name.length - 1;\n\n                // Node .js allowance:\n                if (config.nodeIdCompat && jsSuffixRegExp.test(name[lastIndex])) {\n                    name[lastIndex] = name[lastIndex].replace(jsSuffixRegExp, '');\n                }\n\n                //Lop off the last part of baseParts, so that . matches the\n                //\"directory\" and not name of the baseName's module. For instance,\n                //baseName of \"one/two/three\", maps to \"one/two/three.js\", but we\n                //want the directory, \"one/two\" for this normalization.\n                name = baseParts.slice(0, baseParts.length - 1).concat(name);\n\n                //start trimDots\n                for (i = 0; i < name.length; i += 1) {\n                    part = name[i];\n                    if (part === \".\") {\n                        name.splice(i, 1);\n                        i -= 1;\n                    } else if (part === \"..\") {\n                        if (i === 1 && (name[2] === '..' || name[0] === '..')) {\n                            //End of the line. Keep at least one non-dot\n                            //path segment at the front so it can be mapped\n                            //correctly to disk. Otherwise, there is likely\n                            //no path mapping for a path starting with '..'.\n                            //This can still fail, but catches the most reasonable\n                            //uses of ..\n                            break;\n                        } else if (i > 0) {\n                            name.splice(i - 1, 2);\n                            i -= 2;\n                        }\n                    }\n                }\n                //end trimDots\n\n                name = name.join(\"/\");\n            } else if (name.indexOf('./') === 0) {\n                // No baseName, so this is ID is resolved relative\n                // to baseUrl, pull off the leading dot.\n                name = name.substring(2);\n            }\n        }\n\n        //Apply map config if available.\n        if ((baseParts || starMap) && map) {\n            nameParts = name.split('/');\n\n            for (i = nameParts.length; i > 0; i -= 1) {\n                nameSegment = nameParts.slice(0, i).join(\"/\");\n\n                if (baseParts) {\n                    //Find the longest baseName segment match in the config.\n                    //So, do joins on the biggest to smallest lengths of baseParts.\n                    for (j = baseParts.length; j > 0; j -= 1) {\n                        mapValue = map[baseParts.slice(0, j).join('/')];\n\n                        //baseName segment has  config, find if it has one for\n                        //this name.\n                        if (mapValue) {\n                            mapValue = mapValue[nameSegment];\n                            if (mapValue) {\n                                //Match, update name to the new value.\n                                foundMap = mapValue;\n                                foundI = i;\n                                break;\n                            }\n                        }\n                    }\n                }\n\n                if (foundMap) {\n                    break;\n                }\n\n                //Check for a star map match, but just hold on to it,\n                //if there is a shorter segment match later in a matching\n                //config, then favor over this star map.\n                if (!foundStarMap && starMap && starMap[nameSegment]) {\n                    foundStarMap = starMap[nameSegment];\n                    starI = i;\n                }\n            }\n\n            if (!foundMap && foundStarMap) {\n                foundMap = foundStarMap;\n                foundI = starI;\n            }\n\n            if (foundMap) {\n                nameParts.splice(0, foundI, foundMap);\n                name = nameParts.join('/');\n            }\n        }\n\n        return name;\n    }\n\n    function makeRequire(relName, forceSync) {\n        return function () {\n            //A version of a require function that passes a moduleName\n            //value for items that may need to\n            //look up paths relative to the moduleName\n            var args = aps.call(arguments, 0);\n\n            //If first arg is not require('string'), and there is only\n            //one arg, it is the array form without a callback. Insert\n            //a null so that the following concat is correct.\n            if (typeof args[0] !== 'string' && args.length === 1) {\n                args.push(null);\n            }\n            return req.apply(undef, args.concat([relName, forceSync]));\n        };\n    }\n\n    function makeNormalize(relName) {\n        return function (name) {\n            return normalize(name, relName);\n        };\n    }\n\n    function makeLoad(depName) {\n        return function (value) {\n            defined[depName] = value;\n        };\n    }\n\n    function callDep(name) {\n        if (hasProp(waiting, name)) {\n            var args = waiting[name];\n            delete waiting[name];\n            defining[name] = true;\n            main.apply(undef, args);\n        }\n\n        if (!hasProp(defined, name) && !hasProp(defining, name)) {\n            throw new Error('No ' + name);\n        }\n        return defined[name];\n    }\n\n    //Turns a plugin!resource to [plugin, resource]\n    //with the plugin being undefined if the name\n    //did not have a plugin prefix.\n    function splitPrefix(name) {\n        var prefix,\n            index = name ? name.indexOf('!') : -1;\n        if (index > -1) {\n            prefix = name.substring(0, index);\n            name = name.substring(index + 1, name.length);\n        }\n        return [prefix, name];\n    }\n\n    /**\n     * Makes a name map, normalizing the name, and using a plugin\n     * for normalization if necessary. Grabs a ref to plugin\n     * too, as an optimization.\n     */\n    makeMap = function (name, relName) {\n        var plugin,\n            parts = splitPrefix(name),\n            prefix = parts[0];\n\n        name = parts[1];\n\n        if (prefix) {\n            prefix = normalize(prefix, relName);\n            plugin = callDep(prefix);\n        }\n\n        //Normalize according\n        if (prefix) {\n            if (plugin && plugin.normalize) {\n                name = plugin.normalize(name, makeNormalize(relName));\n            } else {\n                name = normalize(name, relName);\n            }\n        } else {\n            name = normalize(name, relName);\n            parts = splitPrefix(name);\n            prefix = parts[0];\n            name = parts[1];\n            if (prefix) {\n                plugin = callDep(prefix);\n            }\n        }\n\n        //Using ridiculous property names for space reasons\n        return {\n            f: prefix ? prefix + '!' + name : name, //fullName\n            n: name,\n            pr: prefix,\n            p: plugin\n        };\n    };\n\n    function makeConfig(name) {\n        return function () {\n            return (config && config.config && config.config[name]) || {};\n        };\n    }\n\n    handlers = {\n        require: function (name) {\n            return makeRequire(name);\n        },\n        exports: function (name) {\n            var e = defined[name];\n            if (typeof e !== 'undefined') {\n                return e;\n            } else {\n                return (defined[name] = {});\n            }\n        },\n        module: function (name) {\n            return {\n                id: name,\n                uri: '',\n                exports: defined[name],\n                config: makeConfig(name)\n            };\n        }\n    };\n\n    main = function (name, deps, callback, relName) {\n        var cjsModule, depName, ret, map, i,\n            args = [],\n            callbackType = typeof callback,\n            usingExports;\n\n        //Use name if no relName\n        relName = relName || name;\n\n        //Call the callback to define the module, if necessary.\n        if (callbackType === 'undefined' || callbackType === 'function') {\n            //Pull out the defined dependencies and pass the ordered\n            //values to the callback.\n            //Default to [require, exports, module] if no deps\n            deps = !deps.length && callback.length ? ['require', 'exports', 'module'] : deps;\n            for (i = 0; i < deps.length; i += 1) {\n                map = makeMap(deps[i], relName);\n                depName = map.f;\n\n                //Fast path CommonJS standard dependencies.\n                if (depName === \"require\") {\n                    args[i] = handlers.require(name);\n                } else if (depName === \"exports\") {\n                    //CommonJS module spec 1.1\n                    args[i] = handlers.exports(name);\n                    usingExports = true;\n                } else if (depName === \"module\") {\n                    //CommonJS module spec 1.1\n                    cjsModule = args[i] = handlers.module(name);\n                } else if (hasProp(defined, depName) ||\n                           hasProp(waiting, depName) ||\n                           hasProp(defining, depName)) {\n                    args[i] = callDep(depName);\n                } else if (map.p) {\n                    map.p.load(map.n, makeRequire(relName, true), makeLoad(depName), {});\n                    args[i] = defined[depName];\n                } else {\n                    throw new Error(name + ' missing ' + depName);\n                }\n            }\n\n            ret = callback ? callback.apply(defined[name], args) : undefined;\n\n            if (name) {\n                //If setting exports via \"module\" is in play,\n                //favor that over return value and exports. After that,\n                //favor a non-undefined return value over exports use.\n                if (cjsModule && cjsModule.exports !== undef &&\n                        cjsModule.exports !== defined[name]) {\n                    defined[name] = cjsModule.exports;\n                } else if (ret !== undef || !usingExports) {\n                    //Use the return value from the function.\n                    defined[name] = ret;\n                }\n            }\n        } else if (name) {\n            //May just be an object definition for the module. Only\n            //worry about defining if have a module name.\n            defined[name] = callback;\n        }\n    };\n\n    requirejs = require = req = function (deps, callback, relName, forceSync, alt) {\n        if (typeof deps === \"string\") {\n            if (handlers[deps]) {\n                //callback in this case is really relName\n                return handlers[deps](callback);\n            }\n            //Just return the module wanted. In this scenario, the\n            //deps arg is the module name, and second arg (if passed)\n            //is just the relName.\n            //Normalize module name, if it contains . or ..\n            return callDep(makeMap(deps, callback).f);\n        } else if (!deps.splice) {\n            //deps is a config object, not an array.\n            config = deps;\n            if (config.deps) {\n                req(config.deps, config.callback);\n            }\n            if (!callback) {\n                return;\n            }\n\n            if (callback.splice) {\n                //callback is an array, which means it is a dependency list.\n                //Adjust args if there are dependencies\n                deps = callback;\n                callback = relName;\n                relName = null;\n            } else {\n                deps = undef;\n            }\n        }\n\n        //Support require(['a'])\n        callback = callback || function () {};\n\n        //If relName is a function, it is an errback handler,\n        //so remove it.\n        if (typeof relName === 'function') {\n            relName = forceSync;\n            forceSync = alt;\n        }\n\n        //Simulate async callback;\n        if (forceSync) {\n            main(undef, deps, callback, relName);\n        } else {\n            //Using a non-zero value because of concern for what old browsers\n            //do, and latest browsers \"upgrade\" to 4 if lower value is used:\n            //http://www.whatwg.org/specs/web-apps/current-work/multipage/timers.html#dom-windowtimers-settimeout:\n            //If want a value immediately, use require('id') instead -- something\n            //that works in almond on the global level, but not guaranteed and\n            //unlikely to work in other AMD implementations.\n            setTimeout(function () {\n                main(undef, deps, callback, relName);\n            }, 4);\n        }\n\n        return req;\n    };\n\n    /**\n     * Just drops the config on the floor, but returns req in case\n     * the config return value is used.\n     */\n    req.config = function (cfg) {\n        return req(cfg);\n    };\n\n    /**\n     * Expose module registry for debugging and tooling\n     */\n    requirejs._defined = defined;\n\n    define = function (name, deps, callback) {\n        if (typeof name !== 'string') {\n            throw new Error('See almond README: incorrect module build, no module name');\n        }\n\n        //This module may not have dependencies\n        if (!deps.splice) {\n            //deps is not an array, so probably means\n            //an object literal or factory function for\n            //the value. Adjust args.\n            callback = deps;\n            deps = [];\n        }\n\n        if (!hasProp(defined, name) && !hasProp(waiting, name)) {\n            waiting[name] = [name, deps, callback];\n        }\n    };\n\n    define.amd = {\n        jQuery: true\n    };\n}());\n\nS2.requirejs = requirejs;S2.require = require;S2.define = define;\n}\n}());\nS2.define(\"almond\", function(){});\n\n/* global jQuery:false, $:false */\nS2.define('jquery',[],function () {\n  var _$ = jQuery || $;\n\n  if (_$ == null && console && console.error) {\n    console.error(\n      'Select2: An instance of jQuery or a jQuery-compatible library was not ' +\n      'found. Make sure that you are including jQuery before Select2 on your ' +\n      'web page.'\n    );\n  }\n\n  return _$;\n});\n\nS2.define('select2/utils',[\n  'jquery'\n], function ($) {\n  var Utils = {};\n\n  Utils.Extend = function (ChildClass, SuperClass) {\n    var __hasProp = {}.hasOwnProperty;\n\n    function BaseConstructor () {\n      this.constructor = ChildClass;\n    }\n\n    for (var key in SuperClass) {\n      if (__hasProp.call(SuperClass, key)) {\n        ChildClass[key] = SuperClass[key];\n      }\n    }\n\n    BaseConstructor.prototype = SuperClass.prototype;\n    ChildClass.prototype = new BaseConstructor();\n    ChildClass.__super__ = SuperClass.prototype;\n\n    return ChildClass;\n  };\n\n  function getMethods (theClass) {\n    var proto = theClass.prototype;\n\n    var methods = [];\n\n    for (var methodName in proto) {\n      var m = proto[methodName];\n\n      if (typeof m !== 'function') {\n        continue;\n      }\n\n      if (methodName === 'constructor') {\n        continue;\n      }\n\n      methods.push(methodName);\n    }\n\n    return methods;\n  }\n\n  Utils.Decorate = function (SuperClass, DecoratorClass) {\n    var decoratedMethods = getMethods(DecoratorClass);\n    var superMethods = getMethods(SuperClass);\n\n    function DecoratedClass () {\n      var unshift = Array.prototype.unshift;\n\n      var argCount = DecoratorClass.prototype.constructor.length;\n\n      var calledConstructor = SuperClass.prototype.constructor;\n\n      if (argCount > 0) {\n        unshift.call(arguments, SuperClass.prototype.constructor);\n\n        calledConstructor = DecoratorClass.prototype.constructor;\n      }\n\n      calledConstructor.apply(this, arguments);\n    }\n\n    DecoratorClass.displayName = SuperClass.displayName;\n\n    function ctr () {\n      this.constructor = DecoratedClass;\n    }\n\n    DecoratedClass.prototype = new ctr();\n\n    for (var m = 0; m < superMethods.length; m++) {\n        var superMethod = superMethods[m];\n\n        DecoratedClass.prototype[superMethod] =\n          SuperClass.prototype[superMethod];\n    }\n\n    var calledMethod = function (methodName) {\n      // Stub out the original method if it's not decorating an actual method\n      var originalMethod = function () {};\n\n      if (methodName in DecoratedClass.prototype) {\n        originalMethod = DecoratedClass.prototype[methodName];\n      }\n\n      var decoratedMethod = DecoratorClass.prototype[methodName];\n\n      return function () {\n        var unshift = Array.prototype.unshift;\n\n        unshift.call(arguments, originalMethod);\n\n        return decoratedMethod.apply(this, arguments);\n      };\n    };\n\n    for (var d = 0; d < decoratedMethods.length; d++) {\n      var decoratedMethod = decoratedMethods[d];\n\n      DecoratedClass.prototype[decoratedMethod] = calledMethod(decoratedMethod);\n    }\n\n    return DecoratedClass;\n  };\n\n  var Observable = function () {\n    this.listeners = {};\n  };\n\n  Observable.prototype.on = function (event, callback) {\n    this.listeners = this.listeners || {};\n\n    if (event in this.listeners) {\n      this.listeners[event].push(callback);\n    } else {\n      this.listeners[event] = [callback];\n    }\n  };\n\n  Observable.prototype.trigger = function (event) {\n    var slice = Array.prototype.slice;\n    var params = slice.call(arguments, 1);\n\n    this.listeners = this.listeners || {};\n\n    // Params should always come in as an array\n    if (params == null) {\n      params = [];\n    }\n\n    // If there are no arguments to the event, use a temporary object\n    if (params.length === 0) {\n      params.push({});\n    }\n\n    // Set the `_type` of the first object to the event\n    params[0]._type = event;\n\n    if (event in this.listeners) {\n      this.invoke(this.listeners[event], slice.call(arguments, 1));\n    }\n\n    if ('*' in this.listeners) {\n      this.invoke(this.listeners['*'], arguments);\n    }\n  };\n\n  Observable.prototype.invoke = function (listeners, params) {\n    for (var i = 0, len = listeners.length; i < len; i++) {\n      listeners[i].apply(this, params);\n    }\n  };\n\n  Utils.Observable = Observable;\n\n  Utils.generateChars = function (length) {\n    var chars = '';\n\n    for (var i = 0; i < length; i++) {\n      var randomChar = Math.floor(Math.random() * 36);\n      chars += randomChar.toString(36);\n    }\n\n    return chars;\n  };\n\n  Utils.bind = function (func, context) {\n    return function () {\n      func.apply(context, arguments);\n    };\n  };\n\n  Utils._convertData = function (data) {\n    for (var originalKey in data) {\n      var keys = originalKey.split('-');\n\n      var dataLevel = data;\n\n      if (keys.length === 1) {\n        continue;\n      }\n\n      for (var k = 0; k < keys.length; k++) {\n        var key = keys[k];\n\n        // Lowercase the first letter\n        // By default, dash-separated becomes camelCase\n        key = key.substring(0, 1).toLowerCase() + key.substring(1);\n\n        if (!(key in dataLevel)) {\n          dataLevel[key] = {};\n        }\n\n        if (k == keys.length - 1) {\n          dataLevel[key] = data[originalKey];\n        }\n\n        dataLevel = dataLevel[key];\n      }\n\n      delete data[originalKey];\n    }\n\n    return data;\n  };\n\n  Utils.hasScroll = function (index, el) {\n    // Adapted from the function created by @ShadowScripter\n    // and adapted by @BillBarry on the Stack Exchange Code Review website.\n    // The original code can be found at\n    // http://codereview.stackexchange.com/q/13338\n    // and was designed to be used with the Sizzle selector engine.\n\n    var $el = $(el);\n    var overflowX = el.style.overflowX;\n    var overflowY = el.style.overflowY;\n\n    //Check both x and y declarations\n    if (overflowX === overflowY &&\n        (overflowY === 'hidden' || overflowY === 'visible')) {\n      return false;\n    }\n\n    if (overflowX === 'scroll' || overflowY === 'scroll') {\n      return true;\n    }\n\n    return ($el.innerHeight() < el.scrollHeight ||\n      $el.innerWidth() < el.scrollWidth);\n  };\n\n  Utils.escapeMarkup = function (markup) {\n    var replaceMap = {\n      '\\\\': '&#92;',\n      '&': '&amp;',\n      '<': '&lt;',\n      '>': '&gt;',\n      '\"': '&quot;',\n      '\\'': '&#39;',\n      '/': '&#47;'\n    };\n\n    // Do not try to escape the markup if it's not a string\n    if (typeof markup !== 'string') {\n      return markup;\n    }\n\n    return String(markup).replace(/[&<>\"'\\/\\\\]/g, function (match) {\n      return replaceMap[match];\n    });\n  };\n\n  // Append an array of jQuery nodes to a given element.\n  Utils.appendMany = function ($element, $nodes) {\n    // jQuery 1.7.x does not support $.fn.append() with an array\n    // Fall back to a jQuery object collection using $.fn.add()\n    if ($.fn.jquery.substr(0, 3) === '1.7') {\n      var $jqNodes = $();\n\n      $.map($nodes, function (node) {\n        $jqNodes = $jqNodes.add(node);\n      });\n\n      $nodes = $jqNodes;\n    }\n\n    $element.append($nodes);\n  };\n\n  return Utils;\n});\n\nS2.define('select2/results',[\n  'jquery',\n  './utils'\n], function ($, Utils) {\n  function Results ($element, options, dataAdapter) {\n    this.$element = $element;\n    this.data = dataAdapter;\n    this.options = options;\n\n    Results.__super__.constructor.call(this);\n  }\n\n  Utils.Extend(Results, Utils.Observable);\n\n  Results.prototype.render = function () {\n    var $results = $(\n      '<ul class=\"select2-results__options\" role=\"tree\"></ul>'\n    );\n\n    if (this.options.get('multiple')) {\n      $results.attr('aria-multiselectable', 'true');\n    }\n\n    this.$results = $results;\n\n    return $results;\n  };\n\n  Results.prototype.clear = function () {\n    this.$results.empty();\n  };\n\n  Results.prototype.displayMessage = function (params) {\n    var escapeMarkup = this.options.get('escapeMarkup');\n\n    this.clear();\n    this.hideLoading();\n\n    var $message = $(\n      '<li role=\"treeitem\" aria-live=\"assertive\"' +\n      ' class=\"select2-results__option\"></li>'\n    );\n\n    var message = this.options.get('translations').get(params.message);\n\n    $message.append(\n      escapeMarkup(\n        message(params.args)\n      )\n    );\n\n    $message[0].className += ' select2-results__message';\n\n    this.$results.append($message);\n  };\n\n  Results.prototype.hideMessages = function () {\n    this.$results.find('.select2-results__message').remove();\n  };\n\n  Results.prototype.append = function (data) {\n    this.hideLoading();\n\n    var $options = [];\n\n    if (data.results == null || data.results.length === 0) {\n      if (this.$results.children().length === 0) {\n        this.trigger('results:message', {\n          message: 'noResults'\n        });\n      }\n\n      return;\n    }\n\n    data.results = this.sort(data.results);\n\n    for (var d = 0; d < data.results.length; d++) {\n      var item = data.results[d];\n\n      var $option = this.option(item);\n\n      $options.push($option);\n    }\n\n    this.$results.append($options);\n  };\n\n  Results.prototype.position = function ($results, $dropdown) {\n    var $resultsContainer = $dropdown.find('.select2-results');\n    $resultsContainer.append($results);\n  };\n\n  Results.prototype.sort = function (data) {\n    var sorter = this.options.get('sorter');\n\n    return sorter(data);\n  };\n\n  Results.prototype.highlightFirstItem = function () {\n    var $options = this.$results\n      .find('.select2-results__option[aria-selected]');\n\n    var $selected = $options.filter('[aria-selected=true]');\n\n    // Check if there are any selected options\n    if ($selected.length > 0) {\n      // If there are selected options, highlight the first\n      $selected.first().trigger('mouseenter');\n    } else {\n      // If there are no selected options, highlight the first option\n      // in the dropdown\n      $options.first().trigger('mouseenter');\n    }\n\n    this.ensureHighlightVisible();\n  };\n\n  Results.prototype.setClasses = function () {\n    var self = this;\n\n    this.data.current(function (selected) {\n      var selectedIds = $.map(selected, function (s) {\n        return s.id.toString();\n      });\n\n      var $options = self.$results\n        .find('.select2-results__option[aria-selected]');\n\n      $options.each(function () {\n        var $option = $(this);\n\n        var item = $.data(this, 'data');\n\n        // id needs to be converted to a string when comparing\n        var id = '' + item.id;\n\n        if ((item.element != null && item.element.selected) ||\n            (item.element == null && $.inArray(id, selectedIds) > -1)) {\n          $option.attr('aria-selected', 'true');\n        } else {\n          $option.attr('aria-selected', 'false');\n        }\n      });\n\n    });\n  };\n\n  Results.prototype.showLoading = function (params) {\n    this.hideLoading();\n\n    var loadingMore = this.options.get('translations').get('searching');\n\n    var loading = {\n      disabled: true,\n      loading: true,\n      text: loadingMore(params)\n    };\n    var $loading = this.option(loading);\n    $loading.className += ' loading-results';\n\n    this.$results.prepend($loading);\n  };\n\n  Results.prototype.hideLoading = function () {\n    this.$results.find('.loading-results').remove();\n  };\n\n  Results.prototype.option = function (data) {\n    var option = document.createElement('li');\n    option.className = 'select2-results__option';\n\n    var attrs = {\n      'role': 'treeitem',\n      'aria-selected': 'false'\n    };\n\n    if (data.disabled) {\n      delete attrs['aria-selected'];\n      attrs['aria-disabled'] = 'true';\n    }\n\n    if (data.id == null) {\n      delete attrs['aria-selected'];\n    }\n\n    if (data._resultId != null) {\n      option.id = data._resultId;\n    }\n\n    if (data.title) {\n      option.title = data.title;\n    }\n\n    if (data.children) {\n      attrs.role = 'group';\n      attrs['aria-label'] = data.text;\n      delete attrs['aria-selected'];\n    }\n\n    for (var attr in attrs) {\n      var val = attrs[attr];\n\n      option.setAttribute(attr, val);\n    }\n\n    if (data.children) {\n      var $option = $(option);\n\n      var label = document.createElement('strong');\n      label.className = 'select2-results__group';\n\n      var $label = $(label);\n      this.template(data, label);\n\n      var $children = [];\n\n      for (var c = 0; c < data.children.length; c++) {\n        var child = data.children[c];\n\n        var $child = this.option(child);\n\n        $children.push($child);\n      }\n\n      var $childrenContainer = $('<ul></ul>', {\n        'class': 'select2-results__options select2-results__options--nested'\n      });\n\n      $childrenContainer.append($children);\n\n      $option.append(label);\n      $option.append($childrenContainer);\n    } else {\n      this.template(data, option);\n    }\n\n    $.data(option, 'data', data);\n\n    return option;\n  };\n\n  Results.prototype.bind = function (container, $container) {\n    var self = this;\n\n    var id = container.id + '-results';\n\n    this.$results.attr('id', id);\n\n    container.on('results:all', function (params) {\n      self.clear();\n      self.append(params.data);\n\n      if (container.isOpen()) {\n        self.setClasses();\n        self.highlightFirstItem();\n      }\n    });\n\n    container.on('results:append', function (params) {\n      self.append(params.data);\n\n      if (container.isOpen()) {\n        self.setClasses();\n      }\n    });\n\n    container.on('query', function (params) {\n      self.hideMessages();\n      self.showLoading(params);\n    });\n\n    container.on('select', function () {\n      if (!container.isOpen()) {\n        return;\n      }\n\n      self.setClasses();\n      self.highlightFirstItem();\n    });\n\n    container.on('unselect', function () {\n      if (!container.isOpen()) {\n        return;\n      }\n\n      self.setClasses();\n      self.highlightFirstItem();\n    });\n\n    container.on('open', function () {\n      // When the dropdown is open, aria-expended=\"true\"\n      self.$results.attr('aria-expanded', 'true');\n      self.$results.attr('aria-hidden', 'false');\n\n      self.setClasses();\n      self.ensureHighlightVisible();\n    });\n\n    container.on('close', function () {\n      // When the dropdown is closed, aria-expended=\"false\"\n      self.$results.attr('aria-expanded', 'false');\n      self.$results.attr('aria-hidden', 'true');\n      self.$results.removeAttr('aria-activedescendant');\n    });\n\n    container.on('results:toggle', function () {\n      var $highlighted = self.getHighlightedResults();\n\n      if ($highlighted.length === 0) {\n        return;\n      }\n\n      $highlighted.trigger('mouseup');\n    });\n\n    container.on('results:select', function () {\n      var $highlighted = self.getHighlightedResults();\n\n      if ($highlighted.length === 0) {\n        return;\n      }\n\n      var data = $highlighted.data('data');\n\n      if ($highlighted.attr('aria-selected') == 'true') {\n        self.trigger('close', {});\n      } else {\n        self.trigger('select', {\n          data: data\n        });\n      }\n    });\n\n    container.on('results:previous', function () {\n      var $highlighted = self.getHighlightedResults();\n\n      var $options = self.$results.find('[aria-selected]');\n\n      var currentIndex = $options.index($highlighted);\n\n      // If we are already at te top, don't move further\n      if (currentIndex === 0) {\n        return;\n      }\n\n      var nextIndex = currentIndex - 1;\n\n      // If none are highlighted, highlight the first\n      if ($highlighted.length === 0) {\n        nextIndex = 0;\n      }\n\n      var $next = $options.eq(nextIndex);\n\n      $next.trigger('mouseenter');\n\n      var currentOffset = self.$results.offset().top;\n      var nextTop = $next.offset().top;\n      var nextOffset = self.$results.scrollTop() + (nextTop - currentOffset);\n\n      if (nextIndex === 0) {\n        self.$results.scrollTop(0);\n      } else if (nextTop - currentOffset < 0) {\n        self.$results.scrollTop(nextOffset);\n      }\n    });\n\n    container.on('results:next', function () {\n      var $highlighted = self.getHighlightedResults();\n\n      var $options = self.$results.find('[aria-selected]');\n\n      var currentIndex = $options.index($highlighted);\n\n      var nextIndex = currentIndex + 1;\n\n      // If we are at the last option, stay there\n      if (nextIndex >= $options.length) {\n        return;\n      }\n\n      var $next = $options.eq(nextIndex);\n\n      $next.trigger('mouseenter');\n\n      var currentOffset = self.$results.offset().top +\n        self.$results.outerHeight(false);\n      var nextBottom = $next.offset().top + $next.outerHeight(false);\n      var nextOffset = self.$results.scrollTop() + nextBottom - currentOffset;\n\n      if (nextIndex === 0) {\n        self.$results.scrollTop(0);\n      } else if (nextBottom > currentOffset) {\n        self.$results.scrollTop(nextOffset);\n      }\n    });\n\n    container.on('results:focus', function (params) {\n      params.element.addClass('select2-results__option--highlighted');\n    });\n\n    container.on('results:message', function (params) {\n      self.displayMessage(params);\n    });\n\n    if ($.fn.mousewheel) {\n      this.$results.on('mousewheel', function (e) {\n        var top = self.$results.scrollTop();\n\n        var bottom = self.$results.get(0).scrollHeight - top + e.deltaY;\n\n        var isAtTop = e.deltaY > 0 && top - e.deltaY <= 0;\n        var isAtBottom = e.deltaY < 0 && bottom <= self.$results.height();\n\n        if (isAtTop) {\n          self.$results.scrollTop(0);\n\n          e.preventDefault();\n          e.stopPropagation();\n        } else if (isAtBottom) {\n          self.$results.scrollTop(\n            self.$results.get(0).scrollHeight - self.$results.height()\n          );\n\n          e.preventDefault();\n          e.stopPropagation();\n        }\n      });\n    }\n\n    this.$results.on('mouseup', '.select2-results__option[aria-selected]',\n      function (evt) {\n      var $this = $(this);\n\n      var data = $this.data('data');\n\n      if ($this.attr('aria-selected') === 'true') {\n        if (self.options.get('multiple')) {\n          self.trigger('unselect', {\n            originalEvent: evt,\n            data: data\n          });\n        } else {\n          self.trigger('close', {});\n        }\n\n        return;\n      }\n\n      self.trigger('select', {\n        originalEvent: evt,\n        data: data\n      });\n    });\n\n    this.$results.on('mouseenter', '.select2-results__option[aria-selected]',\n      function (evt) {\n      var data = $(this).data('data');\n\n      self.getHighlightedResults()\n          .removeClass('select2-results__option--highlighted');\n\n      self.trigger('results:focus', {\n        data: data,\n        element: $(this)\n      });\n    });\n  };\n\n  Results.prototype.getHighlightedResults = function () {\n    var $highlighted = this.$results\n    .find('.select2-results__option--highlighted');\n\n    return $highlighted;\n  };\n\n  Results.prototype.destroy = function () {\n    this.$results.remove();\n  };\n\n  Results.prototype.ensureHighlightVisible = function () {\n    var $highlighted = this.getHighlightedResults();\n\n    if ($highlighted.length === 0) {\n      return;\n    }\n\n    var $options = this.$results.find('[aria-selected]');\n\n    var currentIndex = $options.index($highlighted);\n\n    var currentOffset = this.$results.offset().top;\n    var nextTop = $highlighted.offset().top;\n    var nextOffset = this.$results.scrollTop() + (nextTop - currentOffset);\n\n    var offsetDelta = nextTop - currentOffset;\n    nextOffset -= $highlighted.outerHeight(false) * 2;\n\n    if (currentIndex <= 2) {\n      this.$results.scrollTop(0);\n    } else if (offsetDelta > this.$results.outerHeight() || offsetDelta < 0) {\n      this.$results.scrollTop(nextOffset);\n    }\n  };\n\n  Results.prototype.template = function (result, container) {\n    var template = this.options.get('templateResult');\n    var escapeMarkup = this.options.get('escapeMarkup');\n\n    var content = template(result, container);\n\n    if (content == null) {\n      container.style.display = 'none';\n    } else if (typeof content === 'string') {\n      container.innerHTML = escapeMarkup(content);\n    } else {\n      $(container).append(content);\n    }\n  };\n\n  return Results;\n});\n\nS2.define('select2/keys',[\n\n], function () {\n  var KEYS = {\n    BACKSPACE: 8,\n    TAB: 9,\n    ENTER: 13,\n    SHIFT: 16,\n    CTRL: 17,\n    ALT: 18,\n    ESC: 27,\n    SPACE: 32,\n    PAGE_UP: 33,\n    PAGE_DOWN: 34,\n    END: 35,\n    HOME: 36,\n    LEFT: 37,\n    UP: 38,\n    RIGHT: 39,\n    DOWN: 40,\n    DELETE: 46\n  };\n\n  return KEYS;\n});\n\nS2.define('select2/selection/base',[\n  'jquery',\n  '../utils',\n  '../keys'\n], function ($, Utils, KEYS) {\n  function BaseSelection ($element, options) {\n    this.$element = $element;\n    this.options = options;\n\n    BaseSelection.__super__.constructor.call(this);\n  }\n\n  Utils.Extend(BaseSelection, Utils.Observable);\n\n  BaseSelection.prototype.render = function () {\n    var $selection = $(\n      '<span class=\"select2-selection\" role=\"combobox\" ' +\n      ' aria-haspopup=\"true\" aria-expanded=\"false\">' +\n      '</span>'\n    );\n\n    this._tabindex = 0;\n\n    if (this.$element.data('old-tabindex') != null) {\n      this._tabindex = this.$element.data('old-tabindex');\n    } else if (this.$element.attr('tabindex') != null) {\n      this._tabindex = this.$element.attr('tabindex');\n    }\n\n    $selection.attr('title', this.$element.attr('title'));\n    $selection.attr('tabindex', this._tabindex);\n\n    this.$selection = $selection;\n\n    return $selection;\n  };\n\n  BaseSelection.prototype.bind = function (container, $container) {\n    var self = this;\n\n    var id = container.id + '-container';\n    var resultsId = container.id + '-results';\n\n    this.container = container;\n\n    this.$selection.on('focus', function (evt) {\n      self.trigger('focus', evt);\n    });\n\n    this.$selection.on('blur', function (evt) {\n      self._handleBlur(evt);\n    });\n\n    this.$selection.on('keydown', function (evt) {\n      self.trigger('keypress', evt);\n\n      if (evt.which === KEYS.SPACE) {\n        evt.preventDefault();\n      }\n    });\n\n    container.on('results:focus', function (params) {\n      self.$selection.attr('aria-activedescendant', params.data._resultId);\n    });\n\n    container.on('selection:update', function (params) {\n      self.update(params.data);\n    });\n\n    container.on('open', function () {\n      // When the dropdown is open, aria-expanded=\"true\"\n      self.$selection.attr('aria-expanded', 'true');\n      self.$selection.attr('aria-owns', resultsId);\n\n      self._attachCloseHandler(container);\n    });\n\n    container.on('close', function () {\n      // When the dropdown is closed, aria-expanded=\"false\"\n      self.$selection.attr('aria-expanded', 'false');\n      self.$selection.removeAttr('aria-activedescendant');\n      self.$selection.removeAttr('aria-owns');\n\n      self.$selection.focus();\n\n      self._detachCloseHandler(container);\n    });\n\n    container.on('enable', function () {\n      self.$selection.attr('tabindex', self._tabindex);\n    });\n\n    container.on('disable', function () {\n      self.$selection.attr('tabindex', '-1');\n    });\n  };\n\n  BaseSelection.prototype._handleBlur = function (evt) {\n    var self = this;\n\n    // This needs to be delayed as the active element is the body when the tab\n    // key is pressed, possibly along with others.\n    window.setTimeout(function () {\n      // Don't trigger `blur` if the focus is still in the selection\n      if (\n        (document.activeElement == self.$selection[0]) ||\n        ($.contains(self.$selection[0], document.activeElement))\n      ) {\n        return;\n      }\n\n      self.trigger('blur', evt);\n    }, 1);\n  };\n\n  BaseSelection.prototype._attachCloseHandler = function (container) {\n    var self = this;\n\n    $(document.body).on('mousedown.select2.' + container.id, function (e) {\n      var $target = $(e.target);\n\n      var $select = $target.closest('.select2');\n\n      var $all = $('.select2.select2-container--open');\n\n      $all.each(function () {\n        var $this = $(this);\n\n        if (this == $select[0]) {\n          return;\n        }\n\n        var $element = $this.data('element');\n\n        $element.select2('close');\n      });\n    });\n  };\n\n  BaseSelection.prototype._detachCloseHandler = function (container) {\n    $(document.body).off('mousedown.select2.' + container.id);\n  };\n\n  BaseSelection.prototype.position = function ($selection, $container) {\n    var $selectionContainer = $container.find('.selection');\n    $selectionContainer.append($selection);\n  };\n\n  BaseSelection.prototype.destroy = function () {\n    this._detachCloseHandler(this.container);\n  };\n\n  BaseSelection.prototype.update = function (data) {\n    throw new Error('The `update` method must be defined in child classes.');\n  };\n\n  return BaseSelection;\n});\n\nS2.define('select2/selection/single',[\n  'jquery',\n  './base',\n  '../utils',\n  '../keys'\n], function ($, BaseSelection, Utils, KEYS) {\n  function SingleSelection () {\n    SingleSelection.__super__.constructor.apply(this, arguments);\n  }\n\n  Utils.Extend(SingleSelection, BaseSelection);\n\n  SingleSelection.prototype.render = function () {\n    var $selection = SingleSelection.__super__.render.call(this);\n\n    $selection.addClass('select2-selection--single');\n\n    $selection.html(\n      '<span class=\"select2-selection__rendered\"></span>' +\n      '<span class=\"select2-selection__arrow\" role=\"presentation\">' +\n        '<b role=\"presentation\"></b>' +\n      '</span>'\n    );\n\n    return $selection;\n  };\n\n  SingleSelection.prototype.bind = function (container, $container) {\n    var self = this;\n\n    SingleSelection.__super__.bind.apply(this, arguments);\n\n    var id = container.id + '-container';\n\n    this.$selection.find('.select2-selection__rendered').attr('id', id);\n    this.$selection.attr('aria-labelledby', id);\n\n    this.$selection.on('mousedown', function (evt) {\n      // Only respond to left clicks\n      if (evt.which !== 1) {\n        return;\n      }\n\n      self.trigger('toggle', {\n        originalEvent: evt\n      });\n    });\n\n    this.$selection.on('focus', function (evt) {\n      // User focuses on the container\n    });\n\n    this.$selection.on('blur', function (evt) {\n      // User exits the container\n    });\n\n    container.on('focus', function (evt) {\n      if (!container.isOpen()) {\n        self.$selection.focus();\n      }\n    });\n\n    container.on('selection:update', function (params) {\n      self.update(params.data);\n    });\n  };\n\n  SingleSelection.prototype.clear = function () {\n    this.$selection.find('.select2-selection__rendered').empty();\n  };\n\n  SingleSelection.prototype.display = function (data, container) {\n    var template = this.options.get('templateSelection');\n    var escapeMarkup = this.options.get('escapeMarkup');\n\n    return escapeMarkup(template(data, container));\n  };\n\n  SingleSelection.prototype.selectionContainer = function () {\n    return $('<span></span>');\n  };\n\n  SingleSelection.prototype.update = function (data) {\n    if (data.length === 0) {\n      this.clear();\n      return;\n    }\n\n    var selection = data[0];\n\n    var $rendered = this.$selection.find('.select2-selection__rendered');\n    var formatted = this.display(selection, $rendered);\n\n    $rendered.empty().append(formatted);\n    $rendered.prop('title', selection.title || selection.text);\n  };\n\n  return SingleSelection;\n});\n\nS2.define('select2/selection/multiple',[\n  'jquery',\n  './base',\n  '../utils'\n], function ($, BaseSelection, Utils) {\n  function MultipleSelection ($element, options) {\n    MultipleSelection.__super__.constructor.apply(this, arguments);\n  }\n\n  Utils.Extend(MultipleSelection, BaseSelection);\n\n  MultipleSelection.prototype.render = function () {\n    var $selection = MultipleSelection.__super__.render.call(this);\n\n    $selection.addClass('select2-selection--multiple');\n\n    $selection.html(\n      '<ul class=\"select2-selection__rendered\"></ul>'\n    );\n\n    return $selection;\n  };\n\n  MultipleSelection.prototype.bind = function (container, $container) {\n    var self = this;\n\n    MultipleSelection.__super__.bind.apply(this, arguments);\n\n    this.$selection.on('click', function (evt) {\n      self.trigger('toggle', {\n        originalEvent: evt\n      });\n    });\n\n    this.$selection.on(\n      'click',\n      '.select2-selection__choice__remove',\n      function (evt) {\n        // Ignore the event if it is disabled\n        if (self.options.get('disabled')) {\n          return;\n        }\n\n        var $remove = $(this);\n        var $selection = $remove.parent();\n\n        var data = $selection.data('data');\n\n        self.trigger('unselect', {\n          originalEvent: evt,\n          data: data\n        });\n      }\n    );\n  };\n\n  MultipleSelection.prototype.clear = function () {\n    this.$selection.find('.select2-selection__rendered').empty();\n  };\n\n  MultipleSelection.prototype.display = function (data, container) {\n    var template = this.options.get('templateSelection');\n    var escapeMarkup = this.options.get('escapeMarkup');\n\n    return escapeMarkup(template(data, container));\n  };\n\n  MultipleSelection.prototype.selectionContainer = function () {\n    var $container = $(\n      '<li class=\"select2-selection__choice\">' +\n        '<span class=\"select2-selection__choice__remove\" role=\"presentation\">' +\n          '&times;' +\n        '</span>' +\n      '</li>'\n    );\n\n    return $container;\n  };\n\n  MultipleSelection.prototype.update = function (data) {\n    this.clear();\n\n    if (data.length === 0) {\n      return;\n    }\n\n    var $selections = [];\n\n    for (var d = 0; d < data.length; d++) {\n      var selection = data[d];\n\n      var $selection = this.selectionContainer();\n      var formatted = this.display(selection, $selection);\n\n      $selection.append(formatted);\n      $selection.prop('title', selection.title || selection.text);\n\n      $selection.data('data', selection);\n\n      $selections.push($selection);\n    }\n\n    var $rendered = this.$selection.find('.select2-selection__rendered');\n\n    Utils.appendMany($rendered, $selections);\n  };\n\n  return MultipleSelection;\n});\n\nS2.define('select2/selection/placeholder',[\n  '../utils'\n], function (Utils) {\n  function Placeholder (decorated, $element, options) {\n    this.placeholder = this.normalizePlaceholder(options.get('placeholder'));\n\n    decorated.call(this, $element, options);\n  }\n\n  Placeholder.prototype.normalizePlaceholder = function (_, placeholder) {\n    if (typeof placeholder === 'string') {\n      placeholder = {\n        id: '',\n        text: placeholder\n      };\n    }\n\n    return placeholder;\n  };\n\n  Placeholder.prototype.createPlaceholder = function (decorated, placeholder) {\n    var $placeholder = this.selectionContainer();\n\n    $placeholder.html(this.display(placeholder));\n    $placeholder.addClass('select2-selection__placeholder')\n                .removeClass('select2-selection__choice');\n\n    return $placeholder;\n  };\n\n  Placeholder.prototype.update = function (decorated, data) {\n    var singlePlaceholder = (\n      data.length == 1 && data[0].id != this.placeholder.id\n    );\n    var multipleSelections = data.length > 1;\n\n    if (multipleSelections || singlePlaceholder) {\n      return decorated.call(this, data);\n    }\n\n    this.clear();\n\n    var $placeholder = this.createPlaceholder(this.placeholder);\n\n    this.$selection.find('.select2-selection__rendered').append($placeholder);\n  };\n\n  return Placeholder;\n});\n\nS2.define('select2/selection/allowClear',[\n  'jquery',\n  '../keys'\n], function ($, KEYS) {\n  function AllowClear () { }\n\n  AllowClear.prototype.bind = function (decorated, container, $container) {\n    var self = this;\n\n    decorated.call(this, container, $container);\n\n    if (this.placeholder == null) {\n      if (this.options.get('debug') && window.console && console.error) {\n        console.error(\n          'Select2: The `allowClear` option should be used in combination ' +\n          'with the `placeholder` option.'\n        );\n      }\n    }\n\n    this.$selection.on('mousedown', '.select2-selection__clear',\n      function (evt) {\n        self._handleClear(evt);\n    });\n\n    container.on('keypress', function (evt) {\n      self._handleKeyboardClear(evt, container);\n    });\n  };\n\n  AllowClear.prototype._handleClear = function (_, evt) {\n    // Ignore the event if it is disabled\n    if (this.options.get('disabled')) {\n      return;\n    }\n\n    var $clear = this.$selection.find('.select2-selection__clear');\n\n    // Ignore the event if nothing has been selected\n    if ($clear.length === 0) {\n      return;\n    }\n\n    evt.stopPropagation();\n\n    var data = $clear.data('data');\n\n    for (var d = 0; d < data.length; d++) {\n      var unselectData = {\n        data: data[d]\n      };\n\n      // Trigger the `unselect` event, so people can prevent it from being\n      // cleared.\n      this.trigger('unselect', unselectData);\n\n      // If the event was prevented, don't clear it out.\n      if (unselectData.prevented) {\n        return;\n      }\n    }\n\n    this.$element.val(this.placeholder.id).trigger('change');\n\n    this.trigger('toggle', {});\n  };\n\n  AllowClear.prototype._handleKeyboardClear = function (_, evt, container) {\n    if (container.isOpen()) {\n      return;\n    }\n\n    if (evt.which == KEYS.DELETE || evt.which == KEYS.BACKSPACE) {\n      this._handleClear(evt);\n    }\n  };\n\n  AllowClear.prototype.update = function (decorated, data) {\n    decorated.call(this, data);\n\n    if (this.$selection.find('.select2-selection__placeholder').length > 0 ||\n        data.length === 0) {\n      return;\n    }\n\n    var $remove = $(\n      '<span class=\"select2-selection__clear\">' +\n        '&times;' +\n      '</span>'\n    );\n    $remove.data('data', data);\n\n    this.$selection.find('.select2-selection__rendered').prepend($remove);\n  };\n\n  return AllowClear;\n});\n\nS2.define('select2/selection/search',[\n  'jquery',\n  '../utils',\n  '../keys'\n], function ($, Utils, KEYS) {\n  function Search (decorated, $element, options) {\n    decorated.call(this, $element, options);\n  }\n\n  Search.prototype.render = function (decorated) {\n    var $search = $(\n      '<li class=\"select2-search select2-search--inline\">' +\n        '<input class=\"select2-search__field\" type=\"search\" tabindex=\"-1\"' +\n        ' autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\"' +\n        ' spellcheck=\"false\" role=\"textbox\" aria-autocomplete=\"list\" />' +\n      '</li>'\n    );\n\n    this.$searchContainer = $search;\n    this.$search = $search.find('input');\n\n    var $rendered = decorated.call(this);\n\n    this._transferTabIndex();\n\n    return $rendered;\n  };\n\n  Search.prototype.bind = function (decorated, container, $container) {\n    var self = this;\n\n    decorated.call(this, container, $container);\n\n    container.on('open', function () {\n      self.$search.trigger('focus');\n    });\n\n    container.on('close', function () {\n      self.$search.val('');\n      self.$search.removeAttr('aria-activedescendant');\n      self.$search.trigger('focus');\n    });\n\n    container.on('enable', function () {\n      self.$search.prop('disabled', false);\n\n      self._transferTabIndex();\n    });\n\n    container.on('disable', function () {\n      self.$search.prop('disabled', true);\n    });\n\n    container.on('focus', function (evt) {\n      self.$search.trigger('focus');\n    });\n\n    container.on('results:focus', function (params) {\n      self.$search.attr('aria-activedescendant', params.id);\n    });\n\n    this.$selection.on('focusin', '.select2-search--inline', function (evt) {\n      self.trigger('focus', evt);\n    });\n\n    this.$selection.on('focusout', '.select2-search--inline', function (evt) {\n      self._handleBlur(evt);\n    });\n\n    this.$selection.on('keydown', '.select2-search--inline', function (evt) {\n      evt.stopPropagation();\n\n      self.trigger('keypress', evt);\n\n      self._keyUpPrevented = evt.isDefaultPrevented();\n\n      var key = evt.which;\n\n      if (key === KEYS.BACKSPACE && self.$search.val() === '') {\n        var $previousChoice = self.$searchContainer\n          .prev('.select2-selection__choice');\n\n        if ($previousChoice.length > 0) {\n          var item = $previousChoice.data('data');\n\n          self.searchRemoveChoice(item);\n\n          evt.preventDefault();\n        }\n      }\n    });\n\n    // Try to detect the IE version should the `documentMode` property that\n    // is stored on the document. This is only implemented in IE and is\n    // slightly cleaner than doing a user agent check.\n    // This property is not available in Edge, but Edge also doesn't have\n    // this bug.\n    var msie = document.documentMode;\n    var disableInputEvents = msie && msie <= 11;\n\n    // Workaround for browsers which do not support the `input` event\n    // This will prevent double-triggering of events for browsers which support\n    // both the `keyup` and `input` events.\n    this.$selection.on(\n      'input.searchcheck',\n      '.select2-search--inline',\n      function (evt) {\n        // IE will trigger the `input` event when a placeholder is used on a\n        // search box. To get around this issue, we are forced to ignore all\n        // `input` events in IE and keep using `keyup`.\n        if (disableInputEvents) {\n          self.$selection.off('input.search input.searchcheck');\n          return;\n        }\n\n        // Unbind the duplicated `keyup` event\n        self.$selection.off('keyup.search');\n      }\n    );\n\n    this.$selection.on(\n      'keyup.search input.search',\n      '.select2-search--inline',\n      function (evt) {\n        // IE will trigger the `input` event when a placeholder is used on a\n        // search box. To get around this issue, we are forced to ignore all\n        // `input` events in IE and keep using `keyup`.\n        if (disableInputEvents && evt.type === 'input') {\n          self.$selection.off('input.search input.searchcheck');\n          return;\n        }\n\n        var key = evt.which;\n\n        // We can freely ignore events from modifier keys\n        if (key == KEYS.SHIFT || key == KEYS.CTRL || key == KEYS.ALT) {\n          return;\n        }\n\n        // Tabbing will be handled during the `keydown` phase\n        if (key == KEYS.TAB) {\n          return;\n        }\n\n        self.handleSearch(evt);\n      }\n    );\n  };\n\n  /**\n   * This method will transfer the tabindex attribute from the rendered\n   * selection to the search box. This allows for the search box to be used as\n   * the primary focus instead of the selection container.\n   *\n   * @private\n   */\n  Search.prototype._transferTabIndex = function (decorated) {\n    this.$search.attr('tabindex', this.$selection.attr('tabindex'));\n    this.$selection.attr('tabindex', '-1');\n  };\n\n  Search.prototype.createPlaceholder = function (decorated, placeholder) {\n    this.$search.attr('placeholder', placeholder.text);\n  };\n\n  Search.prototype.update = function (decorated, data) {\n    var searchHadFocus = this.$search[0] == document.activeElement;\n\n    this.$search.attr('placeholder', '');\n\n    decorated.call(this, data);\n\n    this.$selection.find('.select2-selection__rendered')\n                   .append(this.$searchContainer);\n\n    this.resizeSearch();\n    if (searchHadFocus) {\n      this.$search.focus();\n    }\n  };\n\n  Search.prototype.handleSearch = function () {\n    this.resizeSearch();\n\n    if (!this._keyUpPrevented) {\n      var input = this.$search.val();\n\n      this.trigger('query', {\n        term: input\n      });\n    }\n\n    this._keyUpPrevented = false;\n  };\n\n  Search.prototype.searchRemoveChoice = function (decorated, item) {\n    this.trigger('unselect', {\n      data: item\n    });\n\n    this.$search.val(item.text);\n    this.handleSearch();\n  };\n\n  Search.prototype.resizeSearch = function () {\n    this.$search.css('width', '25px');\n\n    var width = '';\n\n    if (this.$search.attr('placeholder') !== '') {\n      width = this.$selection.find('.select2-selection__rendered').innerWidth();\n    } else {\n      var minimumWidth = this.$search.val().length + 1;\n\n      width = (minimumWidth * 0.75) + 'em';\n    }\n\n    this.$search.css('width', width);\n  };\n\n  return Search;\n});\n\nS2.define('select2/selection/eventRelay',[\n  'jquery'\n], function ($) {\n  function EventRelay () { }\n\n  EventRelay.prototype.bind = function (decorated, container, $container) {\n    var self = this;\n    var relayEvents = [\n      'open', 'opening',\n      'close', 'closing',\n      'select', 'selecting',\n      'unselect', 'unselecting'\n    ];\n\n    var preventableEvents = ['opening', 'closing', 'selecting', 'unselecting'];\n\n    decorated.call(this, container, $container);\n\n    container.on('*', function (name, params) {\n      // Ignore events that should not be relayed\n      if ($.inArray(name, relayEvents) === -1) {\n        return;\n      }\n\n      // The parameters should always be an object\n      params = params || {};\n\n      // Generate the jQuery event for the Select2 event\n      var evt = $.Event('select2:' + name, {\n        params: params\n      });\n\n      self.$element.trigger(evt);\n\n      // Only handle preventable events if it was one\n      if ($.inArray(name, preventableEvents) === -1) {\n        return;\n      }\n\n      params.prevented = evt.isDefaultPrevented();\n    });\n  };\n\n  return EventRelay;\n});\n\nS2.define('select2/translation',[\n  'jquery',\n  'require'\n], function ($, require) {\n  function Translation (dict) {\n    this.dict = dict || {};\n  }\n\n  Translation.prototype.all = function () {\n    return this.dict;\n  };\n\n  Translation.prototype.get = function (key) {\n    return this.dict[key];\n  };\n\n  Translation.prototype.extend = function (translation) {\n    this.dict = $.extend({}, translation.all(), this.dict);\n  };\n\n  // Static functions\n\n  Translation._cache = {};\n\n  Translation.loadPath = function (path) {\n    if (!(path in Translation._cache)) {\n      var translations = require(path);\n\n      Translation._cache[path] = translations;\n    }\n\n    return new Translation(Translation._cache[path]);\n  };\n\n  return Translation;\n});\n\nS2.define('select2/diacritics',[\n\n], function () {\n  var diacritics = {\n    '\\u24B6': 'A',\n    '\\uFF21': 'A',\n    '\\u00C0': 'A',\n    '\\u00C1': 'A',\n    '\\u00C2': 'A',\n    '\\u1EA6': 'A',\n    '\\u1EA4': 'A',\n    '\\u1EAA': 'A',\n    '\\u1EA8': 'A',\n    '\\u00C3': 'A',\n    '\\u0100': 'A',\n    '\\u0102': 'A',\n    '\\u1EB0': 'A',\n    '\\u1EAE': 'A',\n    '\\u1EB4': 'A',\n    '\\u1EB2': 'A',\n    '\\u0226': 'A',\n    '\\u01E0': 'A',\n    '\\u00C4': 'A',\n    '\\u01DE': 'A',\n    '\\u1EA2': 'A',\n    '\\u00C5': 'A',\n    '\\u01FA': 'A',\n    '\\u01CD': 'A',\n    '\\u0200': 'A',\n    '\\u0202': 'A',\n    '\\u1EA0': 'A',\n    '\\u1EAC': 'A',\n    '\\u1EB6': 'A',\n    '\\u1E00': 'A',\n    '\\u0104': 'A',\n    '\\u023A': 'A',\n    '\\u2C6F': 'A',\n    '\\uA732': 'AA',\n    '\\u00C6': 'AE',\n    '\\u01FC': 'AE',\n    '\\u01E2': 'AE',\n    '\\uA734': 'AO',\n    '\\uA736': 'AU',\n    '\\uA738': 'AV',\n    '\\uA73A': 'AV',\n    '\\uA73C': 'AY',\n    '\\u24B7': 'B',\n    '\\uFF22': 'B',\n    '\\u1E02': 'B',\n    '\\u1E04': 'B',\n    '\\u1E06': 'B',\n    '\\u0243': 'B',\n    '\\u0182': 'B',\n    '\\u0181': 'B',\n    '\\u24B8': 'C',\n    '\\uFF23': 'C',\n    '\\u0106': 'C',\n    '\\u0108': 'C',\n    '\\u010A': 'C',\n    '\\u010C': 'C',\n    '\\u00C7': 'C',\n    '\\u1E08': 'C',\n    '\\u0187': 'C',\n    '\\u023B': 'C',\n    '\\uA73E': 'C',\n    '\\u24B9': 'D',\n    '\\uFF24': 'D',\n    '\\u1E0A': 'D',\n    '\\u010E': 'D',\n    '\\u1E0C': 'D',\n    '\\u1E10': 'D',\n    '\\u1E12': 'D',\n    '\\u1E0E': 'D',\n    '\\u0110': 'D',\n    '\\u018B': 'D',\n    '\\u018A': 'D',\n    '\\u0189': 'D',\n    '\\uA779': 'D',\n    '\\u01F1': 'DZ',\n    '\\u01C4': 'DZ',\n    '\\u01F2': 'Dz',\n    '\\u01C5': 'Dz',\n    '\\u24BA': 'E',\n    '\\uFF25': 'E',\n    '\\u00C8': 'E',\n    '\\u00C9': 'E',\n    '\\u00CA': 'E',\n    '\\u1EC0': 'E',\n    '\\u1EBE': 'E',\n    '\\u1EC4': 'E',\n    '\\u1EC2': 'E',\n    '\\u1EBC': 'E',\n    '\\u0112': 'E',\n    '\\u1E14': 'E',\n    '\\u1E16': 'E',\n    '\\u0114': 'E',\n    '\\u0116': 'E',\n    '\\u00CB': 'E',\n    '\\u1EBA': 'E',\n    '\\u011A': 'E',\n    '\\u0204': 'E',\n    '\\u0206': 'E',\n    '\\u1EB8': 'E',\n    '\\u1EC6': 'E',\n    '\\u0228': 'E',\n    '\\u1E1C': 'E',\n    '\\u0118': 'E',\n    '\\u1E18': 'E',\n    '\\u1E1A': 'E',\n    '\\u0190': 'E',\n    '\\u018E': 'E',\n    '\\u24BB': 'F',\n    '\\uFF26': 'F',\n    '\\u1E1E': 'F',\n    '\\u0191': 'F',\n    '\\uA77B': 'F',\n    '\\u24BC': 'G',\n    '\\uFF27': 'G',\n    '\\u01F4': 'G',\n    '\\u011C': 'G',\n    '\\u1E20': 'G',\n    '\\u011E': 'G',\n    '\\u0120': 'G',\n    '\\u01E6': 'G',\n    '\\u0122': 'G',\n    '\\u01E4': 'G',\n    '\\u0193': 'G',\n    '\\uA7A0': 'G',\n    '\\uA77D': 'G',\n    '\\uA77E': 'G',\n    '\\u24BD': 'H',\n    '\\uFF28': 'H',\n    '\\u0124': 'H',\n    '\\u1E22': 'H',\n    '\\u1E26': 'H',\n    '\\u021E': 'H',\n    '\\u1E24': 'H',\n    '\\u1E28': 'H',\n    '\\u1E2A': 'H',\n    '\\u0126': 'H',\n    '\\u2C67': 'H',\n    '\\u2C75': 'H',\n    '\\uA78D': 'H',\n    '\\u24BE': 'I',\n    '\\uFF29': 'I',\n    '\\u00CC': 'I',\n    '\\u00CD': 'I',\n    '\\u00CE': 'I',\n    '\\u0128': 'I',\n    '\\u012A': 'I',\n    '\\u012C': 'I',\n    '\\u0130': 'I',\n    '\\u00CF': 'I',\n    '\\u1E2E': 'I',\n    '\\u1EC8': 'I',\n    '\\u01CF': 'I',\n    '\\u0208': 'I',\n    '\\u020A': 'I',\n    '\\u1ECA': 'I',\n    '\\u012E': 'I',\n    '\\u1E2C': 'I',\n    '\\u0197': 'I',\n    '\\u24BF': 'J',\n    '\\uFF2A': 'J',\n    '\\u0134': 'J',\n    '\\u0248': 'J',\n    '\\u24C0': 'K',\n    '\\uFF2B': 'K',\n    '\\u1E30': 'K',\n    '\\u01E8': 'K',\n    '\\u1E32': 'K',\n    '\\u0136': 'K',\n    '\\u1E34': 'K',\n    '\\u0198': 'K',\n    '\\u2C69': 'K',\n    '\\uA740': 'K',\n    '\\uA742': 'K',\n    '\\uA744': 'K',\n    '\\uA7A2': 'K',\n    '\\u24C1': 'L',\n    '\\uFF2C': 'L',\n    '\\u013F': 'L',\n    '\\u0139': 'L',\n    '\\u013D': 'L',\n    '\\u1E36': 'L',\n    '\\u1E38': 'L',\n    '\\u013B': 'L',\n    '\\u1E3C': 'L',\n    '\\u1E3A': 'L',\n    '\\u0141': 'L',\n    '\\u023D': 'L',\n    '\\u2C62': 'L',\n    '\\u2C60': 'L',\n    '\\uA748': 'L',\n    '\\uA746': 'L',\n    '\\uA780': 'L',\n    '\\u01C7': 'LJ',\n    '\\u01C8': 'Lj',\n    '\\u24C2': 'M',\n    '\\uFF2D': 'M',\n    '\\u1E3E': 'M',\n    '\\u1E40': 'M',\n    '\\u1E42': 'M',\n    '\\u2C6E': 'M',\n    '\\u019C': 'M',\n    '\\u24C3': 'N',\n    '\\uFF2E': 'N',\n    '\\u01F8': 'N',\n    '\\u0143': 'N',\n    '\\u00D1': 'N',\n    '\\u1E44': 'N',\n    '\\u0147': 'N',\n    '\\u1E46': 'N',\n    '\\u0145': 'N',\n    '\\u1E4A': 'N',\n    '\\u1E48': 'N',\n    '\\u0220': 'N',\n    '\\u019D': 'N',\n    '\\uA790': 'N',\n    '\\uA7A4': 'N',\n    '\\u01CA': 'NJ',\n    '\\u01CB': 'Nj',\n    '\\u24C4': 'O',\n    '\\uFF2F': 'O',\n    '\\u00D2': 'O',\n    '\\u00D3': 'O',\n    '\\u00D4': 'O',\n    '\\u1ED2': 'O',\n    '\\u1ED0': 'O',\n    '\\u1ED6': 'O',\n    '\\u1ED4': 'O',\n    '\\u00D5': 'O',\n    '\\u1E4C': 'O',\n    '\\u022C': 'O',\n    '\\u1E4E': 'O',\n    '\\u014C': 'O',\n    '\\u1E50': 'O',\n    '\\u1E52': 'O',\n    '\\u014E': 'O',\n    '\\u022E': 'O',\n    '\\u0230': 'O',\n    '\\u00D6': 'O',\n    '\\u022A': 'O',\n    '\\u1ECE': 'O',\n    '\\u0150': 'O',\n    '\\u01D1': 'O',\n    '\\u020C': 'O',\n    '\\u020E': 'O',\n    '\\u01A0': 'O',\n    '\\u1EDC': 'O',\n    '\\u1EDA': 'O',\n    '\\u1EE0': 'O',\n    '\\u1EDE': 'O',\n    '\\u1EE2': 'O',\n    '\\u1ECC': 'O',\n    '\\u1ED8': 'O',\n    '\\u01EA': 'O',\n    '\\u01EC': 'O',\n    '\\u00D8': 'O',\n    '\\u01FE': 'O',\n    '\\u0186': 'O',\n    '\\u019F': 'O',\n    '\\uA74A': 'O',\n    '\\uA74C': 'O',\n    '\\u01A2': 'OI',\n    '\\uA74E': 'OO',\n    '\\u0222': 'OU',\n    '\\u24C5': 'P',\n    '\\uFF30': 'P',\n    '\\u1E54': 'P',\n    '\\u1E56': 'P',\n    '\\u01A4': 'P',\n    '\\u2C63': 'P',\n    '\\uA750': 'P',\n    '\\uA752': 'P',\n    '\\uA754': 'P',\n    '\\u24C6': 'Q',\n    '\\uFF31': 'Q',\n    '\\uA756': 'Q',\n    '\\uA758': 'Q',\n    '\\u024A': 'Q',\n    '\\u24C7': 'R',\n    '\\uFF32': 'R',\n    '\\u0154': 'R',\n    '\\u1E58': 'R',\n    '\\u0158': 'R',\n    '\\u0210': 'R',\n    '\\u0212': 'R',\n    '\\u1E5A': 'R',\n    '\\u1E5C': 'R',\n    '\\u0156': 'R',\n    '\\u1E5E': 'R',\n    '\\u024C': 'R',\n    '\\u2C64': 'R',\n    '\\uA75A': 'R',\n    '\\uA7A6': 'R',\n    '\\uA782': 'R',\n    '\\u24C8': 'S',\n    '\\uFF33': 'S',\n    '\\u1E9E': 'S',\n    '\\u015A': 'S',\n    '\\u1E64': 'S',\n    '\\u015C': 'S',\n    '\\u1E60': 'S',\n    '\\u0160': 'S',\n    '\\u1E66': 'S',\n    '\\u1E62': 'S',\n    '\\u1E68': 'S',\n    '\\u0218': 'S',\n    '\\u015E': 'S',\n    '\\u2C7E': 'S',\n    '\\uA7A8': 'S',\n    '\\uA784': 'S',\n    '\\u24C9': 'T',\n    '\\uFF34': 'T',\n    '\\u1E6A': 'T',\n    '\\u0164': 'T',\n    '\\u1E6C': 'T',\n    '\\u021A': 'T',\n    '\\u0162': 'T',\n    '\\u1E70': 'T',\n    '\\u1E6E': 'T',\n    '\\u0166': 'T',\n    '\\u01AC': 'T',\n    '\\u01AE': 'T',\n    '\\u023E': 'T',\n    '\\uA786': 'T',\n    '\\uA728': 'TZ',\n    '\\u24CA': 'U',\n    '\\uFF35': 'U',\n    '\\u00D9': 'U',\n    '\\u00DA': 'U',\n    '\\u00DB': 'U',\n    '\\u0168': 'U',\n    '\\u1E78': 'U',\n    '\\u016A': 'U',\n    '\\u1E7A': 'U',\n    '\\u016C': 'U',\n    '\\u00DC': 'U',\n    '\\u01DB': 'U',\n    '\\u01D7': 'U',\n    '\\u01D5': 'U',\n    '\\u01D9': 'U',\n    '\\u1EE6': 'U',\n    '\\u016E': 'U',\n    '\\u0170': 'U',\n    '\\u01D3': 'U',\n    '\\u0214': 'U',\n    '\\u0216': 'U',\n    '\\u01AF': 'U',\n    '\\u1EEA': 'U',\n    '\\u1EE8': 'U',\n    '\\u1EEE': 'U',\n    '\\u1EEC': 'U',\n    '\\u1EF0': 'U',\n    '\\u1EE4': 'U',\n    '\\u1E72': 'U',\n    '\\u0172': 'U',\n    '\\u1E76': 'U',\n    '\\u1E74': 'U',\n    '\\u0244': 'U',\n    '\\u24CB': 'V',\n    '\\uFF36': 'V',\n    '\\u1E7C': 'V',\n    '\\u1E7E': 'V',\n    '\\u01B2': 'V',\n    '\\uA75E': 'V',\n    '\\u0245': 'V',\n    '\\uA760': 'VY',\n    '\\u24CC': 'W',\n    '\\uFF37': 'W',\n    '\\u1E80': 'W',\n    '\\u1E82': 'W',\n    '\\u0174': 'W',\n    '\\u1E86': 'W',\n    '\\u1E84': 'W',\n    '\\u1E88': 'W',\n    '\\u2C72': 'W',\n    '\\u24CD': 'X',\n    '\\uFF38': 'X',\n    '\\u1E8A': 'X',\n    '\\u1E8C': 'X',\n    '\\u24CE': 'Y',\n    '\\uFF39': 'Y',\n    '\\u1EF2': 'Y',\n    '\\u00DD': 'Y',\n    '\\u0176': 'Y',\n    '\\u1EF8': 'Y',\n    '\\u0232': 'Y',\n    '\\u1E8E': 'Y',\n    '\\u0178': 'Y',\n    '\\u1EF6': 'Y',\n    '\\u1EF4': 'Y',\n    '\\u01B3': 'Y',\n    '\\u024E': 'Y',\n    '\\u1EFE': 'Y',\n    '\\u24CF': 'Z',\n    '\\uFF3A': 'Z',\n    '\\u0179': 'Z',\n    '\\u1E90': 'Z',\n    '\\u017B': 'Z',\n    '\\u017D': 'Z',\n    '\\u1E92': 'Z',\n    '\\u1E94': 'Z',\n    '\\u01B5': 'Z',\n    '\\u0224': 'Z',\n    '\\u2C7F': 'Z',\n    '\\u2C6B': 'Z',\n    '\\uA762': 'Z',\n    '\\u24D0': 'a',\n    '\\uFF41': 'a',\n    '\\u1E9A': 'a',\n    '\\u00E0': 'a',\n    '\\u00E1': 'a',\n    '\\u00E2': 'a',\n    '\\u1EA7': 'a',\n    '\\u1EA5': 'a',\n    '\\u1EAB': 'a',\n    '\\u1EA9': 'a',\n    '\\u00E3': 'a',\n    '\\u0101': 'a',\n    '\\u0103': 'a',\n    '\\u1EB1': 'a',\n    '\\u1EAF': 'a',\n    '\\u1EB5': 'a',\n    '\\u1EB3': 'a',\n    '\\u0227': 'a',\n    '\\u01E1': 'a',\n    '\\u00E4': 'a',\n    '\\u01DF': 'a',\n    '\\u1EA3': 'a',\n    '\\u00E5': 'a',\n    '\\u01FB': 'a',\n    '\\u01CE': 'a',\n    '\\u0201': 'a',\n    '\\u0203': 'a',\n    '\\u1EA1': 'a',\n    '\\u1EAD': 'a',\n    '\\u1EB7': 'a',\n    '\\u1E01': 'a',\n    '\\u0105': 'a',\n    '\\u2C65': 'a',\n    '\\u0250': 'a',\n    '\\uA733': 'aa',\n    '\\u00E6': 'ae',\n    '\\u01FD': 'ae',\n    '\\u01E3': 'ae',\n    '\\uA735': 'ao',\n    '\\uA737': 'au',\n    '\\uA739': 'av',\n    '\\uA73B': 'av',\n    '\\uA73D': 'ay',\n    '\\u24D1': 'b',\n    '\\uFF42': 'b',\n    '\\u1E03': 'b',\n    '\\u1E05': 'b',\n    '\\u1E07': 'b',\n    '\\u0180': 'b',\n    '\\u0183': 'b',\n    '\\u0253': 'b',\n    '\\u24D2': 'c',\n    '\\uFF43': 'c',\n    '\\u0107': 'c',\n    '\\u0109': 'c',\n    '\\u010B': 'c',\n    '\\u010D': 'c',\n    '\\u00E7': 'c',\n    '\\u1E09': 'c',\n    '\\u0188': 'c',\n    '\\u023C': 'c',\n    '\\uA73F': 'c',\n    '\\u2184': 'c',\n    '\\u24D3': 'd',\n    '\\uFF44': 'd',\n    '\\u1E0B': 'd',\n    '\\u010F': 'd',\n    '\\u1E0D': 'd',\n    '\\u1E11': 'd',\n    '\\u1E13': 'd',\n    '\\u1E0F': 'd',\n    '\\u0111': 'd',\n    '\\u018C': 'd',\n    '\\u0256': 'd',\n    '\\u0257': 'd',\n    '\\uA77A': 'd',\n    '\\u01F3': 'dz',\n    '\\u01C6': 'dz',\n    '\\u24D4': 'e',\n    '\\uFF45': 'e',\n    '\\u00E8': 'e',\n    '\\u00E9': 'e',\n    '\\u00EA': 'e',\n    '\\u1EC1': 'e',\n    '\\u1EBF': 'e',\n    '\\u1EC5': 'e',\n    '\\u1EC3': 'e',\n    '\\u1EBD': 'e',\n    '\\u0113': 'e',\n    '\\u1E15': 'e',\n    '\\u1E17': 'e',\n    '\\u0115': 'e',\n    '\\u0117': 'e',\n    '\\u00EB': 'e',\n    '\\u1EBB': 'e',\n    '\\u011B': 'e',\n    '\\u0205': 'e',\n    '\\u0207': 'e',\n    '\\u1EB9': 'e',\n    '\\u1EC7': 'e',\n    '\\u0229': 'e',\n    '\\u1E1D': 'e',\n    '\\u0119': 'e',\n    '\\u1E19': 'e',\n    '\\u1E1B': 'e',\n    '\\u0247': 'e',\n    '\\u025B': 'e',\n    '\\u01DD': 'e',\n    '\\u24D5': 'f',\n    '\\uFF46': 'f',\n    '\\u1E1F': 'f',\n    '\\u0192': 'f',\n    '\\uA77C': 'f',\n    '\\u24D6': 'g',\n    '\\uFF47': 'g',\n    '\\u01F5': 'g',\n    '\\u011D': 'g',\n    '\\u1E21': 'g',\n    '\\u011F': 'g',\n    '\\u0121': 'g',\n    '\\u01E7': 'g',\n    '\\u0123': 'g',\n    '\\u01E5': 'g',\n    '\\u0260': 'g',\n    '\\uA7A1': 'g',\n    '\\u1D79': 'g',\n    '\\uA77F': 'g',\n    '\\u24D7': 'h',\n    '\\uFF48': 'h',\n    '\\u0125': 'h',\n    '\\u1E23': 'h',\n    '\\u1E27': 'h',\n    '\\u021F': 'h',\n    '\\u1E25': 'h',\n    '\\u1E29': 'h',\n    '\\u1E2B': 'h',\n    '\\u1E96': 'h',\n    '\\u0127': 'h',\n    '\\u2C68': 'h',\n    '\\u2C76': 'h',\n    '\\u0265': 'h',\n    '\\u0195': 'hv',\n    '\\u24D8': 'i',\n    '\\uFF49': 'i',\n    '\\u00EC': 'i',\n    '\\u00ED': 'i',\n    '\\u00EE': 'i',\n    '\\u0129': 'i',\n    '\\u012B': 'i',\n    '\\u012D': 'i',\n    '\\u00EF': 'i',\n    '\\u1E2F': 'i',\n    '\\u1EC9': 'i',\n    '\\u01D0': 'i',\n    '\\u0209': 'i',\n    '\\u020B': 'i',\n    '\\u1ECB': 'i',\n    '\\u012F': 'i',\n    '\\u1E2D': 'i',\n    '\\u0268': 'i',\n    '\\u0131': 'i',\n    '\\u24D9': 'j',\n    '\\uFF4A': 'j',\n    '\\u0135': 'j',\n    '\\u01F0': 'j',\n    '\\u0249': 'j',\n    '\\u24DA': 'k',\n    '\\uFF4B': 'k',\n    '\\u1E31': 'k',\n    '\\u01E9': 'k',\n    '\\u1E33': 'k',\n    '\\u0137': 'k',\n    '\\u1E35': 'k',\n    '\\u0199': 'k',\n    '\\u2C6A': 'k',\n    '\\uA741': 'k',\n    '\\uA743': 'k',\n    '\\uA745': 'k',\n    '\\uA7A3': 'k',\n    '\\u24DB': 'l',\n    '\\uFF4C': 'l',\n    '\\u0140': 'l',\n    '\\u013A': 'l',\n    '\\u013E': 'l',\n    '\\u1E37': 'l',\n    '\\u1E39': 'l',\n    '\\u013C': 'l',\n    '\\u1E3D': 'l',\n    '\\u1E3B': 'l',\n    '\\u017F': 'l',\n    '\\u0142': 'l',\n    '\\u019A': 'l',\n    '\\u026B': 'l',\n    '\\u2C61': 'l',\n    '\\uA749': 'l',\n    '\\uA781': 'l',\n    '\\uA747': 'l',\n    '\\u01C9': 'lj',\n    '\\u24DC': 'm',\n    '\\uFF4D': 'm',\n    '\\u1E3F': 'm',\n    '\\u1E41': 'm',\n    '\\u1E43': 'm',\n    '\\u0271': 'm',\n    '\\u026F': 'm',\n    '\\u24DD': 'n',\n    '\\uFF4E': 'n',\n    '\\u01F9': 'n',\n    '\\u0144': 'n',\n    '\\u00F1': 'n',\n    '\\u1E45': 'n',\n    '\\u0148': 'n',\n    '\\u1E47': 'n',\n    '\\u0146': 'n',\n    '\\u1E4B': 'n',\n    '\\u1E49': 'n',\n    '\\u019E': 'n',\n    '\\u0272': 'n',\n    '\\u0149': 'n',\n    '\\uA791': 'n',\n    '\\uA7A5': 'n',\n    '\\u01CC': 'nj',\n    '\\u24DE': 'o',\n    '\\uFF4F': 'o',\n    '\\u00F2': 'o',\n    '\\u00F3': 'o',\n    '\\u00F4': 'o',\n    '\\u1ED3': 'o',\n    '\\u1ED1': 'o',\n    '\\u1ED7': 'o',\n    '\\u1ED5': 'o',\n    '\\u00F5': 'o',\n    '\\u1E4D': 'o',\n    '\\u022D': 'o',\n    '\\u1E4F': 'o',\n    '\\u014D': 'o',\n    '\\u1E51': 'o',\n    '\\u1E53': 'o',\n    '\\u014F': 'o',\n    '\\u022F': 'o',\n    '\\u0231': 'o',\n    '\\u00F6': 'o',\n    '\\u022B': 'o',\n    '\\u1ECF': 'o',\n    '\\u0151': 'o',\n    '\\u01D2': 'o',\n    '\\u020D': 'o',\n    '\\u020F': 'o',\n    '\\u01A1': 'o',\n    '\\u1EDD': 'o',\n    '\\u1EDB': 'o',\n    '\\u1EE1': 'o',\n    '\\u1EDF': 'o',\n    '\\u1EE3': 'o',\n    '\\u1ECD': 'o',\n    '\\u1ED9': 'o',\n    '\\u01EB': 'o',\n    '\\u01ED': 'o',\n    '\\u00F8': 'o',\n    '\\u01FF': 'o',\n    '\\u0254': 'o',\n    '\\uA74B': 'o',\n    '\\uA74D': 'o',\n    '\\u0275': 'o',\n    '\\u01A3': 'oi',\n    '\\u0223': 'ou',\n    '\\uA74F': 'oo',\n    '\\u24DF': 'p',\n    '\\uFF50': 'p',\n    '\\u1E55': 'p',\n    '\\u1E57': 'p',\n    '\\u01A5': 'p',\n    '\\u1D7D': 'p',\n    '\\uA751': 'p',\n    '\\uA753': 'p',\n    '\\uA755': 'p',\n    '\\u24E0': 'q',\n    '\\uFF51': 'q',\n    '\\u024B': 'q',\n    '\\uA757': 'q',\n    '\\uA759': 'q',\n    '\\u24E1': 'r',\n    '\\uFF52': 'r',\n    '\\u0155': 'r',\n    '\\u1E59': 'r',\n    '\\u0159': 'r',\n    '\\u0211': 'r',\n    '\\u0213': 'r',\n    '\\u1E5B': 'r',\n    '\\u1E5D': 'r',\n    '\\u0157': 'r',\n    '\\u1E5F': 'r',\n    '\\u024D': 'r',\n    '\\u027D': 'r',\n    '\\uA75B': 'r',\n    '\\uA7A7': 'r',\n    '\\uA783': 'r',\n    '\\u24E2': 's',\n    '\\uFF53': 's',\n    '\\u00DF': 's',\n    '\\u015B': 's',\n    '\\u1E65': 's',\n    '\\u015D': 's',\n    '\\u1E61': 's',\n    '\\u0161': 's',\n    '\\u1E67': 's',\n    '\\u1E63': 's',\n    '\\u1E69': 's',\n    '\\u0219': 's',\n    '\\u015F': 's',\n    '\\u023F': 's',\n    '\\uA7A9': 's',\n    '\\uA785': 's',\n    '\\u1E9B': 's',\n    '\\u24E3': 't',\n    '\\uFF54': 't',\n    '\\u1E6B': 't',\n    '\\u1E97': 't',\n    '\\u0165': 't',\n    '\\u1E6D': 't',\n    '\\u021B': 't',\n    '\\u0163': 't',\n    '\\u1E71': 't',\n    '\\u1E6F': 't',\n    '\\u0167': 't',\n    '\\u01AD': 't',\n    '\\u0288': 't',\n    '\\u2C66': 't',\n    '\\uA787': 't',\n    '\\uA729': 'tz',\n    '\\u24E4': 'u',\n    '\\uFF55': 'u',\n    '\\u00F9': 'u',\n    '\\u00FA': 'u',\n    '\\u00FB': 'u',\n    '\\u0169': 'u',\n    '\\u1E79': 'u',\n    '\\u016B': 'u',\n    '\\u1E7B': 'u',\n    '\\u016D': 'u',\n    '\\u00FC': 'u',\n    '\\u01DC': 'u',\n    '\\u01D8': 'u',\n    '\\u01D6': 'u',\n    '\\u01DA': 'u',\n    '\\u1EE7': 'u',\n    '\\u016F': 'u',\n    '\\u0171': 'u',\n    '\\u01D4': 'u',\n    '\\u0215': 'u',\n    '\\u0217': 'u',\n    '\\u01B0': 'u',\n    '\\u1EEB': 'u',\n    '\\u1EE9': 'u',\n    '\\u1EEF': 'u',\n    '\\u1EED': 'u',\n    '\\u1EF1': 'u',\n    '\\u1EE5': 'u',\n    '\\u1E73': 'u',\n    '\\u0173': 'u',\n    '\\u1E77': 'u',\n    '\\u1E75': 'u',\n    '\\u0289': 'u',\n    '\\u24E5': 'v',\n    '\\uFF56': 'v',\n    '\\u1E7D': 'v',\n    '\\u1E7F': 'v',\n    '\\u028B': 'v',\n    '\\uA75F': 'v',\n    '\\u028C': 'v',\n    '\\uA761': 'vy',\n    '\\u24E6': 'w',\n    '\\uFF57': 'w',\n    '\\u1E81': 'w',\n    '\\u1E83': 'w',\n    '\\u0175': 'w',\n    '\\u1E87': 'w',\n    '\\u1E85': 'w',\n    '\\u1E98': 'w',\n    '\\u1E89': 'w',\n    '\\u2C73': 'w',\n    '\\u24E7': 'x',\n    '\\uFF58': 'x',\n    '\\u1E8B': 'x',\n    '\\u1E8D': 'x',\n    '\\u24E8': 'y',\n    '\\uFF59': 'y',\n    '\\u1EF3': 'y',\n    '\\u00FD': 'y',\n    '\\u0177': 'y',\n    '\\u1EF9': 'y',\n    '\\u0233': 'y',\n    '\\u1E8F': 'y',\n    '\\u00FF': 'y',\n    '\\u1EF7': 'y',\n    '\\u1E99': 'y',\n    '\\u1EF5': 'y',\n    '\\u01B4': 'y',\n    '\\u024F': 'y',\n    '\\u1EFF': 'y',\n    '\\u24E9': 'z',\n    '\\uFF5A': 'z',\n    '\\u017A': 'z',\n    '\\u1E91': 'z',\n    '\\u017C': 'z',\n    '\\u017E': 'z',\n    '\\u1E93': 'z',\n    '\\u1E95': 'z',\n    '\\u01B6': 'z',\n    '\\u0225': 'z',\n    '\\u0240': 'z',\n    '\\u2C6C': 'z',\n    '\\uA763': 'z',\n    '\\u0386': '\\u0391',\n    '\\u0388': '\\u0395',\n    '\\u0389': '\\u0397',\n    '\\u038A': '\\u0399',\n    '\\u03AA': '\\u0399',\n    '\\u038C': '\\u039F',\n    '\\u038E': '\\u03A5',\n    '\\u03AB': '\\u03A5',\n    '\\u038F': '\\u03A9',\n    '\\u03AC': '\\u03B1',\n    '\\u03AD': '\\u03B5',\n    '\\u03AE': '\\u03B7',\n    '\\u03AF': '\\u03B9',\n    '\\u03CA': '\\u03B9',\n    '\\u0390': '\\u03B9',\n    '\\u03CC': '\\u03BF',\n    '\\u03CD': '\\u03C5',\n    '\\u03CB': '\\u03C5',\n    '\\u03B0': '\\u03C5',\n    '\\u03C9': '\\u03C9',\n    '\\u03C2': '\\u03C3'\n  };\n\n  return diacritics;\n});\n\nS2.define('select2/data/base',[\n  '../utils'\n], function (Utils) {\n  function BaseAdapter ($element, options) {\n    BaseAdapter.__super__.constructor.call(this);\n  }\n\n  Utils.Extend(BaseAdapter, Utils.Observable);\n\n  BaseAdapter.prototype.current = function (callback) {\n    throw new Error('The `current` method must be defined in child classes.');\n  };\n\n  BaseAdapter.prototype.query = function (params, callback) {\n    throw new Error('The `query` method must be defined in child classes.');\n  };\n\n  BaseAdapter.prototype.bind = function (container, $container) {\n    // Can be implemented in subclasses\n  };\n\n  BaseAdapter.prototype.destroy = function () {\n    // Can be implemented in subclasses\n  };\n\n  BaseAdapter.prototype.generateResultId = function (container, data) {\n    var id = container.id + '-result-';\n\n    id += Utils.generateChars(4);\n\n    if (data.id != null) {\n      id += '-' + data.id.toString();\n    } else {\n      id += '-' + Utils.generateChars(4);\n    }\n    return id;\n  };\n\n  return BaseAdapter;\n});\n\nS2.define('select2/data/select',[\n  './base',\n  '../utils',\n  'jquery'\n], function (BaseAdapter, Utils, $) {\n  function SelectAdapter ($element, options) {\n    this.$element = $element;\n    this.options = options;\n\n    SelectAdapter.__super__.constructor.call(this);\n  }\n\n  Utils.Extend(SelectAdapter, BaseAdapter);\n\n  SelectAdapter.prototype.current = function (callback) {\n    var data = [];\n    var self = this;\n\n    this.$element.find(':selected').each(function () {\n      var $option = $(this);\n\n      var option = self.item($option);\n\n      data.push(option);\n    });\n\n    callback(data);\n  };\n\n  SelectAdapter.prototype.select = function (data) {\n    var self = this;\n\n    data.selected = true;\n\n    // If data.element is a DOM node, use it instead\n    if ($(data.element).is('option')) {\n      data.element.selected = true;\n\n      this.$element.trigger('change');\n\n      return;\n    }\n\n    if (this.$element.prop('multiple')) {\n      this.current(function (currentData) {\n        var val = [];\n\n        data = [data];\n        data.push.apply(data, currentData);\n\n        for (var d = 0; d < data.length; d++) {\n          var id = data[d].id;\n\n          if ($.inArray(id, val) === -1) {\n            val.push(id);\n          }\n        }\n\n        self.$element.val(val);\n        self.$element.trigger('change');\n      });\n    } else {\n      var val = data.id;\n\n      this.$element.val(val);\n      this.$element.trigger('change');\n    }\n  };\n\n  SelectAdapter.prototype.unselect = function (data) {\n    var self = this;\n\n    if (!this.$element.prop('multiple')) {\n      return;\n    }\n\n    data.selected = false;\n\n    if ($(data.element).is('option')) {\n      data.element.selected = false;\n\n      this.$element.trigger('change');\n\n      return;\n    }\n\n    this.current(function (currentData) {\n      var val = [];\n\n      for (var d = 0; d < currentData.length; d++) {\n        var id = currentData[d].id;\n\n        if (id !== data.id && $.inArray(id, val) === -1) {\n          val.push(id);\n        }\n      }\n\n      self.$element.val(val);\n\n      self.$element.trigger('change');\n    });\n  };\n\n  SelectAdapter.prototype.bind = function (container, $container) {\n    var self = this;\n\n    this.container = container;\n\n    container.on('select', function (params) {\n      self.select(params.data);\n    });\n\n    container.on('unselect', function (params) {\n      self.unselect(params.data);\n    });\n  };\n\n  SelectAdapter.prototype.destroy = function () {\n    // Remove anything added to child elements\n    this.$element.find('*').each(function () {\n      // Remove any custom data set by Select2\n      $.removeData(this, 'data');\n    });\n  };\n\n  SelectAdapter.prototype.query = function (params, callback) {\n    var data = [];\n    var self = this;\n\n    var $options = this.$element.children();\n\n    $options.each(function () {\n      var $option = $(this);\n\n      if (!$option.is('option') && !$option.is('optgroup')) {\n        return;\n      }\n\n      var option = self.item($option);\n\n      var matches = self.matches(params, option);\n\n      if (matches !== null) {\n        data.push(matches);\n      }\n    });\n\n    callback({\n      results: data\n    });\n  };\n\n  SelectAdapter.prototype.addOptions = function ($options) {\n    Utils.appendMany(this.$element, $options);\n  };\n\n  SelectAdapter.prototype.option = function (data) {\n    var option;\n\n    if (data.children) {\n      option = document.createElement('optgroup');\n      option.label = data.text;\n    } else {\n      option = document.createElement('option');\n\n      if (option.textContent !== undefined) {\n        option.textContent = data.text;\n      } else {\n        option.innerText = data.text;\n      }\n    }\n\n    if (data.id) {\n      option.value = data.id;\n    }\n\n    if (data.disabled) {\n      option.disabled = true;\n    }\n\n    if (data.selected) {\n      option.selected = true;\n    }\n\n    if (data.title) {\n      option.title = data.title;\n    }\n\n    var $option = $(option);\n\n    var normalizedData = this._normalizeItem(data);\n    normalizedData.element = option;\n\n    // Override the option's data with the combined data\n    $.data(option, 'data', normalizedData);\n\n    return $option;\n  };\n\n  SelectAdapter.prototype.item = function ($option) {\n    var data = {};\n\n    data = $.data($option[0], 'data');\n\n    if (data != null) {\n      return data;\n    }\n\n    if ($option.is('option')) {\n      data = {\n        id: $option.val(),\n        text: $option.text(),\n        disabled: $option.prop('disabled'),\n        selected: $option.prop('selected'),\n        title: $option.prop('title')\n      };\n    } else if ($option.is('optgroup')) {\n      data = {\n        text: $option.prop('label'),\n        children: [],\n        title: $option.prop('title')\n      };\n\n      var $children = $option.children('option');\n      var children = [];\n\n      for (var c = 0; c < $children.length; c++) {\n        var $child = $($children[c]);\n\n        var child = this.item($child);\n\n        children.push(child);\n      }\n\n      data.children = children;\n    }\n\n    data = this._normalizeItem(data);\n    data.element = $option[0];\n\n    $.data($option[0], 'data', data);\n\n    return data;\n  };\n\n  SelectAdapter.prototype._normalizeItem = function (item) {\n    if (!$.isPlainObject(item)) {\n      item = {\n        id: item,\n        text: item\n      };\n    }\n\n    item = $.extend({}, {\n      text: ''\n    }, item);\n\n    var defaults = {\n      selected: false,\n      disabled: false\n    };\n\n    if (item.id != null) {\n      item.id = item.id.toString();\n    }\n\n    if (item.text != null) {\n      item.text = item.text.toString();\n    }\n\n    if (item._resultId == null && item.id && this.container != null) {\n      item._resultId = this.generateResultId(this.container, item);\n    }\n\n    return $.extend({}, defaults, item);\n  };\n\n  SelectAdapter.prototype.matches = function (params, data) {\n    var matcher = this.options.get('matcher');\n\n    return matcher(params, data);\n  };\n\n  return SelectAdapter;\n});\n\nS2.define('select2/data/array',[\n  './select',\n  '../utils',\n  'jquery'\n], function (SelectAdapter, Utils, $) {\n  function ArrayAdapter ($element, options) {\n    var data = options.get('data') || [];\n\n    ArrayAdapter.__super__.constructor.call(this, $element, options);\n\n    this.addOptions(this.convertToOptions(data));\n  }\n\n  Utils.Extend(ArrayAdapter, SelectAdapter);\n\n  ArrayAdapter.prototype.select = function (data) {\n    var $option = this.$element.find('option').filter(function (i, elm) {\n      return elm.value == data.id.toString();\n    });\n\n    if ($option.length === 0) {\n      $option = this.option(data);\n\n      this.addOptions($option);\n    }\n\n    ArrayAdapter.__super__.select.call(this, data);\n  };\n\n  ArrayAdapter.prototype.convertToOptions = function (data) {\n    var self = this;\n\n    var $existing = this.$element.find('option');\n    var existingIds = $existing.map(function () {\n      return self.item($(this)).id;\n    }).get();\n\n    var $options = [];\n\n    // Filter out all items except for the one passed in the argument\n    function onlyItem (item) {\n      return function () {\n        return $(this).val() == item.id;\n      };\n    }\n\n    for (var d = 0; d < data.length; d++) {\n      var item = this._normalizeItem(data[d]);\n\n      // Skip items which were pre-loaded, only merge the data\n      if ($.inArray(item.id, existingIds) >= 0) {\n        var $existingOption = $existing.filter(onlyItem(item));\n\n        var existingData = this.item($existingOption);\n        var newData = $.extend(true, {}, item, existingData);\n\n        var $newOption = this.option(newData);\n\n        $existingOption.replaceWith($newOption);\n\n        continue;\n      }\n\n      var $option = this.option(item);\n\n      if (item.children) {\n        var $children = this.convertToOptions(item.children);\n\n        Utils.appendMany($option, $children);\n      }\n\n      $options.push($option);\n    }\n\n    return $options;\n  };\n\n  return ArrayAdapter;\n});\n\nS2.define('select2/data/ajax',[\n  './array',\n  '../utils',\n  'jquery'\n], function (ArrayAdapter, Utils, $) {\n  function AjaxAdapter ($element, options) {\n    this.ajaxOptions = this._applyDefaults(options.get('ajax'));\n\n    if (this.ajaxOptions.processResults != null) {\n      this.processResults = this.ajaxOptions.processResults;\n    }\n\n    AjaxAdapter.__super__.constructor.call(this, $element, options);\n  }\n\n  Utils.Extend(AjaxAdapter, ArrayAdapter);\n\n  AjaxAdapter.prototype._applyDefaults = function (options) {\n    var defaults = {\n      data: function (params) {\n        return $.extend({}, params, {\n          q: params.term\n        });\n      },\n      transport: function (params, success, failure) {\n        var $request = $.ajax(params);\n\n        $request.then(success);\n        $request.fail(failure);\n\n        return $request;\n      }\n    };\n\n    return $.extend({}, defaults, options, true);\n  };\n\n  AjaxAdapter.prototype.processResults = function (results) {\n    return results;\n  };\n\n  AjaxAdapter.prototype.query = function (params, callback) {\n    var matches = [];\n    var self = this;\n\n    if (this._request != null) {\n      // JSONP requests cannot always be aborted\n      if ($.isFunction(this._request.abort)) {\n        this._request.abort();\n      }\n\n      this._request = null;\n    }\n\n    var options = $.extend({\n      type: 'GET'\n    }, this.ajaxOptions);\n\n    if (typeof options.url === 'function') {\n      options.url = options.url.call(this.$element, params);\n    }\n\n    if (typeof options.data === 'function') {\n      options.data = options.data.call(this.$element, params);\n    }\n\n    function request () {\n      var $request = options.transport(options, function (data) {\n        var results = self.processResults(data, params);\n\n        if (self.options.get('debug') && window.console && console.error) {\n          // Check to make sure that the response included a `results` key.\n          if (!results || !results.results || !$.isArray(results.results)) {\n            console.error(\n              'Select2: The AJAX results did not return an array in the ' +\n              '`results` key of the response.'\n            );\n          }\n        }\n\n        callback(results);\n      }, function () {\n        // Attempt to detect if a request was aborted\n        // Only works if the transport exposes a status property\n        if ($request.status && $request.status === '0') {\n          return;\n        }\n\n        self.trigger('results:message', {\n          message: 'errorLoading'\n        });\n      });\n\n      self._request = $request;\n    }\n\n    if (this.ajaxOptions.delay && params.term != null) {\n      if (this._queryTimeout) {\n        window.clearTimeout(this._queryTimeout);\n      }\n\n      this._queryTimeout = window.setTimeout(request, this.ajaxOptions.delay);\n    } else {\n      request();\n    }\n  };\n\n  return AjaxAdapter;\n});\n\nS2.define('select2/data/tags',[\n  'jquery'\n], function ($) {\n  function Tags (decorated, $element, options) {\n    var tags = options.get('tags');\n\n    var createTag = options.get('createTag');\n\n    if (createTag !== undefined) {\n      this.createTag = createTag;\n    }\n\n    var insertTag = options.get('insertTag');\n\n    if (insertTag !== undefined) {\n        this.insertTag = insertTag;\n    }\n\n    decorated.call(this, $element, options);\n\n    if ($.isArray(tags)) {\n      for (var t = 0; t < tags.length; t++) {\n        var tag = tags[t];\n        var item = this._normalizeItem(tag);\n\n        var $option = this.option(item);\n\n        this.$element.append($option);\n      }\n    }\n  }\n\n  Tags.prototype.query = function (decorated, params, callback) {\n    var self = this;\n\n    this._removeOldTags();\n\n    if (params.term == null || params.page != null) {\n      decorated.call(this, params, callback);\n      return;\n    }\n\n    function wrapper (obj, child) {\n      var data = obj.results;\n\n      for (var i = 0; i < data.length; i++) {\n        var option = data[i];\n\n        var checkChildren = (\n          option.children != null &&\n          !wrapper({\n            results: option.children\n          }, true)\n        );\n\n        var checkText = option.text === params.term;\n\n        if (checkText || checkChildren) {\n          if (child) {\n            return false;\n          }\n\n          obj.data = data;\n          callback(obj);\n\n          return;\n        }\n      }\n\n      if (child) {\n        return true;\n      }\n\n      var tag = self.createTag(params);\n\n      if (tag != null) {\n        var $option = self.option(tag);\n        $option.attr('data-select2-tag', true);\n\n        self.addOptions([$option]);\n\n        self.insertTag(data, tag);\n      }\n\n      obj.results = data;\n\n      callback(obj);\n    }\n\n    decorated.call(this, params, wrapper);\n  };\n\n  Tags.prototype.createTag = function (decorated, params) {\n    var term = $.trim(params.term);\n\n    if (term === '') {\n      return null;\n    }\n\n    return {\n      id: term,\n      text: term\n    };\n  };\n\n  Tags.prototype.insertTag = function (_, data, tag) {\n    data.unshift(tag);\n  };\n\n  Tags.prototype._removeOldTags = function (_) {\n    var tag = this._lastTag;\n\n    var $options = this.$element.find('option[data-select2-tag]');\n\n    $options.each(function () {\n      if (this.selected) {\n        return;\n      }\n\n      $(this).remove();\n    });\n  };\n\n  return Tags;\n});\n\nS2.define('select2/data/tokenizer',[\n  'jquery'\n], function ($) {\n  function Tokenizer (decorated, $element, options) {\n    var tokenizer = options.get('tokenizer');\n\n    if (tokenizer !== undefined) {\n      this.tokenizer = tokenizer;\n    }\n\n    decorated.call(this, $element, options);\n  }\n\n  Tokenizer.prototype.bind = function (decorated, container, $container) {\n    decorated.call(this, container, $container);\n\n    this.$search =  container.dropdown.$search || container.selection.$search ||\n      $container.find('.select2-search__field');\n  };\n\n  Tokenizer.prototype.query = function (decorated, params, callback) {\n    var self = this;\n\n    function createAndSelect (data) {\n      // Normalize the data object so we can use it for checks\n      var item = self._normalizeItem(data);\n\n      // Check if the data object already exists as a tag\n      // Select it if it doesn't\n      var $existingOptions = self.$element.find('option').filter(function () {\n        return $(this).val() === item.id;\n      });\n\n      // If an existing option wasn't found for it, create the option\n      if (!$existingOptions.length) {\n        var $option = self.option(item);\n        $option.attr('data-select2-tag', true);\n\n        self._removeOldTags();\n        self.addOptions([$option]);\n      }\n\n      // Select the item, now that we know there is an option for it\n      select(item);\n    }\n\n    function select (data) {\n      self.trigger('select', {\n        data: data\n      });\n    }\n\n    params.term = params.term || '';\n\n    var tokenData = this.tokenizer(params, this.options, createAndSelect);\n\n    if (tokenData.term !== params.term) {\n      // Replace the search term if we have the search box\n      if (this.$search.length) {\n        this.$search.val(tokenData.term);\n        this.$search.focus();\n      }\n\n      params.term = tokenData.term;\n    }\n\n    decorated.call(this, params, callback);\n  };\n\n  Tokenizer.prototype.tokenizer = function (_, params, options, callback) {\n    var separators = options.get('tokenSeparators') || [];\n    var term = params.term;\n    var i = 0;\n\n    var createTag = this.createTag || function (params) {\n      return {\n        id: params.term,\n        text: params.term\n      };\n    };\n\n    while (i < term.length) {\n      var termChar = term[i];\n\n      if ($.inArray(termChar, separators) === -1) {\n        i++;\n\n        continue;\n      }\n\n      var part = term.substr(0, i);\n      var partParams = $.extend({}, params, {\n        term: part\n      });\n\n      var data = createTag(partParams);\n\n      if (data == null) {\n        i++;\n        continue;\n      }\n\n      callback(data);\n\n      // Reset the term to not include the tokenized portion\n      term = term.substr(i + 1) || '';\n      i = 0;\n    }\n\n    return {\n      term: term\n    };\n  };\n\n  return Tokenizer;\n});\n\nS2.define('select2/data/minimumInputLength',[\n\n], function () {\n  function MinimumInputLength (decorated, $e, options) {\n    this.minimumInputLength = options.get('minimumInputLength');\n\n    decorated.call(this, $e, options);\n  }\n\n  MinimumInputLength.prototype.query = function (decorated, params, callback) {\n    params.term = params.term || '';\n\n    if (params.term.length < this.minimumInputLength) {\n      this.trigger('results:message', {\n        message: 'inputTooShort',\n        args: {\n          minimum: this.minimumInputLength,\n          input: params.term,\n          params: params\n        }\n      });\n\n      return;\n    }\n\n    decorated.call(this, params, callback);\n  };\n\n  return MinimumInputLength;\n});\n\nS2.define('select2/data/maximumInputLength',[\n\n], function () {\n  function MaximumInputLength (decorated, $e, options) {\n    this.maximumInputLength = options.get('maximumInputLength');\n\n    decorated.call(this, $e, options);\n  }\n\n  MaximumInputLength.prototype.query = function (decorated, params, callback) {\n    params.term = params.term || '';\n\n    if (this.maximumInputLength > 0 &&\n        params.term.length > this.maximumInputLength) {\n      this.trigger('results:message', {\n        message: 'inputTooLong',\n        args: {\n          maximum: this.maximumInputLength,\n          input: params.term,\n          params: params\n        }\n      });\n\n      return;\n    }\n\n    decorated.call(this, params, callback);\n  };\n\n  return MaximumInputLength;\n});\n\nS2.define('select2/data/maximumSelectionLength',[\n\n], function (){\n  function MaximumSelectionLength (decorated, $e, options) {\n    this.maximumSelectionLength = options.get('maximumSelectionLength');\n\n    decorated.call(this, $e, options);\n  }\n\n  MaximumSelectionLength.prototype.query =\n    function (decorated, params, callback) {\n      var self = this;\n\n      this.current(function (currentData) {\n        var count = currentData != null ? currentData.length : 0;\n        if (self.maximumSelectionLength > 0 &&\n          count >= self.maximumSelectionLength) {\n          self.trigger('results:message', {\n            message: 'maximumSelected',\n            args: {\n              maximum: self.maximumSelectionLength\n            }\n          });\n          return;\n        }\n        decorated.call(self, params, callback);\n      });\n  };\n\n  return MaximumSelectionLength;\n});\n\nS2.define('select2/dropdown',[\n  'jquery',\n  './utils'\n], function ($, Utils) {\n  function Dropdown ($element, options) {\n    this.$element = $element;\n    this.options = options;\n\n    Dropdown.__super__.constructor.call(this);\n  }\n\n  Utils.Extend(Dropdown, Utils.Observable);\n\n  Dropdown.prototype.render = function () {\n    var $dropdown = $(\n      '<span class=\"select2-dropdown\">' +\n        '<span class=\"select2-results\"></span>' +\n      '</span>'\n    );\n\n    $dropdown.attr('dir', this.options.get('dir'));\n\n    this.$dropdown = $dropdown;\n\n    return $dropdown;\n  };\n\n  Dropdown.prototype.bind = function () {\n    // Should be implemented in subclasses\n  };\n\n  Dropdown.prototype.position = function ($dropdown, $container) {\n    // Should be implmented in subclasses\n  };\n\n  Dropdown.prototype.destroy = function () {\n    // Remove the dropdown from the DOM\n    this.$dropdown.remove();\n  };\n\n  return Dropdown;\n});\n\nS2.define('select2/dropdown/search',[\n  'jquery',\n  '../utils'\n], function ($, Utils) {\n  function Search () { }\n\n  Search.prototype.render = function (decorated) {\n    var $rendered = decorated.call(this);\n\n    var $search = $(\n      '<span class=\"select2-search select2-search--dropdown\">' +\n        '<input class=\"select2-search__field\" type=\"search\" tabindex=\"-1\"' +\n        ' autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\"' +\n        ' spellcheck=\"false\" role=\"textbox\" />' +\n      '</span>'\n    );\n\n    this.$searchContainer = $search;\n    this.$search = $search.find('input');\n\n    $rendered.prepend($search);\n\n    return $rendered;\n  };\n\n  Search.prototype.bind = function (decorated, container, $container) {\n    var self = this;\n\n    decorated.call(this, container, $container);\n\n    this.$search.on('keydown', function (evt) {\n      self.trigger('keypress', evt);\n\n      self._keyUpPrevented = evt.isDefaultPrevented();\n    });\n\n    // Workaround for browsers which do not support the `input` event\n    // This will prevent double-triggering of events for browsers which support\n    // both the `keyup` and `input` events.\n    this.$search.on('input', function (evt) {\n      // Unbind the duplicated `keyup` event\n      $(this).off('keyup');\n    });\n\n    this.$search.on('keyup input', function (evt) {\n      self.handleSearch(evt);\n    });\n\n    container.on('open', function () {\n      self.$search.attr('tabindex', 0);\n\n      self.$search.focus();\n\n      window.setTimeout(function () {\n        self.$search.focus();\n      }, 0);\n    });\n\n    container.on('close', function () {\n      self.$search.attr('tabindex', -1);\n\n      self.$search.val('');\n    });\n\n    container.on('focus', function () {\n      if (container.isOpen()) {\n        self.$search.focus();\n      }\n    });\n\n    container.on('results:all', function (params) {\n      if (params.query.term == null || params.query.term === '') {\n        var showSearch = self.showSearch(params);\n\n        if (showSearch) {\n          self.$searchContainer.removeClass('select2-search--hide');\n        } else {\n          self.$searchContainer.addClass('select2-search--hide');\n        }\n      }\n    });\n  };\n\n  Search.prototype.handleSearch = function (evt) {\n    if (!this._keyUpPrevented) {\n      var input = this.$search.val();\n\n      this.trigger('query', {\n        term: input\n      });\n    }\n\n    this._keyUpPrevented = false;\n  };\n\n  Search.prototype.showSearch = function (_, params) {\n    return true;\n  };\n\n  return Search;\n});\n\nS2.define('select2/dropdown/hidePlaceholder',[\n\n], function () {\n  function HidePlaceholder (decorated, $element, options, dataAdapter) {\n    this.placeholder = this.normalizePlaceholder(options.get('placeholder'));\n\n    decorated.call(this, $element, options, dataAdapter);\n  }\n\n  HidePlaceholder.prototype.append = function (decorated, data) {\n    data.results = this.removePlaceholder(data.results);\n\n    decorated.call(this, data);\n  };\n\n  HidePlaceholder.prototype.normalizePlaceholder = function (_, placeholder) {\n    if (typeof placeholder === 'string') {\n      placeholder = {\n        id: '',\n        text: placeholder\n      };\n    }\n\n    return placeholder;\n  };\n\n  HidePlaceholder.prototype.removePlaceholder = function (_, data) {\n    var modifiedData = data.slice(0);\n\n    for (var d = data.length - 1; d >= 0; d--) {\n      var item = data[d];\n\n      if (this.placeholder.id === item.id) {\n        modifiedData.splice(d, 1);\n      }\n    }\n\n    return modifiedData;\n  };\n\n  return HidePlaceholder;\n});\n\nS2.define('select2/dropdown/infiniteScroll',[\n  'jquery'\n], function ($) {\n  function InfiniteScroll (decorated, $element, options, dataAdapter) {\n    this.lastParams = {};\n\n    decorated.call(this, $element, options, dataAdapter);\n\n    this.$loadingMore = this.createLoadingMore();\n    this.loading = false;\n  }\n\n  InfiniteScroll.prototype.append = function (decorated, data) {\n    this.$loadingMore.remove();\n    this.loading = false;\n\n    decorated.call(this, data);\n\n    if (this.showLoadingMore(data)) {\n      this.$results.append(this.$loadingMore);\n    }\n  };\n\n  InfiniteScroll.prototype.bind = function (decorated, container, $container) {\n    var self = this;\n\n    decorated.call(this, container, $container);\n\n    container.on('query', function (params) {\n      self.lastParams = params;\n      self.loading = true;\n    });\n\n    container.on('query:append', function (params) {\n      self.lastParams = params;\n      self.loading = true;\n    });\n\n    this.$results.on('scroll', function () {\n      var isLoadMoreVisible = $.contains(\n        document.documentElement,\n        self.$loadingMore[0]\n      );\n\n      if (self.loading || !isLoadMoreVisible) {\n        return;\n      }\n\n      var currentOffset = self.$results.offset().top +\n        self.$results.outerHeight(false);\n      var loadingMoreOffset = self.$loadingMore.offset().top +\n        self.$loadingMore.outerHeight(false);\n\n      if (currentOffset + 50 >= loadingMoreOffset) {\n        self.loadMore();\n      }\n    });\n  };\n\n  InfiniteScroll.prototype.loadMore = function () {\n    this.loading = true;\n\n    var params = $.extend({}, {page: 1}, this.lastParams);\n\n    params.page++;\n\n    this.trigger('query:append', params);\n  };\n\n  InfiniteScroll.prototype.showLoadingMore = function (_, data) {\n    return data.pagination && data.pagination.more;\n  };\n\n  InfiniteScroll.prototype.createLoadingMore = function () {\n    var $option = $(\n      '<li ' +\n      'class=\"select2-results__option select2-results__option--load-more\"' +\n      'role=\"treeitem\" aria-disabled=\"true\"></li>'\n    );\n\n    var message = this.options.get('translations').get('loadingMore');\n\n    $option.html(message(this.lastParams));\n\n    return $option;\n  };\n\n  return InfiniteScroll;\n});\n\nS2.define('select2/dropdown/attachBody',[\n  'jquery',\n  '../utils'\n], function ($, Utils) {\n  function AttachBody (decorated, $element, options) {\n    this.$dropdownParent = options.get('dropdownParent') || $(document.body);\n\n    decorated.call(this, $element, options);\n  }\n\n  AttachBody.prototype.bind = function (decorated, container, $container) {\n    var self = this;\n\n    var setupResultsEvents = false;\n\n    decorated.call(this, container, $container);\n\n    container.on('open', function () {\n      self._showDropdown();\n      self._attachPositioningHandler(container);\n\n      if (!setupResultsEvents) {\n        setupResultsEvents = true;\n\n        container.on('results:all', function () {\n          self._positionDropdown();\n          self._resizeDropdown();\n        });\n\n        container.on('results:append', function () {\n          self._positionDropdown();\n          self._resizeDropdown();\n        });\n      }\n    });\n\n    container.on('close', function () {\n      self._hideDropdown();\n      self._detachPositioningHandler(container);\n    });\n\n    this.$dropdownContainer.on('mousedown', function (evt) {\n      evt.stopPropagation();\n    });\n  };\n\n  AttachBody.prototype.destroy = function (decorated) {\n    decorated.call(this);\n\n    this.$dropdownContainer.remove();\n  };\n\n  AttachBody.prototype.position = function (decorated, $dropdown, $container) {\n    // Clone all of the container classes\n    $dropdown.attr('class', $container.attr('class'));\n\n    $dropdown.removeClass('select2');\n    $dropdown.addClass('select2-container--open');\n\n    $dropdown.css({\n      position: 'absolute',\n      top: -999999\n    });\n\n    this.$container = $container;\n  };\n\n  AttachBody.prototype.render = function (decorated) {\n    var $container = $('<span></span>');\n\n    var $dropdown = decorated.call(this);\n    $container.append($dropdown);\n\n    this.$dropdownContainer = $container;\n\n    return $container;\n  };\n\n  AttachBody.prototype._hideDropdown = function (decorated) {\n    this.$dropdownContainer.detach();\n  };\n\n  AttachBody.prototype._attachPositioningHandler =\n      function (decorated, container) {\n    var self = this;\n\n    var scrollEvent = 'scroll.select2.' + container.id;\n    var resizeEvent = 'resize.select2.' + container.id;\n    var orientationEvent = 'orientationchange.select2.' + container.id;\n\n    var $watchers = this.$container.parents().filter(Utils.hasScroll);\n    $watchers.each(function () {\n      $(this).data('select2-scroll-position', {\n        x: $(this).scrollLeft(),\n        y: $(this).scrollTop()\n      });\n    });\n\n    $watchers.on(scrollEvent, function (ev) {\n      var position = $(this).data('select2-scroll-position');\n      $(this).scrollTop(position.y);\n    });\n\n    $(window).on(scrollEvent + ' ' + resizeEvent + ' ' + orientationEvent,\n      function (e) {\n      self._positionDropdown();\n      self._resizeDropdown();\n    });\n  };\n\n  AttachBody.prototype._detachPositioningHandler =\n      function (decorated, container) {\n    var scrollEvent = 'scroll.select2.' + container.id;\n    var resizeEvent = 'resize.select2.' + container.id;\n    var orientationEvent = 'orientationchange.select2.' + container.id;\n\n    var $watchers = this.$container.parents().filter(Utils.hasScroll);\n    $watchers.off(scrollEvent);\n\n    $(window).off(scrollEvent + ' ' + resizeEvent + ' ' + orientationEvent);\n  };\n\n  AttachBody.prototype._positionDropdown = function () {\n    var $window = $(window);\n\n    var isCurrentlyAbove = this.$dropdown.hasClass('select2-dropdown--above');\n    var isCurrentlyBelow = this.$dropdown.hasClass('select2-dropdown--below');\n\n    var newDirection = null;\n\n    var offset = this.$container.offset();\n\n    offset.bottom = offset.top + this.$container.outerHeight(false);\n\n    var container = {\n      height: this.$container.outerHeight(false)\n    };\n\n    container.top = offset.top;\n    container.bottom = offset.top + container.height;\n\n    var dropdown = {\n      height: this.$dropdown.outerHeight(false)\n    };\n\n    var viewport = {\n      top: $window.scrollTop(),\n      bottom: $window.scrollTop() + $window.height()\n    };\n\n    var enoughRoomAbove = viewport.top < (offset.top - dropdown.height);\n    var enoughRoomBelow = viewport.bottom > (offset.bottom + dropdown.height);\n\n    var css = {\n      left: offset.left,\n      top: container.bottom\n    };\n\n    // Determine what the parent element is to use for calciulating the offset\n    var $offsetParent = this.$dropdownParent;\n\n    // For statically positoned elements, we need to get the element\n    // that is determining the offset\n    if ($offsetParent.css('position') === 'static') {\n      $offsetParent = $offsetParent.offsetParent();\n    }\n\n    var parentOffset = $offsetParent.offset();\n\n    css.top -= parentOffset.top;\n    css.left -= parentOffset.left;\n\n    if (!isCurrentlyAbove && !isCurrentlyBelow) {\n      newDirection = 'below';\n    }\n\n    if (!enoughRoomBelow && enoughRoomAbove && !isCurrentlyAbove) {\n      newDirection = 'above';\n    } else if (!enoughRoomAbove && enoughRoomBelow && isCurrentlyAbove) {\n      newDirection = 'below';\n    }\n\n    if (newDirection == 'above' ||\n      (isCurrentlyAbove && newDirection !== 'below')) {\n      css.top = container.top - parentOffset.top - dropdown.height;\n    }\n\n    if (newDirection != null) {\n      this.$dropdown\n        .removeClass('select2-dropdown--below select2-dropdown--above')\n        .addClass('select2-dropdown--' + newDirection);\n      this.$container\n        .removeClass('select2-container--below select2-container--above')\n        .addClass('select2-container--' + newDirection);\n    }\n\n    this.$dropdownContainer.css(css);\n  };\n\n  AttachBody.prototype._resizeDropdown = function () {\n    var css = {\n      width: this.$container.outerWidth(false) + 'px'\n    };\n\n    if (this.options.get('dropdownAutoWidth')) {\n      css.minWidth = css.width;\n      css.position = 'relative';\n      css.width = 'auto';\n    }\n\n    this.$dropdown.css(css);\n  };\n\n  AttachBody.prototype._showDropdown = function (decorated) {\n    this.$dropdownContainer.appendTo(this.$dropdownParent);\n\n    this._positionDropdown();\n    this._resizeDropdown();\n  };\n\n  return AttachBody;\n});\n\nS2.define('select2/dropdown/minimumResultsForSearch',[\n\n], function () {\n  function countResults (data) {\n    var count = 0;\n\n    for (var d = 0; d < data.length; d++) {\n      var item = data[d];\n\n      if (item.children) {\n        count += countResults(item.children);\n      } else {\n        count++;\n      }\n    }\n\n    return count;\n  }\n\n  function MinimumResultsForSearch (decorated, $element, options, dataAdapter) {\n    this.minimumResultsForSearch = options.get('minimumResultsForSearch');\n\n    if (this.minimumResultsForSearch < 0) {\n      this.minimumResultsForSearch = Infinity;\n    }\n\n    decorated.call(this, $element, options, dataAdapter);\n  }\n\n  MinimumResultsForSearch.prototype.showSearch = function (decorated, params) {\n    if (countResults(params.data.results) < this.minimumResultsForSearch) {\n      return false;\n    }\n\n    return decorated.call(this, params);\n  };\n\n  return MinimumResultsForSearch;\n});\n\nS2.define('select2/dropdown/selectOnClose',[\n\n], function () {\n  function SelectOnClose () { }\n\n  SelectOnClose.prototype.bind = function (decorated, container, $container) {\n    var self = this;\n\n    decorated.call(this, container, $container);\n\n    container.on('close', function (params) {\n      self._handleSelectOnClose(params);\n    });\n  };\n\n  SelectOnClose.prototype._handleSelectOnClose = function (_, params) {\n    if (params && params.originalSelect2Event != null) {\n      var event = params.originalSelect2Event;\n\n      // Don't select an item if the close event was triggered from a select or\n      // unselect event\n      if (event._type === 'select' || event._type === 'unselect') {\n        return;\n      }\n    }\n\n    var $highlightedResults = this.getHighlightedResults();\n\n    // Only select highlighted results\n    if ($highlightedResults.length < 1) {\n      return;\n    }\n\n    var data = $highlightedResults.data('data');\n\n    // Don't re-select already selected resulte\n    if (\n      (data.element != null && data.element.selected) ||\n      (data.element == null && data.selected)\n    ) {\n      return;\n    }\n\n    this.trigger('select', {\n        data: data\n    });\n  };\n\n  return SelectOnClose;\n});\n\nS2.define('select2/dropdown/closeOnSelect',[\n\n], function () {\n  function CloseOnSelect () { }\n\n  CloseOnSelect.prototype.bind = function (decorated, container, $container) {\n    var self = this;\n\n    decorated.call(this, container, $container);\n\n    container.on('select', function (evt) {\n      self._selectTriggered(evt);\n    });\n\n    container.on('unselect', function (evt) {\n      self._selectTriggered(evt);\n    });\n  };\n\n  CloseOnSelect.prototype._selectTriggered = function (_, evt) {\n    var originalEvent = evt.originalEvent;\n\n    // Don't close if the control key is being held\n    if (originalEvent && originalEvent.ctrlKey) {\n      return;\n    }\n\n    this.trigger('close', {\n      originalEvent: originalEvent,\n      originalSelect2Event: evt\n    });\n  };\n\n  return CloseOnSelect;\n});\n\nS2.define('select2/i18n/en',[],function () {\n  // English\n  return {\n    errorLoading: function () {\n      return 'The results could not be loaded.';\n    },\n    inputTooLong: function (args) {\n      var overChars = args.input.length - args.maximum;\n\n      var message = 'Please delete ' + overChars + ' character';\n\n      if (overChars != 1) {\n        message += 's';\n      }\n\n      return message;\n    },\n    inputTooShort: function (args) {\n      var remainingChars = args.minimum - args.input.length;\n\n      var message = 'Please enter ' + remainingChars + ' or more characters';\n\n      return message;\n    },\n    loadingMore: function () {\n      return 'Loading more results…';\n    },\n    maximumSelected: function (args) {\n      var message = 'You can only select ' + args.maximum + ' item';\n\n      if (args.maximum != 1) {\n        message += 's';\n      }\n\n      return message;\n    },\n    noResults: function () {\n      return 'No results found';\n    },\n    searching: function () {\n      return 'Searching…';\n    }\n  };\n});\n\nS2.define('select2/defaults',[\n  'jquery',\n  'require',\n\n  './results',\n\n  './selection/single',\n  './selection/multiple',\n  './selection/placeholder',\n  './selection/allowClear',\n  './selection/search',\n  './selection/eventRelay',\n\n  './utils',\n  './translation',\n  './diacritics',\n\n  './data/select',\n  './data/array',\n  './data/ajax',\n  './data/tags',\n  './data/tokenizer',\n  './data/minimumInputLength',\n  './data/maximumInputLength',\n  './data/maximumSelectionLength',\n\n  './dropdown',\n  './dropdown/search',\n  './dropdown/hidePlaceholder',\n  './dropdown/infiniteScroll',\n  './dropdown/attachBody',\n  './dropdown/minimumResultsForSearch',\n  './dropdown/selectOnClose',\n  './dropdown/closeOnSelect',\n\n  './i18n/en'\n], function ($, require,\n\n             ResultsList,\n\n             SingleSelection, MultipleSelection, Placeholder, AllowClear,\n             SelectionSearch, EventRelay,\n\n             Utils, Translation, DIACRITICS,\n\n             SelectData, ArrayData, AjaxData, Tags, Tokenizer,\n             MinimumInputLength, MaximumInputLength, MaximumSelectionLength,\n\n             Dropdown, DropdownSearch, HidePlaceholder, InfiniteScroll,\n             AttachBody, MinimumResultsForSearch, SelectOnClose, CloseOnSelect,\n\n             EnglishTranslation) {\n  function Defaults () {\n    this.reset();\n  }\n\n  Defaults.prototype.apply = function (options) {\n    options = $.extend(true, {}, this.defaults, options);\n\n    if (options.dataAdapter == null) {\n      if (options.ajax != null) {\n        options.dataAdapter = AjaxData;\n      } else if (options.data != null) {\n        options.dataAdapter = ArrayData;\n      } else {\n        options.dataAdapter = SelectData;\n      }\n\n      if (options.minimumInputLength > 0) {\n        options.dataAdapter = Utils.Decorate(\n          options.dataAdapter,\n          MinimumInputLength\n        );\n      }\n\n      if (options.maximumInputLength > 0) {\n        options.dataAdapter = Utils.Decorate(\n          options.dataAdapter,\n          MaximumInputLength\n        );\n      }\n\n      if (options.maximumSelectionLength > 0) {\n        options.dataAdapter = Utils.Decorate(\n          options.dataAdapter,\n          MaximumSelectionLength\n        );\n      }\n\n      if (options.tags) {\n        options.dataAdapter = Utils.Decorate(options.dataAdapter, Tags);\n      }\n\n      if (options.tokenSeparators != null || options.tokenizer != null) {\n        options.dataAdapter = Utils.Decorate(\n          options.dataAdapter,\n          Tokenizer\n        );\n      }\n\n      if (options.query != null) {\n        var Query = require(options.amdBase + 'compat/query');\n\n        options.dataAdapter = Utils.Decorate(\n          options.dataAdapter,\n          Query\n        );\n      }\n\n      if (options.initSelection != null) {\n        var InitSelection = require(options.amdBase + 'compat/initSelection');\n\n        options.dataAdapter = Utils.Decorate(\n          options.dataAdapter,\n          InitSelection\n        );\n      }\n    }\n\n    if (options.resultsAdapter == null) {\n      options.resultsAdapter = ResultsList;\n\n      if (options.ajax != null) {\n        options.resultsAdapter = Utils.Decorate(\n          options.resultsAdapter,\n          InfiniteScroll\n        );\n      }\n\n      if (options.placeholder != null) {\n        options.resultsAdapter = Utils.Decorate(\n          options.resultsAdapter,\n          HidePlaceholder\n        );\n      }\n\n      if (options.selectOnClose) {\n        options.resultsAdapter = Utils.Decorate(\n          options.resultsAdapter,\n          SelectOnClose\n        );\n      }\n    }\n\n    if (options.dropdownAdapter == null) {\n      if (options.multiple) {\n        options.dropdownAdapter = Dropdown;\n      } else {\n        var SearchableDropdown = Utils.Decorate(Dropdown, DropdownSearch);\n\n        options.dropdownAdapter = SearchableDropdown;\n      }\n\n      if (options.minimumResultsForSearch !== 0) {\n        options.dropdownAdapter = Utils.Decorate(\n          options.dropdownAdapter,\n          MinimumResultsForSearch\n        );\n      }\n\n      if (options.closeOnSelect) {\n        options.dropdownAdapter = Utils.Decorate(\n          options.dropdownAdapter,\n          CloseOnSelect\n        );\n      }\n\n      if (\n        options.dropdownCssClass != null ||\n        options.dropdownCss != null ||\n        options.adaptDropdownCssClass != null\n      ) {\n        var DropdownCSS = require(options.amdBase + 'compat/dropdownCss');\n\n        options.dropdownAdapter = Utils.Decorate(\n          options.dropdownAdapter,\n          DropdownCSS\n        );\n      }\n\n      options.dropdownAdapter = Utils.Decorate(\n        options.dropdownAdapter,\n        AttachBody\n      );\n    }\n\n    if (options.selectionAdapter == null) {\n      if (options.multiple) {\n        options.selectionAdapter = MultipleSelection;\n      } else {\n        options.selectionAdapter = SingleSelection;\n      }\n\n      // Add the placeholder mixin if a placeholder was specified\n      if (options.placeholder != null) {\n        options.selectionAdapter = Utils.Decorate(\n          options.selectionAdapter,\n          Placeholder\n        );\n      }\n\n      if (options.allowClear) {\n        options.selectionAdapter = Utils.Decorate(\n          options.selectionAdapter,\n          AllowClear\n        );\n      }\n\n      if (options.multiple) {\n        options.selectionAdapter = Utils.Decorate(\n          options.selectionAdapter,\n          SelectionSearch\n        );\n      }\n\n      if (\n        options.containerCssClass != null ||\n        options.containerCss != null ||\n        options.adaptContainerCssClass != null\n      ) {\n        var ContainerCSS = require(options.amdBase + 'compat/containerCss');\n\n        options.selectionAdapter = Utils.Decorate(\n          options.selectionAdapter,\n          ContainerCSS\n        );\n      }\n\n      options.selectionAdapter = Utils.Decorate(\n        options.selectionAdapter,\n        EventRelay\n      );\n    }\n\n    if (typeof options.language === 'string') {\n      // Check if the language is specified with a region\n      if (options.language.indexOf('-') > 0) {\n        // Extract the region information if it is included\n        var languageParts = options.language.split('-');\n        var baseLanguage = languageParts[0];\n\n        options.language = [options.language, baseLanguage];\n      } else {\n        options.language = [options.language];\n      }\n    }\n\n    if ($.isArray(options.language)) {\n      var languages = new Translation();\n      options.language.push('en');\n\n      var languageNames = options.language;\n\n      for (var l = 0; l < languageNames.length; l++) {\n        var name = languageNames[l];\n        var language = {};\n\n        try {\n          // Try to load it with the original name\n          language = Translation.loadPath(name);\n        } catch (e) {\n          try {\n            // If we couldn't load it, check if it wasn't the full path\n            name = this.defaults.amdLanguageBase + name;\n            language = Translation.loadPath(name);\n          } catch (ex) {\n            // The translation could not be loaded at all. Sometimes this is\n            // because of a configuration problem, other times this can be\n            // because of how Select2 helps load all possible translation files.\n            if (options.debug && window.console && console.warn) {\n              console.warn(\n                'Select2: The language file for \"' + name + '\" could not be ' +\n                'automatically loaded. A fallback will be used instead.'\n              );\n            }\n\n            continue;\n          }\n        }\n\n        languages.extend(language);\n      }\n\n      options.translations = languages;\n    } else {\n      var baseTranslation = Translation.loadPath(\n        this.defaults.amdLanguageBase + 'en'\n      );\n      var customTranslation = new Translation(options.language);\n\n      customTranslation.extend(baseTranslation);\n\n      options.translations = customTranslation;\n    }\n\n    return options;\n  };\n\n  Defaults.prototype.reset = function () {\n    function stripDiacritics (text) {\n      // Used 'uni range + named function' from http://jsperf.com/diacritics/18\n      function match(a) {\n        return DIACRITICS[a] || a;\n      }\n\n      return text.replace(/[^\\u0000-\\u007E]/g, match);\n    }\n\n    function matcher (params, data) {\n      // Always return the object if there is nothing to compare\n      if ($.trim(params.term) === '') {\n        return data;\n      }\n\n      // Do a recursive check for options with children\n      if (data.children && data.children.length > 0) {\n        // Clone the data object if there are children\n        // This is required as we modify the object to remove any non-matches\n        var match = $.extend(true, {}, data);\n\n        // Check each child of the option\n        for (var c = data.children.length - 1; c >= 0; c--) {\n          var child = data.children[c];\n\n          var matches = matcher(params, child);\n\n          // If there wasn't a match, remove the object in the array\n          if (matches == null) {\n            match.children.splice(c, 1);\n          }\n        }\n\n        // If any children matched, return the new object\n        if (match.children.length > 0) {\n          return match;\n        }\n\n        // If there were no matching children, check just the plain object\n        return matcher(params, match);\n      }\n\n      var original = stripDiacritics(data.text).toUpperCase();\n      var term = stripDiacritics(params.term).toUpperCase();\n\n      // Check if the text contains the term\n      if (original.indexOf(term) > -1) {\n        return data;\n      }\n\n      // If it doesn't contain the term, don't return anything\n      return null;\n    }\n\n    this.defaults = {\n      amdBase: './',\n      amdLanguageBase: './i18n/',\n      closeOnSelect: true,\n      debug: false,\n      dropdownAutoWidth: false,\n      escapeMarkup: Utils.escapeMarkup,\n      language: EnglishTranslation,\n      matcher: matcher,\n      minimumInputLength: 0,\n      maximumInputLength: 0,\n      maximumSelectionLength: 0,\n      minimumResultsForSearch: 0,\n      selectOnClose: false,\n      sorter: function (data) {\n        return data;\n      },\n      templateResult: function (result) {\n        return result.text;\n      },\n      templateSelection: function (selection) {\n        return selection.text;\n      },\n      theme: 'default',\n      width: 'resolve'\n    };\n  };\n\n  Defaults.prototype.set = function (key, value) {\n    var camelKey = $.camelCase(key);\n\n    var data = {};\n    data[camelKey] = value;\n\n    var convertedData = Utils._convertData(data);\n\n    $.extend(this.defaults, convertedData);\n  };\n\n  var defaults = new Defaults();\n\n  return defaults;\n});\n\nS2.define('select2/options',[\n  'require',\n  'jquery',\n  './defaults',\n  './utils'\n], function (require, $, Defaults, Utils) {\n  function Options (options, $element) {\n    this.options = options;\n\n    if ($element != null) {\n      this.fromElement($element);\n    }\n\n    this.options = Defaults.apply(this.options);\n\n    if ($element && $element.is('input')) {\n      var InputCompat = require(this.get('amdBase') + 'compat/inputData');\n\n      this.options.dataAdapter = Utils.Decorate(\n        this.options.dataAdapter,\n        InputCompat\n      );\n    }\n  }\n\n  Options.prototype.fromElement = function ($e) {\n    var excludedData = ['select2'];\n\n    if (this.options.multiple == null) {\n      this.options.multiple = $e.prop('multiple');\n    }\n\n    if (this.options.disabled == null) {\n      this.options.disabled = $e.prop('disabled');\n    }\n\n    if (this.options.language == null) {\n      if ($e.prop('lang')) {\n        this.options.language = $e.prop('lang').toLowerCase();\n      } else if ($e.closest('[lang]').prop('lang')) {\n        this.options.language = $e.closest('[lang]').prop('lang');\n      }\n    }\n\n    if (this.options.dir == null) {\n      if ($e.prop('dir')) {\n        this.options.dir = $e.prop('dir');\n      } else if ($e.closest('[dir]').prop('dir')) {\n        this.options.dir = $e.closest('[dir]').prop('dir');\n      } else {\n        this.options.dir = 'ltr';\n      }\n    }\n\n    $e.prop('disabled', this.options.disabled);\n    $e.prop('multiple', this.options.multiple);\n\n    if ($e.data('select2Tags')) {\n      if (this.options.debug && window.console && console.warn) {\n        console.warn(\n          'Select2: The `data-select2-tags` attribute has been changed to ' +\n          'use the `data-data` and `data-tags=\"true\"` attributes and will be ' +\n          'removed in future versions of Select2.'\n        );\n      }\n\n      $e.data('data', $e.data('select2Tags'));\n      $e.data('tags', true);\n    }\n\n    if ($e.data('ajaxUrl')) {\n      if (this.options.debug && window.console && console.warn) {\n        console.warn(\n          'Select2: The `data-ajax-url` attribute has been changed to ' +\n          '`data-ajax--url` and support for the old attribute will be removed' +\n          ' in future versions of Select2.'\n        );\n      }\n\n      $e.attr('ajax--url', $e.data('ajaxUrl'));\n      $e.data('ajax--url', $e.data('ajaxUrl'));\n    }\n\n    var dataset = {};\n\n    // Prefer the element's `dataset` attribute if it exists\n    // jQuery 1.x does not correctly handle data attributes with multiple dashes\n    if ($.fn.jquery && $.fn.jquery.substr(0, 2) == '1.' && $e[0].dataset) {\n      dataset = $.extend(true, {}, $e[0].dataset, $e.data());\n    } else {\n      dataset = $e.data();\n    }\n\n    var data = $.extend(true, {}, dataset);\n\n    data = Utils._convertData(data);\n\n    for (var key in data) {\n      if ($.inArray(key, excludedData) > -1) {\n        continue;\n      }\n\n      if ($.isPlainObject(this.options[key])) {\n        $.extend(this.options[key], data[key]);\n      } else {\n        this.options[key] = data[key];\n      }\n    }\n\n    return this;\n  };\n\n  Options.prototype.get = function (key) {\n    return this.options[key];\n  };\n\n  Options.prototype.set = function (key, val) {\n    this.options[key] = val;\n  };\n\n  return Options;\n});\n\nS2.define('select2/core',[\n  'jquery',\n  './options',\n  './utils',\n  './keys'\n], function ($, Options, Utils, KEYS) {\n  var Select2 = function ($element, options) {\n    if ($element.data('select2') != null) {\n      $element.data('select2').destroy();\n    }\n\n    this.$element = $element;\n\n    this.id = this._generateId($element);\n\n    options = options || {};\n\n    this.options = new Options(options, $element);\n\n    Select2.__super__.constructor.call(this);\n\n    // Set up the tabindex\n\n    var tabindex = $element.attr('tabindex') || 0;\n    $element.data('old-tabindex', tabindex);\n    $element.attr('tabindex', '-1');\n\n    // Set up containers and adapters\n\n    var DataAdapter = this.options.get('dataAdapter');\n    this.dataAdapter = new DataAdapter($element, this.options);\n\n    var $container = this.render();\n\n    this._placeContainer($container);\n\n    var SelectionAdapter = this.options.get('selectionAdapter');\n    this.selection = new SelectionAdapter($element, this.options);\n    this.$selection = this.selection.render();\n\n    this.selection.position(this.$selection, $container);\n\n    var DropdownAdapter = this.options.get('dropdownAdapter');\n    this.dropdown = new DropdownAdapter($element, this.options);\n    this.$dropdown = this.dropdown.render();\n\n    this.dropdown.position(this.$dropdown, $container);\n\n    var ResultsAdapter = this.options.get('resultsAdapter');\n    this.results = new ResultsAdapter($element, this.options, this.dataAdapter);\n    this.$results = this.results.render();\n\n    this.results.position(this.$results, this.$dropdown);\n\n    // Bind events\n\n    var self = this;\n\n    // Bind the container to all of the adapters\n    this._bindAdapters();\n\n    // Register any DOM event handlers\n    this._registerDomEvents();\n\n    // Register any internal event handlers\n    this._registerDataEvents();\n    this._registerSelectionEvents();\n    this._registerDropdownEvents();\n    this._registerResultsEvents();\n    this._registerEvents();\n\n    // Set the initial state\n    this.dataAdapter.current(function (initialData) {\n      self.trigger('selection:update', {\n        data: initialData\n      });\n    });\n\n    // Hide the original select\n    $element.addClass('select2-hidden-accessible');\n    $element.attr('aria-hidden', 'true');\n\n    // Synchronize any monitored attributes\n    this._syncAttributes();\n\n    $element.data('select2', this);\n  };\n\n  Utils.Extend(Select2, Utils.Observable);\n\n  Select2.prototype._generateId = function ($element) {\n    var id = '';\n\n    if ($element.attr('id') != null) {\n      id = $element.attr('id');\n    } else if ($element.attr('name') != null) {\n      id = $element.attr('name') + '-' + Utils.generateChars(2);\n    } else {\n      id = Utils.generateChars(4);\n    }\n\n    id = id.replace(/(:|\\.|\\[|\\]|,)/g, '');\n    id = 'select2-' + id;\n\n    return id;\n  };\n\n  Select2.prototype._placeContainer = function ($container) {\n    $container.insertAfter(this.$element);\n\n    var width = this._resolveWidth(this.$element, this.options.get('width'));\n\n    if (width != null) {\n      $container.css('width', width);\n    }\n  };\n\n  Select2.prototype._resolveWidth = function ($element, method) {\n    var WIDTH = /^width:(([-+]?([0-9]*\\.)?[0-9]+)(px|em|ex|%|in|cm|mm|pt|pc))/i;\n\n    if (method == 'resolve') {\n      var styleWidth = this._resolveWidth($element, 'style');\n\n      if (styleWidth != null) {\n        return styleWidth;\n      }\n\n      return this._resolveWidth($element, 'element');\n    }\n\n    if (method == 'element') {\n      var elementWidth = $element.outerWidth(false);\n\n      if (elementWidth <= 0) {\n        return 'auto';\n      }\n\n      return elementWidth + 'px';\n    }\n\n    if (method == 'style') {\n      var style = $element.attr('style');\n\n      if (typeof(style) !== 'string') {\n        return null;\n      }\n\n      var attrs = style.split(';');\n\n      for (var i = 0, l = attrs.length; i < l; i = i + 1) {\n        var attr = attrs[i].replace(/\\s/g, '');\n        var matches = attr.match(WIDTH);\n\n        if (matches !== null && matches.length >= 1) {\n          return matches[1];\n        }\n      }\n\n      return null;\n    }\n\n    return method;\n  };\n\n  Select2.prototype._bindAdapters = function () {\n    this.dataAdapter.bind(this, this.$container);\n    this.selection.bind(this, this.$container);\n\n    this.dropdown.bind(this, this.$container);\n    this.results.bind(this, this.$container);\n  };\n\n  Select2.prototype._registerDomEvents = function () {\n    var self = this;\n\n    this.$element.on('change.select2', function () {\n      self.dataAdapter.current(function (data) {\n        self.trigger('selection:update', {\n          data: data\n        });\n      });\n    });\n\n    this.$element.on('focus.select2', function (evt) {\n      self.trigger('focus', evt);\n    });\n\n    this._syncA = Utils.bind(this._syncAttributes, this);\n    this._syncS = Utils.bind(this._syncSubtree, this);\n\n    if (this.$element[0].attachEvent) {\n      this.$element[0].attachEvent('onpropertychange', this._syncA);\n    }\n\n    var observer = window.MutationObserver ||\n      window.WebKitMutationObserver ||\n      window.MozMutationObserver\n    ;\n\n    if (observer != null) {\n      this._observer = new observer(function (mutations) {\n        $.each(mutations, self._syncA);\n        $.each(mutations, self._syncS);\n      });\n      this._observer.observe(this.$element[0], {\n        attributes: true,\n        childList: true,\n        subtree: false\n      });\n    } else if (this.$element[0].addEventListener) {\n      this.$element[0].addEventListener(\n        'DOMAttrModified',\n        self._syncA,\n        false\n      );\n      this.$element[0].addEventListener(\n        'DOMNodeInserted',\n        self._syncS,\n        false\n      );\n      this.$element[0].addEventListener(\n        'DOMNodeRemoved',\n        self._syncS,\n        false\n      );\n    }\n  };\n\n  Select2.prototype._registerDataEvents = function () {\n    var self = this;\n\n    this.dataAdapter.on('*', function (name, params) {\n      self.trigger(name, params);\n    });\n  };\n\n  Select2.prototype._registerSelectionEvents = function () {\n    var self = this;\n    var nonRelayEvents = ['toggle', 'focus'];\n\n    this.selection.on('toggle', function () {\n      self.toggleDropdown();\n    });\n\n    this.selection.on('focus', function (params) {\n      self.focus(params);\n    });\n\n    this.selection.on('*', function (name, params) {\n      if ($.inArray(name, nonRelayEvents) !== -1) {\n        return;\n      }\n\n      self.trigger(name, params);\n    });\n  };\n\n  Select2.prototype._registerDropdownEvents = function () {\n    var self = this;\n\n    this.dropdown.on('*', function (name, params) {\n      self.trigger(name, params);\n    });\n  };\n\n  Select2.prototype._registerResultsEvents = function () {\n    var self = this;\n\n    this.results.on('*', function (name, params) {\n      self.trigger(name, params);\n    });\n  };\n\n  Select2.prototype._registerEvents = function () {\n    var self = this;\n\n    this.on('open', function () {\n      self.$container.addClass('select2-container--open');\n    });\n\n    this.on('close', function () {\n      self.$container.removeClass('select2-container--open');\n    });\n\n    this.on('enable', function () {\n      self.$container.removeClass('select2-container--disabled');\n    });\n\n    this.on('disable', function () {\n      self.$container.addClass('select2-container--disabled');\n    });\n\n    this.on('blur', function () {\n      self.$container.removeClass('select2-container--focus');\n    });\n\n    this.on('query', function (params) {\n      if (!self.isOpen()) {\n        self.trigger('open', {});\n      }\n\n      this.dataAdapter.query(params, function (data) {\n        self.trigger('results:all', {\n          data: data,\n          query: params\n        });\n      });\n    });\n\n    this.on('query:append', function (params) {\n      this.dataAdapter.query(params, function (data) {\n        self.trigger('results:append', {\n          data: data,\n          query: params\n        });\n      });\n    });\n\n    this.on('keypress', function (evt) {\n      var key = evt.which;\n\n      if (self.isOpen()) {\n        if (key === KEYS.ESC || key === KEYS.TAB ||\n            (key === KEYS.UP && evt.altKey)) {\n          self.close();\n\n          evt.preventDefault();\n        } else if (key === KEYS.ENTER) {\n          self.trigger('results:select', {});\n\n          evt.preventDefault();\n        } else if ((key === KEYS.SPACE && evt.ctrlKey)) {\n          self.trigger('results:toggle', {});\n\n          evt.preventDefault();\n        } else if (key === KEYS.UP) {\n          self.trigger('results:previous', {});\n\n          evt.preventDefault();\n        } else if (key === KEYS.DOWN) {\n          self.trigger('results:next', {});\n\n          evt.preventDefault();\n        }\n      } else {\n        if (key === KEYS.ENTER || key === KEYS.SPACE ||\n            (key === KEYS.DOWN && evt.altKey)) {\n          self.open();\n\n          evt.preventDefault();\n        }\n      }\n    });\n  };\n\n  Select2.prototype._syncAttributes = function () {\n    this.options.set('disabled', this.$element.prop('disabled'));\n\n    if (this.options.get('disabled')) {\n      if (this.isOpen()) {\n        this.close();\n      }\n\n      this.trigger('disable', {});\n    } else {\n      this.trigger('enable', {});\n    }\n  };\n\n  Select2.prototype._syncSubtree = function (evt, mutations) {\n    var changed = false;\n    var self = this;\n\n    // Ignore any mutation events raised for elements that aren't options or\n    // optgroups. This handles the case when the select element is destroyed\n    if (\n      evt && evt.target && (\n        evt.target.nodeName !== 'OPTION' && evt.target.nodeName !== 'OPTGROUP'\n      )\n    ) {\n      return;\n    }\n\n    if (!mutations) {\n      // If mutation events aren't supported, then we can only assume that the\n      // change affected the selections\n      changed = true;\n    } else if (mutations.addedNodes && mutations.addedNodes.length > 0) {\n      for (var n = 0; n < mutations.addedNodes.length; n++) {\n        var node = mutations.addedNodes[n];\n\n        if (node.selected) {\n          changed = true;\n        }\n      }\n    } else if (mutations.removedNodes && mutations.removedNodes.length > 0) {\n      changed = true;\n    }\n\n    // Only re-pull the data if we think there is a change\n    if (changed) {\n      this.dataAdapter.current(function (currentData) {\n        self.trigger('selection:update', {\n          data: currentData\n        });\n      });\n    }\n  };\n\n  /**\n   * Override the trigger method to automatically trigger pre-events when\n   * there are events that can be prevented.\n   */\n  Select2.prototype.trigger = function (name, args) {\n    var actualTrigger = Select2.__super__.trigger;\n    var preTriggerMap = {\n      'open': 'opening',\n      'close': 'closing',\n      'select': 'selecting',\n      'unselect': 'unselecting'\n    };\n\n    if (args === undefined) {\n      args = {};\n    }\n\n    if (name in preTriggerMap) {\n      var preTriggerName = preTriggerMap[name];\n      var preTriggerArgs = {\n        prevented: false,\n        name: name,\n        args: args\n      };\n\n      actualTrigger.call(this, preTriggerName, preTriggerArgs);\n\n      if (preTriggerArgs.prevented) {\n        args.prevented = true;\n\n        return;\n      }\n    }\n\n    actualTrigger.call(this, name, args);\n  };\n\n  Select2.prototype.toggleDropdown = function () {\n    if (this.options.get('disabled')) {\n      return;\n    }\n\n    if (this.isOpen()) {\n      this.close();\n    } else {\n      this.open();\n    }\n  };\n\n  Select2.prototype.open = function () {\n    if (this.isOpen()) {\n      return;\n    }\n\n    this.trigger('query', {});\n  };\n\n  Select2.prototype.close = function () {\n    if (!this.isOpen()) {\n      return;\n    }\n\n    this.trigger('close', {});\n  };\n\n  Select2.prototype.isOpen = function () {\n    return this.$container.hasClass('select2-container--open');\n  };\n\n  Select2.prototype.hasFocus = function () {\n    return this.$container.hasClass('select2-container--focus');\n  };\n\n  Select2.prototype.focus = function (data) {\n    // No need to re-trigger focus events if we are already focused\n    if (this.hasFocus()) {\n      return;\n    }\n\n    this.$container.addClass('select2-container--focus');\n    this.trigger('focus', {});\n  };\n\n  Select2.prototype.enable = function (args) {\n    if (this.options.get('debug') && window.console && console.warn) {\n      console.warn(\n        'Select2: The `select2(\"enable\")` method has been deprecated and will' +\n        ' be removed in later Select2 versions. Use $element.prop(\"disabled\")' +\n        ' instead.'\n      );\n    }\n\n    if (args == null || args.length === 0) {\n      args = [true];\n    }\n\n    var disabled = !args[0];\n\n    this.$element.prop('disabled', disabled);\n  };\n\n  Select2.prototype.data = function () {\n    if (this.options.get('debug') &&\n        arguments.length > 0 && window.console && console.warn) {\n      console.warn(\n        'Select2: Data can no longer be set using `select2(\"data\")`. You ' +\n        'should consider setting the value instead using `$element.val()`.'\n      );\n    }\n\n    var data = [];\n\n    this.dataAdapter.current(function (currentData) {\n      data = currentData;\n    });\n\n    return data;\n  };\n\n  Select2.prototype.val = function (args) {\n    if (this.options.get('debug') && window.console && console.warn) {\n      console.warn(\n        'Select2: The `select2(\"val\")` method has been deprecated and will be' +\n        ' removed in later Select2 versions. Use $element.val() instead.'\n      );\n    }\n\n    if (args == null || args.length === 0) {\n      return this.$element.val();\n    }\n\n    var newVal = args[0];\n\n    if ($.isArray(newVal)) {\n      newVal = $.map(newVal, function (obj) {\n        return obj.toString();\n      });\n    }\n\n    this.$element.val(newVal).trigger('change');\n  };\n\n  Select2.prototype.destroy = function () {\n    this.$container.remove();\n\n    if (this.$element[0].detachEvent) {\n      this.$element[0].detachEvent('onpropertychange', this._syncA);\n    }\n\n    if (this._observer != null) {\n      this._observer.disconnect();\n      this._observer = null;\n    } else if (this.$element[0].removeEventListener) {\n      this.$element[0]\n        .removeEventListener('DOMAttrModified', this._syncA, false);\n      this.$element[0]\n        .removeEventListener('DOMNodeInserted', this._syncS, false);\n      this.$element[0]\n        .removeEventListener('DOMNodeRemoved', this._syncS, false);\n    }\n\n    this._syncA = null;\n    this._syncS = null;\n\n    this.$element.off('.select2');\n    this.$element.attr('tabindex', this.$element.data('old-tabindex'));\n\n    this.$element.removeClass('select2-hidden-accessible');\n    this.$element.attr('aria-hidden', 'false');\n    this.$element.removeData('select2');\n\n    this.dataAdapter.destroy();\n    this.selection.destroy();\n    this.dropdown.destroy();\n    this.results.destroy();\n\n    this.dataAdapter = null;\n    this.selection = null;\n    this.dropdown = null;\n    this.results = null;\n  };\n\n  Select2.prototype.render = function () {\n    var $container = $(\n      '<span class=\"select2 select2-container\">' +\n        '<span class=\"selection\"></span>' +\n        '<span class=\"dropdown-wrapper\" aria-hidden=\"true\"></span>' +\n      '</span>'\n    );\n\n    $container.attr('dir', this.options.get('dir'));\n\n    this.$container = $container;\n\n    this.$container.addClass('select2-container--' + this.options.get('theme'));\n\n    $container.data('element', this.$element);\n\n    return $container;\n  };\n\n  return Select2;\n});\n\nS2.define('select2/compat/utils',[\n  'jquery'\n], function ($) {\n  function syncCssClasses ($dest, $src, adapter) {\n    var classes, replacements = [], adapted;\n\n    classes = $.trim($dest.attr('class'));\n\n    if (classes) {\n      classes = '' + classes; // for IE which returns object\n\n      $(classes.split(/\\s+/)).each(function () {\n        // Save all Select2 classes\n        if (this.indexOf('select2-') === 0) {\n          replacements.push(this);\n        }\n      });\n    }\n\n    classes = $.trim($src.attr('class'));\n\n    if (classes) {\n      classes = '' + classes; // for IE which returns object\n\n      $(classes.split(/\\s+/)).each(function () {\n        // Only adapt non-Select2 classes\n        if (this.indexOf('select2-') !== 0) {\n          adapted = adapter(this);\n\n          if (adapted != null) {\n            replacements.push(adapted);\n          }\n        }\n      });\n    }\n\n    $dest.attr('class', replacements.join(' '));\n  }\n\n  return {\n    syncCssClasses: syncCssClasses\n  };\n});\n\nS2.define('select2/compat/containerCss',[\n  'jquery',\n  './utils'\n], function ($, CompatUtils) {\n  // No-op CSS adapter that discards all classes by default\n  function _containerAdapter (clazz) {\n    return null;\n  }\n\n  function ContainerCSS () { }\n\n  ContainerCSS.prototype.render = function (decorated) {\n    var $container = decorated.call(this);\n\n    var containerCssClass = this.options.get('containerCssClass') || '';\n\n    if ($.isFunction(containerCssClass)) {\n      containerCssClass = containerCssClass(this.$element);\n    }\n\n    var containerCssAdapter = this.options.get('adaptContainerCssClass');\n    containerCssAdapter = containerCssAdapter || _containerAdapter;\n\n    if (containerCssClass.indexOf(':all:') !== -1) {\n      containerCssClass = containerCssClass.replace(':all:', '');\n\n      var _cssAdapter = containerCssAdapter;\n\n      containerCssAdapter = function (clazz) {\n        var adapted = _cssAdapter(clazz);\n\n        if (adapted != null) {\n          // Append the old one along with the adapted one\n          return adapted + ' ' + clazz;\n        }\n\n        return clazz;\n      };\n    }\n\n    var containerCss = this.options.get('containerCss') || {};\n\n    if ($.isFunction(containerCss)) {\n      containerCss = containerCss(this.$element);\n    }\n\n    CompatUtils.syncCssClasses($container, this.$element, containerCssAdapter);\n\n    $container.css(containerCss);\n    $container.addClass(containerCssClass);\n\n    return $container;\n  };\n\n  return ContainerCSS;\n});\n\nS2.define('select2/compat/dropdownCss',[\n  'jquery',\n  './utils'\n], function ($, CompatUtils) {\n  // No-op CSS adapter that discards all classes by default\n  function _dropdownAdapter (clazz) {\n    return null;\n  }\n\n  function DropdownCSS () { }\n\n  DropdownCSS.prototype.render = function (decorated) {\n    var $dropdown = decorated.call(this);\n\n    var dropdownCssClass = this.options.get('dropdownCssClass') || '';\n\n    if ($.isFunction(dropdownCssClass)) {\n      dropdownCssClass = dropdownCssClass(this.$element);\n    }\n\n    var dropdownCssAdapter = this.options.get('adaptDropdownCssClass');\n    dropdownCssAdapter = dropdownCssAdapter || _dropdownAdapter;\n\n    if (dropdownCssClass.indexOf(':all:') !== -1) {\n      dropdownCssClass = dropdownCssClass.replace(':all:', '');\n\n      var _cssAdapter = dropdownCssAdapter;\n\n      dropdownCssAdapter = function (clazz) {\n        var adapted = _cssAdapter(clazz);\n\n        if (adapted != null) {\n          // Append the old one along with the adapted one\n          return adapted + ' ' + clazz;\n        }\n\n        return clazz;\n      };\n    }\n\n    var dropdownCss = this.options.get('dropdownCss') || {};\n\n    if ($.isFunction(dropdownCss)) {\n      dropdownCss = dropdownCss(this.$element);\n    }\n\n    CompatUtils.syncCssClasses($dropdown, this.$element, dropdownCssAdapter);\n\n    $dropdown.css(dropdownCss);\n    $dropdown.addClass(dropdownCssClass);\n\n    return $dropdown;\n  };\n\n  return DropdownCSS;\n});\n\nS2.define('select2/compat/initSelection',[\n  'jquery'\n], function ($) {\n  function InitSelection (decorated, $element, options) {\n    if (options.get('debug') && window.console && console.warn) {\n      console.warn(\n        'Select2: The `initSelection` option has been deprecated in favor' +\n        ' of a custom data adapter that overrides the `current` method. ' +\n        'This method is now called multiple times instead of a single ' +\n        'time when the instance is initialized. Support will be removed ' +\n        'for the `initSelection` option in future versions of Select2'\n      );\n    }\n\n    this.initSelection = options.get('initSelection');\n    this._isInitialized = false;\n\n    decorated.call(this, $element, options);\n  }\n\n  InitSelection.prototype.current = function (decorated, callback) {\n    var self = this;\n\n    if (this._isInitialized) {\n      decorated.call(this, callback);\n\n      return;\n    }\n\n    this.initSelection.call(null, this.$element, function (data) {\n      self._isInitialized = true;\n\n      if (!$.isArray(data)) {\n        data = [data];\n      }\n\n      callback(data);\n    });\n  };\n\n  return InitSelection;\n});\n\nS2.define('select2/compat/inputData',[\n  'jquery'\n], function ($) {\n  function InputData (decorated, $element, options) {\n    this._currentData = [];\n    this._valueSeparator = options.get('valueSeparator') || ',';\n\n    if ($element.prop('type') === 'hidden') {\n      if (options.get('debug') && console && console.warn) {\n        console.warn(\n          'Select2: Using a hidden input with Select2 is no longer ' +\n          'supported and may stop working in the future. It is recommended ' +\n          'to use a `<select>` element instead.'\n        );\n      }\n    }\n\n    decorated.call(this, $element, options);\n  }\n\n  InputData.prototype.current = function (_, callback) {\n    function getSelected (data, selectedIds) {\n      var selected = [];\n\n      if (data.selected || $.inArray(data.id, selectedIds) !== -1) {\n        data.selected = true;\n        selected.push(data);\n      } else {\n        data.selected = false;\n      }\n\n      if (data.children) {\n        selected.push.apply(selected, getSelected(data.children, selectedIds));\n      }\n\n      return selected;\n    }\n\n    var selected = [];\n\n    for (var d = 0; d < this._currentData.length; d++) {\n      var data = this._currentData[d];\n\n      selected.push.apply(\n        selected,\n        getSelected(\n          data,\n          this.$element.val().split(\n            this._valueSeparator\n          )\n        )\n      );\n    }\n\n    callback(selected);\n  };\n\n  InputData.prototype.select = function (_, data) {\n    if (!this.options.get('multiple')) {\n      this.current(function (allData) {\n        $.map(allData, function (data) {\n          data.selected = false;\n        });\n      });\n\n      this.$element.val(data.id);\n      this.$element.trigger('change');\n    } else {\n      var value = this.$element.val();\n      value += this._valueSeparator + data.id;\n\n      this.$element.val(value);\n      this.$element.trigger('change');\n    }\n  };\n\n  InputData.prototype.unselect = function (_, data) {\n    var self = this;\n\n    data.selected = false;\n\n    this.current(function (allData) {\n      var values = [];\n\n      for (var d = 0; d < allData.length; d++) {\n        var item = allData[d];\n\n        if (data.id == item.id) {\n          continue;\n        }\n\n        values.push(item.id);\n      }\n\n      self.$element.val(values.join(self._valueSeparator));\n      self.$element.trigger('change');\n    });\n  };\n\n  InputData.prototype.query = function (_, params, callback) {\n    var results = [];\n\n    for (var d = 0; d < this._currentData.length; d++) {\n      var data = this._currentData[d];\n\n      var matches = this.matches(params, data);\n\n      if (matches !== null) {\n        results.push(matches);\n      }\n    }\n\n    callback({\n      results: results\n    });\n  };\n\n  InputData.prototype.addOptions = function (_, $options) {\n    var options = $.map($options, function ($option) {\n      return $.data($option[0], 'data');\n    });\n\n    this._currentData.push.apply(this._currentData, options);\n  };\n\n  return InputData;\n});\n\nS2.define('select2/compat/matcher',[\n  'jquery'\n], function ($) {\n  function oldMatcher (matcher) {\n    function wrappedMatcher (params, data) {\n      var match = $.extend(true, {}, data);\n\n      if (params.term == null || $.trim(params.term) === '') {\n        return match;\n      }\n\n      if (data.children) {\n        for (var c = data.children.length - 1; c >= 0; c--) {\n          var child = data.children[c];\n\n          // Check if the child object matches\n          // The old matcher returned a boolean true or false\n          var doesMatch = matcher(params.term, child.text, child);\n\n          // If the child didn't match, pop it off\n          if (!doesMatch) {\n            match.children.splice(c, 1);\n          }\n        }\n\n        if (match.children.length > 0) {\n          return match;\n        }\n      }\n\n      if (matcher(params.term, data.text, data)) {\n        return match;\n      }\n\n      return null;\n    }\n\n    return wrappedMatcher;\n  }\n\n  return oldMatcher;\n});\n\nS2.define('select2/compat/query',[\n\n], function () {\n  function Query (decorated, $element, options) {\n    if (options.get('debug') && window.console && console.warn) {\n      console.warn(\n        'Select2: The `query` option has been deprecated in favor of a ' +\n        'custom data adapter that overrides the `query` method. Support ' +\n        'will be removed for the `query` option in future versions of ' +\n        'Select2.'\n      );\n    }\n\n    decorated.call(this, $element, options);\n  }\n\n  Query.prototype.query = function (_, params, callback) {\n    params.callback = callback;\n\n    var query = this.options.get('query');\n\n    query.call(null, params);\n  };\n\n  return Query;\n});\n\nS2.define('select2/dropdown/attachContainer',[\n\n], function () {\n  function AttachContainer (decorated, $element, options) {\n    decorated.call(this, $element, options);\n  }\n\n  AttachContainer.prototype.position =\n    function (decorated, $dropdown, $container) {\n    var $dropdownContainer = $container.find('.dropdown-wrapper');\n    $dropdownContainer.append($dropdown);\n\n    $dropdown.addClass('select2-dropdown--below');\n    $container.addClass('select2-container--below');\n  };\n\n  return AttachContainer;\n});\n\nS2.define('select2/dropdown/stopPropagation',[\n\n], function () {\n  function StopPropagation () { }\n\n  StopPropagation.prototype.bind = function (decorated, container, $container) {\n    decorated.call(this, container, $container);\n\n    var stoppedEvents = [\n    'blur',\n    'change',\n    'click',\n    'dblclick',\n    'focus',\n    'focusin',\n    'focusout',\n    'input',\n    'keydown',\n    'keyup',\n    'keypress',\n    'mousedown',\n    'mouseenter',\n    'mouseleave',\n    'mousemove',\n    'mouseover',\n    'mouseup',\n    'search',\n    'touchend',\n    'touchstart'\n    ];\n\n    this.$dropdown.on(stoppedEvents.join(' '), function (evt) {\n      evt.stopPropagation();\n    });\n  };\n\n  return StopPropagation;\n});\n\nS2.define('select2/selection/stopPropagation',[\n\n], function () {\n  function StopPropagation () { }\n\n  StopPropagation.prototype.bind = function (decorated, container, $container) {\n    decorated.call(this, container, $container);\n\n    var stoppedEvents = [\n      'blur',\n      'change',\n      'click',\n      'dblclick',\n      'focus',\n      'focusin',\n      'focusout',\n      'input',\n      'keydown',\n      'keyup',\n      'keypress',\n      'mousedown',\n      'mouseenter',\n      'mouseleave',\n      'mousemove',\n      'mouseover',\n      'mouseup',\n      'search',\n      'touchend',\n      'touchstart'\n    ];\n\n    this.$selection.on(stoppedEvents.join(' '), function (evt) {\n      evt.stopPropagation();\n    });\n  };\n\n  return StopPropagation;\n});\n\n/*!\n * jQuery Mousewheel 3.1.13\n *\n * Copyright jQuery Foundation and other contributors\n * Released under the MIT license\n * http://jquery.org/license\n */\n\n(function (factory) {\n    if ( typeof S2.define === 'function' && S2.define.amd ) {\n        // AMD. Register as an anonymous module.\n        S2.define('jquery-mousewheel',['jquery'], factory);\n    } else if (typeof exports === 'object') {\n        // Node/CommonJS style for Browserify\n        module.exports = factory;\n    } else {\n        // Browser globals\n        factory(jQuery);\n    }\n}(function ($) {\n\n    var toFix  = ['wheel', 'mousewheel', 'DOMMouseScroll', 'MozMousePixelScroll'],\n        toBind = ( 'onwheel' in document || document.documentMode >= 9 ) ?\n                    ['wheel'] : ['mousewheel', 'DomMouseScroll', 'MozMousePixelScroll'],\n        slice  = Array.prototype.slice,\n        nullLowestDeltaTimeout, lowestDelta;\n\n    if ( $.event.fixHooks ) {\n        for ( var i = toFix.length; i; ) {\n            $.event.fixHooks[ toFix[--i] ] = $.event.mouseHooks;\n        }\n    }\n\n    var special = $.event.special.mousewheel = {\n        version: '3.1.12',\n\n        setup: function() {\n            if ( this.addEventListener ) {\n                for ( var i = toBind.length; i; ) {\n                    this.addEventListener( toBind[--i], handler, false );\n                }\n            } else {\n                this.onmousewheel = handler;\n            }\n            // Store the line height and page height for this particular element\n            $.data(this, 'mousewheel-line-height', special.getLineHeight(this));\n            $.data(this, 'mousewheel-page-height', special.getPageHeight(this));\n        },\n\n        teardown: function() {\n            if ( this.removeEventListener ) {\n                for ( var i = toBind.length; i; ) {\n                    this.removeEventListener( toBind[--i], handler, false );\n                }\n            } else {\n                this.onmousewheel = null;\n            }\n            // Clean up the data we added to the element\n            $.removeData(this, 'mousewheel-line-height');\n            $.removeData(this, 'mousewheel-page-height');\n        },\n\n        getLineHeight: function(elem) {\n            var $elem = $(elem),\n                $parent = $elem['offsetParent' in $.fn ? 'offsetParent' : 'parent']();\n            if (!$parent.length) {\n                $parent = $('body');\n            }\n            return parseInt($parent.css('fontSize'), 10) || parseInt($elem.css('fontSize'), 10) || 16;\n        },\n\n        getPageHeight: function(elem) {\n            return $(elem).height();\n        },\n\n        settings: {\n            adjustOldDeltas: true, // see shouldAdjustOldDeltas() below\n            normalizeOffset: true  // calls getBoundingClientRect for each event\n        }\n    };\n\n    $.fn.extend({\n        mousewheel: function(fn) {\n            return fn ? this.bind('mousewheel', fn) : this.trigger('mousewheel');\n        },\n\n        unmousewheel: function(fn) {\n            return this.unbind('mousewheel', fn);\n        }\n    });\n\n\n    function handler(event) {\n        var orgEvent   = event || window.event,\n            args       = slice.call(arguments, 1),\n            delta      = 0,\n            deltaX     = 0,\n            deltaY     = 0,\n            absDelta   = 0,\n            offsetX    = 0,\n            offsetY    = 0;\n        event = $.event.fix(orgEvent);\n        event.type = 'mousewheel';\n\n        // Old school scrollwheel delta\n        if ( 'detail'      in orgEvent ) { deltaY = orgEvent.detail * -1;      }\n        if ( 'wheelDelta'  in orgEvent ) { deltaY = orgEvent.wheelDelta;       }\n        if ( 'wheelDeltaY' in orgEvent ) { deltaY = orgEvent.wheelDeltaY;      }\n        if ( 'wheelDeltaX' in orgEvent ) { deltaX = orgEvent.wheelDeltaX * -1; }\n\n        // Firefox < 17 horizontal scrolling related to DOMMouseScroll event\n        if ( 'axis' in orgEvent && orgEvent.axis === orgEvent.HORIZONTAL_AXIS ) {\n            deltaX = deltaY * -1;\n            deltaY = 0;\n        }\n\n        // Set delta to be deltaY or deltaX if deltaY is 0 for backwards compatabilitiy\n        delta = deltaY === 0 ? deltaX : deltaY;\n\n        // New school wheel delta (wheel event)\n        if ( 'deltaY' in orgEvent ) {\n            deltaY = orgEvent.deltaY * -1;\n            delta  = deltaY;\n        }\n        if ( 'deltaX' in orgEvent ) {\n            deltaX = orgEvent.deltaX;\n            if ( deltaY === 0 ) { delta  = deltaX * -1; }\n        }\n\n        // No change actually happened, no reason to go any further\n        if ( deltaY === 0 && deltaX === 0 ) { return; }\n\n        // Need to convert lines and pages to pixels if we aren't already in pixels\n        // There are three delta modes:\n        //   * deltaMode 0 is by pixels, nothing to do\n        //   * deltaMode 1 is by lines\n        //   * deltaMode 2 is by pages\n        if ( orgEvent.deltaMode === 1 ) {\n            var lineHeight = $.data(this, 'mousewheel-line-height');\n            delta  *= lineHeight;\n            deltaY *= lineHeight;\n            deltaX *= lineHeight;\n        } else if ( orgEvent.deltaMode === 2 ) {\n            var pageHeight = $.data(this, 'mousewheel-page-height');\n            delta  *= pageHeight;\n            deltaY *= pageHeight;\n            deltaX *= pageHeight;\n        }\n\n        // Store lowest absolute delta to normalize the delta values\n        absDelta = Math.max( Math.abs(deltaY), Math.abs(deltaX) );\n\n        if ( !lowestDelta || absDelta < lowestDelta ) {\n            lowestDelta = absDelta;\n\n            // Adjust older deltas if necessary\n            if ( shouldAdjustOldDeltas(orgEvent, absDelta) ) {\n                lowestDelta /= 40;\n            }\n        }\n\n        // Adjust older deltas if necessary\n        if ( shouldAdjustOldDeltas(orgEvent, absDelta) ) {\n            // Divide all the things by 40!\n            delta  /= 40;\n            deltaX /= 40;\n            deltaY /= 40;\n        }\n\n        // Get a whole, normalized value for the deltas\n        delta  = Math[ delta  >= 1 ? 'floor' : 'ceil' ](delta  / lowestDelta);\n        deltaX = Math[ deltaX >= 1 ? 'floor' : 'ceil' ](deltaX / lowestDelta);\n        deltaY = Math[ deltaY >= 1 ? 'floor' : 'ceil' ](deltaY / lowestDelta);\n\n        // Normalise offsetX and offsetY properties\n        if ( special.settings.normalizeOffset && this.getBoundingClientRect ) {\n            var boundingRect = this.getBoundingClientRect();\n            offsetX = event.clientX - boundingRect.left;\n            offsetY = event.clientY - boundingRect.top;\n        }\n\n        // Add information to the event object\n        event.deltaX = deltaX;\n        event.deltaY = deltaY;\n        event.deltaFactor = lowestDelta;\n        event.offsetX = offsetX;\n        event.offsetY = offsetY;\n        // Go ahead and set deltaMode to 0 since we converted to pixels\n        // Although this is a little odd since we overwrite the deltaX/Y\n        // properties with normalized deltas.\n        event.deltaMode = 0;\n\n        // Add event and delta to the front of the arguments\n        args.unshift(event, delta, deltaX, deltaY);\n\n        // Clearout lowestDelta after sometime to better\n        // handle multiple device types that give different\n        // a different lowestDelta\n        // Ex: trackpad = 3 and mouse wheel = 120\n        if (nullLowestDeltaTimeout) { clearTimeout(nullLowestDeltaTimeout); }\n        nullLowestDeltaTimeout = setTimeout(nullLowestDelta, 200);\n\n        return ($.event.dispatch || $.event.handle).apply(this, args);\n    }\n\n    function nullLowestDelta() {\n        lowestDelta = null;\n    }\n\n    function shouldAdjustOldDeltas(orgEvent, absDelta) {\n        // If this is an older event and the delta is divisable by 120,\n        // then we are assuming that the browser is treating this as an\n        // older mouse wheel event and that we should divide the deltas\n        // by 40 to try and get a more usable deltaFactor.\n        // Side note, this actually impacts the reported scroll distance\n        // in older browsers and can cause scrolling to be slower than native.\n        // Turn this off by setting $.event.special.mousewheel.settings.adjustOldDeltas to false.\n        return special.settings.adjustOldDeltas && orgEvent.type === 'mousewheel' && absDelta % 120 === 0;\n    }\n\n}));\n\nS2.define('jquery.select2',[\n  'jquery',\n  'jquery-mousewheel',\n\n  './select2/core',\n  './select2/defaults'\n], function ($, _, Select2, Defaults) {\n  if ($.fn.select2 == null) {\n    // All methods that should return the element\n    var thisMethods = ['open', 'close', 'destroy'];\n\n    $.fn.select2 = function (options) {\n      options = options || {};\n\n      if (typeof options === 'object') {\n        this.each(function () {\n          var instanceOptions = $.extend(true, {}, options);\n\n          var instance = new Select2($(this), instanceOptions);\n        });\n\n        return this;\n      } else if (typeof options === 'string') {\n        var ret;\n        var args = Array.prototype.slice.call(arguments, 1);\n\n        this.each(function () {\n          var instance = $(this).data('select2');\n\n          if (instance == null && window.console && console.error) {\n            console.error(\n              'The select2(\\'' + options + '\\') method was called on an ' +\n              'element that is not using Select2.'\n            );\n          }\n\n          ret = instance[options].apply(instance, args);\n        });\n\n        // Check if we should be returning `this`\n        if ($.inArray(options, thisMethods) > -1) {\n          return this;\n        }\n\n        return ret;\n      } else {\n        throw new Error('Invalid arguments for Select2: ' + options);\n      }\n    };\n  }\n\n  if ($.fn.select2.defaults == null) {\n    $.fn.select2.defaults = Defaults;\n  }\n\n  return Select2;\n});\n\n  // Return the AMD loader configuration so it can be used outside of this file\n  return {\n    define: S2.define,\n    require: S2.require\n  };\n}());\n\n  // Autoload the jQuery bindings\n  // We know that all of the modules exist above this, so we're safe\n  var select2 = S2.require('jquery.select2');\n\n  // Hold the AMD module references on the jQuery function that was just loaded\n  // This allows Select2 to use the internal loader outside of this file, such\n  // as in the language files.\n  jQuery.fn.select2.amd = S2;\n\n  // Return the Select2 instance for anyone who is importing it.\n  return select2;\n}));\n"
  },
  {
    "path": "src/static_cdn/admin/js/vendor/xregexp/LICENSE.txt",
    "content": "The MIT License\n\nCopyright (c) 2007-2012 Steven Levithan <http://xregexp.com/>\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n"
  },
  {
    "path": "src/static_cdn/admin/js/vendor/xregexp/xregexp.js",
    "content": "\n/***** xregexp.js *****/\n\n/*!\n * XRegExp v2.0.0\n * (c) 2007-2012 Steven Levithan <http://xregexp.com/>\n * MIT License\n */\n\n/**\n * XRegExp provides augmented, extensible JavaScript regular expressions. You get new syntax,\n * flags, and methods beyond what browsers support natively. XRegExp is also a regex utility belt\n * with tools to make your client-side grepping simpler and more powerful, while freeing you from\n * worrying about pesky cross-browser inconsistencies and the dubious `lastIndex` property. See\n * XRegExp's documentation (http://xregexp.com/) for more details.\n * @module xregexp\n * @requires N/A\n */\nvar XRegExp;\n\n// Avoid running twice; that would reset tokens and could break references to native globals\nXRegExp = XRegExp || (function (undef) {\n    \"use strict\";\n\n/*--------------------------------------\n *  Private variables\n *------------------------------------*/\n\n    var self,\n        addToken,\n        add,\n\n// Optional features; can be installed and uninstalled\n        features = {\n            natives: false,\n            extensibility: false\n        },\n\n// Store native methods to use and restore (\"native\" is an ES3 reserved keyword)\n        nativ = {\n            exec: RegExp.prototype.exec,\n            test: RegExp.prototype.test,\n            match: String.prototype.match,\n            replace: String.prototype.replace,\n            split: String.prototype.split\n        },\n\n// Storage for fixed/extended native methods\n        fixed = {},\n\n// Storage for cached regexes\n        cache = {},\n\n// Storage for addon tokens\n        tokens = [],\n\n// Token scopes\n        defaultScope = \"default\",\n        classScope = \"class\",\n\n// Regexes that match native regex syntax\n        nativeTokens = {\n            // Any native multicharacter token in default scope (includes octals, excludes character classes)\n            \"default\": /^(?:\\\\(?:0(?:[0-3][0-7]{0,2}|[4-7][0-7]?)?|[1-9]\\d*|x[\\dA-Fa-f]{2}|u[\\dA-Fa-f]{4}|c[A-Za-z]|[\\s\\S])|\\(\\?[:=!]|[?*+]\\?|{\\d+(?:,\\d*)?}\\??)/,\n            // Any native multicharacter token in character class scope (includes octals)\n            \"class\": /^(?:\\\\(?:[0-3][0-7]{0,2}|[4-7][0-7]?|x[\\dA-Fa-f]{2}|u[\\dA-Fa-f]{4}|c[A-Za-z]|[\\s\\S]))/\n        },\n\n// Any backreference in replacement strings\n        replacementToken = /\\$(?:{([\\w$]+)}|(\\d\\d?|[\\s\\S]))/g,\n\n// Any character with a later instance in the string\n        duplicateFlags = /([\\s\\S])(?=[\\s\\S]*\\1)/g,\n\n// Any greedy/lazy quantifier\n        quantifier = /^(?:[?*+]|{\\d+(?:,\\d*)?})\\??/,\n\n// Check for correct `exec` handling of nonparticipating capturing groups\n        compliantExecNpcg = nativ.exec.call(/()??/, \"\")[1] === undef,\n\n// Check for flag y support (Firefox 3+)\n        hasNativeY = RegExp.prototype.sticky !== undef,\n\n// Used to kill infinite recursion during XRegExp construction\n        isInsideConstructor = false,\n\n// Storage for known flags, including addon flags\n        registeredFlags = \"gim\" + (hasNativeY ? \"y\" : \"\");\n\n/*--------------------------------------\n *  Private helper functions\n *------------------------------------*/\n\n/**\n * Attaches XRegExp.prototype properties and named capture supporting data to a regex object.\n * @private\n * @param {RegExp} regex Regex to augment.\n * @param {Array} captureNames Array with capture names, or null.\n * @param {Boolean} [isNative] Whether the regex was created by `RegExp` rather than `XRegExp`.\n * @returns {RegExp} Augmented regex.\n */\n    function augment(regex, captureNames, isNative) {\n        var p;\n        // Can't auto-inherit these since the XRegExp constructor returns a nonprimitive value\n        for (p in self.prototype) {\n            if (self.prototype.hasOwnProperty(p)) {\n                regex[p] = self.prototype[p];\n            }\n        }\n        regex.xregexp = {captureNames: captureNames, isNative: !!isNative};\n        return regex;\n    }\n\n/**\n * Returns native `RegExp` flags used by a regex object.\n * @private\n * @param {RegExp} regex Regex to check.\n * @returns {String} Native flags in use.\n */\n    function getNativeFlags(regex) {\n        //return nativ.exec.call(/\\/([a-z]*)$/i, String(regex))[1];\n        return (regex.global     ? \"g\" : \"\") +\n               (regex.ignoreCase ? \"i\" : \"\") +\n               (regex.multiline  ? \"m\" : \"\") +\n               (regex.extended   ? \"x\" : \"\") + // Proposed for ES6, included in AS3\n               (regex.sticky     ? \"y\" : \"\"); // Proposed for ES6, included in Firefox 3+\n    }\n\n/**\n * Copies a regex object while preserving special properties for named capture and augmenting with\n * `XRegExp.prototype` methods. The copy has a fresh `lastIndex` property (set to zero). Allows\n * adding and removing flags while copying the regex.\n * @private\n * @param {RegExp} regex Regex to copy.\n * @param {String} [addFlags] Flags to be added while copying the regex.\n * @param {String} [removeFlags] Flags to be removed while copying the regex.\n * @returns {RegExp} Copy of the provided regex, possibly with modified flags.\n */\n    function copy(regex, addFlags, removeFlags) {\n        if (!self.isRegExp(regex)) {\n            throw new TypeError(\"type RegExp expected\");\n        }\n        var flags = nativ.replace.call(getNativeFlags(regex) + (addFlags || \"\"), duplicateFlags, \"\");\n        if (removeFlags) {\n            // Would need to escape `removeFlags` if this was public\n            flags = nativ.replace.call(flags, new RegExp(\"[\" + removeFlags + \"]+\", \"g\"), \"\");\n        }\n        if (regex.xregexp && !regex.xregexp.isNative) {\n            // Compiling the current (rather than precompilation) source preserves the effects of nonnative source flags\n            regex = augment(self(regex.source, flags),\n                            regex.xregexp.captureNames ? regex.xregexp.captureNames.slice(0) : null);\n        } else {\n            // Augment with `XRegExp.prototype` methods, but use native `RegExp` (avoid searching for special tokens)\n            regex = augment(new RegExp(regex.source, flags), null, true);\n        }\n        return regex;\n    }\n\n/*\n * Returns the last index at which a given value can be found in an array, or `-1` if it's not\n * present. The array is searched backwards.\n * @private\n * @param {Array} array Array to search.\n * @param {*} value Value to locate in the array.\n * @returns {Number} Last zero-based index at which the item is found, or -1.\n */\n    function lastIndexOf(array, value) {\n        var i = array.length;\n        if (Array.prototype.lastIndexOf) {\n            return array.lastIndexOf(value); // Use the native method if available\n        }\n        while (i--) {\n            if (array[i] === value) {\n                return i;\n            }\n        }\n        return -1;\n    }\n\n/**\n * Determines whether an object is of the specified type.\n * @private\n * @param {*} value Object to check.\n * @param {String} type Type to check for, in lowercase.\n * @returns {Boolean} Whether the object matches the type.\n */\n    function isType(value, type) {\n        return Object.prototype.toString.call(value).toLowerCase() === \"[object \" + type + \"]\";\n    }\n\n/**\n * Prepares an options object from the given value.\n * @private\n * @param {String|Object} value Value to convert to an options object.\n * @returns {Object} Options object.\n */\n    function prepareOptions(value) {\n        value = value || {};\n        if (value === \"all\" || value.all) {\n            value = {natives: true, extensibility: true};\n        } else if (isType(value, \"string\")) {\n            value = self.forEach(value, /[^\\s,]+/, function (m) {\n                this[m] = true;\n            }, {});\n        }\n        return value;\n    }\n\n/**\n * Runs built-in/custom tokens in reverse insertion order, until a match is found.\n * @private\n * @param {String} pattern Original pattern from which an XRegExp object is being built.\n * @param {Number} pos Position to search for tokens within `pattern`.\n * @param {Number} scope Current regex scope.\n * @param {Object} context Context object assigned to token handler functions.\n * @returns {Object} Object with properties `output` (the substitution string returned by the\n *   successful token handler) and `match` (the token's match array), or null.\n */\n    function runTokens(pattern, pos, scope, context) {\n        var i = tokens.length,\n            result = null,\n            match,\n            t;\n        // Protect against constructing XRegExps within token handler and trigger functions\n        isInsideConstructor = true;\n        // Must reset `isInsideConstructor`, even if a `trigger` or `handler` throws\n        try {\n            while (i--) { // Run in reverse order\n                t = tokens[i];\n                if ((t.scope === \"all\" || t.scope === scope) && (!t.trigger || t.trigger.call(context))) {\n                    t.pattern.lastIndex = pos;\n                    match = fixed.exec.call(t.pattern, pattern); // Fixed `exec` here allows use of named backreferences, etc.\n                    if (match && match.index === pos) {\n                        result = {\n                            output: t.handler.call(context, match, scope),\n                            match: match\n                        };\n                        break;\n                    }\n                }\n            }\n        } catch (err) {\n            throw err;\n        } finally {\n            isInsideConstructor = false;\n        }\n        return result;\n    }\n\n/**\n * Enables or disables XRegExp syntax and flag extensibility.\n * @private\n * @param {Boolean} on `true` to enable; `false` to disable.\n */\n    function setExtensibility(on) {\n        self.addToken = addToken[on ? \"on\" : \"off\"];\n        features.extensibility = on;\n    }\n\n/**\n * Enables or disables native method overrides.\n * @private\n * @param {Boolean} on `true` to enable; `false` to disable.\n */\n    function setNatives(on) {\n        RegExp.prototype.exec = (on ? fixed : nativ).exec;\n        RegExp.prototype.test = (on ? fixed : nativ).test;\n        String.prototype.match = (on ? fixed : nativ).match;\n        String.prototype.replace = (on ? fixed : nativ).replace;\n        String.prototype.split = (on ? fixed : nativ).split;\n        features.natives = on;\n    }\n\n/*--------------------------------------\n *  Constructor\n *------------------------------------*/\n\n/**\n * Creates an extended regular expression object for matching text with a pattern. Differs from a\n * native regular expression in that additional syntax and flags are supported. The returned object\n * is in fact a native `RegExp` and works with all native methods.\n * @class XRegExp\n * @constructor\n * @param {String|RegExp} pattern Regex pattern string, or an existing `RegExp` object to copy.\n * @param {String} [flags] Any combination of flags:\n *   <li>`g` - global\n *   <li>`i` - ignore case\n *   <li>`m` - multiline anchors\n *   <li>`n` - explicit capture\n *   <li>`s` - dot matches all (aka singleline)\n *   <li>`x` - free-spacing and line comments (aka extended)\n *   <li>`y` - sticky (Firefox 3+ only)\n *   Flags cannot be provided when constructing one `RegExp` from another.\n * @returns {RegExp} Extended regular expression object.\n * @example\n *\n * // With named capture and flag x\n * date = XRegExp('(?<year>  [0-9]{4}) -?  # year  \\n\\\n *                 (?<month> [0-9]{2}) -?  # month \\n\\\n *                 (?<day>   [0-9]{2})     # day   ', 'x');\n *\n * // Passing a regex object to copy it. The copy maintains special properties for named capture,\n * // is augmented with `XRegExp.prototype` methods, and has a fresh `lastIndex` property (set to\n * // zero). Native regexes are not recompiled using XRegExp syntax.\n * XRegExp(/regex/);\n */\n    self = function (pattern, flags) {\n        if (self.isRegExp(pattern)) {\n            if (flags !== undef) {\n                throw new TypeError(\"can't supply flags when constructing one RegExp from another\");\n            }\n            return copy(pattern);\n        }\n        // Tokens become part of the regex construction process, so protect against infinite recursion\n        // when an XRegExp is constructed within a token handler function\n        if (isInsideConstructor) {\n            throw new Error(\"can't call the XRegExp constructor within token definition functions\");\n        }\n\n        var output = [],\n            scope = defaultScope,\n            tokenContext = {\n                hasNamedCapture: false,\n                captureNames: [],\n                hasFlag: function (flag) {\n                    return flags.indexOf(flag) > -1;\n                }\n            },\n            pos = 0,\n            tokenResult,\n            match,\n            chr;\n        pattern = pattern === undef ? \"\" : String(pattern);\n        flags = flags === undef ? \"\" : String(flags);\n\n        if (nativ.match.call(flags, duplicateFlags)) { // Don't use test/exec because they would update lastIndex\n            throw new SyntaxError(\"invalid duplicate regular expression flag\");\n        }\n        // Strip/apply leading mode modifier with any combination of flags except g or y: (?imnsx)\n        pattern = nativ.replace.call(pattern, /^\\(\\?([\\w$]+)\\)/, function ($0, $1) {\n            if (nativ.test.call(/[gy]/, $1)) {\n                throw new SyntaxError(\"can't use flag g or y in mode modifier\");\n            }\n            flags = nativ.replace.call(flags + $1, duplicateFlags, \"\");\n            return \"\";\n        });\n        self.forEach(flags, /[\\s\\S]/, function (m) {\n            if (registeredFlags.indexOf(m[0]) < 0) {\n                throw new SyntaxError(\"invalid regular expression flag \" + m[0]);\n            }\n        });\n\n        while (pos < pattern.length) {\n            // Check for custom tokens at the current position\n            tokenResult = runTokens(pattern, pos, scope, tokenContext);\n            if (tokenResult) {\n                output.push(tokenResult.output);\n                pos += (tokenResult.match[0].length || 1);\n            } else {\n                // Check for native tokens (except character classes) at the current position\n                match = nativ.exec.call(nativeTokens[scope], pattern.slice(pos));\n                if (match) {\n                    output.push(match[0]);\n                    pos += match[0].length;\n                } else {\n                    chr = pattern.charAt(pos);\n                    if (chr === \"[\") {\n                        scope = classScope;\n                    } else if (chr === \"]\") {\n                        scope = defaultScope;\n                    }\n                    // Advance position by one character\n                    output.push(chr);\n                    ++pos;\n                }\n            }\n        }\n\n        return augment(new RegExp(output.join(\"\"), nativ.replace.call(flags, /[^gimy]+/g, \"\")),\n                       tokenContext.hasNamedCapture ? tokenContext.captureNames : null);\n    };\n\n/*--------------------------------------\n *  Public methods/properties\n *------------------------------------*/\n\n// Installed and uninstalled states for `XRegExp.addToken`\n    addToken = {\n        on: function (regex, handler, options) {\n            options = options || {};\n            if (regex) {\n                tokens.push({\n                    pattern: copy(regex, \"g\" + (hasNativeY ? \"y\" : \"\")),\n                    handler: handler,\n                    scope: options.scope || defaultScope,\n                    trigger: options.trigger || null\n                });\n            }\n            // Providing `customFlags` with null `regex` and `handler` allows adding flags that do\n            // nothing, but don't throw an error\n            if (options.customFlags) {\n                registeredFlags = nativ.replace.call(registeredFlags + options.customFlags, duplicateFlags, \"\");\n            }\n        },\n        off: function () {\n            throw new Error(\"extensibility must be installed before using addToken\");\n        }\n    };\n\n/**\n * Extends or changes XRegExp syntax and allows custom flags. This is used internally and can be\n * used to create XRegExp addons. `XRegExp.install('extensibility')` must be run before calling\n * this function, or an error is thrown. If more than one token can match the same string, the last\n * added wins.\n * @memberOf XRegExp\n * @param {RegExp} regex Regex object that matches the new token.\n * @param {Function} handler Function that returns a new pattern string (using native regex syntax)\n *   to replace the matched token within all future XRegExp regexes. Has access to persistent\n *   properties of the regex being built, through `this`. Invoked with two arguments:\n *   <li>The match array, with named backreference properties.\n *   <li>The regex scope where the match was found.\n * @param {Object} [options] Options object with optional properties:\n *   <li>`scope` {String} Scopes where the token applies: 'default', 'class', or 'all'.\n *   <li>`trigger` {Function} Function that returns `true` when the token should be applied; e.g.,\n *     if a flag is set. If `false` is returned, the matched string can be matched by other tokens.\n *     Has access to persistent properties of the regex being built, through `this` (including\n *     function `this.hasFlag`).\n *   <li>`customFlags` {String} Nonnative flags used by the token's handler or trigger functions.\n *     Prevents XRegExp from throwing an invalid flag error when the specified flags are used.\n * @example\n *\n * // Basic usage: Adds \\a for ALERT character\n * XRegExp.addToken(\n *   /\\\\a/,\n *   function () {return '\\\\x07';},\n *   {scope: 'all'}\n * );\n * XRegExp('\\\\a[\\\\a-\\\\n]+').test('\\x07\\n\\x07'); // -> true\n */\n    self.addToken = addToken.off;\n\n/**\n * Caches and returns the result of calling `XRegExp(pattern, flags)`. On any subsequent call with\n * the same pattern and flag combination, the cached copy is returned.\n * @memberOf XRegExp\n * @param {String} pattern Regex pattern string.\n * @param {String} [flags] Any combination of XRegExp flags.\n * @returns {RegExp} Cached XRegExp object.\n * @example\n *\n * while (match = XRegExp.cache('.', 'gs').exec(str)) {\n *   // The regex is compiled once only\n * }\n */\n    self.cache = function (pattern, flags) {\n        var key = pattern + \"/\" + (flags || \"\");\n        return cache[key] || (cache[key] = self(pattern, flags));\n    };\n\n/**\n * Escapes any regular expression metacharacters, for use when matching literal strings. The result\n * can safely be used at any point within a regex that uses any flags.\n * @memberOf XRegExp\n * @param {String} str String to escape.\n * @returns {String} String with regex metacharacters escaped.\n * @example\n *\n * XRegExp.escape('Escaped? <.>');\n * // -> 'Escaped\\?\\ <\\.>'\n */\n    self.escape = function (str) {\n        return nativ.replace.call(str, /[-[\\]{}()*+?.,\\\\^$|#\\s]/g, \"\\\\$&\");\n    };\n\n/**\n * Executes a regex search in a specified string. Returns a match array or `null`. If the provided\n * regex uses named capture, named backreference properties are included on the match array.\n * Optional `pos` and `sticky` arguments specify the search start position, and whether the match\n * must start at the specified position only. The `lastIndex` property of the provided regex is not\n * used, but is updated for compatibility. Also fixes browser bugs compared to the native\n * `RegExp.prototype.exec` and can be used reliably cross-browser.\n * @memberOf XRegExp\n * @param {String} str String to search.\n * @param {RegExp} regex Regex to search with.\n * @param {Number} [pos=0] Zero-based index at which to start the search.\n * @param {Boolean|String} [sticky=false] Whether the match must start at the specified position\n *   only. The string `'sticky'` is accepted as an alternative to `true`.\n * @returns {Array} Match array with named backreference properties, or null.\n * @example\n *\n * // Basic use, with named backreference\n * var match = XRegExp.exec('U+2620', XRegExp('U\\\\+(?<hex>[0-9A-F]{4})'));\n * match.hex; // -> '2620'\n *\n * // With pos and sticky, in a loop\n * var pos = 2, result = [], match;\n * while (match = XRegExp.exec('<1><2><3><4>5<6>', /<(\\d)>/, pos, 'sticky')) {\n *   result.push(match[1]);\n *   pos = match.index + match[0].length;\n * }\n * // result -> ['2', '3', '4']\n */\n    self.exec = function (str, regex, pos, sticky) {\n        var r2 = copy(regex, \"g\" + (sticky && hasNativeY ? \"y\" : \"\"), (sticky === false ? \"y\" : \"\")),\n            match;\n        r2.lastIndex = pos = pos || 0;\n        match = fixed.exec.call(r2, str); // Fixed `exec` required for `lastIndex` fix, etc.\n        if (sticky && match && match.index !== pos) {\n            match = null;\n        }\n        if (regex.global) {\n            regex.lastIndex = match ? r2.lastIndex : 0;\n        }\n        return match;\n    };\n\n/**\n * Executes a provided function once per regex match.\n * @memberOf XRegExp\n * @param {String} str String to search.\n * @param {RegExp} regex Regex to search with.\n * @param {Function} callback Function to execute for each match. Invoked with four arguments:\n *   <li>The match array, with named backreference properties.\n *   <li>The zero-based match index.\n *   <li>The string being traversed.\n *   <li>The regex object being used to traverse the string.\n * @param {*} [context] Object to use as `this` when executing `callback`.\n * @returns {*} Provided `context` object.\n * @example\n *\n * // Extracts every other digit from a string\n * XRegExp.forEach('1a2345', /\\d/, function (match, i) {\n *   if (i % 2) this.push(+match[0]);\n * }, []);\n * // -> [2, 4]\n */\n    self.forEach = function (str, regex, callback, context) {\n        var pos = 0,\n            i = -1,\n            match;\n        while ((match = self.exec(str, regex, pos))) {\n            callback.call(context, match, ++i, str, regex);\n            pos = match.index + (match[0].length || 1);\n        }\n        return context;\n    };\n\n/**\n * Copies a regex object and adds flag `g`. The copy maintains special properties for named\n * capture, is augmented with `XRegExp.prototype` methods, and has a fresh `lastIndex` property\n * (set to zero). Native regexes are not recompiled using XRegExp syntax.\n * @memberOf XRegExp\n * @param {RegExp} regex Regex to globalize.\n * @returns {RegExp} Copy of the provided regex with flag `g` added.\n * @example\n *\n * var globalCopy = XRegExp.globalize(/regex/);\n * globalCopy.global; // -> true\n */\n    self.globalize = function (regex) {\n        return copy(regex, \"g\");\n    };\n\n/**\n * Installs optional features according to the specified options.\n * @memberOf XRegExp\n * @param {Object|String} options Options object or string.\n * @example\n *\n * // With an options object\n * XRegExp.install({\n *   // Overrides native regex methods with fixed/extended versions that support named\n *   // backreferences and fix numerous cross-browser bugs\n *   natives: true,\n *\n *   // Enables extensibility of XRegExp syntax and flags\n *   extensibility: true\n * });\n *\n * // With an options string\n * XRegExp.install('natives extensibility');\n *\n * // Using a shortcut to install all optional features\n * XRegExp.install('all');\n */\n    self.install = function (options) {\n        options = prepareOptions(options);\n        if (!features.natives && options.natives) {\n            setNatives(true);\n        }\n        if (!features.extensibility && options.extensibility) {\n            setExtensibility(true);\n        }\n    };\n\n/**\n * Checks whether an individual optional feature is installed.\n * @memberOf XRegExp\n * @param {String} feature Name of the feature to check. One of:\n *   <li>`natives`\n *   <li>`extensibility`\n * @returns {Boolean} Whether the feature is installed.\n * @example\n *\n * XRegExp.isInstalled('natives');\n */\n    self.isInstalled = function (feature) {\n        return !!(features[feature]);\n    };\n\n/**\n * Returns `true` if an object is a regex; `false` if it isn't. This works correctly for regexes\n * created in another frame, when `instanceof` and `constructor` checks would fail.\n * @memberOf XRegExp\n * @param {*} value Object to check.\n * @returns {Boolean} Whether the object is a `RegExp` object.\n * @example\n *\n * XRegExp.isRegExp('string'); // -> false\n * XRegExp.isRegExp(/regex/i); // -> true\n * XRegExp.isRegExp(RegExp('^', 'm')); // -> true\n * XRegExp.isRegExp(XRegExp('(?s).')); // -> true\n */\n    self.isRegExp = function (value) {\n        return isType(value, \"regexp\");\n    };\n\n/**\n * Retrieves the matches from searching a string using a chain of regexes that successively search\n * within previous matches. The provided `chain` array can contain regexes and objects with `regex`\n * and `backref` properties. When a backreference is specified, the named or numbered backreference\n * is passed forward to the next regex or returned.\n * @memberOf XRegExp\n * @param {String} str String to search.\n * @param {Array} chain Regexes that each search for matches within preceding results.\n * @returns {Array} Matches by the last regex in the chain, or an empty array.\n * @example\n *\n * // Basic usage; matches numbers within <b> tags\n * XRegExp.matchChain('1 <b>2</b> 3 <b>4 a 56</b>', [\n *   XRegExp('(?is)<b>.*?</b>'),\n *   /\\d+/\n * ]);\n * // -> ['2', '4', '56']\n *\n * // Passing forward and returning specific backreferences\n * html = '<a href=\"http://xregexp.com/api/\">XRegExp</a>\\\n *         <a href=\"http://www.google.com/\">Google</a>';\n * XRegExp.matchChain(html, [\n *   {regex: /<a href=\"([^\"]+)\">/i, backref: 1},\n *   {regex: XRegExp('(?i)^https?://(?<domain>[^/?#]+)'), backref: 'domain'}\n * ]);\n * // -> ['xregexp.com', 'www.google.com']\n */\n    self.matchChain = function (str, chain) {\n        return (function recurseChain(values, level) {\n            var item = chain[level].regex ? chain[level] : {regex: chain[level]},\n                matches = [],\n                addMatch = function (match) {\n                    matches.push(item.backref ? (match[item.backref] || \"\") : match[0]);\n                },\n                i;\n            for (i = 0; i < values.length; ++i) {\n                self.forEach(values[i], item.regex, addMatch);\n            }\n            return ((level === chain.length - 1) || !matches.length) ?\n                    matches :\n                    recurseChain(matches, level + 1);\n        }([str], 0));\n    };\n\n/**\n * Returns a new string with one or all matches of a pattern replaced. The pattern can be a string\n * or regex, and the replacement can be a string or a function to be called for each match. To\n * perform a global search and replace, use the optional `scope` argument or include flag `g` if\n * using a regex. Replacement strings can use `${n}` for named and numbered backreferences.\n * Replacement functions can use named backreferences via `arguments[0].name`. Also fixes browser\n * bugs compared to the native `String.prototype.replace` and can be used reliably cross-browser.\n * @memberOf XRegExp\n * @param {String} str String to search.\n * @param {RegExp|String} search Search pattern to be replaced.\n * @param {String|Function} replacement Replacement string or a function invoked to create it.\n *   Replacement strings can include special replacement syntax:\n *     <li>$$ - Inserts a literal '$'.\n *     <li>$&, $0 - Inserts the matched substring.\n *     <li>$` - Inserts the string that precedes the matched substring (left context).\n *     <li>$' - Inserts the string that follows the matched substring (right context).\n *     <li>$n, $nn - Where n/nn are digits referencing an existent capturing group, inserts\n *       backreference n/nn.\n *     <li>${n} - Where n is a name or any number of digits that reference an existent capturing\n *       group, inserts backreference n.\n *   Replacement functions are invoked with three or more arguments:\n *     <li>The matched substring (corresponds to $& above). Named backreferences are accessible as\n *       properties of this first argument.\n *     <li>0..n arguments, one for each backreference (corresponding to $1, $2, etc. above).\n *     <li>The zero-based index of the match within the total search string.\n *     <li>The total string being searched.\n * @param {String} [scope='one'] Use 'one' to replace the first match only, or 'all'. If not\n *   explicitly specified and using a regex with flag `g`, `scope` is 'all'.\n * @returns {String} New string with one or all matches replaced.\n * @example\n *\n * // Regex search, using named backreferences in replacement string\n * var name = XRegExp('(?<first>\\\\w+) (?<last>\\\\w+)');\n * XRegExp.replace('John Smith', name, '${last}, ${first}');\n * // -> 'Smith, John'\n *\n * // Regex search, using named backreferences in replacement function\n * XRegExp.replace('John Smith', name, function (match) {\n *   return match.last + ', ' + match.first;\n * });\n * // -> 'Smith, John'\n *\n * // Global string search/replacement\n * XRegExp.replace('RegExp builds RegExps', 'RegExp', 'XRegExp', 'all');\n * // -> 'XRegExp builds XRegExps'\n */\n    self.replace = function (str, search, replacement, scope) {\n        var isRegex = self.isRegExp(search),\n            search2 = search,\n            result;\n        if (isRegex) {\n            if (scope === undef && search.global) {\n                scope = \"all\"; // Follow flag g when `scope` isn't explicit\n            }\n            // Note that since a copy is used, `search`'s `lastIndex` isn't updated *during* replacement iterations\n            search2 = copy(search, scope === \"all\" ? \"g\" : \"\", scope === \"all\" ? \"\" : \"g\");\n        } else if (scope === \"all\") {\n            search2 = new RegExp(self.escape(String(search)), \"g\");\n        }\n        result = fixed.replace.call(String(str), search2, replacement); // Fixed `replace` required for named backreferences, etc.\n        if (isRegex && search.global) {\n            search.lastIndex = 0; // Fixes IE, Safari bug (last tested IE 9, Safari 5.1)\n        }\n        return result;\n    };\n\n/**\n * Splits a string into an array of strings using a regex or string separator. Matches of the\n * separator are not included in the result array. However, if `separator` is a regex that contains\n * capturing groups, backreferences are spliced into the result each time `separator` is matched.\n * Fixes browser bugs compared to the native `String.prototype.split` and can be used reliably\n * cross-browser.\n * @memberOf XRegExp\n * @param {String} str String to split.\n * @param {RegExp|String} separator Regex or string to use for separating the string.\n * @param {Number} [limit] Maximum number of items to include in the result array.\n * @returns {Array} Array of substrings.\n * @example\n *\n * // Basic use\n * XRegExp.split('a b c', ' ');\n * // -> ['a', 'b', 'c']\n *\n * // With limit\n * XRegExp.split('a b c', ' ', 2);\n * // -> ['a', 'b']\n *\n * // Backreferences in result array\n * XRegExp.split('..word1..', /([a-z]+)(\\d+)/i);\n * // -> ['..', 'word', '1', '..']\n */\n    self.split = function (str, separator, limit) {\n        return fixed.split.call(str, separator, limit);\n    };\n\n/**\n * Executes a regex search in a specified string. Returns `true` or `false`. Optional `pos` and\n * `sticky` arguments specify the search start position, and whether the match must start at the\n * specified position only. The `lastIndex` property of the provided regex is not used, but is\n * updated for compatibility. Also fixes browser bugs compared to the native\n * `RegExp.prototype.test` and can be used reliably cross-browser.\n * @memberOf XRegExp\n * @param {String} str String to search.\n * @param {RegExp} regex Regex to search with.\n * @param {Number} [pos=0] Zero-based index at which to start the search.\n * @param {Boolean|String} [sticky=false] Whether the match must start at the specified position\n *   only. The string `'sticky'` is accepted as an alternative to `true`.\n * @returns {Boolean} Whether the regex matched the provided value.\n * @example\n *\n * // Basic use\n * XRegExp.test('abc', /c/); // -> true\n *\n * // With pos and sticky\n * XRegExp.test('abc', /c/, 0, 'sticky'); // -> false\n */\n    self.test = function (str, regex, pos, sticky) {\n        // Do this the easy way :-)\n        return !!self.exec(str, regex, pos, sticky);\n    };\n\n/**\n * Uninstalls optional features according to the specified options.\n * @memberOf XRegExp\n * @param {Object|String} options Options object or string.\n * @example\n *\n * // With an options object\n * XRegExp.uninstall({\n *   // Restores native regex methods\n *   natives: true,\n *\n *   // Disables additional syntax and flag extensions\n *   extensibility: true\n * });\n *\n * // With an options string\n * XRegExp.uninstall('natives extensibility');\n *\n * // Using a shortcut to uninstall all optional features\n * XRegExp.uninstall('all');\n */\n    self.uninstall = function (options) {\n        options = prepareOptions(options);\n        if (features.natives && options.natives) {\n            setNatives(false);\n        }\n        if (features.extensibility && options.extensibility) {\n            setExtensibility(false);\n        }\n    };\n\n/**\n * Returns an XRegExp object that is the union of the given patterns. Patterns can be provided as\n * regex objects or strings. Metacharacters are escaped in patterns provided as strings.\n * Backreferences in provided regex objects are automatically renumbered to work correctly. Native\n * flags used by provided regexes are ignored in favor of the `flags` argument.\n * @memberOf XRegExp\n * @param {Array} patterns Regexes and strings to combine.\n * @param {String} [flags] Any combination of XRegExp flags.\n * @returns {RegExp} Union of the provided regexes and strings.\n * @example\n *\n * XRegExp.union(['a+b*c', /(dogs)\\1/, /(cats)\\1/], 'i');\n * // -> /a\\+b\\*c|(dogs)\\1|(cats)\\2/i\n *\n * XRegExp.union([XRegExp('(?<pet>dogs)\\\\k<pet>'), XRegExp('(?<pet>cats)\\\\k<pet>')]);\n * // -> XRegExp('(?<pet>dogs)\\\\k<pet>|(?<pet>cats)\\\\k<pet>')\n */\n    self.union = function (patterns, flags) {\n        var parts = /(\\()(?!\\?)|\\\\([1-9]\\d*)|\\\\[\\s\\S]|\\[(?:[^\\\\\\]]|\\\\[\\s\\S])*]/g,\n            numCaptures = 0,\n            numPriorCaptures,\n            captureNames,\n            rewrite = function (match, paren, backref) {\n                var name = captureNames[numCaptures - numPriorCaptures];\n                if (paren) { // Capturing group\n                    ++numCaptures;\n                    if (name) { // If the current capture has a name\n                        return \"(?<\" + name + \">\";\n                    }\n                } else if (backref) { // Backreference\n                    return \"\\\\\" + (+backref + numPriorCaptures);\n                }\n                return match;\n            },\n            output = [],\n            pattern,\n            i;\n        if (!(isType(patterns, \"array\") && patterns.length)) {\n            throw new TypeError(\"patterns must be a nonempty array\");\n        }\n        for (i = 0; i < patterns.length; ++i) {\n            pattern = patterns[i];\n            if (self.isRegExp(pattern)) {\n                numPriorCaptures = numCaptures;\n                captureNames = (pattern.xregexp && pattern.xregexp.captureNames) || [];\n                // Rewrite backreferences. Passing to XRegExp dies on octals and ensures patterns\n                // are independently valid; helps keep this simple. Named captures are put back\n                output.push(self(pattern.source).source.replace(parts, rewrite));\n            } else {\n                output.push(self.escape(pattern));\n            }\n        }\n        return self(output.join(\"|\"), flags);\n    };\n\n/**\n * The XRegExp version number.\n * @static\n * @memberOf XRegExp\n * @type String\n */\n    self.version = \"2.0.0\";\n\n/*--------------------------------------\n *  Fixed/extended native methods\n *------------------------------------*/\n\n/**\n * Adds named capture support (with backreferences returned as `result.name`), and fixes browser\n * bugs in the native `RegExp.prototype.exec`. Calling `XRegExp.install('natives')` uses this to\n * override the native method. Use via `XRegExp.exec` without overriding natives.\n * @private\n * @param {String} str String to search.\n * @returns {Array} Match array with named backreference properties, or null.\n */\n    fixed.exec = function (str) {\n        var match, name, r2, origLastIndex, i;\n        if (!this.global) {\n            origLastIndex = this.lastIndex;\n        }\n        match = nativ.exec.apply(this, arguments);\n        if (match) {\n            // Fix browsers whose `exec` methods don't consistently return `undefined` for\n            // nonparticipating capturing groups\n            if (!compliantExecNpcg && match.length > 1 && lastIndexOf(match, \"\") > -1) {\n                r2 = new RegExp(this.source, nativ.replace.call(getNativeFlags(this), \"g\", \"\"));\n                // Using `str.slice(match.index)` rather than `match[0]` in case lookahead allowed\n                // matching due to characters outside the match\n                nativ.replace.call(String(str).slice(match.index), r2, function () {\n                    var i;\n                    for (i = 1; i < arguments.length - 2; ++i) {\n                        if (arguments[i] === undef) {\n                            match[i] = undef;\n                        }\n                    }\n                });\n            }\n            // Attach named capture properties\n            if (this.xregexp && this.xregexp.captureNames) {\n                for (i = 1; i < match.length; ++i) {\n                    name = this.xregexp.captureNames[i - 1];\n                    if (name) {\n                        match[name] = match[i];\n                    }\n                }\n            }\n            // Fix browsers that increment `lastIndex` after zero-length matches\n            if (this.global && !match[0].length && (this.lastIndex > match.index)) {\n                this.lastIndex = match.index;\n            }\n        }\n        if (!this.global) {\n            this.lastIndex = origLastIndex; // Fixes IE, Opera bug (last tested IE 9, Opera 11.6)\n        }\n        return match;\n    };\n\n/**\n * Fixes browser bugs in the native `RegExp.prototype.test`. Calling `XRegExp.install('natives')`\n * uses this to override the native method.\n * @private\n * @param {String} str String to search.\n * @returns {Boolean} Whether the regex matched the provided value.\n */\n    fixed.test = function (str) {\n        // Do this the easy way :-)\n        return !!fixed.exec.call(this, str);\n    };\n\n/**\n * Adds named capture support (with backreferences returned as `result.name`), and fixes browser\n * bugs in the native `String.prototype.match`. Calling `XRegExp.install('natives')` uses this to\n * override the native method.\n * @private\n * @param {RegExp} regex Regex to search with.\n * @returns {Array} If `regex` uses flag g, an array of match strings or null. Without flag g, the\n *   result of calling `regex.exec(this)`.\n */\n    fixed.match = function (regex) {\n        if (!self.isRegExp(regex)) {\n            regex = new RegExp(regex); // Use native `RegExp`\n        } else if (regex.global) {\n            var result = nativ.match.apply(this, arguments);\n            regex.lastIndex = 0; // Fixes IE bug\n            return result;\n        }\n        return fixed.exec.call(regex, this);\n    };\n\n/**\n * Adds support for `${n}` tokens for named and numbered backreferences in replacement text, and\n * provides named backreferences to replacement functions as `arguments[0].name`. Also fixes\n * browser bugs in replacement text syntax when performing a replacement using a nonregex search\n * value, and the value of a replacement regex's `lastIndex` property during replacement iterations\n * and upon completion. Note that this doesn't support SpiderMonkey's proprietary third (`flags`)\n * argument. Calling `XRegExp.install('natives')` uses this to override the native method. Use via\n * `XRegExp.replace` without overriding natives.\n * @private\n * @param {RegExp|String} search Search pattern to be replaced.\n * @param {String|Function} replacement Replacement string or a function invoked to create it.\n * @returns {String} New string with one or all matches replaced.\n */\n    fixed.replace = function (search, replacement) {\n        var isRegex = self.isRegExp(search), captureNames, result, str, origLastIndex;\n        if (isRegex) {\n            if (search.xregexp) {\n                captureNames = search.xregexp.captureNames;\n            }\n            if (!search.global) {\n                origLastIndex = search.lastIndex;\n            }\n        } else {\n            search += \"\";\n        }\n        if (isType(replacement, \"function\")) {\n            result = nativ.replace.call(String(this), search, function () {\n                var args = arguments, i;\n                if (captureNames) {\n                    // Change the `arguments[0]` string primitive to a `String` object that can store properties\n                    args[0] = new String(args[0]);\n                    // Store named backreferences on the first argument\n                    for (i = 0; i < captureNames.length; ++i) {\n                        if (captureNames[i]) {\n                            args[0][captureNames[i]] = args[i + 1];\n                        }\n                    }\n                }\n                // Update `lastIndex` before calling `replacement`.\n                // Fixes IE, Chrome, Firefox, Safari bug (last tested IE 9, Chrome 17, Firefox 11, Safari 5.1)\n                if (isRegex && search.global) {\n                    search.lastIndex = args[args.length - 2] + args[0].length;\n                }\n                return replacement.apply(null, args);\n            });\n        } else {\n            str = String(this); // Ensure `args[args.length - 1]` will be a string when given nonstring `this`\n            result = nativ.replace.call(str, search, function () {\n                var args = arguments; // Keep this function's `arguments` available through closure\n                return nativ.replace.call(String(replacement), replacementToken, function ($0, $1, $2) {\n                    var n;\n                    // Named or numbered backreference with curly brackets\n                    if ($1) {\n                        /* XRegExp behavior for `${n}`:\n                         * 1. Backreference to numbered capture, where `n` is 1+ digits. `0`, `00`, etc. is the entire match.\n                         * 2. Backreference to named capture `n`, if it exists and is not a number overridden by numbered capture.\n                         * 3. Otherwise, it's an error.\n                         */\n                        n = +$1; // Type-convert; drop leading zeros\n                        if (n <= args.length - 3) {\n                            return args[n] || \"\";\n                        }\n                        n = captureNames ? lastIndexOf(captureNames, $1) : -1;\n                        if (n < 0) {\n                            throw new SyntaxError(\"backreference to undefined group \" + $0);\n                        }\n                        return args[n + 1] || \"\";\n                    }\n                    // Else, special variable or numbered backreference (without curly brackets)\n                    if ($2 === \"$\") return \"$\";\n                    if ($2 === \"&\" || +$2 === 0) return args[0]; // $&, $0 (not followed by 1-9), $00\n                    if ($2 === \"`\") return args[args.length - 1].slice(0, args[args.length - 2]);\n                    if ($2 === \"'\") return args[args.length - 1].slice(args[args.length - 2] + args[0].length);\n                    // Else, numbered backreference (without curly brackets)\n                    $2 = +$2; // Type-convert; drop leading zero\n                    /* XRegExp behavior:\n                     * - Backreferences without curly brackets end after 1 or 2 digits. Use `${..}` for more digits.\n                     * - `$1` is an error if there are no capturing groups.\n                     * - `$10` is an error if there are less than 10 capturing groups. Use `${1}0` instead.\n                     * - `$01` is equivalent to `$1` if a capturing group exists, otherwise it's an error.\n                     * - `$0` (not followed by 1-9), `$00`, and `$&` are the entire match.\n                     * Native behavior, for comparison:\n                     * - Backreferences end after 1 or 2 digits. Cannot use backreference to capturing group 100+.\n                     * - `$1` is a literal `$1` if there are no capturing groups.\n                     * - `$10` is `$1` followed by a literal `0` if there are less than 10 capturing groups.\n                     * - `$01` is equivalent to `$1` if a capturing group exists, otherwise it's a literal `$01`.\n                     * - `$0` is a literal `$0`. `$&` is the entire match.\n                     */\n                    if (!isNaN($2)) {\n                        if ($2 > args.length - 3) {\n                            throw new SyntaxError(\"backreference to undefined group \" + $0);\n                        }\n                        return args[$2] || \"\";\n                    }\n                    throw new SyntaxError(\"invalid token \" + $0);\n                });\n            });\n        }\n        if (isRegex) {\n            if (search.global) {\n                search.lastIndex = 0; // Fixes IE, Safari bug (last tested IE 9, Safari 5.1)\n            } else {\n                search.lastIndex = origLastIndex; // Fixes IE, Opera bug (last tested IE 9, Opera 11.6)\n            }\n        }\n        return result;\n    };\n\n/**\n * Fixes browser bugs in the native `String.prototype.split`. Calling `XRegExp.install('natives')`\n * uses this to override the native method. Use via `XRegExp.split` without overriding natives.\n * @private\n * @param {RegExp|String} separator Regex or string to use for separating the string.\n * @param {Number} [limit] Maximum number of items to include in the result array.\n * @returns {Array} Array of substrings.\n */\n    fixed.split = function (separator, limit) {\n        if (!self.isRegExp(separator)) {\n            return nativ.split.apply(this, arguments); // use faster native method\n        }\n        var str = String(this),\n            origLastIndex = separator.lastIndex,\n            output = [],\n            lastLastIndex = 0,\n            lastLength;\n        /* Values for `limit`, per the spec:\n         * If undefined: pow(2,32) - 1\n         * If 0, Infinity, or NaN: 0\n         * If positive number: limit = floor(limit); if (limit >= pow(2,32)) limit -= pow(2,32);\n         * If negative number: pow(2,32) - floor(abs(limit))\n         * If other: Type-convert, then use the above rules\n         */\n        limit = (limit === undef ? -1 : limit) >>> 0;\n        self.forEach(str, separator, function (match) {\n            if ((match.index + match[0].length) > lastLastIndex) { // != `if (match[0].length)`\n                output.push(str.slice(lastLastIndex, match.index));\n                if (match.length > 1 && match.index < str.length) {\n                    Array.prototype.push.apply(output, match.slice(1));\n                }\n                lastLength = match[0].length;\n                lastLastIndex = match.index + lastLength;\n            }\n        });\n        if (lastLastIndex === str.length) {\n            if (!nativ.test.call(separator, \"\") || lastLength) {\n                output.push(\"\");\n            }\n        } else {\n            output.push(str.slice(lastLastIndex));\n        }\n        separator.lastIndex = origLastIndex;\n        return output.length > limit ? output.slice(0, limit) : output;\n    };\n\n/*--------------------------------------\n *  Built-in tokens\n *------------------------------------*/\n\n// Shortcut\n    add = addToken.on;\n\n/* Letter identity escapes that natively match literal characters: \\p, \\P, etc.\n * Should be SyntaxErrors but are allowed in web reality. XRegExp makes them errors for cross-\n * browser consistency and to reserve their syntax, but lets them be superseded by XRegExp addons.\n */\n    add(/\\\\([ABCE-RTUVXYZaeg-mopqyz]|c(?![A-Za-z])|u(?![\\dA-Fa-f]{4})|x(?![\\dA-Fa-f]{2}))/,\n        function (match, scope) {\n            // \\B is allowed in default scope only\n            if (match[1] === \"B\" && scope === defaultScope) {\n                return match[0];\n            }\n            throw new SyntaxError(\"invalid escape \" + match[0]);\n        },\n        {scope: \"all\"});\n\n/* Empty character class: [] or [^]\n * Fixes a critical cross-browser syntax inconsistency. Unless this is standardized (per the spec),\n * regex syntax can't be accurately parsed because character class endings can't be determined.\n */\n    add(/\\[(\\^?)]/,\n        function (match) {\n            // For cross-browser compatibility with ES3, convert [] to \\b\\B and [^] to [\\s\\S].\n            // (?!) should work like \\b\\B, but is unreliable in Firefox\n            return match[1] ? \"[\\\\s\\\\S]\" : \"\\\\b\\\\B\";\n        });\n\n/* Comment pattern: (?# )\n * Inline comments are an alternative to the line comments allowed in free-spacing mode (flag x).\n */\n    add(/(?:\\(\\?#[^)]*\\))+/,\n        function (match) {\n            // Keep tokens separated unless the following token is a quantifier\n            return nativ.test.call(quantifier, match.input.slice(match.index + match[0].length)) ? \"\" : \"(?:)\";\n        });\n\n/* Named backreference: \\k<name>\n * Backreference names can use the characters A-Z, a-z, 0-9, _, and $ only.\n */\n    add(/\\\\k<([\\w$]+)>/,\n        function (match) {\n            var index = isNaN(match[1]) ? (lastIndexOf(this.captureNames, match[1]) + 1) : +match[1],\n                endIndex = match.index + match[0].length;\n            if (!index || index > this.captureNames.length) {\n                throw new SyntaxError(\"backreference to undefined group \" + match[0]);\n            }\n            // Keep backreferences separate from subsequent literal numbers\n            return \"\\\\\" + index + (\n                endIndex === match.input.length || isNaN(match.input.charAt(endIndex)) ? \"\" : \"(?:)\"\n            );\n        });\n\n/* Whitespace and line comments, in free-spacing mode (aka extended mode, flag x) only.\n */\n    add(/(?:\\s+|#.*)+/,\n        function (match) {\n            // Keep tokens separated unless the following token is a quantifier\n            return nativ.test.call(quantifier, match.input.slice(match.index + match[0].length)) ? \"\" : \"(?:)\";\n        },\n        {\n            trigger: function () {\n                return this.hasFlag(\"x\");\n            },\n            customFlags: \"x\"\n        });\n\n/* Dot, in dotall mode (aka singleline mode, flag s) only.\n */\n    add(/\\./,\n        function () {\n            return \"[\\\\s\\\\S]\";\n        },\n        {\n            trigger: function () {\n                return this.hasFlag(\"s\");\n            },\n            customFlags: \"s\"\n        });\n\n/* Named capturing group; match the opening delimiter only: (?<name>\n * Capture names can use the characters A-Z, a-z, 0-9, _, and $ only. Names can't be integers.\n * Supports Python-style (?P<name> as an alternate syntax to avoid issues in recent Opera (which\n * natively supports the Python-style syntax). Otherwise, XRegExp might treat numbered\n * backreferences to Python-style named capture as octals.\n */\n    add(/\\(\\?P?<([\\w$]+)>/,\n        function (match) {\n            if (!isNaN(match[1])) {\n                // Avoid incorrect lookups, since named backreferences are added to match arrays\n                throw new SyntaxError(\"can't use integer as capture name \" + match[0]);\n            }\n            this.captureNames.push(match[1]);\n            this.hasNamedCapture = true;\n            return \"(\";\n        });\n\n/* Numbered backreference or octal, plus any following digits: \\0, \\11, etc.\n * Octals except \\0 not followed by 0-9 and backreferences to unopened capture groups throw an\n * error. Other matches are returned unaltered. IE <= 8 doesn't support backreferences greater than\n * \\99 in regex syntax.\n */\n    add(/\\\\(\\d+)/,\n        function (match, scope) {\n            if (!(scope === defaultScope && /^[1-9]/.test(match[1]) && +match[1] <= this.captureNames.length) &&\n                    match[1] !== \"0\") {\n                throw new SyntaxError(\"can't use octal escape or backreference to undefined group \" + match[0]);\n            }\n            return match[0];\n        },\n        {scope: \"all\"});\n\n/* Capturing group; match the opening parenthesis only.\n * Required for support of named capturing groups. Also adds explicit capture mode (flag n).\n */\n    add(/\\((?!\\?)/,\n        function () {\n            if (this.hasFlag(\"n\")) {\n                return \"(?:\";\n            }\n            this.captureNames.push(null);\n            return \"(\";\n        },\n        {customFlags: \"n\"});\n\n/*--------------------------------------\n *  Expose XRegExp\n *------------------------------------*/\n\n// For CommonJS enviroments\n    if (typeof exports !== \"undefined\") {\n        exports.XRegExp = self;\n    }\n\n    return self;\n\n}());\n\n\n/***** unicode-base.js *****/\n\n/*!\n * XRegExp Unicode Base v1.0.0\n * (c) 2008-2012 Steven Levithan <http://xregexp.com/>\n * MIT License\n * Uses Unicode 6.1 <http://unicode.org/>\n */\n\n/**\n * Adds support for the `\\p{L}` or `\\p{Letter}` Unicode category. Addon packages for other Unicode\n * categories, scripts, blocks, and properties are available separately. All Unicode tokens can be\n * inverted using `\\P{..}` or `\\p{^..}`. Token names are case insensitive, and any spaces, hyphens,\n * and underscores are ignored.\n * @requires XRegExp\n */\n(function (XRegExp) {\n    \"use strict\";\n\n    var unicode = {};\n\n/*--------------------------------------\n *  Private helper functions\n *------------------------------------*/\n\n// Generates a standardized token name (lowercase, with hyphens, spaces, and underscores removed)\n    function slug(name) {\n        return name.replace(/[- _]+/g, \"\").toLowerCase();\n    }\n\n// Expands a list of Unicode code points and ranges to be usable in a regex character class\n    function expand(str) {\n        return str.replace(/\\w{4}/g, \"\\\\u$&\");\n    }\n\n// Adds leading zeros if shorter than four characters\n    function pad4(str) {\n        while (str.length < 4) {\n            str = \"0\" + str;\n        }\n        return str;\n    }\n\n// Converts a hexadecimal number to decimal\n    function dec(hex) {\n        return parseInt(hex, 16);\n    }\n\n// Converts a decimal number to hexadecimal\n    function hex(dec) {\n        return parseInt(dec, 10).toString(16);\n    }\n\n// Inverts a list of Unicode code points and ranges\n    function invert(range) {\n        var output = [],\n            lastEnd = -1,\n            start;\n        XRegExp.forEach(range, /\\\\u(\\w{4})(?:-\\\\u(\\w{4}))?/, function (m) {\n            start = dec(m[1]);\n            if (start > (lastEnd + 1)) {\n                output.push(\"\\\\u\" + pad4(hex(lastEnd + 1)));\n                if (start > (lastEnd + 2)) {\n                    output.push(\"-\\\\u\" + pad4(hex(start - 1)));\n                }\n            }\n            lastEnd = dec(m[2] || m[1]);\n        });\n        if (lastEnd < 0xFFFF) {\n            output.push(\"\\\\u\" + pad4(hex(lastEnd + 1)));\n            if (lastEnd < 0xFFFE) {\n                output.push(\"-\\\\uFFFF\");\n            }\n        }\n        return output.join(\"\");\n    }\n\n// Generates an inverted token on first use\n    function cacheInversion(item) {\n        return unicode[\"^\" + item] || (unicode[\"^\" + item] = invert(unicode[item]));\n    }\n\n/*--------------------------------------\n *  Core functionality\n *------------------------------------*/\n\n    XRegExp.install(\"extensibility\");\n\n/**\n * Adds to the list of Unicode properties that XRegExp regexes can match via \\p{..} or \\P{..}.\n * @memberOf XRegExp\n * @param {Object} pack Named sets of Unicode code points and ranges.\n * @param {Object} [aliases] Aliases for the primary token names.\n * @example\n *\n * XRegExp.addUnicodePackage({\n *   XDigit: '0030-00390041-00460061-0066' // 0-9A-Fa-f\n * }, {\n *   XDigit: 'Hexadecimal'\n * });\n */\n    XRegExp.addUnicodePackage = function (pack, aliases) {\n        var p;\n        if (!XRegExp.isInstalled(\"extensibility\")) {\n            throw new Error(\"extensibility must be installed before adding Unicode packages\");\n        }\n        if (pack) {\n            for (p in pack) {\n                if (pack.hasOwnProperty(p)) {\n                    unicode[slug(p)] = expand(pack[p]);\n                }\n            }\n        }\n        if (aliases) {\n            for (p in aliases) {\n                if (aliases.hasOwnProperty(p)) {\n                    unicode[slug(aliases[p])] = unicode[slug(p)];\n                }\n            }\n        }\n    };\n\n/* Adds data for the Unicode `Letter` category. Addon packages include other categories, scripts,\n * blocks, and properties.\n */\n    XRegExp.addUnicodePackage({\n        L: \"0041-005A0061-007A00AA00B500BA00C0-00D600D8-00F600F8-02C102C6-02D102E0-02E402EC02EE0370-037403760377037A-037D03860388-038A038C038E-03A103A3-03F503F7-0481048A-05270531-055605590561-058705D0-05EA05F0-05F20620-064A066E066F0671-06D306D506E506E606EE06EF06FA-06FC06FF07100712-072F074D-07A507B107CA-07EA07F407F507FA0800-0815081A082408280840-085808A008A2-08AC0904-0939093D09500958-09610971-09770979-097F0985-098C098F09900993-09A809AA-09B009B209B6-09B909BD09CE09DC09DD09DF-09E109F009F10A05-0A0A0A0F0A100A13-0A280A2A-0A300A320A330A350A360A380A390A59-0A5C0A5E0A72-0A740A85-0A8D0A8F-0A910A93-0AA80AAA-0AB00AB20AB30AB5-0AB90ABD0AD00AE00AE10B05-0B0C0B0F0B100B13-0B280B2A-0B300B320B330B35-0B390B3D0B5C0B5D0B5F-0B610B710B830B85-0B8A0B8E-0B900B92-0B950B990B9A0B9C0B9E0B9F0BA30BA40BA8-0BAA0BAE-0BB90BD00C05-0C0C0C0E-0C100C12-0C280C2A-0C330C35-0C390C3D0C580C590C600C610C85-0C8C0C8E-0C900C92-0CA80CAA-0CB30CB5-0CB90CBD0CDE0CE00CE10CF10CF20D05-0D0C0D0E-0D100D12-0D3A0D3D0D4E0D600D610D7A-0D7F0D85-0D960D9A-0DB10DB3-0DBB0DBD0DC0-0DC60E01-0E300E320E330E40-0E460E810E820E840E870E880E8A0E8D0E94-0E970E99-0E9F0EA1-0EA30EA50EA70EAA0EAB0EAD-0EB00EB20EB30EBD0EC0-0EC40EC60EDC-0EDF0F000F40-0F470F49-0F6C0F88-0F8C1000-102A103F1050-1055105A-105D106110651066106E-10701075-1081108E10A0-10C510C710CD10D0-10FA10FC-1248124A-124D1250-12561258125A-125D1260-1288128A-128D1290-12B012B2-12B512B8-12BE12C012C2-12C512C8-12D612D8-13101312-13151318-135A1380-138F13A0-13F41401-166C166F-167F1681-169A16A0-16EA1700-170C170E-17111720-17311740-17511760-176C176E-17701780-17B317D717DC1820-18771880-18A818AA18B0-18F51900-191C1950-196D1970-19741980-19AB19C1-19C71A00-1A161A20-1A541AA71B05-1B331B45-1B4B1B83-1BA01BAE1BAF1BBA-1BE51C00-1C231C4D-1C4F1C5A-1C7D1CE9-1CEC1CEE-1CF11CF51CF61D00-1DBF1E00-1F151F18-1F1D1F20-1F451F48-1F4D1F50-1F571F591F5B1F5D1F5F-1F7D1F80-1FB41FB6-1FBC1FBE1FC2-1FC41FC6-1FCC1FD0-1FD31FD6-1FDB1FE0-1FEC1FF2-1FF41FF6-1FFC2071207F2090-209C21022107210A-211321152119-211D212421262128212A-212D212F-2139213C-213F2145-2149214E218321842C00-2C2E2C30-2C5E2C60-2CE42CEB-2CEE2CF22CF32D00-2D252D272D2D2D30-2D672D6F2D80-2D962DA0-2DA62DA8-2DAE2DB0-2DB62DB8-2DBE2DC0-2DC62DC8-2DCE2DD0-2DD62DD8-2DDE2E2F300530063031-3035303B303C3041-3096309D-309F30A1-30FA30FC-30FF3105-312D3131-318E31A0-31BA31F0-31FF3400-4DB54E00-9FCCA000-A48CA4D0-A4FDA500-A60CA610-A61FA62AA62BA640-A66EA67F-A697A6A0-A6E5A717-A71FA722-A788A78B-A78EA790-A793A7A0-A7AAA7F8-A801A803-A805A807-A80AA80C-A822A840-A873A882-A8B3A8F2-A8F7A8FBA90A-A925A930-A946A960-A97CA984-A9B2A9CFAA00-AA28AA40-AA42AA44-AA4BAA60-AA76AA7AAA80-AAAFAAB1AAB5AAB6AAB9-AABDAAC0AAC2AADB-AADDAAE0-AAEAAAF2-AAF4AB01-AB06AB09-AB0EAB11-AB16AB20-AB26AB28-AB2EABC0-ABE2AC00-D7A3D7B0-D7C6D7CB-D7FBF900-FA6DFA70-FAD9FB00-FB06FB13-FB17FB1DFB1F-FB28FB2A-FB36FB38-FB3CFB3EFB40FB41FB43FB44FB46-FBB1FBD3-FD3DFD50-FD8FFD92-FDC7FDF0-FDFBFE70-FE74FE76-FEFCFF21-FF3AFF41-FF5AFF66-FFBEFFC2-FFC7FFCA-FFCFFFD2-FFD7FFDA-FFDC\"\n    }, {\n        L: \"Letter\"\n    });\n\n/* Adds Unicode property syntax to XRegExp: \\p{..}, \\P{..}, \\p{^..}\n */\n    XRegExp.addToken(\n        /\\\\([pP]){(\\^?)([^}]*)}/,\n        function (match, scope) {\n            var inv = (match[1] === \"P\" || match[2]) ? \"^\" : \"\",\n                item = slug(match[3]);\n            // The double negative \\P{^..} is invalid\n            if (match[1] === \"P\" && match[2]) {\n                throw new SyntaxError(\"invalid double negation \\\\P{^\");\n            }\n            if (!unicode.hasOwnProperty(item)) {\n                throw new SyntaxError(\"invalid or unknown Unicode property \" + match[0]);\n            }\n            return scope === \"class\" ?\n                    (inv ? cacheInversion(item) : unicode[item]) :\n                    \"[\" + inv + unicode[item] + \"]\";\n        },\n        {scope: \"all\"}\n    );\n\n}(XRegExp));\n\n\n/***** unicode-categories.js *****/\n\n/*!\n * XRegExp Unicode Categories v1.2.0\n * (c) 2010-2012 Steven Levithan <http://xregexp.com/>\n * MIT License\n * Uses Unicode 6.1 <http://unicode.org/>\n */\n\n/**\n * Adds support for all Unicode categories (aka properties) E.g., `\\p{Lu}` or\n * `\\p{Uppercase Letter}`. Token names are case insensitive, and any spaces, hyphens, and\n * underscores are ignored.\n * @requires XRegExp, XRegExp Unicode Base\n */\n(function (XRegExp) {\n    \"use strict\";\n\n    if (!XRegExp.addUnicodePackage) {\n        throw new ReferenceError(\"Unicode Base must be loaded before Unicode Categories\");\n    }\n\n    XRegExp.install(\"extensibility\");\n\n    XRegExp.addUnicodePackage({\n        //L: \"\", // Included in the Unicode Base addon\n        Ll: \"0061-007A00B500DF-00F600F8-00FF01010103010501070109010B010D010F01110113011501170119011B011D011F01210123012501270129012B012D012F01310133013501370138013A013C013E014001420144014601480149014B014D014F01510153015501570159015B015D015F01610163016501670169016B016D016F0171017301750177017A017C017E-0180018301850188018C018D019201950199-019B019E01A101A301A501A801AA01AB01AD01B001B401B601B901BA01BD-01BF01C601C901CC01CE01D001D201D401D601D801DA01DC01DD01DF01E101E301E501E701E901EB01ED01EF01F001F301F501F901FB01FD01FF02010203020502070209020B020D020F02110213021502170219021B021D021F02210223022502270229022B022D022F02310233-0239023C023F0240024202470249024B024D024F-02930295-02AF037103730377037B-037D039003AC-03CE03D003D103D5-03D703D903DB03DD03DF03E103E303E503E703E903EB03ED03EF-03F303F503F803FB03FC0430-045F04610463046504670469046B046D046F04710473047504770479047B047D047F0481048B048D048F04910493049504970499049B049D049F04A104A304A504A704A904AB04AD04AF04B104B304B504B704B904BB04BD04BF04C204C404C604C804CA04CC04CE04CF04D104D304D504D704D904DB04DD04DF04E104E304E504E704E904EB04ED04EF04F104F304F504F704F904FB04FD04FF05010503050505070509050B050D050F05110513051505170519051B051D051F05210523052505270561-05871D00-1D2B1D6B-1D771D79-1D9A1E011E031E051E071E091E0B1E0D1E0F1E111E131E151E171E191E1B1E1D1E1F1E211E231E251E271E291E2B1E2D1E2F1E311E331E351E371E391E3B1E3D1E3F1E411E431E451E471E491E4B1E4D1E4F1E511E531E551E571E591E5B1E5D1E5F1E611E631E651E671E691E6B1E6D1E6F1E711E731E751E771E791E7B1E7D1E7F1E811E831E851E871E891E8B1E8D1E8F1E911E931E95-1E9D1E9F1EA11EA31EA51EA71EA91EAB1EAD1EAF1EB11EB31EB51EB71EB91EBB1EBD1EBF1EC11EC31EC51EC71EC91ECB1ECD1ECF1ED11ED31ED51ED71ED91EDB1EDD1EDF1EE11EE31EE51EE71EE91EEB1EED1EEF1EF11EF31EF51EF71EF91EFB1EFD1EFF-1F071F10-1F151F20-1F271F30-1F371F40-1F451F50-1F571F60-1F671F70-1F7D1F80-1F871F90-1F971FA0-1FA71FB0-1FB41FB61FB71FBE1FC2-1FC41FC61FC71FD0-1FD31FD61FD71FE0-1FE71FF2-1FF41FF61FF7210A210E210F2113212F21342139213C213D2146-2149214E21842C30-2C5E2C612C652C662C682C6A2C6C2C712C732C742C76-2C7B2C812C832C852C872C892C8B2C8D2C8F2C912C932C952C972C992C9B2C9D2C9F2CA12CA32CA52CA72CA92CAB2CAD2CAF2CB12CB32CB52CB72CB92CBB2CBD2CBF2CC12CC32CC52CC72CC92CCB2CCD2CCF2CD12CD32CD52CD72CD92CDB2CDD2CDF2CE12CE32CE42CEC2CEE2CF32D00-2D252D272D2DA641A643A645A647A649A64BA64DA64FA651A653A655A657A659A65BA65DA65FA661A663A665A667A669A66BA66DA681A683A685A687A689A68BA68DA68FA691A693A695A697A723A725A727A729A72BA72DA72F-A731A733A735A737A739A73BA73DA73FA741A743A745A747A749A74BA74DA74FA751A753A755A757A759A75BA75DA75FA761A763A765A767A769A76BA76DA76FA771-A778A77AA77CA77FA781A783A785A787A78CA78EA791A793A7A1A7A3A7A5A7A7A7A9A7FAFB00-FB06FB13-FB17FF41-FF5A\",\n        Lu: \"0041-005A00C0-00D600D8-00DE01000102010401060108010A010C010E01100112011401160118011A011C011E01200122012401260128012A012C012E01300132013401360139013B013D013F0141014301450147014A014C014E01500152015401560158015A015C015E01600162016401660168016A016C016E017001720174017601780179017B017D018101820184018601870189-018B018E-0191019301940196-0198019C019D019F01A001A201A401A601A701A901AC01AE01AF01B1-01B301B501B701B801BC01C401C701CA01CD01CF01D101D301D501D701D901DB01DE01E001E201E401E601E801EA01EC01EE01F101F401F6-01F801FA01FC01FE02000202020402060208020A020C020E02100212021402160218021A021C021E02200222022402260228022A022C022E02300232023A023B023D023E02410243-02460248024A024C024E03700372037603860388-038A038C038E038F0391-03A103A3-03AB03CF03D2-03D403D803DA03DC03DE03E003E203E403E603E803EA03EC03EE03F403F703F903FA03FD-042F04600462046404660468046A046C046E04700472047404760478047A047C047E0480048A048C048E04900492049404960498049A049C049E04A004A204A404A604A804AA04AC04AE04B004B204B404B604B804BA04BC04BE04C004C104C304C504C704C904CB04CD04D004D204D404D604D804DA04DC04DE04E004E204E404E604E804EA04EC04EE04F004F204F404F604F804FA04FC04FE05000502050405060508050A050C050E05100512051405160518051A051C051E05200522052405260531-055610A0-10C510C710CD1E001E021E041E061E081E0A1E0C1E0E1E101E121E141E161E181E1A1E1C1E1E1E201E221E241E261E281E2A1E2C1E2E1E301E321E341E361E381E3A1E3C1E3E1E401E421E441E461E481E4A1E4C1E4E1E501E521E541E561E581E5A1E5C1E5E1E601E621E641E661E681E6A1E6C1E6E1E701E721E741E761E781E7A1E7C1E7E1E801E821E841E861E881E8A1E8C1E8E1E901E921E941E9E1EA01EA21EA41EA61EA81EAA1EAC1EAE1EB01EB21EB41EB61EB81EBA1EBC1EBE1EC01EC21EC41EC61EC81ECA1ECC1ECE1ED01ED21ED41ED61ED81EDA1EDC1EDE1EE01EE21EE41EE61EE81EEA1EEC1EEE1EF01EF21EF41EF61EF81EFA1EFC1EFE1F08-1F0F1F18-1F1D1F28-1F2F1F38-1F3F1F48-1F4D1F591F5B1F5D1F5F1F68-1F6F1FB8-1FBB1FC8-1FCB1FD8-1FDB1FE8-1FEC1FF8-1FFB21022107210B-210D2110-211221152119-211D212421262128212A-212D2130-2133213E213F214521832C00-2C2E2C602C62-2C642C672C692C6B2C6D-2C702C722C752C7E-2C802C822C842C862C882C8A2C8C2C8E2C902C922C942C962C982C9A2C9C2C9E2CA02CA22CA42CA62CA82CAA2CAC2CAE2CB02CB22CB42CB62CB82CBA2CBC2CBE2CC02CC22CC42CC62CC82CCA2CCC2CCE2CD02CD22CD42CD62CD82CDA2CDC2CDE2CE02CE22CEB2CED2CF2A640A642A644A646A648A64AA64CA64EA650A652A654A656A658A65AA65CA65EA660A662A664A666A668A66AA66CA680A682A684A686A688A68AA68CA68EA690A692A694A696A722A724A726A728A72AA72CA72EA732A734A736A738A73AA73CA73EA740A742A744A746A748A74AA74CA74EA750A752A754A756A758A75AA75CA75EA760A762A764A766A768A76AA76CA76EA779A77BA77DA77EA780A782A784A786A78BA78DA790A792A7A0A7A2A7A4A7A6A7A8A7AAFF21-FF3A\",\n        Lt: \"01C501C801CB01F21F88-1F8F1F98-1F9F1FA8-1FAF1FBC1FCC1FFC\",\n        Lm: \"02B0-02C102C6-02D102E0-02E402EC02EE0374037A0559064006E506E607F407F507FA081A0824082809710E460EC610FC17D718431AA71C78-1C7D1D2C-1D6A1D781D9B-1DBF2071207F2090-209C2C7C2C7D2D6F2E2F30053031-3035303B309D309E30FC-30FEA015A4F8-A4FDA60CA67FA717-A71FA770A788A7F8A7F9A9CFAA70AADDAAF3AAF4FF70FF9EFF9F\",\n        Lo: \"00AA00BA01BB01C0-01C3029405D0-05EA05F0-05F20620-063F0641-064A066E066F0671-06D306D506EE06EF06FA-06FC06FF07100712-072F074D-07A507B107CA-07EA0800-08150840-085808A008A2-08AC0904-0939093D09500958-09610972-09770979-097F0985-098C098F09900993-09A809AA-09B009B209B6-09B909BD09CE09DC09DD09DF-09E109F009F10A05-0A0A0A0F0A100A13-0A280A2A-0A300A320A330A350A360A380A390A59-0A5C0A5E0A72-0A740A85-0A8D0A8F-0A910A93-0AA80AAA-0AB00AB20AB30AB5-0AB90ABD0AD00AE00AE10B05-0B0C0B0F0B100B13-0B280B2A-0B300B320B330B35-0B390B3D0B5C0B5D0B5F-0B610B710B830B85-0B8A0B8E-0B900B92-0B950B990B9A0B9C0B9E0B9F0BA30BA40BA8-0BAA0BAE-0BB90BD00C05-0C0C0C0E-0C100C12-0C280C2A-0C330C35-0C390C3D0C580C590C600C610C85-0C8C0C8E-0C900C92-0CA80CAA-0CB30CB5-0CB90CBD0CDE0CE00CE10CF10CF20D05-0D0C0D0E-0D100D12-0D3A0D3D0D4E0D600D610D7A-0D7F0D85-0D960D9A-0DB10DB3-0DBB0DBD0DC0-0DC60E01-0E300E320E330E40-0E450E810E820E840E870E880E8A0E8D0E94-0E970E99-0E9F0EA1-0EA30EA50EA70EAA0EAB0EAD-0EB00EB20EB30EBD0EC0-0EC40EDC-0EDF0F000F40-0F470F49-0F6C0F88-0F8C1000-102A103F1050-1055105A-105D106110651066106E-10701075-1081108E10D0-10FA10FD-1248124A-124D1250-12561258125A-125D1260-1288128A-128D1290-12B012B2-12B512B8-12BE12C012C2-12C512C8-12D612D8-13101312-13151318-135A1380-138F13A0-13F41401-166C166F-167F1681-169A16A0-16EA1700-170C170E-17111720-17311740-17511760-176C176E-17701780-17B317DC1820-18421844-18771880-18A818AA18B0-18F51900-191C1950-196D1970-19741980-19AB19C1-19C71A00-1A161A20-1A541B05-1B331B45-1B4B1B83-1BA01BAE1BAF1BBA-1BE51C00-1C231C4D-1C4F1C5A-1C771CE9-1CEC1CEE-1CF11CF51CF62135-21382D30-2D672D80-2D962DA0-2DA62DA8-2DAE2DB0-2DB62DB8-2DBE2DC0-2DC62DC8-2DCE2DD0-2DD62DD8-2DDE3006303C3041-3096309F30A1-30FA30FF3105-312D3131-318E31A0-31BA31F0-31FF3400-4DB54E00-9FCCA000-A014A016-A48CA4D0-A4F7A500-A60BA610-A61FA62AA62BA66EA6A0-A6E5A7FB-A801A803-A805A807-A80AA80C-A822A840-A873A882-A8B3A8F2-A8F7A8FBA90A-A925A930-A946A960-A97CA984-A9B2AA00-AA28AA40-AA42AA44-AA4BAA60-AA6FAA71-AA76AA7AAA80-AAAFAAB1AAB5AAB6AAB9-AABDAAC0AAC2AADBAADCAAE0-AAEAAAF2AB01-AB06AB09-AB0EAB11-AB16AB20-AB26AB28-AB2EABC0-ABE2AC00-D7A3D7B0-D7C6D7CB-D7FBF900-FA6DFA70-FAD9FB1DFB1F-FB28FB2A-FB36FB38-FB3CFB3EFB40FB41FB43FB44FB46-FBB1FBD3-FD3DFD50-FD8FFD92-FDC7FDF0-FDFBFE70-FE74FE76-FEFCFF66-FF6FFF71-FF9DFFA0-FFBEFFC2-FFC7FFCA-FFCFFFD2-FFD7FFDA-FFDC\",\n        M: \"0300-036F0483-04890591-05BD05BF05C105C205C405C505C70610-061A064B-065F067006D6-06DC06DF-06E406E706E806EA-06ED07110730-074A07A6-07B007EB-07F30816-0819081B-08230825-08270829-082D0859-085B08E4-08FE0900-0903093A-093C093E-094F0951-0957096209630981-098309BC09BE-09C409C709C809CB-09CD09D709E209E30A01-0A030A3C0A3E-0A420A470A480A4B-0A4D0A510A700A710A750A81-0A830ABC0ABE-0AC50AC7-0AC90ACB-0ACD0AE20AE30B01-0B030B3C0B3E-0B440B470B480B4B-0B4D0B560B570B620B630B820BBE-0BC20BC6-0BC80BCA-0BCD0BD70C01-0C030C3E-0C440C46-0C480C4A-0C4D0C550C560C620C630C820C830CBC0CBE-0CC40CC6-0CC80CCA-0CCD0CD50CD60CE20CE30D020D030D3E-0D440D46-0D480D4A-0D4D0D570D620D630D820D830DCA0DCF-0DD40DD60DD8-0DDF0DF20DF30E310E34-0E3A0E47-0E4E0EB10EB4-0EB90EBB0EBC0EC8-0ECD0F180F190F350F370F390F3E0F3F0F71-0F840F860F870F8D-0F970F99-0FBC0FC6102B-103E1056-1059105E-10601062-10641067-106D1071-10741082-108D108F109A-109D135D-135F1712-17141732-1734175217531772177317B4-17D317DD180B-180D18A91920-192B1930-193B19B0-19C019C819C91A17-1A1B1A55-1A5E1A60-1A7C1A7F1B00-1B041B34-1B441B6B-1B731B80-1B821BA1-1BAD1BE6-1BF31C24-1C371CD0-1CD21CD4-1CE81CED1CF2-1CF41DC0-1DE61DFC-1DFF20D0-20F02CEF-2CF12D7F2DE0-2DFF302A-302F3099309AA66F-A672A674-A67DA69FA6F0A6F1A802A806A80BA823-A827A880A881A8B4-A8C4A8E0-A8F1A926-A92DA947-A953A980-A983A9B3-A9C0AA29-AA36AA43AA4CAA4DAA7BAAB0AAB2-AAB4AAB7AAB8AABEAABFAAC1AAEB-AAEFAAF5AAF6ABE3-ABEAABECABEDFB1EFE00-FE0FFE20-FE26\",\n        Mn: \"0300-036F0483-04870591-05BD05BF05C105C205C405C505C70610-061A064B-065F067006D6-06DC06DF-06E406E706E806EA-06ED07110730-074A07A6-07B007EB-07F30816-0819081B-08230825-08270829-082D0859-085B08E4-08FE0900-0902093A093C0941-0948094D0951-095709620963098109BC09C1-09C409CD09E209E30A010A020A3C0A410A420A470A480A4B-0A4D0A510A700A710A750A810A820ABC0AC1-0AC50AC70AC80ACD0AE20AE30B010B3C0B3F0B41-0B440B4D0B560B620B630B820BC00BCD0C3E-0C400C46-0C480C4A-0C4D0C550C560C620C630CBC0CBF0CC60CCC0CCD0CE20CE30D41-0D440D4D0D620D630DCA0DD2-0DD40DD60E310E34-0E3A0E47-0E4E0EB10EB4-0EB90EBB0EBC0EC8-0ECD0F180F190F350F370F390F71-0F7E0F80-0F840F860F870F8D-0F970F99-0FBC0FC6102D-10301032-10371039103A103D103E10581059105E-10601071-1074108210851086108D109D135D-135F1712-17141732-1734175217531772177317B417B517B7-17BD17C617C9-17D317DD180B-180D18A91920-19221927192819321939-193B1A171A181A561A58-1A5E1A601A621A65-1A6C1A73-1A7C1A7F1B00-1B031B341B36-1B3A1B3C1B421B6B-1B731B801B811BA2-1BA51BA81BA91BAB1BE61BE81BE91BED1BEF-1BF11C2C-1C331C361C371CD0-1CD21CD4-1CE01CE2-1CE81CED1CF41DC0-1DE61DFC-1DFF20D0-20DC20E120E5-20F02CEF-2CF12D7F2DE0-2DFF302A-302D3099309AA66FA674-A67DA69FA6F0A6F1A802A806A80BA825A826A8C4A8E0-A8F1A926-A92DA947-A951A980-A982A9B3A9B6-A9B9A9BCAA29-AA2EAA31AA32AA35AA36AA43AA4CAAB0AAB2-AAB4AAB7AAB8AABEAABFAAC1AAECAAEDAAF6ABE5ABE8ABEDFB1EFE00-FE0FFE20-FE26\",\n        Mc: \"0903093B093E-09400949-094C094E094F0982098309BE-09C009C709C809CB09CC09D70A030A3E-0A400A830ABE-0AC00AC90ACB0ACC0B020B030B3E0B400B470B480B4B0B4C0B570BBE0BBF0BC10BC20BC6-0BC80BCA-0BCC0BD70C01-0C030C41-0C440C820C830CBE0CC0-0CC40CC70CC80CCA0CCB0CD50CD60D020D030D3E-0D400D46-0D480D4A-0D4C0D570D820D830DCF-0DD10DD8-0DDF0DF20DF30F3E0F3F0F7F102B102C10311038103B103C105610571062-10641067-106D108310841087-108C108F109A-109C17B617BE-17C517C717C81923-19261929-192B193019311933-193819B0-19C019C819C91A19-1A1B1A551A571A611A631A641A6D-1A721B041B351B3B1B3D-1B411B431B441B821BA11BA61BA71BAA1BAC1BAD1BE71BEA-1BEC1BEE1BF21BF31C24-1C2B1C341C351CE11CF21CF3302E302FA823A824A827A880A881A8B4-A8C3A952A953A983A9B4A9B5A9BAA9BBA9BD-A9C0AA2FAA30AA33AA34AA4DAA7BAAEBAAEEAAEFAAF5ABE3ABE4ABE6ABE7ABE9ABEAABEC\",\n        Me: \"0488048920DD-20E020E2-20E4A670-A672\",\n        N: \"0030-003900B200B300B900BC-00BE0660-066906F0-06F907C0-07C90966-096F09E6-09EF09F4-09F90A66-0A6F0AE6-0AEF0B66-0B6F0B72-0B770BE6-0BF20C66-0C6F0C78-0C7E0CE6-0CEF0D66-0D750E50-0E590ED0-0ED90F20-0F331040-10491090-10991369-137C16EE-16F017E0-17E917F0-17F91810-18191946-194F19D0-19DA1A80-1A891A90-1A991B50-1B591BB0-1BB91C40-1C491C50-1C5920702074-20792080-20892150-21822185-21892460-249B24EA-24FF2776-27932CFD30073021-30293038-303A3192-31953220-32293248-324F3251-325F3280-328932B1-32BFA620-A629A6E6-A6EFA830-A835A8D0-A8D9A900-A909A9D0-A9D9AA50-AA59ABF0-ABF9FF10-FF19\",\n        Nd: \"0030-00390660-066906F0-06F907C0-07C90966-096F09E6-09EF0A66-0A6F0AE6-0AEF0B66-0B6F0BE6-0BEF0C66-0C6F0CE6-0CEF0D66-0D6F0E50-0E590ED0-0ED90F20-0F291040-10491090-109917E0-17E91810-18191946-194F19D0-19D91A80-1A891A90-1A991B50-1B591BB0-1BB91C40-1C491C50-1C59A620-A629A8D0-A8D9A900-A909A9D0-A9D9AA50-AA59ABF0-ABF9FF10-FF19\",\n        Nl: \"16EE-16F02160-21822185-218830073021-30293038-303AA6E6-A6EF\",\n        No: \"00B200B300B900BC-00BE09F4-09F90B72-0B770BF0-0BF20C78-0C7E0D70-0D750F2A-0F331369-137C17F0-17F919DA20702074-20792080-20892150-215F21892460-249B24EA-24FF2776-27932CFD3192-31953220-32293248-324F3251-325F3280-328932B1-32BFA830-A835\",\n        P: \"0021-00230025-002A002C-002F003A003B003F0040005B-005D005F007B007D00A100A700AB00B600B700BB00BF037E0387055A-055F0589058A05BE05C005C305C605F305F40609060A060C060D061B061E061F066A-066D06D40700-070D07F7-07F90830-083E085E0964096509700AF00DF40E4F0E5A0E5B0F04-0F120F140F3A-0F3D0F850FD0-0FD40FD90FDA104A-104F10FB1360-13681400166D166E169B169C16EB-16ED1735173617D4-17D617D8-17DA1800-180A194419451A1E1A1F1AA0-1AA61AA8-1AAD1B5A-1B601BFC-1BFF1C3B-1C3F1C7E1C7F1CC0-1CC71CD32010-20272030-20432045-20512053-205E207D207E208D208E2329232A2768-277527C527C627E6-27EF2983-299829D8-29DB29FC29FD2CF9-2CFC2CFE2CFF2D702E00-2E2E2E30-2E3B3001-30033008-30113014-301F3030303D30A030FBA4FEA4FFA60D-A60FA673A67EA6F2-A6F7A874-A877A8CEA8CFA8F8-A8FAA92EA92FA95FA9C1-A9CDA9DEA9DFAA5C-AA5FAADEAADFAAF0AAF1ABEBFD3EFD3FFE10-FE19FE30-FE52FE54-FE61FE63FE68FE6AFE6BFF01-FF03FF05-FF0AFF0C-FF0FFF1AFF1BFF1FFF20FF3B-FF3DFF3FFF5BFF5DFF5F-FF65\",\n        Pd: \"002D058A05BE140018062010-20152E172E1A2E3A2E3B301C303030A0FE31FE32FE58FE63FF0D\",\n        Ps: \"0028005B007B0F3A0F3C169B201A201E2045207D208D23292768276A276C276E27702772277427C527E627E827EA27EC27EE2983298529872989298B298D298F299129932995299729D829DA29FC2E222E242E262E283008300A300C300E3010301430163018301A301DFD3EFE17FE35FE37FE39FE3BFE3DFE3FFE41FE43FE47FE59FE5BFE5DFF08FF3BFF5BFF5FFF62\",\n        Pe: \"0029005D007D0F3B0F3D169C2046207E208E232A2769276B276D276F27712773277527C627E727E927EB27ED27EF298429862988298A298C298E2990299229942996299829D929DB29FD2E232E252E272E293009300B300D300F3011301530173019301B301E301FFD3FFE18FE36FE38FE3AFE3CFE3EFE40FE42FE44FE48FE5AFE5CFE5EFF09FF3DFF5DFF60FF63\",\n        Pi: \"00AB2018201B201C201F20392E022E042E092E0C2E1C2E20\",\n        Pf: \"00BB2019201D203A2E032E052E0A2E0D2E1D2E21\",\n        Pc: \"005F203F20402054FE33FE34FE4D-FE4FFF3F\",\n        Po: \"0021-00230025-0027002A002C002E002F003A003B003F0040005C00A100A700B600B700BF037E0387055A-055F058905C005C305C605F305F40609060A060C060D061B061E061F066A-066D06D40700-070D07F7-07F90830-083E085E0964096509700AF00DF40E4F0E5A0E5B0F04-0F120F140F850FD0-0FD40FD90FDA104A-104F10FB1360-1368166D166E16EB-16ED1735173617D4-17D617D8-17DA1800-18051807-180A194419451A1E1A1F1AA0-1AA61AA8-1AAD1B5A-1B601BFC-1BFF1C3B-1C3F1C7E1C7F1CC0-1CC71CD3201620172020-20272030-2038203B-203E2041-20432047-205120532055-205E2CF9-2CFC2CFE2CFF2D702E002E012E06-2E082E0B2E0E-2E162E182E192E1B2E1E2E1F2E2A-2E2E2E30-2E393001-3003303D30FBA4FEA4FFA60D-A60FA673A67EA6F2-A6F7A874-A877A8CEA8CFA8F8-A8FAA92EA92FA95FA9C1-A9CDA9DEA9DFAA5C-AA5FAADEAADFAAF0AAF1ABEBFE10-FE16FE19FE30FE45FE46FE49-FE4CFE50-FE52FE54-FE57FE5F-FE61FE68FE6AFE6BFF01-FF03FF05-FF07FF0AFF0CFF0EFF0FFF1AFF1BFF1FFF20FF3CFF61FF64FF65\",\n        S: \"0024002B003C-003E005E0060007C007E00A2-00A600A800A900AC00AE-00B100B400B800D700F702C2-02C502D2-02DF02E5-02EB02ED02EF-02FF03750384038503F60482058F0606-0608060B060E060F06DE06E906FD06FE07F609F209F309FA09FB0AF10B700BF3-0BFA0C7F0D790E3F0F01-0F030F130F15-0F170F1A-0F1F0F340F360F380FBE-0FC50FC7-0FCC0FCE0FCF0FD5-0FD8109E109F1390-139917DB194019DE-19FF1B61-1B6A1B74-1B7C1FBD1FBF-1FC11FCD-1FCF1FDD-1FDF1FED-1FEF1FFD1FFE20442052207A-207C208A-208C20A0-20B9210021012103-21062108210921142116-2118211E-2123212521272129212E213A213B2140-2144214A-214D214F2190-2328232B-23F32400-24262440-244A249C-24E92500-26FF2701-27672794-27C427C7-27E527F0-29822999-29D729DC-29FB29FE-2B4C2B50-2B592CE5-2CEA2E80-2E992E9B-2EF32F00-2FD52FF0-2FFB300430123013302030363037303E303F309B309C319031913196-319F31C0-31E33200-321E322A-324732503260-327F328A-32B032C0-32FE3300-33FF4DC0-4DFFA490-A4C6A700-A716A720A721A789A78AA828-A82BA836-A839AA77-AA79FB29FBB2-FBC1FDFCFDFDFE62FE64-FE66FE69FF04FF0BFF1C-FF1EFF3EFF40FF5CFF5EFFE0-FFE6FFE8-FFEEFFFCFFFD\",\n        Sm: \"002B003C-003E007C007E00AC00B100D700F703F60606-060820442052207A-207C208A-208C21182140-2144214B2190-2194219A219B21A021A321A621AE21CE21CF21D221D421F4-22FF2308-230B23202321237C239B-23B323DC-23E125B725C125F8-25FF266F27C0-27C427C7-27E527F0-27FF2900-29822999-29D729DC-29FB29FE-2AFF2B30-2B442B47-2B4CFB29FE62FE64-FE66FF0BFF1C-FF1EFF5CFF5EFFE2FFE9-FFEC\",\n        Sc: \"002400A2-00A5058F060B09F209F309FB0AF10BF90E3F17DB20A0-20B9A838FDFCFE69FF04FFE0FFE1FFE5FFE6\",\n        Sk: \"005E006000A800AF00B400B802C2-02C502D2-02DF02E5-02EB02ED02EF-02FF0375038403851FBD1FBF-1FC11FCD-1FCF1FDD-1FDF1FED-1FEF1FFD1FFE309B309CA700-A716A720A721A789A78AFBB2-FBC1FF3EFF40FFE3\",\n        So: \"00A600A900AE00B00482060E060F06DE06E906FD06FE07F609FA0B700BF3-0BF80BFA0C7F0D790F01-0F030F130F15-0F170F1A-0F1F0F340F360F380FBE-0FC50FC7-0FCC0FCE0FCF0FD5-0FD8109E109F1390-1399194019DE-19FF1B61-1B6A1B74-1B7C210021012103-210621082109211421162117211E-2123212521272129212E213A213B214A214C214D214F2195-2199219C-219F21A121A221A421A521A7-21AD21AF-21CD21D021D121D321D5-21F32300-2307230C-231F2322-2328232B-237B237D-239A23B4-23DB23E2-23F32400-24262440-244A249C-24E92500-25B625B8-25C025C2-25F72600-266E2670-26FF2701-27672794-27BF2800-28FF2B00-2B2F2B452B462B50-2B592CE5-2CEA2E80-2E992E9B-2EF32F00-2FD52FF0-2FFB300430123013302030363037303E303F319031913196-319F31C0-31E33200-321E322A-324732503260-327F328A-32B032C0-32FE3300-33FF4DC0-4DFFA490-A4C6A828-A82BA836A837A839AA77-AA79FDFDFFE4FFE8FFEDFFEEFFFCFFFD\",\n        Z: \"002000A01680180E2000-200A20282029202F205F3000\",\n        Zs: \"002000A01680180E2000-200A202F205F3000\",\n        Zl: \"2028\",\n        Zp: \"2029\",\n        C: \"0000-001F007F-009F00AD03780379037F-0383038B038D03A20528-05300557055805600588058B-058E059005C8-05CF05EB-05EF05F5-0605061C061D06DD070E070F074B074C07B2-07BF07FB-07FF082E082F083F085C085D085F-089F08A108AD-08E308FF097809800984098D098E0991099209A909B109B3-09B509BA09BB09C509C609C909CA09CF-09D609D8-09DB09DE09E409E509FC-0A000A040A0B-0A0E0A110A120A290A310A340A370A3A0A3B0A3D0A43-0A460A490A4A0A4E-0A500A52-0A580A5D0A5F-0A650A76-0A800A840A8E0A920AA90AB10AB40ABA0ABB0AC60ACA0ACE0ACF0AD1-0ADF0AE40AE50AF2-0B000B040B0D0B0E0B110B120B290B310B340B3A0B3B0B450B460B490B4A0B4E-0B550B58-0B5B0B5E0B640B650B78-0B810B840B8B-0B8D0B910B96-0B980B9B0B9D0BA0-0BA20BA5-0BA70BAB-0BAD0BBA-0BBD0BC3-0BC50BC90BCE0BCF0BD1-0BD60BD8-0BE50BFB-0C000C040C0D0C110C290C340C3A-0C3C0C450C490C4E-0C540C570C5A-0C5F0C640C650C70-0C770C800C810C840C8D0C910CA90CB40CBA0CBB0CC50CC90CCE-0CD40CD7-0CDD0CDF0CE40CE50CF00CF3-0D010D040D0D0D110D3B0D3C0D450D490D4F-0D560D58-0D5F0D640D650D76-0D780D800D810D840D97-0D990DB20DBC0DBE0DBF0DC7-0DC90DCB-0DCE0DD50DD70DE0-0DF10DF5-0E000E3B-0E3E0E5C-0E800E830E850E860E890E8B0E8C0E8E-0E930E980EA00EA40EA60EA80EA90EAC0EBA0EBE0EBF0EC50EC70ECE0ECF0EDA0EDB0EE0-0EFF0F480F6D-0F700F980FBD0FCD0FDB-0FFF10C610C8-10CC10CE10CF1249124E124F12571259125E125F1289128E128F12B112B612B712BF12C112C612C712D7131113161317135B135C137D-137F139A-139F13F5-13FF169D-169F16F1-16FF170D1715-171F1737-173F1754-175F176D17711774-177F17DE17DF17EA-17EF17FA-17FF180F181A-181F1878-187F18AB-18AF18F6-18FF191D-191F192C-192F193C-193F1941-1943196E196F1975-197F19AC-19AF19CA-19CF19DB-19DD1A1C1A1D1A5F1A7D1A7E1A8A-1A8F1A9A-1A9F1AAE-1AFF1B4C-1B4F1B7D-1B7F1BF4-1BFB1C38-1C3A1C4A-1C4C1C80-1CBF1CC8-1CCF1CF7-1CFF1DE7-1DFB1F161F171F1E1F1F1F461F471F4E1F4F1F581F5A1F5C1F5E1F7E1F7F1FB51FC51FD41FD51FDC1FF01FF11FF51FFF200B-200F202A-202E2060-206F20722073208F209D-209F20BA-20CF20F1-20FF218A-218F23F4-23FF2427-243F244B-245F27002B4D-2B4F2B5A-2BFF2C2F2C5F2CF4-2CF82D262D28-2D2C2D2E2D2F2D68-2D6E2D71-2D7E2D97-2D9F2DA72DAF2DB72DBF2DC72DCF2DD72DDF2E3C-2E7F2E9A2EF4-2EFF2FD6-2FEF2FFC-2FFF3040309730983100-3104312E-3130318F31BB-31BF31E4-31EF321F32FF4DB6-4DBF9FCD-9FFFA48D-A48FA4C7-A4CFA62C-A63FA698-A69EA6F8-A6FFA78FA794-A79FA7AB-A7F7A82C-A82FA83A-A83FA878-A87FA8C5-A8CDA8DA-A8DFA8FC-A8FFA954-A95EA97D-A97FA9CEA9DA-A9DDA9E0-A9FFAA37-AA3FAA4EAA4FAA5AAA5BAA7C-AA7FAAC3-AADAAAF7-AB00AB07AB08AB0FAB10AB17-AB1FAB27AB2F-ABBFABEEABEFABFA-ABFFD7A4-D7AFD7C7-D7CAD7FC-F8FFFA6EFA6FFADA-FAFFFB07-FB12FB18-FB1CFB37FB3DFB3FFB42FB45FBC2-FBD2FD40-FD4FFD90FD91FDC8-FDEFFDFEFDFFFE1A-FE1FFE27-FE2FFE53FE67FE6C-FE6FFE75FEFD-FF00FFBF-FFC1FFC8FFC9FFD0FFD1FFD8FFD9FFDD-FFDFFFE7FFEF-FFFBFFFEFFFF\",\n        Cc: \"0000-001F007F-009F\",\n        Cf: \"00AD0600-060406DD070F200B-200F202A-202E2060-2064206A-206FFEFFFFF9-FFFB\",\n        Co: \"E000-F8FF\",\n        Cs: \"D800-DFFF\",\n        Cn: \"03780379037F-0383038B038D03A20528-05300557055805600588058B-058E059005C8-05CF05EB-05EF05F5-05FF0605061C061D070E074B074C07B2-07BF07FB-07FF082E082F083F085C085D085F-089F08A108AD-08E308FF097809800984098D098E0991099209A909B109B3-09B509BA09BB09C509C609C909CA09CF-09D609D8-09DB09DE09E409E509FC-0A000A040A0B-0A0E0A110A120A290A310A340A370A3A0A3B0A3D0A43-0A460A490A4A0A4E-0A500A52-0A580A5D0A5F-0A650A76-0A800A840A8E0A920AA90AB10AB40ABA0ABB0AC60ACA0ACE0ACF0AD1-0ADF0AE40AE50AF2-0B000B040B0D0B0E0B110B120B290B310B340B3A0B3B0B450B460B490B4A0B4E-0B550B58-0B5B0B5E0B640B650B78-0B810B840B8B-0B8D0B910B96-0B980B9B0B9D0BA0-0BA20BA5-0BA70BAB-0BAD0BBA-0BBD0BC3-0BC50BC90BCE0BCF0BD1-0BD60BD8-0BE50BFB-0C000C040C0D0C110C290C340C3A-0C3C0C450C490C4E-0C540C570C5A-0C5F0C640C650C70-0C770C800C810C840C8D0C910CA90CB40CBA0CBB0CC50CC90CCE-0CD40CD7-0CDD0CDF0CE40CE50CF00CF3-0D010D040D0D0D110D3B0D3C0D450D490D4F-0D560D58-0D5F0D640D650D76-0D780D800D810D840D97-0D990DB20DBC0DBE0DBF0DC7-0DC90DCB-0DCE0DD50DD70DE0-0DF10DF5-0E000E3B-0E3E0E5C-0E800E830E850E860E890E8B0E8C0E8E-0E930E980EA00EA40EA60EA80EA90EAC0EBA0EBE0EBF0EC50EC70ECE0ECF0EDA0EDB0EE0-0EFF0F480F6D-0F700F980FBD0FCD0FDB-0FFF10C610C8-10CC10CE10CF1249124E124F12571259125E125F1289128E128F12B112B612B712BF12C112C612C712D7131113161317135B135C137D-137F139A-139F13F5-13FF169D-169F16F1-16FF170D1715-171F1737-173F1754-175F176D17711774-177F17DE17DF17EA-17EF17FA-17FF180F181A-181F1878-187F18AB-18AF18F6-18FF191D-191F192C-192F193C-193F1941-1943196E196F1975-197F19AC-19AF19CA-19CF19DB-19DD1A1C1A1D1A5F1A7D1A7E1A8A-1A8F1A9A-1A9F1AAE-1AFF1B4C-1B4F1B7D-1B7F1BF4-1BFB1C38-1C3A1C4A-1C4C1C80-1CBF1CC8-1CCF1CF7-1CFF1DE7-1DFB1F161F171F1E1F1F1F461F471F4E1F4F1F581F5A1F5C1F5E1F7E1F7F1FB51FC51FD41FD51FDC1FF01FF11FF51FFF2065-206920722073208F209D-209F20BA-20CF20F1-20FF218A-218F23F4-23FF2427-243F244B-245F27002B4D-2B4F2B5A-2BFF2C2F2C5F2CF4-2CF82D262D28-2D2C2D2E2D2F2D68-2D6E2D71-2D7E2D97-2D9F2DA72DAF2DB72DBF2DC72DCF2DD72DDF2E3C-2E7F2E9A2EF4-2EFF2FD6-2FEF2FFC-2FFF3040309730983100-3104312E-3130318F31BB-31BF31E4-31EF321F32FF4DB6-4DBF9FCD-9FFFA48D-A48FA4C7-A4CFA62C-A63FA698-A69EA6F8-A6FFA78FA794-A79FA7AB-A7F7A82C-A82FA83A-A83FA878-A87FA8C5-A8CDA8DA-A8DFA8FC-A8FFA954-A95EA97D-A97FA9CEA9DA-A9DDA9E0-A9FFAA37-AA3FAA4EAA4FAA5AAA5BAA7C-AA7FAAC3-AADAAAF7-AB00AB07AB08AB0FAB10AB17-AB1FAB27AB2F-ABBFABEEABEFABFA-ABFFD7A4-D7AFD7C7-D7CAD7FC-D7FFFA6EFA6FFADA-FAFFFB07-FB12FB18-FB1CFB37FB3DFB3FFB42FB45FBC2-FBD2FD40-FD4FFD90FD91FDC8-FDEFFDFEFDFFFE1A-FE1FFE27-FE2FFE53FE67FE6C-FE6FFE75FEFDFEFEFF00FFBF-FFC1FFC8FFC9FFD0FFD1FFD8FFD9FFDD-FFDFFFE7FFEF-FFF8FFFEFFFF\"\n    }, {\n        //L: \"Letter\", // Included in the Unicode Base addon\n        Ll: \"Lowercase_Letter\",\n        Lu: \"Uppercase_Letter\",\n        Lt: \"Titlecase_Letter\",\n        Lm: \"Modifier_Letter\",\n        Lo: \"Other_Letter\",\n        M: \"Mark\",\n        Mn: \"Nonspacing_Mark\",\n        Mc: \"Spacing_Mark\",\n        Me: \"Enclosing_Mark\",\n        N: \"Number\",\n        Nd: \"Decimal_Number\",\n        Nl: \"Letter_Number\",\n        No: \"Other_Number\",\n        P: \"Punctuation\",\n        Pd: \"Dash_Punctuation\",\n        Ps: \"Open_Punctuation\",\n        Pe: \"Close_Punctuation\",\n        Pi: \"Initial_Punctuation\",\n        Pf: \"Final_Punctuation\",\n        Pc: \"Connector_Punctuation\",\n        Po: \"Other_Punctuation\",\n        S: \"Symbol\",\n        Sm: \"Math_Symbol\",\n        Sc: \"Currency_Symbol\",\n        Sk: \"Modifier_Symbol\",\n        So: \"Other_Symbol\",\n        Z: \"Separator\",\n        Zs: \"Space_Separator\",\n        Zl: \"Line_Separator\",\n        Zp: \"Paragraph_Separator\",\n        C: \"Other\",\n        Cc: \"Control\",\n        Cf: \"Format\",\n        Co: \"Private_Use\",\n        Cs: \"Surrogate\",\n        Cn: \"Unassigned\"\n    });\n\n}(XRegExp));\n\n\n/***** unicode-scripts.js *****/\n\n/*!\n * XRegExp Unicode Scripts v1.2.0\n * (c) 2010-2012 Steven Levithan <http://xregexp.com/>\n * MIT License\n * Uses Unicode 6.1 <http://unicode.org/>\n */\n\n/**\n * Adds support for all Unicode scripts in the Basic Multilingual Plane (U+0000-U+FFFF).\n * E.g., `\\p{Latin}`. Token names are case insensitive, and any spaces, hyphens, and underscores\n * are ignored.\n * @requires XRegExp, XRegExp Unicode Base\n */\n(function (XRegExp) {\n    \"use strict\";\n\n    if (!XRegExp.addUnicodePackage) {\n        throw new ReferenceError(\"Unicode Base must be loaded before Unicode Scripts\");\n    }\n\n    XRegExp.install(\"extensibility\");\n\n    XRegExp.addUnicodePackage({\n        Arabic: \"0600-06040606-060B060D-061A061E0620-063F0641-064A0656-065E066A-066F0671-06DC06DE-06FF0750-077F08A008A2-08AC08E4-08FEFB50-FBC1FBD3-FD3DFD50-FD8FFD92-FDC7FDF0-FDFCFE70-FE74FE76-FEFC\",\n        Armenian: \"0531-05560559-055F0561-0587058A058FFB13-FB17\",\n        Balinese: \"1B00-1B4B1B50-1B7C\",\n        Bamum: \"A6A0-A6F7\",\n        Batak: \"1BC0-1BF31BFC-1BFF\",\n        Bengali: \"0981-09830985-098C098F09900993-09A809AA-09B009B209B6-09B909BC-09C409C709C809CB-09CE09D709DC09DD09DF-09E309E6-09FB\",\n        Bopomofo: \"02EA02EB3105-312D31A0-31BA\",\n        Braille: \"2800-28FF\",\n        Buginese: \"1A00-1A1B1A1E1A1F\",\n        Buhid: \"1740-1753\",\n        Canadian_Aboriginal: \"1400-167F18B0-18F5\",\n        Cham: \"AA00-AA36AA40-AA4DAA50-AA59AA5C-AA5F\",\n        Cherokee: \"13A0-13F4\",\n        Common: \"0000-0040005B-0060007B-00A900AB-00B900BB-00BF00D700F702B9-02DF02E5-02E902EC-02FF0374037E038503870589060C061B061F06400660-066906DD096409650E3F0FD5-0FD810FB16EB-16ED173517361802180318051CD31CE11CE9-1CEC1CEE-1CF31CF51CF62000-200B200E-2064206A-20702074-207E2080-208E20A0-20B92100-21252127-2129212C-21312133-214D214F-215F21892190-23F32400-24262440-244A2460-26FF2701-27FF2900-2B4C2B50-2B592E00-2E3B2FF0-2FFB3000-300430063008-30203030-3037303C-303F309B309C30A030FB30FC3190-319F31C0-31E33220-325F327F-32CF3358-33FF4DC0-4DFFA700-A721A788-A78AA830-A839FD3EFD3FFDFDFE10-FE19FE30-FE52FE54-FE66FE68-FE6BFEFFFF01-FF20FF3B-FF40FF5B-FF65FF70FF9EFF9FFFE0-FFE6FFE8-FFEEFFF9-FFFD\",\n        Coptic: \"03E2-03EF2C80-2CF32CF9-2CFF\",\n        Cyrillic: \"0400-04840487-05271D2B1D782DE0-2DFFA640-A697A69F\",\n        Devanagari: \"0900-09500953-09630966-09770979-097FA8E0-A8FB\",\n        Ethiopic: \"1200-1248124A-124D1250-12561258125A-125D1260-1288128A-128D1290-12B012B2-12B512B8-12BE12C012C2-12C512C8-12D612D8-13101312-13151318-135A135D-137C1380-13992D80-2D962DA0-2DA62DA8-2DAE2DB0-2DB62DB8-2DBE2DC0-2DC62DC8-2DCE2DD0-2DD62DD8-2DDEAB01-AB06AB09-AB0EAB11-AB16AB20-AB26AB28-AB2E\",\n        Georgian: \"10A0-10C510C710CD10D0-10FA10FC-10FF2D00-2D252D272D2D\",\n        Glagolitic: \"2C00-2C2E2C30-2C5E\",\n        Greek: \"0370-03730375-0377037A-037D038403860388-038A038C038E-03A103A3-03E103F0-03FF1D26-1D2A1D5D-1D611D66-1D6A1DBF1F00-1F151F18-1F1D1F20-1F451F48-1F4D1F50-1F571F591F5B1F5D1F5F-1F7D1F80-1FB41FB6-1FC41FC6-1FD31FD6-1FDB1FDD-1FEF1FF2-1FF41FF6-1FFE2126\",\n        Gujarati: \"0A81-0A830A85-0A8D0A8F-0A910A93-0AA80AAA-0AB00AB20AB30AB5-0AB90ABC-0AC50AC7-0AC90ACB-0ACD0AD00AE0-0AE30AE6-0AF1\",\n        Gurmukhi: \"0A01-0A030A05-0A0A0A0F0A100A13-0A280A2A-0A300A320A330A350A360A380A390A3C0A3E-0A420A470A480A4B-0A4D0A510A59-0A5C0A5E0A66-0A75\",\n        Han: \"2E80-2E992E9B-2EF32F00-2FD5300530073021-30293038-303B3400-4DB54E00-9FCCF900-FA6DFA70-FAD9\",\n        Hangul: \"1100-11FF302E302F3131-318E3200-321E3260-327EA960-A97CAC00-D7A3D7B0-D7C6D7CB-D7FBFFA0-FFBEFFC2-FFC7FFCA-FFCFFFD2-FFD7FFDA-FFDC\",\n        Hanunoo: \"1720-1734\",\n        Hebrew: \"0591-05C705D0-05EA05F0-05F4FB1D-FB36FB38-FB3CFB3EFB40FB41FB43FB44FB46-FB4F\",\n        Hiragana: \"3041-3096309D-309F\",\n        Inherited: \"0300-036F04850486064B-0655065F0670095109521CD0-1CD21CD4-1CE01CE2-1CE81CED1CF41DC0-1DE61DFC-1DFF200C200D20D0-20F0302A-302D3099309AFE00-FE0FFE20-FE26\",\n        Javanese: \"A980-A9CDA9CF-A9D9A9DEA9DF\",\n        Kannada: \"0C820C830C85-0C8C0C8E-0C900C92-0CA80CAA-0CB30CB5-0CB90CBC-0CC40CC6-0CC80CCA-0CCD0CD50CD60CDE0CE0-0CE30CE6-0CEF0CF10CF2\",\n        Katakana: \"30A1-30FA30FD-30FF31F0-31FF32D0-32FE3300-3357FF66-FF6FFF71-FF9D\",\n        Kayah_Li: \"A900-A92F\",\n        Khmer: \"1780-17DD17E0-17E917F0-17F919E0-19FF\",\n        Lao: \"0E810E820E840E870E880E8A0E8D0E94-0E970E99-0E9F0EA1-0EA30EA50EA70EAA0EAB0EAD-0EB90EBB-0EBD0EC0-0EC40EC60EC8-0ECD0ED0-0ED90EDC-0EDF\",\n        Latin: \"0041-005A0061-007A00AA00BA00C0-00D600D8-00F600F8-02B802E0-02E41D00-1D251D2C-1D5C1D62-1D651D6B-1D771D79-1DBE1E00-1EFF2071207F2090-209C212A212B2132214E2160-21882C60-2C7FA722-A787A78B-A78EA790-A793A7A0-A7AAA7F8-A7FFFB00-FB06FF21-FF3AFF41-FF5A\",\n        Lepcha: \"1C00-1C371C3B-1C491C4D-1C4F\",\n        Limbu: \"1900-191C1920-192B1930-193B19401944-194F\",\n        Lisu: \"A4D0-A4FF\",\n        Malayalam: \"0D020D030D05-0D0C0D0E-0D100D12-0D3A0D3D-0D440D46-0D480D4A-0D4E0D570D60-0D630D66-0D750D79-0D7F\",\n        Mandaic: \"0840-085B085E\",\n        Meetei_Mayek: \"AAE0-AAF6ABC0-ABEDABF0-ABF9\",\n        Mongolian: \"1800180118041806-180E1810-18191820-18771880-18AA\",\n        Myanmar: \"1000-109FAA60-AA7B\",\n        New_Tai_Lue: \"1980-19AB19B0-19C919D0-19DA19DE19DF\",\n        Nko: \"07C0-07FA\",\n        Ogham: \"1680-169C\",\n        Ol_Chiki: \"1C50-1C7F\",\n        Oriya: \"0B01-0B030B05-0B0C0B0F0B100B13-0B280B2A-0B300B320B330B35-0B390B3C-0B440B470B480B4B-0B4D0B560B570B5C0B5D0B5F-0B630B66-0B77\",\n        Phags_Pa: \"A840-A877\",\n        Rejang: \"A930-A953A95F\",\n        Runic: \"16A0-16EA16EE-16F0\",\n        Samaritan: \"0800-082D0830-083E\",\n        Saurashtra: \"A880-A8C4A8CE-A8D9\",\n        Sinhala: \"0D820D830D85-0D960D9A-0DB10DB3-0DBB0DBD0DC0-0DC60DCA0DCF-0DD40DD60DD8-0DDF0DF2-0DF4\",\n        Sundanese: \"1B80-1BBF1CC0-1CC7\",\n        Syloti_Nagri: \"A800-A82B\",\n        Syriac: \"0700-070D070F-074A074D-074F\",\n        Tagalog: \"1700-170C170E-1714\",\n        Tagbanwa: \"1760-176C176E-177017721773\",\n        Tai_Le: \"1950-196D1970-1974\",\n        Tai_Tham: \"1A20-1A5E1A60-1A7C1A7F-1A891A90-1A991AA0-1AAD\",\n        Tai_Viet: \"AA80-AAC2AADB-AADF\",\n        Tamil: \"0B820B830B85-0B8A0B8E-0B900B92-0B950B990B9A0B9C0B9E0B9F0BA30BA40BA8-0BAA0BAE-0BB90BBE-0BC20BC6-0BC80BCA-0BCD0BD00BD70BE6-0BFA\",\n        Telugu: \"0C01-0C030C05-0C0C0C0E-0C100C12-0C280C2A-0C330C35-0C390C3D-0C440C46-0C480C4A-0C4D0C550C560C580C590C60-0C630C66-0C6F0C78-0C7F\",\n        Thaana: \"0780-07B1\",\n        Thai: \"0E01-0E3A0E40-0E5B\",\n        Tibetan: \"0F00-0F470F49-0F6C0F71-0F970F99-0FBC0FBE-0FCC0FCE-0FD40FD90FDA\",\n        Tifinagh: \"2D30-2D672D6F2D702D7F\",\n        Vai: \"A500-A62B\",\n        Yi: \"A000-A48CA490-A4C6\"\n    });\n\n}(XRegExp));\n\n\n/***** unicode-blocks.js *****/\n\n/*!\n * XRegExp Unicode Blocks v1.2.0\n * (c) 2010-2012 Steven Levithan <http://xregexp.com/>\n * MIT License\n * Uses Unicode 6.1 <http://unicode.org/>\n */\n\n/**\n * Adds support for all Unicode blocks in the Basic Multilingual Plane (U+0000-U+FFFF). Unicode\n * blocks use the prefix \"In\". E.g., `\\p{InBasicLatin}`. Token names are case insensitive, and any\n * spaces, hyphens, and underscores are ignored.\n * @requires XRegExp, XRegExp Unicode Base\n */\n(function (XRegExp) {\n    \"use strict\";\n\n    if (!XRegExp.addUnicodePackage) {\n        throw new ReferenceError(\"Unicode Base must be loaded before Unicode Blocks\");\n    }\n\n    XRegExp.install(\"extensibility\");\n\n    XRegExp.addUnicodePackage({\n        InBasic_Latin: \"0000-007F\",\n        InLatin_1_Supplement: \"0080-00FF\",\n        InLatin_Extended_A: \"0100-017F\",\n        InLatin_Extended_B: \"0180-024F\",\n        InIPA_Extensions: \"0250-02AF\",\n        InSpacing_Modifier_Letters: \"02B0-02FF\",\n        InCombining_Diacritical_Marks: \"0300-036F\",\n        InGreek_and_Coptic: \"0370-03FF\",\n        InCyrillic: \"0400-04FF\",\n        InCyrillic_Supplement: \"0500-052F\",\n        InArmenian: \"0530-058F\",\n        InHebrew: \"0590-05FF\",\n        InArabic: \"0600-06FF\",\n        InSyriac: \"0700-074F\",\n        InArabic_Supplement: \"0750-077F\",\n        InThaana: \"0780-07BF\",\n        InNKo: \"07C0-07FF\",\n        InSamaritan: \"0800-083F\",\n        InMandaic: \"0840-085F\",\n        InArabic_Extended_A: \"08A0-08FF\",\n        InDevanagari: \"0900-097F\",\n        InBengali: \"0980-09FF\",\n        InGurmukhi: \"0A00-0A7F\",\n        InGujarati: \"0A80-0AFF\",\n        InOriya: \"0B00-0B7F\",\n        InTamil: \"0B80-0BFF\",\n        InTelugu: \"0C00-0C7F\",\n        InKannada: \"0C80-0CFF\",\n        InMalayalam: \"0D00-0D7F\",\n        InSinhala: \"0D80-0DFF\",\n        InThai: \"0E00-0E7F\",\n        InLao: \"0E80-0EFF\",\n        InTibetan: \"0F00-0FFF\",\n        InMyanmar: \"1000-109F\",\n        InGeorgian: \"10A0-10FF\",\n        InHangul_Jamo: \"1100-11FF\",\n        InEthiopic: \"1200-137F\",\n        InEthiopic_Supplement: \"1380-139F\",\n        InCherokee: \"13A0-13FF\",\n        InUnified_Canadian_Aboriginal_Syllabics: \"1400-167F\",\n        InOgham: \"1680-169F\",\n        InRunic: \"16A0-16FF\",\n        InTagalog: \"1700-171F\",\n        InHanunoo: \"1720-173F\",\n        InBuhid: \"1740-175F\",\n        InTagbanwa: \"1760-177F\",\n        InKhmer: \"1780-17FF\",\n        InMongolian: \"1800-18AF\",\n        InUnified_Canadian_Aboriginal_Syllabics_Extended: \"18B0-18FF\",\n        InLimbu: \"1900-194F\",\n        InTai_Le: \"1950-197F\",\n        InNew_Tai_Lue: \"1980-19DF\",\n        InKhmer_Symbols: \"19E0-19FF\",\n        InBuginese: \"1A00-1A1F\",\n        InTai_Tham: \"1A20-1AAF\",\n        InBalinese: \"1B00-1B7F\",\n        InSundanese: \"1B80-1BBF\",\n        InBatak: \"1BC0-1BFF\",\n        InLepcha: \"1C00-1C4F\",\n        InOl_Chiki: \"1C50-1C7F\",\n        InSundanese_Supplement: \"1CC0-1CCF\",\n        InVedic_Extensions: \"1CD0-1CFF\",\n        InPhonetic_Extensions: \"1D00-1D7F\",\n        InPhonetic_Extensions_Supplement: \"1D80-1DBF\",\n        InCombining_Diacritical_Marks_Supplement: \"1DC0-1DFF\",\n        InLatin_Extended_Additional: \"1E00-1EFF\",\n        InGreek_Extended: \"1F00-1FFF\",\n        InGeneral_Punctuation: \"2000-206F\",\n        InSuperscripts_and_Subscripts: \"2070-209F\",\n        InCurrency_Symbols: \"20A0-20CF\",\n        InCombining_Diacritical_Marks_for_Symbols: \"20D0-20FF\",\n        InLetterlike_Symbols: \"2100-214F\",\n        InNumber_Forms: \"2150-218F\",\n        InArrows: \"2190-21FF\",\n        InMathematical_Operators: \"2200-22FF\",\n        InMiscellaneous_Technical: \"2300-23FF\",\n        InControl_Pictures: \"2400-243F\",\n        InOptical_Character_Recognition: \"2440-245F\",\n        InEnclosed_Alphanumerics: \"2460-24FF\",\n        InBox_Drawing: \"2500-257F\",\n        InBlock_Elements: \"2580-259F\",\n        InGeometric_Shapes: \"25A0-25FF\",\n        InMiscellaneous_Symbols: \"2600-26FF\",\n        InDingbats: \"2700-27BF\",\n        InMiscellaneous_Mathematical_Symbols_A: \"27C0-27EF\",\n        InSupplemental_Arrows_A: \"27F0-27FF\",\n        InBraille_Patterns: \"2800-28FF\",\n        InSupplemental_Arrows_B: \"2900-297F\",\n        InMiscellaneous_Mathematical_Symbols_B: \"2980-29FF\",\n        InSupplemental_Mathematical_Operators: \"2A00-2AFF\",\n        InMiscellaneous_Symbols_and_Arrows: \"2B00-2BFF\",\n        InGlagolitic: \"2C00-2C5F\",\n        InLatin_Extended_C: \"2C60-2C7F\",\n        InCoptic: \"2C80-2CFF\",\n        InGeorgian_Supplement: \"2D00-2D2F\",\n        InTifinagh: \"2D30-2D7F\",\n        InEthiopic_Extended: \"2D80-2DDF\",\n        InCyrillic_Extended_A: \"2DE0-2DFF\",\n        InSupplemental_Punctuation: \"2E00-2E7F\",\n        InCJK_Radicals_Supplement: \"2E80-2EFF\",\n        InKangxi_Radicals: \"2F00-2FDF\",\n        InIdeographic_Description_Characters: \"2FF0-2FFF\",\n        InCJK_Symbols_and_Punctuation: \"3000-303F\",\n        InHiragana: \"3040-309F\",\n        InKatakana: \"30A0-30FF\",\n        InBopomofo: \"3100-312F\",\n        InHangul_Compatibility_Jamo: \"3130-318F\",\n        InKanbun: \"3190-319F\",\n        InBopomofo_Extended: \"31A0-31BF\",\n        InCJK_Strokes: \"31C0-31EF\",\n        InKatakana_Phonetic_Extensions: \"31F0-31FF\",\n        InEnclosed_CJK_Letters_and_Months: \"3200-32FF\",\n        InCJK_Compatibility: \"3300-33FF\",\n        InCJK_Unified_Ideographs_Extension_A: \"3400-4DBF\",\n        InYijing_Hexagram_Symbols: \"4DC0-4DFF\",\n        InCJK_Unified_Ideographs: \"4E00-9FFF\",\n        InYi_Syllables: \"A000-A48F\",\n        InYi_Radicals: \"A490-A4CF\",\n        InLisu: \"A4D0-A4FF\",\n        InVai: \"A500-A63F\",\n        InCyrillic_Extended_B: \"A640-A69F\",\n        InBamum: \"A6A0-A6FF\",\n        InModifier_Tone_Letters: \"A700-A71F\",\n        InLatin_Extended_D: \"A720-A7FF\",\n        InSyloti_Nagri: \"A800-A82F\",\n        InCommon_Indic_Number_Forms: \"A830-A83F\",\n        InPhags_pa: \"A840-A87F\",\n        InSaurashtra: \"A880-A8DF\",\n        InDevanagari_Extended: \"A8E0-A8FF\",\n        InKayah_Li: \"A900-A92F\",\n        InRejang: \"A930-A95F\",\n        InHangul_Jamo_Extended_A: \"A960-A97F\",\n        InJavanese: \"A980-A9DF\",\n        InCham: \"AA00-AA5F\",\n        InMyanmar_Extended_A: \"AA60-AA7F\",\n        InTai_Viet: \"AA80-AADF\",\n        InMeetei_Mayek_Extensions: \"AAE0-AAFF\",\n        InEthiopic_Extended_A: \"AB00-AB2F\",\n        InMeetei_Mayek: \"ABC0-ABFF\",\n        InHangul_Syllables: \"AC00-D7AF\",\n        InHangul_Jamo_Extended_B: \"D7B0-D7FF\",\n        InHigh_Surrogates: \"D800-DB7F\",\n        InHigh_Private_Use_Surrogates: \"DB80-DBFF\",\n        InLow_Surrogates: \"DC00-DFFF\",\n        InPrivate_Use_Area: \"E000-F8FF\",\n        InCJK_Compatibility_Ideographs: \"F900-FAFF\",\n        InAlphabetic_Presentation_Forms: \"FB00-FB4F\",\n        InArabic_Presentation_Forms_A: \"FB50-FDFF\",\n        InVariation_Selectors: \"FE00-FE0F\",\n        InVertical_Forms: \"FE10-FE1F\",\n        InCombining_Half_Marks: \"FE20-FE2F\",\n        InCJK_Compatibility_Forms: \"FE30-FE4F\",\n        InSmall_Form_Variants: \"FE50-FE6F\",\n        InArabic_Presentation_Forms_B: \"FE70-FEFF\",\n        InHalfwidth_and_Fullwidth_Forms: \"FF00-FFEF\",\n        InSpecials: \"FFF0-FFFF\"\n    });\n\n}(XRegExp));\n\n\n/***** unicode-properties.js *****/\n\n/*!\n * XRegExp Unicode Properties v1.0.0\n * (c) 2012 Steven Levithan <http://xregexp.com/>\n * MIT License\n * Uses Unicode 6.1 <http://unicode.org/>\n */\n\n/**\n * Adds Unicode properties necessary to meet Level 1 Unicode support (detailed in UTS#18 RL1.2).\n * Includes code points from the Basic Multilingual Plane (U+0000-U+FFFF) only. Token names are\n * case insensitive, and any spaces, hyphens, and underscores are ignored.\n * @requires XRegExp, XRegExp Unicode Base\n */\n(function (XRegExp) {\n    \"use strict\";\n\n    if (!XRegExp.addUnicodePackage) {\n        throw new ReferenceError(\"Unicode Base must be loaded before Unicode Properties\");\n    }\n\n    XRegExp.install(\"extensibility\");\n\n    XRegExp.addUnicodePackage({\n        Alphabetic: \"0041-005A0061-007A00AA00B500BA00C0-00D600D8-00F600F8-02C102C6-02D102E0-02E402EC02EE03450370-037403760377037A-037D03860388-038A038C038E-03A103A3-03F503F7-0481048A-05270531-055605590561-058705B0-05BD05BF05C105C205C405C505C705D0-05EA05F0-05F20610-061A0620-06570659-065F066E-06D306D5-06DC06E1-06E806ED-06EF06FA-06FC06FF0710-073F074D-07B107CA-07EA07F407F507FA0800-0817081A-082C0840-085808A008A2-08AC08E4-08E908F0-08FE0900-093B093D-094C094E-09500955-09630971-09770979-097F0981-09830985-098C098F09900993-09A809AA-09B009B209B6-09B909BD-09C409C709C809CB09CC09CE09D709DC09DD09DF-09E309F009F10A01-0A030A05-0A0A0A0F0A100A13-0A280A2A-0A300A320A330A350A360A380A390A3E-0A420A470A480A4B0A4C0A510A59-0A5C0A5E0A70-0A750A81-0A830A85-0A8D0A8F-0A910A93-0AA80AAA-0AB00AB20AB30AB5-0AB90ABD-0AC50AC7-0AC90ACB0ACC0AD00AE0-0AE30B01-0B030B05-0B0C0B0F0B100B13-0B280B2A-0B300B320B330B35-0B390B3D-0B440B470B480B4B0B4C0B560B570B5C0B5D0B5F-0B630B710B820B830B85-0B8A0B8E-0B900B92-0B950B990B9A0B9C0B9E0B9F0BA30BA40BA8-0BAA0BAE-0BB90BBE-0BC20BC6-0BC80BCA-0BCC0BD00BD70C01-0C030C05-0C0C0C0E-0C100C12-0C280C2A-0C330C35-0C390C3D-0C440C46-0C480C4A-0C4C0C550C560C580C590C60-0C630C820C830C85-0C8C0C8E-0C900C92-0CA80CAA-0CB30CB5-0CB90CBD-0CC40CC6-0CC80CCA-0CCC0CD50CD60CDE0CE0-0CE30CF10CF20D020D030D05-0D0C0D0E-0D100D12-0D3A0D3D-0D440D46-0D480D4A-0D4C0D4E0D570D60-0D630D7A-0D7F0D820D830D85-0D960D9A-0DB10DB3-0DBB0DBD0DC0-0DC60DCF-0DD40DD60DD8-0DDF0DF20DF30E01-0E3A0E40-0E460E4D0E810E820E840E870E880E8A0E8D0E94-0E970E99-0E9F0EA1-0EA30EA50EA70EAA0EAB0EAD-0EB90EBB-0EBD0EC0-0EC40EC60ECD0EDC-0EDF0F000F40-0F470F49-0F6C0F71-0F810F88-0F970F99-0FBC1000-10361038103B-103F1050-10621065-1068106E-1086108E109C109D10A0-10C510C710CD10D0-10FA10FC-1248124A-124D1250-12561258125A-125D1260-1288128A-128D1290-12B012B2-12B512B8-12BE12C012C2-12C512C8-12D612D8-13101312-13151318-135A135F1380-138F13A0-13F41401-166C166F-167F1681-169A16A0-16EA16EE-16F01700-170C170E-17131720-17331740-17531760-176C176E-1770177217731780-17B317B6-17C817D717DC1820-18771880-18AA18B0-18F51900-191C1920-192B1930-19381950-196D1970-19741980-19AB19B0-19C91A00-1A1B1A20-1A5E1A61-1A741AA71B00-1B331B35-1B431B45-1B4B1B80-1BA91BAC-1BAF1BBA-1BE51BE7-1BF11C00-1C351C4D-1C4F1C5A-1C7D1CE9-1CEC1CEE-1CF31CF51CF61D00-1DBF1E00-1F151F18-1F1D1F20-1F451F48-1F4D1F50-1F571F591F5B1F5D1F5F-1F7D1F80-1FB41FB6-1FBC1FBE1FC2-1FC41FC6-1FCC1FD0-1FD31FD6-1FDB1FE0-1FEC1FF2-1FF41FF6-1FFC2071207F2090-209C21022107210A-211321152119-211D212421262128212A-212D212F-2139213C-213F2145-2149214E2160-218824B6-24E92C00-2C2E2C30-2C5E2C60-2CE42CEB-2CEE2CF22CF32D00-2D252D272D2D2D30-2D672D6F2D80-2D962DA0-2DA62DA8-2DAE2DB0-2DB62DB8-2DBE2DC0-2DC62DC8-2DCE2DD0-2DD62DD8-2DDE2DE0-2DFF2E2F3005-30073021-30293031-30353038-303C3041-3096309D-309F30A1-30FA30FC-30FF3105-312D3131-318E31A0-31BA31F0-31FF3400-4DB54E00-9FCCA000-A48CA4D0-A4FDA500-A60CA610-A61FA62AA62BA640-A66EA674-A67BA67F-A697A69F-A6EFA717-A71FA722-A788A78B-A78EA790-A793A7A0-A7AAA7F8-A801A803-A805A807-A80AA80C-A827A840-A873A880-A8C3A8F2-A8F7A8FBA90A-A92AA930-A952A960-A97CA980-A9B2A9B4-A9BFA9CFAA00-AA36AA40-AA4DAA60-AA76AA7AAA80-AABEAAC0AAC2AADB-AADDAAE0-AAEFAAF2-AAF5AB01-AB06AB09-AB0EAB11-AB16AB20-AB26AB28-AB2EABC0-ABEAAC00-D7A3D7B0-D7C6D7CB-D7FBF900-FA6DFA70-FAD9FB00-FB06FB13-FB17FB1D-FB28FB2A-FB36FB38-FB3CFB3EFB40FB41FB43FB44FB46-FBB1FBD3-FD3DFD50-FD8FFD92-FDC7FDF0-FDFBFE70-FE74FE76-FEFCFF21-FF3AFF41-FF5AFF66-FFBEFFC2-FFC7FFCA-FFCFFFD2-FFD7FFDA-FFDC\",\n        Uppercase: \"0041-005A00C0-00D600D8-00DE01000102010401060108010A010C010E01100112011401160118011A011C011E01200122012401260128012A012C012E01300132013401360139013B013D013F0141014301450147014A014C014E01500152015401560158015A015C015E01600162016401660168016A016C016E017001720174017601780179017B017D018101820184018601870189-018B018E-0191019301940196-0198019C019D019F01A001A201A401A601A701A901AC01AE01AF01B1-01B301B501B701B801BC01C401C701CA01CD01CF01D101D301D501D701D901DB01DE01E001E201E401E601E801EA01EC01EE01F101F401F6-01F801FA01FC01FE02000202020402060208020A020C020E02100212021402160218021A021C021E02200222022402260228022A022C022E02300232023A023B023D023E02410243-02460248024A024C024E03700372037603860388-038A038C038E038F0391-03A103A3-03AB03CF03D2-03D403D803DA03DC03DE03E003E203E403E603E803EA03EC03EE03F403F703F903FA03FD-042F04600462046404660468046A046C046E04700472047404760478047A047C047E0480048A048C048E04900492049404960498049A049C049E04A004A204A404A604A804AA04AC04AE04B004B204B404B604B804BA04BC04BE04C004C104C304C504C704C904CB04CD04D004D204D404D604D804DA04DC04DE04E004E204E404E604E804EA04EC04EE04F004F204F404F604F804FA04FC04FE05000502050405060508050A050C050E05100512051405160518051A051C051E05200522052405260531-055610A0-10C510C710CD1E001E021E041E061E081E0A1E0C1E0E1E101E121E141E161E181E1A1E1C1E1E1E201E221E241E261E281E2A1E2C1E2E1E301E321E341E361E381E3A1E3C1E3E1E401E421E441E461E481E4A1E4C1E4E1E501E521E541E561E581E5A1E5C1E5E1E601E621E641E661E681E6A1E6C1E6E1E701E721E741E761E781E7A1E7C1E7E1E801E821E841E861E881E8A1E8C1E8E1E901E921E941E9E1EA01EA21EA41EA61EA81EAA1EAC1EAE1EB01EB21EB41EB61EB81EBA1EBC1EBE1EC01EC21EC41EC61EC81ECA1ECC1ECE1ED01ED21ED41ED61ED81EDA1EDC1EDE1EE01EE21EE41EE61EE81EEA1EEC1EEE1EF01EF21EF41EF61EF81EFA1EFC1EFE1F08-1F0F1F18-1F1D1F28-1F2F1F38-1F3F1F48-1F4D1F591F5B1F5D1F5F1F68-1F6F1FB8-1FBB1FC8-1FCB1FD8-1FDB1FE8-1FEC1FF8-1FFB21022107210B-210D2110-211221152119-211D212421262128212A-212D2130-2133213E213F21452160-216F218324B6-24CF2C00-2C2E2C602C62-2C642C672C692C6B2C6D-2C702C722C752C7E-2C802C822C842C862C882C8A2C8C2C8E2C902C922C942C962C982C9A2C9C2C9E2CA02CA22CA42CA62CA82CAA2CAC2CAE2CB02CB22CB42CB62CB82CBA2CBC2CBE2CC02CC22CC42CC62CC82CCA2CCC2CCE2CD02CD22CD42CD62CD82CDA2CDC2CDE2CE02CE22CEB2CED2CF2A640A642A644A646A648A64AA64CA64EA650A652A654A656A658A65AA65CA65EA660A662A664A666A668A66AA66CA680A682A684A686A688A68AA68CA68EA690A692A694A696A722A724A726A728A72AA72CA72EA732A734A736A738A73AA73CA73EA740A742A744A746A748A74AA74CA74EA750A752A754A756A758A75AA75CA75EA760A762A764A766A768A76AA76CA76EA779A77BA77DA77EA780A782A784A786A78BA78DA790A792A7A0A7A2A7A4A7A6A7A8A7AAFF21-FF3A\",\n        Lowercase: \"0061-007A00AA00B500BA00DF-00F600F8-00FF01010103010501070109010B010D010F01110113011501170119011B011D011F01210123012501270129012B012D012F01310133013501370138013A013C013E014001420144014601480149014B014D014F01510153015501570159015B015D015F01610163016501670169016B016D016F0171017301750177017A017C017E-0180018301850188018C018D019201950199-019B019E01A101A301A501A801AA01AB01AD01B001B401B601B901BA01BD-01BF01C601C901CC01CE01D001D201D401D601D801DA01DC01DD01DF01E101E301E501E701E901EB01ED01EF01F001F301F501F901FB01FD01FF02010203020502070209020B020D020F02110213021502170219021B021D021F02210223022502270229022B022D022F02310233-0239023C023F0240024202470249024B024D024F-02930295-02B802C002C102E0-02E40345037103730377037A-037D039003AC-03CE03D003D103D5-03D703D903DB03DD03DF03E103E303E503E703E903EB03ED03EF-03F303F503F803FB03FC0430-045F04610463046504670469046B046D046F04710473047504770479047B047D047F0481048B048D048F04910493049504970499049B049D049F04A104A304A504A704A904AB04AD04AF04B104B304B504B704B904BB04BD04BF04C204C404C604C804CA04CC04CE04CF04D104D304D504D704D904DB04DD04DF04E104E304E504E704E904EB04ED04EF04F104F304F504F704F904FB04FD04FF05010503050505070509050B050D050F05110513051505170519051B051D051F05210523052505270561-05871D00-1DBF1E011E031E051E071E091E0B1E0D1E0F1E111E131E151E171E191E1B1E1D1E1F1E211E231E251E271E291E2B1E2D1E2F1E311E331E351E371E391E3B1E3D1E3F1E411E431E451E471E491E4B1E4D1E4F1E511E531E551E571E591E5B1E5D1E5F1E611E631E651E671E691E6B1E6D1E6F1E711E731E751E771E791E7B1E7D1E7F1E811E831E851E871E891E8B1E8D1E8F1E911E931E95-1E9D1E9F1EA11EA31EA51EA71EA91EAB1EAD1EAF1EB11EB31EB51EB71EB91EBB1EBD1EBF1EC11EC31EC51EC71EC91ECB1ECD1ECF1ED11ED31ED51ED71ED91EDB1EDD1EDF1EE11EE31EE51EE71EE91EEB1EED1EEF1EF11EF31EF51EF71EF91EFB1EFD1EFF-1F071F10-1F151F20-1F271F30-1F371F40-1F451F50-1F571F60-1F671F70-1F7D1F80-1F871F90-1F971FA0-1FA71FB0-1FB41FB61FB71FBE1FC2-1FC41FC61FC71FD0-1FD31FD61FD71FE0-1FE71FF2-1FF41FF61FF72071207F2090-209C210A210E210F2113212F21342139213C213D2146-2149214E2170-217F218424D0-24E92C30-2C5E2C612C652C662C682C6A2C6C2C712C732C742C76-2C7D2C812C832C852C872C892C8B2C8D2C8F2C912C932C952C972C992C9B2C9D2C9F2CA12CA32CA52CA72CA92CAB2CAD2CAF2CB12CB32CB52CB72CB92CBB2CBD2CBF2CC12CC32CC52CC72CC92CCB2CCD2CCF2CD12CD32CD52CD72CD92CDB2CDD2CDF2CE12CE32CE42CEC2CEE2CF32D00-2D252D272D2DA641A643A645A647A649A64BA64DA64FA651A653A655A657A659A65BA65DA65FA661A663A665A667A669A66BA66DA681A683A685A687A689A68BA68DA68FA691A693A695A697A723A725A727A729A72BA72DA72F-A731A733A735A737A739A73BA73DA73FA741A743A745A747A749A74BA74DA74FA751A753A755A757A759A75BA75DA75FA761A763A765A767A769A76BA76DA76F-A778A77AA77CA77FA781A783A785A787A78CA78EA791A793A7A1A7A3A7A5A7A7A7A9A7F8-A7FAFB00-FB06FB13-FB17FF41-FF5A\",\n        White_Space: \"0009-000D0020008500A01680180E2000-200A20282029202F205F3000\",\n        Noncharacter_Code_Point: \"FDD0-FDEFFFFEFFFF\",\n        Default_Ignorable_Code_Point: \"00AD034F115F116017B417B5180B-180D200B-200F202A-202E2060-206F3164FE00-FE0FFEFFFFA0FFF0-FFF8\",\n        // \\p{Any} matches a code unit. To match any code point via surrogate pairs, use (?:[\\0-\\uD7FF\\uDC00-\\uFFFF]|[\\uD800-\\uDBFF][\\uDC00-\\uDFFF]|[\\uD800-\\uDBFF])\n        Any: \"0000-FFFF\", // \\p{^Any} compiles to [^\\u0000-\\uFFFF]; [\\p{^Any}] to []\n        Ascii: \"0000-007F\",\n        // \\p{Assigned} is equivalent to \\p{^Cn}\n        //Assigned: XRegExp(\"[\\\\p{^Cn}]\").source.replace(/[[\\]]|\\\\u/g, \"\") // Negation inside a character class triggers inversion\n        Assigned: \"0000-0377037A-037E0384-038A038C038E-03A103A3-05270531-05560559-055F0561-05870589058A058F0591-05C705D0-05EA05F0-05F40600-06040606-061B061E-070D070F-074A074D-07B107C0-07FA0800-082D0830-083E0840-085B085E08A008A2-08AC08E4-08FE0900-09770979-097F0981-09830985-098C098F09900993-09A809AA-09B009B209B6-09B909BC-09C409C709C809CB-09CE09D709DC09DD09DF-09E309E6-09FB0A01-0A030A05-0A0A0A0F0A100A13-0A280A2A-0A300A320A330A350A360A380A390A3C0A3E-0A420A470A480A4B-0A4D0A510A59-0A5C0A5E0A66-0A750A81-0A830A85-0A8D0A8F-0A910A93-0AA80AAA-0AB00AB20AB30AB5-0AB90ABC-0AC50AC7-0AC90ACB-0ACD0AD00AE0-0AE30AE6-0AF10B01-0B030B05-0B0C0B0F0B100B13-0B280B2A-0B300B320B330B35-0B390B3C-0B440B470B480B4B-0B4D0B560B570B5C0B5D0B5F-0B630B66-0B770B820B830B85-0B8A0B8E-0B900B92-0B950B990B9A0B9C0B9E0B9F0BA30BA40BA8-0BAA0BAE-0BB90BBE-0BC20BC6-0BC80BCA-0BCD0BD00BD70BE6-0BFA0C01-0C030C05-0C0C0C0E-0C100C12-0C280C2A-0C330C35-0C390C3D-0C440C46-0C480C4A-0C4D0C550C560C580C590C60-0C630C66-0C6F0C78-0C7F0C820C830C85-0C8C0C8E-0C900C92-0CA80CAA-0CB30CB5-0CB90CBC-0CC40CC6-0CC80CCA-0CCD0CD50CD60CDE0CE0-0CE30CE6-0CEF0CF10CF20D020D030D05-0D0C0D0E-0D100D12-0D3A0D3D-0D440D46-0D480D4A-0D4E0D570D60-0D630D66-0D750D79-0D7F0D820D830D85-0D960D9A-0DB10DB3-0DBB0DBD0DC0-0DC60DCA0DCF-0DD40DD60DD8-0DDF0DF2-0DF40E01-0E3A0E3F-0E5B0E810E820E840E870E880E8A0E8D0E94-0E970E99-0E9F0EA1-0EA30EA50EA70EAA0EAB0EAD-0EB90EBB-0EBD0EC0-0EC40EC60EC8-0ECD0ED0-0ED90EDC-0EDF0F00-0F470F49-0F6C0F71-0F970F99-0FBC0FBE-0FCC0FCE-0FDA1000-10C510C710CD10D0-1248124A-124D1250-12561258125A-125D1260-1288128A-128D1290-12B012B2-12B512B8-12BE12C012C2-12C512C8-12D612D8-13101312-13151318-135A135D-137C1380-139913A0-13F41400-169C16A0-16F01700-170C170E-17141720-17361740-17531760-176C176E-1770177217731780-17DD17E0-17E917F0-17F91800-180E1810-18191820-18771880-18AA18B0-18F51900-191C1920-192B1930-193B19401944-196D1970-19741980-19AB19B0-19C919D0-19DA19DE-1A1B1A1E-1A5E1A60-1A7C1A7F-1A891A90-1A991AA0-1AAD1B00-1B4B1B50-1B7C1B80-1BF31BFC-1C371C3B-1C491C4D-1C7F1CC0-1CC71CD0-1CF61D00-1DE61DFC-1F151F18-1F1D1F20-1F451F48-1F4D1F50-1F571F591F5B1F5D1F5F-1F7D1F80-1FB41FB6-1FC41FC6-1FD31FD6-1FDB1FDD-1FEF1FF2-1FF41FF6-1FFE2000-2064206A-20712074-208E2090-209C20A0-20B920D0-20F02100-21892190-23F32400-24262440-244A2460-26FF2701-2B4C2B50-2B592C00-2C2E2C30-2C5E2C60-2CF32CF9-2D252D272D2D2D30-2D672D6F2D702D7F-2D962DA0-2DA62DA8-2DAE2DB0-2DB62DB8-2DBE2DC0-2DC62DC8-2DCE2DD0-2DD62DD8-2DDE2DE0-2E3B2E80-2E992E9B-2EF32F00-2FD52FF0-2FFB3000-303F3041-30963099-30FF3105-312D3131-318E3190-31BA31C0-31E331F0-321E3220-32FE3300-4DB54DC0-9FCCA000-A48CA490-A4C6A4D0-A62BA640-A697A69F-A6F7A700-A78EA790-A793A7A0-A7AAA7F8-A82BA830-A839A840-A877A880-A8C4A8CE-A8D9A8E0-A8FBA900-A953A95F-A97CA980-A9CDA9CF-A9D9A9DEA9DFAA00-AA36AA40-AA4DAA50-AA59AA5C-AA7BAA80-AAC2AADB-AAF6AB01-AB06AB09-AB0EAB11-AB16AB20-AB26AB28-AB2EABC0-ABEDABF0-ABF9AC00-D7A3D7B0-D7C6D7CB-D7FBD800-FA6DFA70-FAD9FB00-FB06FB13-FB17FB1D-FB36FB38-FB3CFB3EFB40FB41FB43FB44FB46-FBC1FBD3-FD3FFD50-FD8FFD92-FDC7FDF0-FDFDFE00-FE19FE20-FE26FE30-FE52FE54-FE66FE68-FE6BFE70-FE74FE76-FEFCFEFFFF01-FFBEFFC2-FFC7FFCA-FFCFFFD2-FFD7FFDA-FFDCFFE0-FFE6FFE8-FFEEFFF9-FFFD\"\n    });\n\n}(XRegExp));\n\n\n/***** matchrecursive.js *****/\n\n/*!\n * XRegExp.matchRecursive v0.2.0\n * (c) 2009-2012 Steven Levithan <http://xregexp.com/>\n * MIT License\n */\n\n(function (XRegExp) {\n    \"use strict\";\n\n/**\n * Returns a match detail object composed of the provided values.\n * @private\n */\n    function row(value, name, start, end) {\n        return {value:value, name:name, start:start, end:end};\n    }\n\n/**\n * Returns an array of match strings between outermost left and right delimiters, or an array of\n * objects with detailed match parts and position data. An error is thrown if delimiters are\n * unbalanced within the data.\n * @memberOf XRegExp\n * @param {String} str String to search.\n * @param {String} left Left delimiter as an XRegExp pattern.\n * @param {String} right Right delimiter as an XRegExp pattern.\n * @param {String} [flags] Flags for the left and right delimiters. Use any of: `gimnsxy`.\n * @param {Object} [options] Lets you specify `valueNames` and `escapeChar` options.\n * @returns {Array} Array of matches, or an empty array.\n * @example\n *\n * // Basic usage\n * var str = '(t((e))s)t()(ing)';\n * XRegExp.matchRecursive(str, '\\\\(', '\\\\)', 'g');\n * // -> ['t((e))s', '', 'ing']\n *\n * // Extended information mode with valueNames\n * str = 'Here is <div> <div>an</div></div> example';\n * XRegExp.matchRecursive(str, '<div\\\\s*>', '</div>', 'gi', {\n *   valueNames: ['between', 'left', 'match', 'right']\n * });\n * // -> [\n * // {name: 'between', value: 'Here is ',       start: 0,  end: 8},\n * // {name: 'left',    value: '<div>',          start: 8,  end: 13},\n * // {name: 'match',   value: ' <div>an</div>', start: 13, end: 27},\n * // {name: 'right',   value: '</div>',         start: 27, end: 33},\n * // {name: 'between', value: ' example',       start: 33, end: 41}\n * // ]\n *\n * // Omitting unneeded parts with null valueNames, and using escapeChar\n * str = '...{1}\\\\{{function(x,y){return y+x;}}';\n * XRegExp.matchRecursive(str, '{', '}', 'g', {\n *   valueNames: ['literal', null, 'value', null],\n *   escapeChar: '\\\\'\n * });\n * // -> [\n * // {name: 'literal', value: '...', start: 0, end: 3},\n * // {name: 'value',   value: '1',   start: 4, end: 5},\n * // {name: 'literal', value: '\\\\{', start: 6, end: 8},\n * // {name: 'value',   value: 'function(x,y){return y+x;}', start: 9, end: 35}\n * // ]\n *\n * // Sticky mode via flag y\n * str = '<1><<<2>>><3>4<5>';\n * XRegExp.matchRecursive(str, '<', '>', 'gy');\n * // -> ['1', '<<2>>', '3']\n */\n    XRegExp.matchRecursive = function (str, left, right, flags, options) {\n        flags = flags || \"\";\n        options = options || {};\n        var global = flags.indexOf(\"g\") > -1,\n            sticky = flags.indexOf(\"y\") > -1,\n            basicFlags = flags.replace(/y/g, \"\"), // Flag y controlled internally\n            escapeChar = options.escapeChar,\n            vN = options.valueNames,\n            output = [],\n            openTokens = 0,\n            delimStart = 0,\n            delimEnd = 0,\n            lastOuterEnd = 0,\n            outerStart,\n            innerStart,\n            leftMatch,\n            rightMatch,\n            esc;\n        left = XRegExp(left, basicFlags);\n        right = XRegExp(right, basicFlags);\n\n        if (escapeChar) {\n            if (escapeChar.length > 1) {\n                throw new SyntaxError(\"can't use more than one escape character\");\n            }\n            escapeChar = XRegExp.escape(escapeChar);\n            // Using XRegExp.union safely rewrites backreferences in `left` and `right`\n            esc = new RegExp(\n                \"(?:\" + escapeChar + \"[\\\\S\\\\s]|(?:(?!\" + XRegExp.union([left, right]).source + \")[^\" + escapeChar + \"])+)+\",\n                flags.replace(/[^im]+/g, \"\") // Flags gy not needed here; flags nsx handled by XRegExp\n            );\n        }\n\n        while (true) {\n            // If using an escape character, advance to the delimiter's next starting position,\n            // skipping any escaped characters in between\n            if (escapeChar) {\n                delimEnd += (XRegExp.exec(str, esc, delimEnd, \"sticky\") || [\"\"])[0].length;\n            }\n            leftMatch = XRegExp.exec(str, left, delimEnd);\n            rightMatch = XRegExp.exec(str, right, delimEnd);\n            // Keep the leftmost match only\n            if (leftMatch && rightMatch) {\n                if (leftMatch.index <= rightMatch.index) {\n                    rightMatch = null;\n                } else {\n                    leftMatch = null;\n                }\n            }\n            /* Paths (LM:leftMatch, RM:rightMatch, OT:openTokens):\n            LM | RM | OT | Result\n            1  | 0  | 1  | loop\n            1  | 0  | 0  | loop\n            0  | 1  | 1  | loop\n            0  | 1  | 0  | throw\n            0  | 0  | 1  | throw\n            0  | 0  | 0  | break\n            * Doesn't include the sticky mode special case\n            * Loop ends after the first completed match if `!global` */\n            if (leftMatch || rightMatch) {\n                delimStart = (leftMatch || rightMatch).index;\n                delimEnd = delimStart + (leftMatch || rightMatch)[0].length;\n            } else if (!openTokens) {\n                break;\n            }\n            if (sticky && !openTokens && delimStart > lastOuterEnd) {\n                break;\n            }\n            if (leftMatch) {\n                if (!openTokens) {\n                    outerStart = delimStart;\n                    innerStart = delimEnd;\n                }\n                ++openTokens;\n            } else if (rightMatch && openTokens) {\n                if (!--openTokens) {\n                    if (vN) {\n                        if (vN[0] && outerStart > lastOuterEnd) {\n                            output.push(row(vN[0], str.slice(lastOuterEnd, outerStart), lastOuterEnd, outerStart));\n                        }\n                        if (vN[1]) {\n                            output.push(row(vN[1], str.slice(outerStart, innerStart), outerStart, innerStart));\n                        }\n                        if (vN[2]) {\n                            output.push(row(vN[2], str.slice(innerStart, delimStart), innerStart, delimStart));\n                        }\n                        if (vN[3]) {\n                            output.push(row(vN[3], str.slice(delimStart, delimEnd), delimStart, delimEnd));\n                        }\n                    } else {\n                        output.push(str.slice(innerStart, delimStart));\n                    }\n                    lastOuterEnd = delimEnd;\n                    if (!global) {\n                        break;\n                    }\n                }\n            } else {\n                throw new Error(\"string contains unbalanced delimiters\");\n            }\n            // If the delimiter matched an empty string, avoid an infinite loop\n            if (delimStart === delimEnd) {\n                ++delimEnd;\n            }\n        }\n\n        if (global && !sticky && vN && vN[0] && str.length > lastOuterEnd) {\n            output.push(row(vN[0], str.slice(lastOuterEnd), lastOuterEnd, str.length));\n        }\n\n        return output;\n    };\n\n}(XRegExp));\n\n\n/***** build.js *****/\n\n/*!\n * XRegExp.build v0.1.0\n * (c) 2012 Steven Levithan <http://xregexp.com/>\n * MIT License\n * Inspired by RegExp.create by Lea Verou <http://lea.verou.me/>\n */\n\n(function (XRegExp) {\n    \"use strict\";\n\n    var subparts = /(\\()(?!\\?)|\\\\([1-9]\\d*)|\\\\[\\s\\S]|\\[(?:[^\\\\\\]]|\\\\[\\s\\S])*]/g,\n        parts = XRegExp.union([/\\({{([\\w$]+)}}\\)|{{([\\w$]+)}}/, subparts], \"g\");\n\n/**\n * Strips a leading `^` and trailing unescaped `$`, if both are present.\n * @private\n * @param {String} pattern Pattern to process.\n * @returns {String} Pattern with edge anchors removed.\n */\n    function deanchor(pattern) {\n        var startAnchor = /^(?:\\(\\?:\\))?\\^/, // Leading `^` or `(?:)^` (handles /x cruft)\n            endAnchor = /\\$(?:\\(\\?:\\))?$/; // Trailing `$` or `$(?:)` (handles /x cruft)\n        if (endAnchor.test(pattern.replace(/\\\\[\\s\\S]/g, \"\"))) { // Ensure trailing `$` isn't escaped\n            return pattern.replace(startAnchor, \"\").replace(endAnchor, \"\");\n        }\n        return pattern;\n    }\n\n/**\n * Converts the provided value to an XRegExp.\n * @private\n * @param {String|RegExp} value Value to convert.\n * @returns {RegExp} XRegExp object with XRegExp syntax applied.\n */\n    function asXRegExp(value) {\n        return XRegExp.isRegExp(value) ?\n                (value.xregexp && !value.xregexp.isNative ? value : XRegExp(value.source)) :\n                XRegExp(value);\n    }\n\n/**\n * Builds regexes using named subpatterns, for readability and pattern reuse. Backreferences in the\n * outer pattern and provided subpatterns are automatically renumbered to work correctly. Native\n * flags used by provided subpatterns are ignored in favor of the `flags` argument.\n * @memberOf XRegExp\n * @param {String} pattern XRegExp pattern using `{{name}}` for embedded subpatterns. Allows\n *   `({{name}})` as shorthand for `(?<name>{{name}})`. Patterns cannot be embedded within\n *   character classes.\n * @param {Object} subs Lookup object for named subpatterns. Values can be strings or regexes. A\n *   leading `^` and trailing unescaped `$` are stripped from subpatterns, if both are present.\n * @param {String} [flags] Any combination of XRegExp flags.\n * @returns {RegExp} Regex with interpolated subpatterns.\n * @example\n *\n * var time = XRegExp.build('(?x)^ {{hours}} ({{minutes}}) $', {\n *   hours: XRegExp.build('{{h12}} : | {{h24}}', {\n *     h12: /1[0-2]|0?[1-9]/,\n *     h24: /2[0-3]|[01][0-9]/\n *   }, 'x'),\n *   minutes: /^[0-5][0-9]$/\n * });\n * time.test('10:59'); // -> true\n * XRegExp.exec('10:59', time).minutes; // -> '59'\n */\n    XRegExp.build = function (pattern, subs, flags) {\n        var inlineFlags = /^\\(\\?([\\w$]+)\\)/.exec(pattern),\n            data = {},\n            numCaps = 0, // Caps is short for captures\n            numPriorCaps,\n            numOuterCaps = 0,\n            outerCapsMap = [0],\n            outerCapNames,\n            sub,\n            p;\n\n        // Add flags within a leading mode modifier to the overall pattern's flags\n        if (inlineFlags) {\n            flags = flags || \"\";\n            inlineFlags[1].replace(/./g, function (flag) {\n                flags += (flags.indexOf(flag) > -1 ? \"\" : flag); // Don't add duplicates\n            });\n        }\n\n        for (p in subs) {\n            if (subs.hasOwnProperty(p)) {\n                // Passing to XRegExp enables entended syntax for subpatterns provided as strings\n                // and ensures independent validity, lest an unescaped `(`, `)`, `[`, or trailing\n                // `\\` breaks the `(?:)` wrapper. For subpatterns provided as regexes, it dies on\n                // octals and adds the `xregexp` property, for simplicity\n                sub = asXRegExp(subs[p]);\n                // Deanchoring allows embedding independently useful anchored regexes. If you\n                // really need to keep your anchors, double them (i.e., `^^...$$`)\n                data[p] = {pattern: deanchor(sub.source), names: sub.xregexp.captureNames || []};\n            }\n        }\n\n        // Passing to XRegExp dies on octals and ensures the outer pattern is independently valid;\n        // helps keep this simple. Named captures will be put back\n        pattern = asXRegExp(pattern);\n        outerCapNames = pattern.xregexp.captureNames || [];\n        pattern = pattern.source.replace(parts, function ($0, $1, $2, $3, $4) {\n            var subName = $1 || $2, capName, intro;\n            if (subName) { // Named subpattern\n                if (!data.hasOwnProperty(subName)) {\n                    throw new ReferenceError(\"undefined property \" + $0);\n                }\n                if ($1) { // Named subpattern was wrapped in a capturing group\n                    capName = outerCapNames[numOuterCaps];\n                    outerCapsMap[++numOuterCaps] = ++numCaps;\n                    // If it's a named group, preserve the name. Otherwise, use the subpattern name\n                    // as the capture name\n                    intro = \"(?<\" + (capName || subName) + \">\";\n                } else {\n                    intro = \"(?:\";\n                }\n                numPriorCaps = numCaps;\n                return intro + data[subName].pattern.replace(subparts, function (match, paren, backref) {\n                    if (paren) { // Capturing group\n                        capName = data[subName].names[numCaps - numPriorCaps];\n                        ++numCaps;\n                        if (capName) { // If the current capture has a name, preserve the name\n                            return \"(?<\" + capName + \">\";\n                        }\n                    } else if (backref) { // Backreference\n                        return \"\\\\\" + (+backref + numPriorCaps); // Rewrite the backreference\n                    }\n                    return match;\n                }) + \")\";\n            }\n            if ($3) { // Capturing group\n                capName = outerCapNames[numOuterCaps];\n                outerCapsMap[++numOuterCaps] = ++numCaps;\n                if (capName) { // If the current capture has a name, preserve the name\n                    return \"(?<\" + capName + \">\";\n                }\n            } else if ($4) { // Backreference\n                return \"\\\\\" + outerCapsMap[+$4]; // Rewrite the backreference\n            }\n            return $0;\n        });\n\n        return XRegExp(pattern, flags);\n    };\n\n}(XRegExp));\n\n\n/***** prototypes.js *****/\n\n/*!\n * XRegExp Prototype Methods v1.0.0\n * (c) 2012 Steven Levithan <http://xregexp.com/>\n * MIT License\n */\n\n/**\n * Adds a collection of methods to `XRegExp.prototype`. RegExp objects copied by XRegExp are also\n * augmented with any `XRegExp.prototype` methods. Hence, the following work equivalently:\n *\n * XRegExp('[a-z]', 'ig').xexec('abc');\n * XRegExp(/[a-z]/ig).xexec('abc');\n * XRegExp.globalize(/[a-z]/i).xexec('abc');\n */\n(function (XRegExp) {\n    \"use strict\";\n\n/**\n * Copy properties of `b` to `a`.\n * @private\n * @param {Object} a Object that will receive new properties.\n * @param {Object} b Object whose properties will be copied.\n */\n    function extend(a, b) {\n        for (var p in b) {\n            if (b.hasOwnProperty(p)) {\n                a[p] = b[p];\n            }\n        }\n        //return a;\n    }\n\n    extend(XRegExp.prototype, {\n\n/**\n * Implicitly calls the regex's `test` method with the first value in the provided arguments array.\n * @memberOf XRegExp.prototype\n * @param {*} context Ignored. Accepted only for congruity with `Function.prototype.apply`.\n * @param {Array} args Array with the string to search as its first value.\n * @returns {Boolean} Whether the regex matched the provided value.\n * @example\n *\n * XRegExp('[a-z]').apply(null, ['abc']); // -> true\n */\n        apply: function (context, args) {\n            return this.test(args[0]);\n        },\n\n/**\n * Implicitly calls the regex's `test` method with the provided string.\n * @memberOf XRegExp.prototype\n * @param {*} context Ignored. Accepted only for congruity with `Function.prototype.call`.\n * @param {String} str String to search.\n * @returns {Boolean} Whether the regex matched the provided value.\n * @example\n *\n * XRegExp('[a-z]').call(null, 'abc'); // -> true\n */\n        call: function (context, str) {\n            return this.test(str);\n        },\n\n/**\n * Implicitly calls {@link #XRegExp.forEach}.\n * @memberOf XRegExp.prototype\n * @example\n *\n * XRegExp('\\\\d').forEach('1a2345', function (match, i) {\n *   if (i % 2) this.push(+match[0]);\n * }, []);\n * // -> [2, 4]\n */\n        forEach: function (str, callback, context) {\n            return XRegExp.forEach(str, this, callback, context);\n        },\n\n/**\n * Implicitly calls {@link #XRegExp.globalize}.\n * @memberOf XRegExp.prototype\n * @example\n *\n * var globalCopy = XRegExp('regex').globalize();\n * globalCopy.global; // -> true\n */\n        globalize: function () {\n            return XRegExp.globalize(this);\n        },\n\n/**\n * Implicitly calls {@link #XRegExp.exec}.\n * @memberOf XRegExp.prototype\n * @example\n *\n * var match = XRegExp('U\\\\+(?<hex>[0-9A-F]{4})').xexec('U+2620');\n * match.hex; // -> '2620'\n */\n        xexec: function (str, pos, sticky) {\n            return XRegExp.exec(str, this, pos, sticky);\n        },\n\n/**\n * Implicitly calls {@link #XRegExp.test}.\n * @memberOf XRegExp.prototype\n * @example\n *\n * XRegExp('c').xtest('abc'); // -> true\n */\n        xtest: function (str, pos, sticky) {\n            return XRegExp.test(str, this, pos, sticky);\n        }\n\n    });\n\n}(XRegExp));\n\n"
  },
  {
    "path": "src/templates/base.html",
    "content": "<!DOCTYPE html>\n<html lang=en>\n\n<head>\n\t<!-- Required meta tags -->\n    <meta charset=\"utf-8\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, shrink-to-fit=no\">\n\t<link rel=\"stylesheet\" href=\"https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css\" integrity=\"sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T\" crossorigin=\"anonymous\">\n\t\n</head>\n\n<body>\n\n{% include 'snippets/base_css.html' %}\n{% include 'snippets/header.html' %}\n\n<!-- Body -->\n<style type=\"text/css\">\n\t.main{\n\t\tmin-height: 100vh;\n\t\theight: 100%;\n\t}\n</style>\n<div class=\"main\">\n\t{% block content %}\n\n\t{% endblock content %}\n</div>\n<!-- End Body -->\n\n{% include 'snippets/footer.html' %}\n\n</body>\n\n\n</html>"
  },
  {
    "path": "src/templates/registration/password_change.html",
    "content": "{% extends 'base.html' %}\n\n{% block content %}\n<style type=\"text/css\">\n  .form-signin {\n    width: 100%;\n    max-width: 330px;\n    padding: 15px;\n    margin: auto;\n  }\n  .form-signin .checkbox {\n    font-weight: 400;\n  }\n  .form-signin .form-control {\n    position: relative;\n    box-sizing: border-box;\n    height: auto;\n    padding: 10px;\n    font-size: 16px;\n  }\n  .form-signin .form-control:focus {\n    z-index: 2;\n  }\n  .form-signin input[type=\"password\"] {\n    margin-bottom: 10px;\n    border-bottom-right-radius: 0;\n    border-bottom-left-radius: 0;\n  }\n  .h3{\n    text-align: center;\n  }\n</style>\n\n\n<form method=\"POST\" class=\"form-signin\">{% csrf_token %}\n  <h1 class=\"h3 mb-3 font-weight-normal\">Change password</h1>\n    <input name=\"old_password\" class=\"form-control\" placeholder=\"Old password\" type=\"password\" id=\"id_old_password\" required=\"true\">\n    <input name=\"new_password1\" class=\"form-control\" placeholder=\"New password\" type=\"password\" id=\"id_new_password1\" required=\"true\">\n    <input name=\"new_password2\" class=\"form-control\" placeholder=\"Confirm password\" type=\"password\" id=\"id_new_password2\" required=\"true\">\n\n    {% for field in form %}\n      {% for error in field.errors %}\n        <p style=\"color: red\">{{ error }}</p>\n      {% endfor %}\n    {% endfor %}\n\n  <button class=\"btn btn-lg btn-primary btn-block\" type=\"submit\">Update</button>  \n</form>\n\n\n\n{% endblock %}"
  },
  {
    "path": "src/templates/registration/password_change_done.html",
    "content": "{% extends 'base.html' %}\n\n{% block content %}\n\n<div class=\"container\">\n\t<div class=\"d-flex flex-column\">\n\t\t<p class=\"m-auto\">Your password has been Updated.</p>\n\t</div>\n</div>\n\n{% endblock %}"
  },
  {
    "path": "src/templates/registration/password_reset_complete.html",
    "content": "{% extends 'base.html' %}\n\n\n{% block content %}\n\n<div class=\"container\">\n\t<div class=\"d-flex flex-column\">\n\t\t<p class=\"m-auto\">Your password has been reset. You may go ahead and <a href=\"{% url 'login' %}\">sign in</a> now.</p>\n\t</div>\n</div>\n\n{% endblock %}"
  },
  {
    "path": "src/templates/registration/password_reset_done.html",
    "content": "{% extends 'base.html' %}\n\n{% block content %}\n\n<div class=\"container\">\n\n\t<div class=\"d-flex flex-column\">\n\t\t  <p class=\"m-auto p-2\">\n\t\t    We've emailed you instructions for setting your password, if an account exists with the email you entered.\n\t\t    You should receive them shortly.\n\t\t  </p>\n\t\t  <p class=\"m-auto p-2\">\n\t\t    If you don't receive an email, please make sure you've entered the address you registered with,\n\t\t    and check your spam folder.\n\t\t  </p>\n\t\t  <p class=\"m-auto p-2\"><a href=\"{% url 'home' %}\">Return to home page</a></p>\n\t</div>\n</div>\n\n{% endblock %}"
  },
  {
    "path": "src/templates/registration/password_reset_email.html",
    "content": "{% autoescape off %}\nTo initiate the password reset process for your Account {{ user.email }},\nclick the link below:\n\n{{ protocol }}://{{ domain }}{% url 'password_reset_confirm' uidb64=uid token=token %}\n\nIf clicking the link above doesn't work, please copy and paste the URL in a new browser\nwindow instead.\n\nSincerely,\nThe CodingWithMitch Team\n{% endautoescape %}"
  },
  {
    "path": "src/templates/registration/password_reset_form.html",
    "content": "{% extends 'base.html' %}\n\n\n{% block content %}\n\n<style type=\"text/css\">\n  .form-signin {\n    width: 100%;\n    max-width: 330px;\n    padding: 15px;\n    margin: auto;\n  }\n  .form-signin .checkbox {\n    font-weight: 400;\n  }\n  .form-signin .form-control {\n    position: relative;\n    box-sizing: border-box;\n    height: auto;\n    padding: 10px;\n    font-size: 16px;\n  }\n  .form-signin .form-control:focus {\n    z-index: 2;\n  }\n  .form-signin input[type=\"email\"] {\n    margin-bottom: 10px;\n    border-bottom-right-radius: 0;\n    border-bottom-left-radius: 0;\n  }\n  .h3{\n    text-align: center;\n  }\n</style>\n\n\n<form method=\"POST\" class=\"form-signin\">{% csrf_token %}\n\t<h1 class=\"h3 mb-3 font-weight-normal\">Reset password</h1>\n    <input name=\"email\" class=\"form-control\" placeholder=\"Email address\" type=\"email\" id=\"id_email\" required=\"true\">\n\t<button class=\"btn btn-lg btn-primary btn-block\" type=\"submit\">Send reset email</button>  \n</form>\n\n<script type=\"text/javascript\">\n\n  var submitButton = document.getElementById('id_submit_btn');\n  var form = document.getElementById('id_password_reset_form');\n\n  // Add a listener to the click event\n  submitButton.addEventListener('click', function (e) {\n\n      AndroidTextListener.onLoading(true)\n\n      e.preventDefault();\n      var email = document.getElementById(\"id_email\").value\n      \n      var xhr = new XMLHttpRequest();\n      xhr.open('GET', '/api/account/check_if_account_exists/?email=' + email);\n      xhr.onload = function() {\n          if (xhr.status === 200) {\n              var response = JSON.parse(xhr.responseText)\n              if(response.response == email){\n                console.log(email + \" is a valid email!\")\n                form.submit()\n                AndroidTextListener.onSuccess(email)\n              }\n              else{\n                console.log(email + \" is NOT valid email!\")\n                AndroidTextListener.onError(\"That email doesn't exist on our servers.\")\n              }\n          }\n          else {\n              console.log(xhr.status)\n          }\n          AndroidTextListener.onLoading(false)\n      };\n      xhr.send();\n\n  });\n\n</script>\n\n{% endblock %}"
  },
  {
    "path": "src/templates/registration/password_reset_subject.txt",
    "content": "CodingWithMitch password reset"
  },
  {
    "path": "src/templates/snippets/base_css.html",
    "content": "<style type=\"text/css\">\n\tbody{\n\t\tbackground-color: #f2f2f2;\n\t}\n</style>"
  },
  {
    "path": "src/templates/snippets/footer.html",
    "content": "<style type=\"text/css\">\n\t.footer{\n\t\tmin-height: 100px;\n\t}\n</style>\n\n<!-- Footer -->\n\n<div class=\"d-flex flex-row align-items-center footer bg-white shadow-lg\">\n\t<p class=\"m-auto\">CodingWithMitch Blog Course | 2019</p>\n</div>\n<!-- End Footer -->\n\n\n<script src=\"https://code.jquery.com/jquery-3.3.1.slim.min.js\" integrity=\"sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo\" crossorigin=\"anonymous\"></script>\n<script src=\"https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js\" integrity=\"sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1\" crossorigin=\"anonymous\"></script>\n<script src=\"https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js\" integrity=\"sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM\" crossorigin=\"anonymous\"></script>\n\n"
  },
  {
    "path": "src/templates/snippets/header.html",
    "content": "<style type=\"text/css\">\n\t@media (min-width: 768px) {\n\t  html {\n\t    font-size: 16px;\n\t  }\n\t}\n\n\t.search-bar{\n\t\tmax-width: 500px;\n\t\twidth: 100%;\n\t}\n\n\tform{\n\t\twidth: 100%;\n\t}\n\n</style>\n\n<!-- Header -->\n<div class=\"d-flex flex-column flex-md-row align-items-center p-3 px-md-4 mb-3 bg-white border-bottom shadow-sm\">\n  <h5 class=\"my-0 mr-md-auto font-weight-normal\">\n  \t{% if request.user.is_authenticated %}\n  \t\t<p>Hello, {{request.user.username}}</p>\n  \t{% endif %}\n  </h5>\n\n  <div class=\"search-bar mt-sm-2 mr-2\">\n  \t<form onsubmit=\"return executeQuery();\">\n  \t\t<input type=\"text\" class=\"form-control\" name=\"q\" id=\"id_q\" placeholder=\"Search...\">\n  \t</form>\n  </div>\n\n  <nav class=\"my-2 my-md-0 mr-md-3\">\n  \t{% if request.user.is_authenticated %}\n\t  \t<a class=\"p-2 text-dark\" href=\"{% url 'home' %}\">Home</a>\n\t    <a class=\"p-2 text-dark\" href=\"{% url 'account' %}\">Account</a>\n\t    <a class=\"p-2 text-dark\" href=\"{% url 'logout' %}\">Logout</a>\n\t{% else %}\n\t\t<a class=\"p-2 text-dark\" href=\"{% url 'home' %}\">Home</a>\n\t    <a class=\"p-2 text-dark\" href=\"{% url 'login' %}\">Login</a>\n\t    <a class=\"btn btn-outline-primary\" href=\"{% url 'register' %}\">Register</a>\n\t{% endif %}\t\n    \n  </nav>\n</div>\n\n<script type=\"text/javascript\">\n\tdocument.getElementById(\"id_q\").value = \"{{query}}\"\n</script>\n<script type=\"text/javascript\">\n\tfunction executeQuery(){\n\t\tvar query = document.getElementById(\"id_q\").value\n\t\twindow.location.replace(\"http://127.0.0.1:8000/?q=\" + query)\n\t\t// \"https://open-api.xyz/?q=\" + query\n\t\treturn false\n\t}\n</script>\n\n<!-- End Header -->"
  }
]