diff --git a/.browserslistrc b/.browserslistrc
new file mode 100644
index 000000000..e94f8140c
--- /dev/null
+++ b/.browserslistrc
@@ -0,0 +1 @@
+defaults
diff --git a/.gitignore b/.gitignore
index 48c61ae0d..15e28515f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -39,3 +39,4 @@ build/
# unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
.rvmrc
.DS_Store
+node_modules
diff --git a/.ruby-version b/.ruby-version
new file mode 100644
index 000000000..57cf282eb
--- /dev/null
+++ b/.ruby-version
@@ -0,0 +1 @@
+2.6.5
diff --git a/Gemfile b/Gemfile
new file mode 100644
index 000000000..7ff1ec2fc
--- /dev/null
+++ b/Gemfile
@@ -0,0 +1,78 @@
+source 'https://rubygems.org'
+git_source(:github) { |repo| "https://github.com/#{repo}.git" }
+
+ruby '2.6.5'
+
+# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
+gem 'rails', '~> 6.0.2', '>= 6.0.2.2'
+# Use postgresql as the database for Active Record
+gem 'pg', '>= 0.18', '< 2.0'
+# Use Puma as the app server
+gem 'puma', '~> 4.1'
+# Use SCSS for stylesheets
+gem 'sass-rails', '>= 6'
+# Transpile app-like JavaScript. Read more: https://github.com/rails/webpacker
+gem 'webpacker', '~> 4.0'
+# Turbolinks makes navigating your web application faster. Read more: https://github.com/turbolinks/turbolinks
+gem 'turbolinks', '~> 5'
+# Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder
+gem 'jbuilder', '~> 2.7'
+# Use Redis adapter to run Action Cable in production
+# gem 'redis', '~> 4.0'
+# Use Active Model has_secure_password
+# gem 'bcrypt', '~> 3.1.7'
+
+# Use Active Storage variant
+# gem 'image_processing', '~> 1.2'
+
+# Reduces boot times through caching; required in config/boot.rb
+gem 'bootsnap', '>= 1.4.2', require: false
+
+group :development, :test do
+ # Call 'byebug' anywhere in the code to stop execution and get a debugger console
+ gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
+end
+
+group :development do
+ # Access an interactive console on exception pages or by calling 'console' anywhere in the code.
+ gem 'web-console', '>= 3.3.0'
+ gem 'listen', '>= 3.0.5', '< 3.2'
+ # Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring
+ gem 'spring'
+ gem 'spring-watcher-listen', '~> 2.0.0'
+end
+
+group :test do
+ # Adds support for Capybara system testing and selenium driver
+ gem 'capybara', '>= 2.15'
+ gem 'selenium-webdriver'
+ # Easy installation and use of web drivers to run system tests with browsers
+ gem 'webdrivers'
+end
+
+# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
+gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]
+
+gem 'jquery-rails'
+gem 'jquery-turbolinks'
+gem 'bootstrap'
+group :development, :test do
+ gem 'pry-rails'
+end
+
+group :development do
+ gem 'guard'
+ gem 'guard-minitest'
+ gem 'debase', '>= 0.2.4.1'
+ gem 'ruby-debug-ide', '>= 0.7.0'
+end
+
+group :development do
+ gem 'better_errors'
+ gem 'binding_of_caller'
+end
+
+group :test do
+ gem 'minitest-rails'
+ gem 'minitest-reporters'
+end
diff --git a/Gemfile.lock b/Gemfile.lock
new file mode 100644
index 000000000..c2e9441e3
--- /dev/null
+++ b/Gemfile.lock
@@ -0,0 +1,300 @@
+GEM
+ remote: https://rubygems.org/
+ specs:
+ actioncable (6.0.2.2)
+ actionpack (= 6.0.2.2)
+ nio4r (~> 2.0)
+ websocket-driver (>= 0.6.1)
+ actionmailbox (6.0.2.2)
+ actionpack (= 6.0.2.2)
+ activejob (= 6.0.2.2)
+ activerecord (= 6.0.2.2)
+ activestorage (= 6.0.2.2)
+ activesupport (= 6.0.2.2)
+ mail (>= 2.7.1)
+ actionmailer (6.0.2.2)
+ actionpack (= 6.0.2.2)
+ actionview (= 6.0.2.2)
+ activejob (= 6.0.2.2)
+ mail (~> 2.5, >= 2.5.4)
+ rails-dom-testing (~> 2.0)
+ actionpack (6.0.2.2)
+ actionview (= 6.0.2.2)
+ activesupport (= 6.0.2.2)
+ rack (~> 2.0, >= 2.0.8)
+ rack-test (>= 0.6.3)
+ rails-dom-testing (~> 2.0)
+ rails-html-sanitizer (~> 1.0, >= 1.2.0)
+ actiontext (6.0.2.2)
+ actionpack (= 6.0.2.2)
+ activerecord (= 6.0.2.2)
+ activestorage (= 6.0.2.2)
+ activesupport (= 6.0.2.2)
+ nokogiri (>= 1.8.5)
+ actionview (6.0.2.2)
+ activesupport (= 6.0.2.2)
+ builder (~> 3.1)
+ erubi (~> 1.4)
+ rails-dom-testing (~> 2.0)
+ rails-html-sanitizer (~> 1.1, >= 1.2.0)
+ activejob (6.0.2.2)
+ activesupport (= 6.0.2.2)
+ globalid (>= 0.3.6)
+ activemodel (6.0.2.2)
+ activesupport (= 6.0.2.2)
+ activerecord (6.0.2.2)
+ activemodel (= 6.0.2.2)
+ activesupport (= 6.0.2.2)
+ activestorage (6.0.2.2)
+ actionpack (= 6.0.2.2)
+ activejob (= 6.0.2.2)
+ activerecord (= 6.0.2.2)
+ marcel (~> 0.3.1)
+ activesupport (6.0.2.2)
+ concurrent-ruby (~> 1.0, >= 1.0.2)
+ i18n (>= 0.7, < 2)
+ minitest (~> 5.1)
+ tzinfo (~> 1.1)
+ zeitwerk (~> 2.2)
+ addressable (2.7.0)
+ public_suffix (>= 2.0.2, < 5.0)
+ ansi (1.5.0)
+ autoprefixer-rails (9.7.6)
+ execjs
+ better_errors (2.7.0)
+ coderay (>= 1.0.0)
+ erubi (>= 1.0.0)
+ rack (>= 0.9.0)
+ bindex (0.8.1)
+ binding_of_caller (0.8.0)
+ debug_inspector (>= 0.0.1)
+ bootsnap (1.4.6)
+ msgpack (~> 1.0)
+ bootstrap (4.4.1)
+ autoprefixer-rails (>= 9.1.0)
+ popper_js (>= 1.14.3, < 2)
+ sassc-rails (>= 2.0.0)
+ builder (3.2.4)
+ byebug (11.1.3)
+ capybara (3.32.1)
+ addressable
+ mini_mime (>= 0.1.3)
+ nokogiri (~> 1.8)
+ rack (>= 1.6.0)
+ rack-test (>= 0.6.3)
+ regexp_parser (~> 1.5)
+ xpath (~> 3.2)
+ childprocess (3.0.0)
+ coderay (1.1.2)
+ concurrent-ruby (1.1.6)
+ crass (1.0.6)
+ debase (0.2.4.1)
+ debase-ruby_core_source (>= 0.10.2)
+ debase-ruby_core_source (0.10.9)
+ debug_inspector (0.0.3)
+ erubi (1.9.0)
+ execjs (2.7.0)
+ ffi (1.12.2)
+ formatador (0.2.5)
+ globalid (0.4.2)
+ activesupport (>= 4.2.0)
+ guard (2.16.2)
+ formatador (>= 0.2.4)
+ listen (>= 2.7, < 4.0)
+ lumberjack (>= 1.0.12, < 2.0)
+ nenv (~> 0.1)
+ notiffany (~> 0.0)
+ pry (>= 0.9.12)
+ shellany (~> 0.0)
+ thor (>= 0.18.1)
+ guard-compat (1.2.1)
+ guard-minitest (2.4.6)
+ guard-compat (~> 1.2)
+ minitest (>= 3.0)
+ i18n (1.8.2)
+ concurrent-ruby (~> 1.0)
+ jbuilder (2.10.0)
+ activesupport (>= 5.0.0)
+ jquery-rails (4.3.5)
+ rails-dom-testing (>= 1, < 3)
+ railties (>= 4.2.0)
+ thor (>= 0.14, < 2.0)
+ jquery-turbolinks (2.1.0)
+ railties (>= 3.1.0)
+ turbolinks
+ listen (3.1.5)
+ rb-fsevent (~> 0.9, >= 0.9.4)
+ rb-inotify (~> 0.9, >= 0.9.7)
+ ruby_dep (~> 1.2)
+ loofah (2.5.0)
+ crass (~> 1.0.2)
+ nokogiri (>= 1.5.9)
+ lumberjack (1.2.4)
+ mail (2.7.1)
+ mini_mime (>= 0.1.1)
+ marcel (0.3.3)
+ mimemagic (~> 0.3.2)
+ method_source (1.0.0)
+ mimemagic (0.3.4)
+ mini_mime (1.0.2)
+ mini_portile2 (2.4.0)
+ minitest (5.14.0)
+ minitest-rails (6.0.1)
+ minitest (~> 5.10)
+ railties (~> 6.0.0)
+ minitest-reporters (1.4.2)
+ ansi
+ builder
+ minitest (>= 5.0)
+ ruby-progressbar
+ msgpack (1.3.3)
+ nenv (0.3.0)
+ nio4r (2.5.2)
+ nokogiri (1.10.9)
+ mini_portile2 (~> 2.4.0)
+ notiffany (0.1.3)
+ nenv (~> 0.1)
+ shellany (~> 0.0)
+ pg (1.2.3)
+ popper_js (1.16.0)
+ pry (0.13.1)
+ coderay (~> 1.1)
+ method_source (~> 1.0)
+ pry-rails (0.3.9)
+ pry (>= 0.10.4)
+ public_suffix (4.0.4)
+ puma (4.3.3)
+ nio4r (~> 2.0)
+ rack (2.2.2)
+ rack-proxy (0.6.5)
+ rack
+ rack-test (1.1.0)
+ rack (>= 1.0, < 3)
+ rails (6.0.2.2)
+ actioncable (= 6.0.2.2)
+ actionmailbox (= 6.0.2.2)
+ actionmailer (= 6.0.2.2)
+ actionpack (= 6.0.2.2)
+ actiontext (= 6.0.2.2)
+ actionview (= 6.0.2.2)
+ activejob (= 6.0.2.2)
+ activemodel (= 6.0.2.2)
+ activerecord (= 6.0.2.2)
+ activestorage (= 6.0.2.2)
+ activesupport (= 6.0.2.2)
+ bundler (>= 1.3.0)
+ railties (= 6.0.2.2)
+ sprockets-rails (>= 2.0.0)
+ rails-dom-testing (2.0.3)
+ activesupport (>= 4.2.0)
+ nokogiri (>= 1.6)
+ rails-html-sanitizer (1.3.0)
+ loofah (~> 2.3)
+ railties (6.0.2.2)
+ actionpack (= 6.0.2.2)
+ activesupport (= 6.0.2.2)
+ method_source
+ rake (>= 0.8.7)
+ thor (>= 0.20.3, < 2.0)
+ rake (13.0.1)
+ rb-fsevent (0.10.3)
+ rb-inotify (0.10.1)
+ ffi (~> 1.0)
+ regexp_parser (1.7.0)
+ ruby-debug-ide (0.7.2)
+ rake (>= 0.8.1)
+ ruby-progressbar (1.10.1)
+ ruby_dep (1.5.0)
+ rubyzip (2.3.0)
+ sass-rails (6.0.0)
+ sassc-rails (~> 2.1, >= 2.1.1)
+ sassc (2.3.0)
+ ffi (~> 1.9)
+ sassc-rails (2.1.2)
+ railties (>= 4.0.0)
+ sassc (>= 2.0)
+ sprockets (> 3.0)
+ sprockets-rails
+ tilt
+ selenium-webdriver (3.142.7)
+ childprocess (>= 0.5, < 4.0)
+ rubyzip (>= 1.2.2)
+ shellany (0.0.1)
+ spring (2.1.0)
+ spring-watcher-listen (2.0.1)
+ listen (>= 2.7, < 4.0)
+ spring (>= 1.2, < 3.0)
+ sprockets (4.0.0)
+ concurrent-ruby (~> 1.0)
+ rack (> 1, < 3)
+ sprockets-rails (3.2.1)
+ actionpack (>= 4.0)
+ activesupport (>= 4.0)
+ sprockets (>= 3.0.0)
+ thor (1.0.1)
+ thread_safe (0.3.6)
+ tilt (2.0.10)
+ turbolinks (5.2.1)
+ turbolinks-source (~> 5.2)
+ turbolinks-source (5.2.0)
+ tzinfo (1.2.7)
+ thread_safe (~> 0.1)
+ web-console (4.0.1)
+ actionview (>= 6.0.0)
+ activemodel (>= 6.0.0)
+ bindex (>= 0.4.0)
+ railties (>= 6.0.0)
+ webdrivers (4.3.0)
+ nokogiri (~> 1.6)
+ rubyzip (>= 1.3.0)
+ selenium-webdriver (>= 3.0, < 4.0)
+ webpacker (4.2.2)
+ activesupport (>= 4.2)
+ rack-proxy (>= 0.6.1)
+ railties (>= 4.2)
+ websocket-driver (0.7.1)
+ websocket-extensions (>= 0.1.0)
+ websocket-extensions (0.1.4)
+ xpath (3.2.0)
+ nokogiri (~> 1.8)
+ zeitwerk (2.3.0)
+
+PLATFORMS
+ ruby
+
+DEPENDENCIES
+ better_errors
+ binding_of_caller
+ bootsnap (>= 1.4.2)
+ bootstrap
+ byebug
+ capybara (>= 2.15)
+ debase (>= 0.2.4.1)
+ guard
+ guard-minitest
+ jbuilder (~> 2.7)
+ jquery-rails
+ jquery-turbolinks
+ listen (>= 3.0.5, < 3.2)
+ minitest-rails
+ minitest-reporters
+ pg (>= 0.18, < 2.0)
+ pry-rails
+ puma (~> 4.1)
+ rails (~> 6.0.2, >= 6.0.2.2)
+ ruby-debug-ide (>= 0.7.0)
+ sass-rails (>= 6)
+ selenium-webdriver
+ spring
+ spring-watcher-listen (~> 2.0.0)
+ turbolinks (~> 5)
+ tzinfo-data
+ web-console (>= 3.3.0)
+ webdrivers
+ webpacker (~> 4.0)
+
+RUBY VERSION
+ ruby 2.6.5p114
+
+BUNDLED WITH
+ 2.1.4
diff --git a/Guardfile b/Guardfile
new file mode 100644
index 000000000..e34f706f4
--- /dev/null
+++ b/Guardfile
@@ -0,0 +1,9 @@
+guard :minitest, autorun: false, spring: true do
+ watch(%r{^app/(.+).rb$}) { |m| "test/#{m[1]}_test.rb" }
+ watch(%r{^app/controllers/application_controller.rb$}) { 'test/controllers' }
+ watch(%r{^app/controllers/(.+)_controller.rb$}) { |m| "test/integration/#{m[1]}_test.rb" }
+ watch(%r{^app/views/(.+)_mailer/.+}) { |m| "test/mailers/#{m[1]}_mailer_test.rb" }
+ watch(%r{^lib/(.+).rb$}) { |m| "test/lib/#{m[1]}_test.rb" }
+ watch(%r{^test/.+_test.rb$})
+ watch(%r{^test/test_helper.rb$}) { 'test' }
+end
diff --git a/README.md b/README.md
index e8e89b8cc..7db80e4ca 100644
--- a/README.md
+++ b/README.md
@@ -1,95 +1,24 @@
-# Task List
+# README
-Let's build a Task List in Rails! We will solve the problem of tracking tasks in a web application. This project will enable us to keep track of and persist, add, edit and remove tasks.
+This README would normally document whatever steps are necessary to get the
+application up and running.
-## At a Glance
-- Individual, [stage 1](https://github.com/Ada-Developers-Academy/pedagogy/blob/master/classroom/rule-of-three.md#stage-1) project
-- Due before class on **Monday May 4th**
+Things you may want to cover:
-## Learning Goals
+* Ruby version
-Practice all aspects of Rails development.
+* System dependencies
-- Create a new Rails application
-- Explore each aspect of the Rails Request Cycle: Model, View, Controller
-- Implement RESTful routes using Rails standards
-- Complete all CRUD actions in a Rails application
+* Configuration
-## Baseline
+* Database creation
-In this baseline, you'll create a new Rails application and get started with two of the major components: route, controller and view.
+* Database initialization
-- Fork and clone this repository to your computer
-- Create a new Rails application using `rails new .`
- - create a `Tasks` controller
- - create a route to view the task `index` page
- - create a controller action for the task `index` page which contains an array of hard-coded tasks
- - create an ERB view to display the tasks from the controller action
+* How to run the test suite
-### Controller Tests
+* Services (job queues, cache servers, search engines, etc.)
-Tests have been created for waves 1 & 2. You can find the tests in `test/controllers/tasks_controller_test.rb`, and you can execute the tests with `$ rails test`. You may need to update the test file if your schema differs from the one in the spec. For waves 3 & 4, we have not provided tests. You will learn how to write controller tests on Monday. It is an optional requirement to to create your own wave 3 and wave 4 tests.
+* Deployment instructions
-## Wave 1
-
-This wave is where we introduce ActiveRecord to create a model. We use the model to persist our data. Make sure you are building the application so that it meets the requirements of the pre-written tests.
-
-1. create a migration which will create a new `Task` model
- - create the database schema and tables by running the `rails db:migrate` command
- - the `Task` model should include _at least_ a name, a description and a completion date.
- - the three fields should be named:
- - `name` - The name of the task
- - `description` - A text description of the task
- - `completed_at` - The date, saved as text, in which the task was completed.
- - create at least 2 `Task` model instances using the `rails console`
-1. update the controller's `index` action you created to retrieve and show `all` Task objects from the database
- - you may need to update the view as well to use the model fields rather than the hard-coded data
-
-## Wave 2
-
-In this wave, we will expand the actions we support and introduce forms for user interactivity and persistence. Again, make sure you are building the application so that it meets the requirements of the pre-written tests.
-
-1. add support to `show` each task
- - update the task list to link to a `show` action for each individual task
- - create a route
- - create a controller action
- - create an ERB view
-1. Create a new task:
- - update the task list to have a link to add a new task
- - this will give the user a new page with a **form** with the appropriate task fields
- - the site should take the user to the show page for the task that was just added
-1. Verify the success of your controller actions by uncommenting the wave 2 tests and executing them with `$ rails test`.
-
-## Wave 3
-
-In this wave we will extend the interactivity with users, allowing them to edit existing tasks.
-
-1. Edit a task
- - update each task's show page to include an edit link
- - this will give the user a new page with a **form** that is pre-populated with the data about that task
- - the site should take the user back to the task's show page after the task is updated
-
-1. **Optionals**
- - Complete tests by uncommenting and filling in the contents of the Wave 3 tests for the `edit` and `update` actions.
- - DRY up your code by reusing the view code from the `new` functionality
- - Hint: Rendering _partials_ in Rails
-
-## Wave 4
-
-In this wave, we will add the ability to delete tasks. We will also add the ability for a user to mark a task complete. Note: Marking a task complete will require going above and beyond the examples provided in lecture.
-
-1. Delete a task
- On the task list, add a button or link for each task that will, once clicked:
- 1. Ask the user to confirm that they definitely want to delete the task.
- 1. Delete the task from the database and redirect the user back to the list of remaining tasks
-1. Mark a task complete
- - Add a button to the list of tasks on the home page that, when clicked, will mark a task complete
- - Update the database with the task's completed_at date
-1. **Optional**
- Write controller tests for the delete and mark complete actions.
-
-## Optional Wave 5: Design
-
-The focus of this project is to familiarize yourself with rails. Design of this application is optional and secondary to learning goals this project. If you do find you have time to style the design of your application, you can use or own design or the wireframes below.
-
-
+* ...
diff --git a/Rakefile b/Rakefile
new file mode 100644
index 000000000..e85f91391
--- /dev/null
+++ b/Rakefile
@@ -0,0 +1,6 @@
+# Add your own tasks in files placed in lib/tasks ending in .rake,
+# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
+
+require_relative 'config/application'
+
+Rails.application.load_tasks
diff --git a/app/assets/config/manifest.js b/app/assets/config/manifest.js
new file mode 100644
index 000000000..591819335
--- /dev/null
+++ b/app/assets/config/manifest.js
@@ -0,0 +1,2 @@
+//= link_tree ../images
+//= link_directory ../stylesheets .css
diff --git a/app/assets/images/.keep b/app/assets/images/.keep
new file mode 100644
index 000000000..e69de29bb
diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss
new file mode 100644
index 000000000..17320fb11
--- /dev/null
+++ b/app/assets/stylesheets/application.scss
@@ -0,0 +1,18 @@
+/*
+ * This is a manifest file that'll be compiled into application.css, which will include all the files
+ * listed below.
+ *
+ * Any CSS and SCSS file within this directory, lib/assets/stylesheets, or any plugin's
+ * vendor/assets/stylesheets directory can be referenced here using a relative path.
+ *
+ * You're free to add application-wide styles to this file and they'll appear at the bottom of the
+ * compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS
+ * files in this directory. Styles in this file should be added after the last require_* statement.
+ * It is generally better to create a new file per style scope.
+ *
+ */
+
+/* Custom bootstrap variables must be set or imported *before* bootstrap. */
+@import "bootstrap";
+
+@import "**/*";
diff --git a/app/assets/stylesheets/tasks.scss b/app/assets/stylesheets/tasks.scss
new file mode 100644
index 000000000..645de58b1
--- /dev/null
+++ b/app/assets/stylesheets/tasks.scss
@@ -0,0 +1,3 @@
+// Place all the styles related to the Tasks controller here.
+// They will automatically be included in application.css.
+// You can use Sass (SCSS) here: https://sass-lang.com/
diff --git a/app/channels/application_cable/channel.rb b/app/channels/application_cable/channel.rb
new file mode 100644
index 000000000..d67269728
--- /dev/null
+++ b/app/channels/application_cable/channel.rb
@@ -0,0 +1,4 @@
+module ApplicationCable
+ class Channel < ActionCable::Channel::Base
+ end
+end
diff --git a/app/channels/application_cable/connection.rb b/app/channels/application_cable/connection.rb
new file mode 100644
index 000000000..0ff5442f4
--- /dev/null
+++ b/app/channels/application_cable/connection.rb
@@ -0,0 +1,4 @@
+module ApplicationCable
+ class Connection < ActionCable::Connection::Base
+ end
+end
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
new file mode 100644
index 000000000..09705d12a
--- /dev/null
+++ b/app/controllers/application_controller.rb
@@ -0,0 +1,2 @@
+class ApplicationController < ActionController::Base
+end
diff --git a/app/controllers/concerns/.keep b/app/controllers/concerns/.keep
new file mode 100644
index 000000000..e69de29bb
diff --git a/app/controllers/tasks_controller.rb b/app/controllers/tasks_controller.rb
new file mode 100644
index 000000000..beae8c6a6
--- /dev/null
+++ b/app/controllers/tasks_controller.rb
@@ -0,0 +1,103 @@
+require "date"
+
+class TasksController < ApplicationController
+ def index
+ @tasks = Task.all
+ end
+
+ def show
+ task_id = params[:id].to_i
+ @task = Task.find_by(id: task_id)
+
+ if @task.nil?
+ head :not_found
+ return
+ end
+ end
+
+ def new
+ @task = Task.new
+ end
+
+ def create
+ task = Task.new(task_params)
+
+ if task.save
+ redirect_to task_path(task.id)
+ return
+ else
+ render :new, :bad_request
+ return
+ end
+ end
+
+ def edit
+ task_id = params[:id].to_i
+ @task = Task.find_by(id: task_id)
+
+ if @task.nil?
+ head :not_found
+ return
+ else
+ @task.name = @task[:name]
+ @task.description = @task[:description]
+ @task.completed_at = @task[:completed_at]
+ end
+ end
+
+ def update
+ task_id = params[:id].to_i
+ @task = Task.find_by(id: task_id)
+
+ if @task.nil?
+ head :not_found
+ return
+ elsif @task.update(task_params)
+ redirect_to task_path(@task.id)
+ return
+ else
+ render :new, :bad_request
+ return
+ end
+ end
+
+ def destroy
+ @task = Task.find_by(id: params[:id])
+ if @task.nil?
+ head :not_found
+ return
+ else
+ @task.destroy
+ redirect_to root_path
+ return
+ end
+ end
+
+ def mark_complete
+ task_id = params[:id].to_i
+ @task = Task.find_by(id: task_id)
+
+ if @task.nil?
+ head :not_found
+ return
+ end
+
+ if @task[:completed_at].empty?
+ @task[:completed_at] = Date.today.to_s
+ end
+
+ if @task.save
+ redirect_to root_path
+ return
+ else
+ render :new, :bad_request
+ return
+ end
+ end
+
+ private
+
+ def task_params
+ return params.require(:task).permit(:name, :description, :completed_at)
+ end
+end
diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb
new file mode 100644
index 000000000..de6be7945
--- /dev/null
+++ b/app/helpers/application_helper.rb
@@ -0,0 +1,2 @@
+module ApplicationHelper
+end
diff --git a/app/helpers/tasks_helper.rb b/app/helpers/tasks_helper.rb
new file mode 100644
index 000000000..ce894d00c
--- /dev/null
+++ b/app/helpers/tasks_helper.rb
@@ -0,0 +1,2 @@
+module TasksHelper
+end
diff --git a/app/javascript/channels/consumer.js b/app/javascript/channels/consumer.js
new file mode 100644
index 000000000..0eceb59b1
--- /dev/null
+++ b/app/javascript/channels/consumer.js
@@ -0,0 +1,6 @@
+// Action Cable provides the framework to deal with WebSockets in Rails.
+// You can generate new channels where WebSocket features live using the `rails generate channel` command.
+
+import { createConsumer } from "@rails/actioncable"
+
+export default createConsumer()
diff --git a/app/javascript/channels/index.js b/app/javascript/channels/index.js
new file mode 100644
index 000000000..0cfcf7491
--- /dev/null
+++ b/app/javascript/channels/index.js
@@ -0,0 +1,5 @@
+// Load all the channels within this directory and all subdirectories.
+// Channel files must be named *_channel.js.
+
+const channels = require.context('.', true, /_channel\.js$/)
+channels.keys().forEach(channels)
diff --git a/app/javascript/packs/application.js b/app/javascript/packs/application.js
new file mode 100644
index 000000000..529f85b08
--- /dev/null
+++ b/app/javascript/packs/application.js
@@ -0,0 +1,19 @@
+// This file is automatically compiled by Webpack, along with any other files
+// present in this directory. You're encouraged to place your actual application logic in
+// a relevant structure within app/javascript and only use these pack files to reference
+// that code so it'll be compiled.
+
+require("@rails/ujs").start()
+require("turbolinks").start()
+require("@rails/activestorage").start()
+require("channels")
+
+import "bootstrap"
+
+
+// Uncomment to copy all static images under ../images to the output folder and reference
+// them with the image_pack_tag helper in views (e.g <%= image_pack_tag 'rails.png' %>)
+// or the `imagePath` JavaScript helper below.
+//
+// const images = require.context('../images', true)
+// const imagePath = (name) => images(name, true)
diff --git a/app/jobs/application_job.rb b/app/jobs/application_job.rb
new file mode 100644
index 000000000..d394c3d10
--- /dev/null
+++ b/app/jobs/application_job.rb
@@ -0,0 +1,7 @@
+class ApplicationJob < ActiveJob::Base
+ # Automatically retry jobs that encountered a deadlock
+ # retry_on ActiveRecord::Deadlocked
+
+ # Most jobs are safe to ignore if the underlying records are no longer available
+ # discard_on ActiveJob::DeserializationError
+end
diff --git a/app/mailers/application_mailer.rb b/app/mailers/application_mailer.rb
new file mode 100644
index 000000000..286b2239d
--- /dev/null
+++ b/app/mailers/application_mailer.rb
@@ -0,0 +1,4 @@
+class ApplicationMailer < ActionMailer::Base
+ default from: 'from@example.com'
+ layout 'mailer'
+end
diff --git a/app/models/application_record.rb b/app/models/application_record.rb
new file mode 100644
index 000000000..10a4cba84
--- /dev/null
+++ b/app/models/application_record.rb
@@ -0,0 +1,3 @@
+class ApplicationRecord < ActiveRecord::Base
+ self.abstract_class = true
+end
diff --git a/app/models/concerns/.keep b/app/models/concerns/.keep
new file mode 100644
index 000000000..e69de29bb
diff --git a/app/models/task.rb b/app/models/task.rb
new file mode 100644
index 000000000..3c2342421
--- /dev/null
+++ b/app/models/task.rb
@@ -0,0 +1,2 @@
+class Task < ApplicationRecord
+end
diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb
new file mode 100644
index 000000000..7a8dbd9c4
--- /dev/null
+++ b/app/views/layouts/application.html.erb
@@ -0,0 +1,15 @@
+
+
+
+ TaskList
+ <%= csrf_meta_tags %>
+ <%= csp_meta_tag %>
+
+ <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
+ <%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
+
+
+
+ <%= yield %>
+
+
diff --git a/app/views/layouts/mailer.html.erb b/app/views/layouts/mailer.html.erb
new file mode 100644
index 000000000..cbd34d2e9
--- /dev/null
+++ b/app/views/layouts/mailer.html.erb
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+ <%= yield %>
+
+
diff --git a/app/views/layouts/mailer.text.erb b/app/views/layouts/mailer.text.erb
new file mode 100644
index 000000000..37f0bddbd
--- /dev/null
+++ b/app/views/layouts/mailer.text.erb
@@ -0,0 +1 @@
+<%= yield %>
diff --git a/app/views/tasks/_form.html.erb b/app/views/tasks/_form.html.erb
new file mode 100644
index 000000000..c8cba04cc
--- /dev/null
+++ b/app/views/tasks/_form.html.erb
@@ -0,0 +1,17 @@
+<%= form_with model: model, class: 'task_form' do |f| %>
+
+ <%= f.label :name%>
+ <%= f.text_field :name%>
+
+
+
+ <%= f.label :description %>
+ <%= f.text_field :description %>
+
+
+
+ <%= f.label :completed_at %>
+ <%= f.text_area :completed_at %>
+
+ <%= f.submit "Submit" %>
+<% end %>
diff --git a/app/views/tasks/edit.html.erb b/app/views/tasks/edit.html.erb
new file mode 100644
index 000000000..57185477d
--- /dev/null
+++ b/app/views/tasks/edit.html.erb
@@ -0,0 +1,3 @@
+ Edit Task
+
+<%= render partial: 'form', locals: { model: @task } %>
diff --git a/app/views/tasks/index.html.erb b/app/views/tasks/index.html.erb
new file mode 100644
index 000000000..b0a0dda32
--- /dev/null
+++ b/app/views/tasks/index.html.erb
@@ -0,0 +1,25 @@
+Tasks
+
+
+<% if @tasks.length > 0 %>
+
+ <% @tasks.each do |task| %>
+ <%= link_to task.name, task_path(task.id) %>
+ <%= task.description %>
+ <% if !task.completed_at.empty? %>
+ Completed at: <%= task.completed_at %>
+ <% end %>
+
+
+ <%= link_to "Edit Task", edit_task_path(task.id)%>
+ OR
+ <%= link_to "Delete This Task", task_path(task.id), method: :delete, data: { confirm: "Are you sure you want to delete this task?" } %>
+ OR
+ <%= link_to "Mark Task Complete", mark_complete_path(task.id), method: :patch %>
+
+ <% end %>
+
+<% else %>
+ No tasks in the system!
+<% end %>
+<%= link_to "Add a Task", new_task_path %>
diff --git a/app/views/tasks/new.html.erb b/app/views/tasks/new.html.erb
new file mode 100644
index 000000000..9b62f87e9
--- /dev/null
+++ b/app/views/tasks/new.html.erb
@@ -0,0 +1,3 @@
+ Add a NEW Task!
+
+<%= render partial: 'form', locals: { model: @task } %>
diff --git a/app/views/tasks/show.html.erb b/app/views/tasks/show.html.erb
new file mode 100644
index 000000000..7a7987027
--- /dev/null
+++ b/app/views/tasks/show.html.erb
@@ -0,0 +1,5 @@
+ <%= @task.name %>
+ <%= @task.description %>
+ <%= @task.completed_at %>
+
+<%= link_to "Home Page", root_path %>
\ No newline at end of file
diff --git a/babel.config.js b/babel.config.js
new file mode 100644
index 000000000..12f98da5a
--- /dev/null
+++ b/babel.config.js
@@ -0,0 +1,72 @@
+module.exports = function(api) {
+ var validEnv = ['development', 'test', 'production']
+ var currentEnv = api.env()
+ var isDevelopmentEnv = api.env('development')
+ var isProductionEnv = api.env('production')
+ var isTestEnv = api.env('test')
+
+ if (!validEnv.includes(currentEnv)) {
+ throw new Error(
+ 'Please specify a valid `NODE_ENV` or ' +
+ '`BABEL_ENV` environment variables. Valid values are "development", ' +
+ '"test", and "production". Instead, received: ' +
+ JSON.stringify(currentEnv) +
+ '.'
+ )
+ }
+
+ return {
+ presets: [
+ isTestEnv && [
+ '@babel/preset-env',
+ {
+ targets: {
+ node: 'current'
+ }
+ }
+ ],
+ (isProductionEnv || isDevelopmentEnv) && [
+ '@babel/preset-env',
+ {
+ forceAllTransforms: true,
+ useBuiltIns: 'entry',
+ corejs: 3,
+ modules: false,
+ exclude: ['transform-typeof-symbol']
+ }
+ ]
+ ].filter(Boolean),
+ plugins: [
+ 'babel-plugin-macros',
+ '@babel/plugin-syntax-dynamic-import',
+ isTestEnv && 'babel-plugin-dynamic-import-node',
+ '@babel/plugin-transform-destructuring',
+ [
+ '@babel/plugin-proposal-class-properties',
+ {
+ loose: true
+ }
+ ],
+ [
+ '@babel/plugin-proposal-object-rest-spread',
+ {
+ useBuiltIns: true
+ }
+ ],
+ [
+ '@babel/plugin-transform-runtime',
+ {
+ helpers: false,
+ regenerator: true,
+ corejs: false
+ }
+ ],
+ [
+ '@babel/plugin-transform-regenerator',
+ {
+ async: false
+ }
+ ]
+ ].filter(Boolean)
+ }
+}
diff --git a/bin/bundle b/bin/bundle
new file mode 100755
index 000000000..a71368e32
--- /dev/null
+++ b/bin/bundle
@@ -0,0 +1,114 @@
+#!/usr/bin/env ruby
+# frozen_string_literal: true
+
+#
+# This file was generated by Bundler.
+#
+# The application 'bundle' is installed as part of a gem, and
+# this file is here to facilitate running it.
+#
+
+require "rubygems"
+
+m = Module.new do
+ module_function
+
+ def invoked_as_script?
+ File.expand_path($0) == File.expand_path(__FILE__)
+ end
+
+ def env_var_version
+ ENV["BUNDLER_VERSION"]
+ end
+
+ def cli_arg_version
+ return unless invoked_as_script? # don't want to hijack other binstubs
+ return unless "update".start_with?(ARGV.first || " ") # must be running `bundle update`
+ bundler_version = nil
+ update_index = nil
+ ARGV.each_with_index do |a, i|
+ if update_index && update_index.succ == i && a =~ Gem::Version::ANCHORED_VERSION_PATTERN
+ bundler_version = a
+ end
+ next unless a =~ /\A--bundler(?:[= ](#{Gem::Version::VERSION_PATTERN}))?\z/
+ bundler_version = $1
+ update_index = i
+ end
+ bundler_version
+ end
+
+ def gemfile
+ gemfile = ENV["BUNDLE_GEMFILE"]
+ return gemfile if gemfile && !gemfile.empty?
+
+ File.expand_path("../../Gemfile", __FILE__)
+ end
+
+ def lockfile
+ lockfile =
+ case File.basename(gemfile)
+ when "gems.rb" then gemfile.sub(/\.rb$/, gemfile)
+ else "#{gemfile}.lock"
+ end
+ File.expand_path(lockfile)
+ end
+
+ def lockfile_version
+ return unless File.file?(lockfile)
+ lockfile_contents = File.read(lockfile)
+ return unless lockfile_contents =~ /\n\nBUNDLED WITH\n\s{2,}(#{Gem::Version::VERSION_PATTERN})\n/
+ Regexp.last_match(1)
+ end
+
+ def bundler_version
+ @bundler_version ||=
+ env_var_version || cli_arg_version ||
+ lockfile_version
+ end
+
+ def bundler_requirement
+ return "#{Gem::Requirement.default}.a" unless bundler_version
+
+ bundler_gem_version = Gem::Version.new(bundler_version)
+
+ requirement = bundler_gem_version.approximate_recommendation
+
+ return requirement unless Gem::Version.new(Gem::VERSION) < Gem::Version.new("2.7.0")
+
+ requirement += ".a" if bundler_gem_version.prerelease?
+
+ requirement
+ end
+
+ def load_bundler!
+ ENV["BUNDLE_GEMFILE"] ||= gemfile
+
+ activate_bundler
+ end
+
+ def activate_bundler
+ gem_error = activation_error_handling do
+ gem "bundler", bundler_requirement
+ end
+ return if gem_error.nil?
+ require_error = activation_error_handling do
+ require "bundler/version"
+ end
+ return if require_error.nil? && Gem::Requirement.new(bundler_requirement).satisfied_by?(Gem::Version.new(Bundler::VERSION))
+ warn "Activating bundler (#{bundler_requirement}) failed:\n#{gem_error.message}\n\nTo install the version of bundler this project requires, run `gem install bundler -v '#{bundler_requirement}'`"
+ exit 42
+ end
+
+ def activation_error_handling
+ yield
+ nil
+ rescue StandardError, LoadError => e
+ e
+ end
+end
+
+m.load_bundler!
+
+if m.invoked_as_script?
+ load Gem.bin_path("bundler", "bundle")
+end
diff --git a/bin/rails b/bin/rails
new file mode 100755
index 000000000..5badb2fde
--- /dev/null
+++ b/bin/rails
@@ -0,0 +1,9 @@
+#!/usr/bin/env ruby
+begin
+ load File.expand_path('../spring', __FILE__)
+rescue LoadError => e
+ raise unless e.message.include?('spring')
+end
+APP_PATH = File.expand_path('../config/application', __dir__)
+require_relative '../config/boot'
+require 'rails/commands'
diff --git a/bin/rake b/bin/rake
new file mode 100755
index 000000000..d87d5f578
--- /dev/null
+++ b/bin/rake
@@ -0,0 +1,9 @@
+#!/usr/bin/env ruby
+begin
+ load File.expand_path('../spring', __FILE__)
+rescue LoadError => e
+ raise unless e.message.include?('spring')
+end
+require_relative '../config/boot'
+require 'rake'
+Rake.application.run
diff --git a/bin/setup b/bin/setup
new file mode 100755
index 000000000..5853b5ea8
--- /dev/null
+++ b/bin/setup
@@ -0,0 +1,36 @@
+#!/usr/bin/env ruby
+require 'fileutils'
+
+# path to your application root.
+APP_ROOT = File.expand_path('..', __dir__)
+
+def system!(*args)
+ system(*args) || abort("\n== Command #{args} failed ==")
+end
+
+FileUtils.chdir APP_ROOT do
+ # This script is a way to setup or update your development environment automatically.
+ # This script is idempotent, so that you can run it at anytime and get an expectable outcome.
+ # Add necessary setup steps to this file.
+
+ puts '== Installing dependencies =='
+ system! 'gem install bundler --conservative'
+ system('bundle check') || system!('bundle install')
+
+ # Install JavaScript dependencies
+ # system('bin/yarn')
+
+ # puts "\n== Copying sample files =="
+ # unless File.exist?('config/database.yml')
+ # FileUtils.cp 'config/database.yml.sample', 'config/database.yml'
+ # end
+
+ puts "\n== Preparing database =="
+ system! 'bin/rails db:prepare'
+
+ puts "\n== Removing old logs and tempfiles =="
+ system! 'bin/rails log:clear tmp:clear'
+
+ puts "\n== Restarting application server =="
+ system! 'bin/rails restart'
+end
diff --git a/bin/spring b/bin/spring
new file mode 100755
index 000000000..d89ee495f
--- /dev/null
+++ b/bin/spring
@@ -0,0 +1,17 @@
+#!/usr/bin/env ruby
+
+# This file loads Spring without using Bundler, in order to be fast.
+# It gets overwritten when you run the `spring binstub` command.
+
+unless defined?(Spring)
+ require 'rubygems'
+ require 'bundler'
+
+ lockfile = Bundler::LockfileParser.new(Bundler.default_lockfile.read)
+ spring = lockfile.specs.detect { |spec| spec.name == 'spring' }
+ if spring
+ Gem.use_paths Gem.dir, Bundler.bundle_path.to_s, *Gem.path
+ gem 'spring', spring.version
+ require 'spring/binstub'
+ end
+end
diff --git a/bin/webpack b/bin/webpack
new file mode 100755
index 000000000..1031168d0
--- /dev/null
+++ b/bin/webpack
@@ -0,0 +1,18 @@
+#!/usr/bin/env ruby
+
+ENV["RAILS_ENV"] ||= ENV["RACK_ENV"] || "development"
+ENV["NODE_ENV"] ||= "development"
+
+require "pathname"
+ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
+ Pathname.new(__FILE__).realpath)
+
+require "bundler/setup"
+
+require "webpacker"
+require "webpacker/webpack_runner"
+
+APP_ROOT = File.expand_path("..", __dir__)
+Dir.chdir(APP_ROOT) do
+ Webpacker::WebpackRunner.run(ARGV)
+end
diff --git a/bin/webpack-dev-server b/bin/webpack-dev-server
new file mode 100755
index 000000000..dd9662737
--- /dev/null
+++ b/bin/webpack-dev-server
@@ -0,0 +1,18 @@
+#!/usr/bin/env ruby
+
+ENV["RAILS_ENV"] ||= ENV["RACK_ENV"] || "development"
+ENV["NODE_ENV"] ||= "development"
+
+require "pathname"
+ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
+ Pathname.new(__FILE__).realpath)
+
+require "bundler/setup"
+
+require "webpacker"
+require "webpacker/dev_server_runner"
+
+APP_ROOT = File.expand_path("..", __dir__)
+Dir.chdir(APP_ROOT) do
+ Webpacker::DevServerRunner.run(ARGV)
+end
diff --git a/bin/yarn b/bin/yarn
new file mode 100755
index 000000000..460dd565b
--- /dev/null
+++ b/bin/yarn
@@ -0,0 +1,11 @@
+#!/usr/bin/env ruby
+APP_ROOT = File.expand_path('..', __dir__)
+Dir.chdir(APP_ROOT) do
+ begin
+ exec "yarnpkg", *ARGV
+ rescue Errno::ENOENT
+ $stderr.puts "Yarn executable was not detected in the system."
+ $stderr.puts "Download Yarn at https://yarnpkg.com/en/docs/install"
+ exit 1
+ end
+end
diff --git a/config.ru b/config.ru
new file mode 100644
index 000000000..f7ba0b527
--- /dev/null
+++ b/config.ru
@@ -0,0 +1,5 @@
+# This file is used by Rack-based servers to start the application.
+
+require_relative 'config/environment'
+
+run Rails.application
diff --git a/config/application.rb b/config/application.rb
new file mode 100644
index 000000000..8b204cece
--- /dev/null
+++ b/config/application.rb
@@ -0,0 +1,23 @@
+require_relative 'boot'
+
+require 'rails/all'
+
+# Require the gems listed in Gemfile, including any gems
+# you've limited to :test, :development, or :production.
+Bundler.require(*Rails.groups)
+
+module TaskList
+ class Application < Rails::Application
+ config.generators do |g|
+ # Force new test files to be generated in the minitest-spec style
+ g.test_framework :minitest, spec: true
+ end
+ # Initialize configuration defaults for originally generated Rails version.
+ config.load_defaults 6.0
+
+ # Settings in config/environments/* take precedence over those specified here.
+ # Application configuration can go into files in config/initializers
+ # -- all .rb files in that directory are automatically loaded after loading
+ # the framework and any gems in your application.
+ end
+end
diff --git a/config/boot.rb b/config/boot.rb
new file mode 100644
index 000000000..b9e460cef
--- /dev/null
+++ b/config/boot.rb
@@ -0,0 +1,4 @@
+ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__)
+
+require 'bundler/setup' # Set up gems listed in the Gemfile.
+require 'bootsnap/setup' # Speed up boot time by caching expensive operations.
diff --git a/config/cable.yml b/config/cable.yml
new file mode 100644
index 000000000..0ebf2ae2e
--- /dev/null
+++ b/config/cable.yml
@@ -0,0 +1,10 @@
+development:
+ adapter: async
+
+test:
+ adapter: test
+
+production:
+ adapter: redis
+ url: <%= ENV.fetch("REDIS_URL") { "redis://localhost:6379/1" } %>
+ channel_prefix: task_list_production
diff --git a/config/credentials.yml.enc b/config/credentials.yml.enc
new file mode 100644
index 000000000..8cb54228c
--- /dev/null
+++ b/config/credentials.yml.enc
@@ -0,0 +1 @@
+F5P4FeVeiAVc4Ym2nr5hSbdLx9+rqkpeHqbCR0tn9WvHBbGRtArKeRJap3vr+O9tn1aBlMAHf5axAPFgQLYztKAV56APNKjDcPhX41/4ukguTjc9wGgzG3N4jzz4mSiz9eXAIfT5eN+qbJ7Ydv17zR7n308/FoDLtamI2H5dgI9LhzcgNv+jsdrhYS+IQHpoM3GliSYpqJPD5H/TahthkLgmgDid/RE7f+eP948cVJIsdHP2tjw3g69UEBEpa7k0qqLJaJs2thCbfFgYTd23ErnUZYaIYgVFF4OPn8wSHdZjog2TO8sj/mQ4hGaoyP2fd9O4qvKVL8/+eRerBYXVULjCLAyccMe9/QeARVO30+mRjMGfQau4997W0JDw+eBbu+eps7/Xkxro0I4qOIeghW4duFLYiaLkJol+--tDTMTY9c9V2s2Kh/--oKwYGJQYRsklq9T2R0gnuA==
\ No newline at end of file
diff --git a/config/database.yml b/config/database.yml
new file mode 100644
index 000000000..b771c8596
--- /dev/null
+++ b/config/database.yml
@@ -0,0 +1,85 @@
+# PostgreSQL. Versions 9.3 and up are supported.
+#
+# Install the pg driver:
+# gem install pg
+# On macOS with Homebrew:
+# gem install pg -- --with-pg-config=/usr/local/bin/pg_config
+# On macOS with MacPorts:
+# gem install pg -- --with-pg-config=/opt/local/lib/postgresql84/bin/pg_config
+# On Windows:
+# gem install pg
+# Choose the win32 build.
+# Install PostgreSQL and put its /bin directory on your path.
+#
+# Configure Using Gemfile
+# gem 'pg'
+#
+default: &default
+ adapter: postgresql
+ encoding: unicode
+ # For details on connection pooling, see Rails configuration guide
+ # https://guides.rubyonrails.org/configuring.html#database-pooling
+ pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
+
+development:
+ <<: *default
+ database: task_list_development
+
+ # The specified database role being used to connect to postgres.
+ # To create additional roles in postgres see `$ createuser --help`.
+ # When left blank, postgres will use the default role. This is
+ # the same name as the operating system user that initialized the database.
+ #username: task_list
+
+ # The password associated with the postgres role (username).
+ #password:
+
+ # Connect on a TCP socket. Omitted by default since the client uses a
+ # domain socket that doesn't need configuration. Windows does not have
+ # domain sockets, so uncomment these lines.
+ #host: localhost
+
+ # The TCP port the server listens on. Defaults to 5432.
+ # If your server runs on a different port number, change accordingly.
+ #port: 5432
+
+ # Schema search path. The server defaults to $user,public
+ #schema_search_path: myapp,sharedapp,public
+
+ # Minimum log levels, in increasing order:
+ # debug5, debug4, debug3, debug2, debug1,
+ # log, notice, warning, error, fatal, and panic
+ # Defaults to warning.
+ #min_messages: notice
+
+# Warning: The database defined as "test" will be erased and
+# re-generated from your development database when you run "rake".
+# Do not set this db to the same as development or production.
+test:
+ <<: *default
+ database: task_list_test
+
+# As with config/credentials.yml, you never want to store sensitive information,
+# like your database password, in your source code. If your source code is
+# ever seen by anyone, they now have access to your database.
+#
+# Instead, provide the password as a unix environment variable when you boot
+# the app. Read https://guides.rubyonrails.org/configuring.html#configuring-a-database
+# for a full rundown on how to provide these environment variables in a
+# production deployment.
+#
+# On Heroku and other platform providers, you may have a full connection URL
+# available as an environment variable. For example:
+#
+# DATABASE_URL="postgres://myuser:mypass@localhost/somedatabase"
+#
+# You can use this database configuration with:
+#
+# production:
+# url: <%= ENV['DATABASE_URL'] %>
+#
+production:
+ <<: *default
+ database: task_list_production
+ username: task_list
+ password: <%= ENV['TASK_LIST_DATABASE_PASSWORD'] %>
diff --git a/config/environment.rb b/config/environment.rb
new file mode 100644
index 000000000..426333bb4
--- /dev/null
+++ b/config/environment.rb
@@ -0,0 +1,5 @@
+# Load the Rails application.
+require_relative 'application'
+
+# Initialize the Rails application.
+Rails.application.initialize!
diff --git a/config/environments/development.rb b/config/environments/development.rb
new file mode 100644
index 000000000..66df51f6f
--- /dev/null
+++ b/config/environments/development.rb
@@ -0,0 +1,62 @@
+Rails.application.configure do
+ # Settings specified here will take precedence over those in config/application.rb.
+
+ # In the development environment your application's code is reloaded on
+ # every request. This slows down response time but is perfect for development
+ # since you don't have to restart the web server when you make code changes.
+ config.cache_classes = false
+
+ # Do not eager load code on boot.
+ config.eager_load = false
+
+ # Show full error reports.
+ config.consider_all_requests_local = true
+
+ # Enable/disable caching. By default caching is disabled.
+ # Run rails dev:cache to toggle caching.
+ if Rails.root.join('tmp', 'caching-dev.txt').exist?
+ config.action_controller.perform_caching = true
+ config.action_controller.enable_fragment_cache_logging = true
+
+ config.cache_store = :memory_store
+ config.public_file_server.headers = {
+ 'Cache-Control' => "public, max-age=#{2.days.to_i}"
+ }
+ else
+ config.action_controller.perform_caching = false
+
+ config.cache_store = :null_store
+ end
+
+ # Store uploaded files on the local file system (see config/storage.yml for options).
+ config.active_storage.service = :local
+
+ # Don't care if the mailer can't send.
+ config.action_mailer.raise_delivery_errors = false
+
+ config.action_mailer.perform_caching = false
+
+ # Print deprecation notices to the Rails logger.
+ config.active_support.deprecation = :log
+
+ # Raise an error on page load if there are pending migrations.
+ config.active_record.migration_error = :page_load
+
+ # Highlight code that triggered database queries in logs.
+ config.active_record.verbose_query_logs = true
+
+ # Debug mode disables concatenation and preprocessing of assets.
+ # This option may cause significant delays in view rendering with a large
+ # number of complex assets.
+ config.assets.debug = true
+
+ # Suppress logger output for asset requests.
+ config.assets.quiet = true
+
+ # Raises error for missing translations.
+ # config.action_view.raise_on_missing_translations = true
+
+ # Use an evented file watcher to asynchronously detect changes in source code,
+ # routes, locales, etc. This feature depends on the listen gem.
+ config.file_watcher = ActiveSupport::EventedFileUpdateChecker
+end
diff --git a/config/environments/production.rb b/config/environments/production.rb
new file mode 100644
index 000000000..23b587846
--- /dev/null
+++ b/config/environments/production.rb
@@ -0,0 +1,112 @@
+Rails.application.configure do
+ # Settings specified here will take precedence over those in config/application.rb.
+
+ # Code is not reloaded between requests.
+ config.cache_classes = true
+
+ # Eager load code on boot. This eager loads most of Rails and
+ # your application in memory, allowing both threaded web servers
+ # and those relying on copy on write to perform better.
+ # Rake tasks automatically ignore this option for performance.
+ config.eager_load = true
+
+ # Full error reports are disabled and caching is turned on.
+ config.consider_all_requests_local = false
+ config.action_controller.perform_caching = true
+
+ # Ensures that a master key has been made available in either ENV["RAILS_MASTER_KEY"]
+ # or in config/master.key. This key is used to decrypt credentials (and other encrypted files).
+ # config.require_master_key = true
+
+ # Disable serving static files from the `/public` folder by default since
+ # Apache or NGINX already handles this.
+ config.public_file_server.enabled = ENV['RAILS_SERVE_STATIC_FILES'].present?
+
+ # Compress CSS using a preprocessor.
+ # config.assets.css_compressor = :sass
+
+ # Do not fallback to assets pipeline if a precompiled asset is missed.
+ config.assets.compile = false
+
+ # Enable serving of images, stylesheets, and JavaScripts from an asset server.
+ # config.action_controller.asset_host = 'http://assets.example.com'
+
+ # Specifies the header that your server uses for sending files.
+ # config.action_dispatch.x_sendfile_header = 'X-Sendfile' # for Apache
+ # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for NGINX
+
+ # Store uploaded files on the local file system (see config/storage.yml for options).
+ config.active_storage.service = :local
+
+ # Mount Action Cable outside main process or domain.
+ # config.action_cable.mount_path = nil
+ # config.action_cable.url = 'wss://example.com/cable'
+ # config.action_cable.allowed_request_origins = [ 'http://example.com', /http:\/\/example.*/ ]
+
+ # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies.
+ # config.force_ssl = true
+
+ # Use the lowest log level to ensure availability of diagnostic information
+ # when problems arise.
+ config.log_level = :debug
+
+ # Prepend all log lines with the following tags.
+ config.log_tags = [ :request_id ]
+
+ # Use a different cache store in production.
+ # config.cache_store = :mem_cache_store
+
+ # Use a real queuing backend for Active Job (and separate queues per environment).
+ # config.active_job.queue_adapter = :resque
+ # config.active_job.queue_name_prefix = "task_list_production"
+
+ config.action_mailer.perform_caching = false
+
+ # Ignore bad email addresses and do not raise email delivery errors.
+ # Set this to true and configure the email server for immediate delivery to raise delivery errors.
+ # config.action_mailer.raise_delivery_errors = false
+
+ # Enable locale fallbacks for I18n (makes lookups for any locale fall back to
+ # the I18n.default_locale when a translation cannot be found).
+ config.i18n.fallbacks = true
+
+ # Send deprecation notices to registered listeners.
+ config.active_support.deprecation = :notify
+
+ # Use default logging formatter so that PID and timestamp are not suppressed.
+ config.log_formatter = ::Logger::Formatter.new
+
+ # Use a different logger for distributed setups.
+ # require 'syslog/logger'
+ # config.logger = ActiveSupport::TaggedLogging.new(Syslog::Logger.new 'app-name')
+
+ if ENV["RAILS_LOG_TO_STDOUT"].present?
+ logger = ActiveSupport::Logger.new(STDOUT)
+ logger.formatter = config.log_formatter
+ config.logger = ActiveSupport::TaggedLogging.new(logger)
+ end
+
+ # Do not dump schema after migrations.
+ config.active_record.dump_schema_after_migration = false
+
+ # Inserts middleware to perform automatic connection switching.
+ # The `database_selector` hash is used to pass options to the DatabaseSelector
+ # middleware. The `delay` is used to determine how long to wait after a write
+ # to send a subsequent read to the primary.
+ #
+ # The `database_resolver` class is used by the middleware to determine which
+ # database is appropriate to use based on the time delay.
+ #
+ # The `database_resolver_context` class is used by the middleware to set
+ # timestamps for the last write to the primary. The resolver uses the context
+ # class timestamps to determine how long to wait before reading from the
+ # replica.
+ #
+ # By default Rails will store a last write timestamp in the session. The
+ # DatabaseSelector middleware is designed as such you can define your own
+ # strategy for connection switching and pass that into the middleware through
+ # these configuration options.
+ # config.active_record.database_selector = { delay: 2.seconds }
+ # config.active_record.database_resolver = ActiveRecord::Middleware::DatabaseSelector::Resolver
+ # config.active_record.database_resolver_context = ActiveRecord::Middleware::DatabaseSelector::Resolver::Session
+end
diff --git a/config/environments/test.rb b/config/environments/test.rb
new file mode 100644
index 000000000..1d62e91b3
--- /dev/null
+++ b/config/environments/test.rb
@@ -0,0 +1,48 @@
+# The test environment is used exclusively to run your application's
+# test suite. You never need to work with it otherwise. Remember that
+# your test database is "scratch space" for the test suite and is wiped
+# and recreated between test runs. Don't rely on the data there!
+
+Rails.application.configure do
+ # Settings specified here will take precedence over those in config/application.rb.
+
+ config.cache_classes = false
+
+ # Do not eager load code on boot. This avoids loading your whole application
+ # just for the purpose of running a single test. If you are using a tool that
+ # preloads Rails for running tests, you may have to set it to true.
+ config.eager_load = false
+
+ # Configure public file server for tests with Cache-Control for performance.
+ config.public_file_server.enabled = true
+ config.public_file_server.headers = {
+ 'Cache-Control' => "public, max-age=#{1.hour.to_i}"
+ }
+
+ # Show full error reports and disable caching.
+ config.consider_all_requests_local = true
+ config.action_controller.perform_caching = false
+ config.cache_store = :null_store
+
+ # Raise exceptions instead of rendering exception templates.
+ config.action_dispatch.show_exceptions = false
+
+ # Disable request forgery protection in test environment.
+ config.action_controller.allow_forgery_protection = false
+
+ # Store uploaded files on the local file system in a temporary directory.
+ config.active_storage.service = :test
+
+ config.action_mailer.perform_caching = false
+
+ # Tell Action Mailer not to deliver emails to the real world.
+ # The :test delivery method accumulates sent emails in the
+ # ActionMailer::Base.deliveries array.
+ config.action_mailer.delivery_method = :test
+
+ # Print deprecation notices to the stderr.
+ config.active_support.deprecation = :stderr
+
+ # Raises error for missing translations.
+ # config.action_view.raise_on_missing_translations = true
+end
diff --git a/config/initializers/action_view.rb b/config/initializers/action_view.rb
new file mode 100644
index 000000000..142d382f8
--- /dev/null
+++ b/config/initializers/action_view.rb
@@ -0,0 +1 @@
+Rails.application.config.action_view.form_with_generates_remote_forms = false
diff --git a/config/initializers/application_controller_renderer.rb b/config/initializers/application_controller_renderer.rb
new file mode 100644
index 000000000..89d2efab2
--- /dev/null
+++ b/config/initializers/application_controller_renderer.rb
@@ -0,0 +1,8 @@
+# Be sure to restart your server when you modify this file.
+
+# ActiveSupport::Reloader.to_prepare do
+# ApplicationController.renderer.defaults.merge!(
+# http_host: 'example.org',
+# https: false
+# )
+# end
diff --git a/config/initializers/assets.rb b/config/initializers/assets.rb
new file mode 100644
index 000000000..4b828e80c
--- /dev/null
+++ b/config/initializers/assets.rb
@@ -0,0 +1,14 @@
+# Be sure to restart your server when you modify this file.
+
+# Version of your assets, change this if you want to expire all your assets.
+Rails.application.config.assets.version = '1.0'
+
+# Add additional assets to the asset load path.
+# Rails.application.config.assets.paths << Emoji.images_path
+# Add Yarn node_modules folder to the asset load path.
+Rails.application.config.assets.paths << Rails.root.join('node_modules')
+
+# Precompile additional assets.
+# application.js, application.css, and all non-JS/CSS in the app/assets
+# folder are already added.
+# Rails.application.config.assets.precompile += %w( admin.js admin.css )
diff --git a/config/initializers/backtrace_silencers.rb b/config/initializers/backtrace_silencers.rb
new file mode 100644
index 000000000..59385cdf3
--- /dev/null
+++ b/config/initializers/backtrace_silencers.rb
@@ -0,0 +1,7 @@
+# Be sure to restart your server when you modify this file.
+
+# You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces.
+# Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ }
+
+# You can also remove all the silencers if you're trying to debug a problem that might stem from framework code.
+# Rails.backtrace_cleaner.remove_silencers!
diff --git a/config/initializers/content_security_policy.rb b/config/initializers/content_security_policy.rb
new file mode 100644
index 000000000..35d0f26fc
--- /dev/null
+++ b/config/initializers/content_security_policy.rb
@@ -0,0 +1,30 @@
+# Be sure to restart your server when you modify this file.
+
+# Define an application-wide content security policy
+# For further information see the following documentation
+# https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy
+
+# Rails.application.config.content_security_policy do |policy|
+# policy.default_src :self, :https
+# policy.font_src :self, :https, :data
+# policy.img_src :self, :https, :data
+# policy.object_src :none
+# policy.script_src :self, :https
+# policy.style_src :self, :https
+# # If you are using webpack-dev-server then specify webpack-dev-server host
+# policy.connect_src :self, :https, "http://localhost:3035", "ws://localhost:3035" if Rails.env.development?
+
+# # Specify URI for violation reports
+# # policy.report_uri "/csp-violation-report-endpoint"
+# end
+
+# If you are using UJS then enable automatic nonce generation
+# Rails.application.config.content_security_policy_nonce_generator = -> request { SecureRandom.base64(16) }
+
+# Set the nonce only to specific directives
+# Rails.application.config.content_security_policy_nonce_directives = %w(script-src)
+
+# Report CSP violations to a specified URI
+# For further information see the following documentation:
+# https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy-Report-Only
+# Rails.application.config.content_security_policy_report_only = true
diff --git a/config/initializers/cookies_serializer.rb b/config/initializers/cookies_serializer.rb
new file mode 100644
index 000000000..5a6a32d37
--- /dev/null
+++ b/config/initializers/cookies_serializer.rb
@@ -0,0 +1,5 @@
+# Be sure to restart your server when you modify this file.
+
+# Specify a serializer for the signed and encrypted cookie jars.
+# Valid options are :json, :marshal, and :hybrid.
+Rails.application.config.action_dispatch.cookies_serializer = :json
diff --git a/config/initializers/filter_parameter_logging.rb b/config/initializers/filter_parameter_logging.rb
new file mode 100644
index 000000000..4a994e1e7
--- /dev/null
+++ b/config/initializers/filter_parameter_logging.rb
@@ -0,0 +1,4 @@
+# Be sure to restart your server when you modify this file.
+
+# Configure sensitive parameters which will be filtered from the log file.
+Rails.application.config.filter_parameters += [:password]
diff --git a/config/initializers/inflections.rb b/config/initializers/inflections.rb
new file mode 100644
index 000000000..ac033bf9d
--- /dev/null
+++ b/config/initializers/inflections.rb
@@ -0,0 +1,16 @@
+# Be sure to restart your server when you modify this file.
+
+# Add new inflection rules using the following format. Inflections
+# are locale specific, and you may define rules for as many different
+# locales as you wish. All of these examples are active by default:
+# ActiveSupport::Inflector.inflections(:en) do |inflect|
+# inflect.plural /^(ox)$/i, '\1en'
+# inflect.singular /^(ox)en/i, '\1'
+# inflect.irregular 'person', 'people'
+# inflect.uncountable %w( fish sheep )
+# end
+
+# These inflection rules are supported but not enabled by default:
+# ActiveSupport::Inflector.inflections(:en) do |inflect|
+# inflect.acronym 'RESTful'
+# end
diff --git a/config/initializers/mime_types.rb b/config/initializers/mime_types.rb
new file mode 100644
index 000000000..dc1899682
--- /dev/null
+++ b/config/initializers/mime_types.rb
@@ -0,0 +1,4 @@
+# Be sure to restart your server when you modify this file.
+
+# Add new mime types for use in respond_to blocks:
+# Mime::Type.register "text/richtext", :rtf
diff --git a/config/initializers/wrap_parameters.rb b/config/initializers/wrap_parameters.rb
new file mode 100644
index 000000000..bbfc3961b
--- /dev/null
+++ b/config/initializers/wrap_parameters.rb
@@ -0,0 +1,14 @@
+# Be sure to restart your server when you modify this file.
+
+# This file contains settings for ActionController::ParamsWrapper which
+# is enabled by default.
+
+# Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array.
+ActiveSupport.on_load(:action_controller) do
+ wrap_parameters format: [:json]
+end
+
+# To enable root element in JSON for ActiveRecord objects.
+# ActiveSupport.on_load(:active_record) do
+# self.include_root_in_json = true
+# end
diff --git a/config/locales/en.yml b/config/locales/en.yml
new file mode 100644
index 000000000..cf9b342d0
--- /dev/null
+++ b/config/locales/en.yml
@@ -0,0 +1,33 @@
+# Files in the config/locales directory are used for internationalization
+# and are automatically loaded by Rails. If you want to use locales other
+# than English, add the necessary files in this directory.
+#
+# To use the locales, use `I18n.t`:
+#
+# I18n.t 'hello'
+#
+# In views, this is aliased to just `t`:
+#
+# <%= t('hello') %>
+#
+# To use a different locale, set it with `I18n.locale`:
+#
+# I18n.locale = :es
+#
+# This would use the information in config/locales/es.yml.
+#
+# The following keys must be escaped otherwise they will not be retrieved by
+# the default I18n backend:
+#
+# true, false, on, off, yes, no
+#
+# Instead, surround them with single quotes.
+#
+# en:
+# 'true': 'foo'
+#
+# To learn more, please read the Rails Internationalization guide
+# available at https://guides.rubyonrails.org/i18n.html.
+
+en:
+ hello: "Hello world"
diff --git a/config/master.key b/config/master.key
new file mode 100644
index 000000000..8bcd2a138
--- /dev/null
+++ b/config/master.key
@@ -0,0 +1 @@
+a2bdde3696acecbbec7c0da5fe12c0d9
\ No newline at end of file
diff --git a/config/puma.rb b/config/puma.rb
new file mode 100644
index 000000000..5ed443774
--- /dev/null
+++ b/config/puma.rb
@@ -0,0 +1,38 @@
+# Puma can serve each request in a thread from an internal thread pool.
+# The `threads` method setting takes two numbers: a minimum and maximum.
+# Any libraries that use thread pools should be configured to match
+# the maximum value specified for Puma. Default is set to 5 threads for minimum
+# and maximum; this matches the default thread size of Active Record.
+#
+max_threads_count = ENV.fetch("RAILS_MAX_THREADS") { 5 }
+min_threads_count = ENV.fetch("RAILS_MIN_THREADS") { max_threads_count }
+threads min_threads_count, max_threads_count
+
+# Specifies the `port` that Puma will listen on to receive requests; default is 3000.
+#
+port ENV.fetch("PORT") { 3000 }
+
+# Specifies the `environment` that Puma will run in.
+#
+environment ENV.fetch("RAILS_ENV") { "development" }
+
+# Specifies the `pidfile` that Puma will use.
+pidfile ENV.fetch("PIDFILE") { "tmp/pids/server.pid" }
+
+# Specifies the number of `workers` to boot in clustered mode.
+# Workers are forked web server processes. If using threads and workers together
+# the concurrency of the application would be max `threads` * `workers`.
+# Workers do not work on JRuby or Windows (both of which do not support
+# processes).
+#
+# workers ENV.fetch("WEB_CONCURRENCY") { 2 }
+
+# Use the `preload_app!` method when specifying a `workers` number.
+# This directive tells Puma to first boot the application and load code
+# before forking the application. This takes advantage of Copy On Write
+# process behavior so workers use less memory.
+#
+# preload_app!
+
+# Allow puma to be restarted by `rails restart` command.
+plugin :tmp_restart
diff --git a/config/routes.rb b/config/routes.rb
new file mode 100644
index 000000000..0a911c3a8
--- /dev/null
+++ b/config/routes.rb
@@ -0,0 +1,24 @@
+Rails.application.routes.draw do
+ # For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html
+
+
+ root to: 'tasks#index'
+
+ resources :tasks
+ #get '/tasks', to: 'tasks#index'
+
+ #get '/tasks/new', to: 'tasks#new', as: 'new_task'
+
+ #post '/tasks', to: 'tasks#create'
+
+ #get '/tasks/:id', to: 'tasks#show', as: 'task'
+
+ #get '/tasks/:id/edit', to: 'tasks#edit', as: 'edit_task'
+
+ #patch '/tasks/:id', to: 'tasks#update'
+
+ patch 'tasks/:id/complete', to: 'tasks#mark_complete', as: 'mark_complete'
+
+
+ #delete '/tasks/:id', to: 'tasks#destroy'
+end
diff --git a/config/spring.rb b/config/spring.rb
new file mode 100644
index 000000000..db5bf1307
--- /dev/null
+++ b/config/spring.rb
@@ -0,0 +1,6 @@
+Spring.watch(
+ ".ruby-version",
+ ".rbenv-vars",
+ "tmp/restart.txt",
+ "tmp/caching-dev.txt"
+)
diff --git a/config/storage.yml b/config/storage.yml
new file mode 100644
index 000000000..d32f76e8f
--- /dev/null
+++ b/config/storage.yml
@@ -0,0 +1,34 @@
+test:
+ service: Disk
+ root: <%= Rails.root.join("tmp/storage") %>
+
+local:
+ service: Disk
+ root: <%= Rails.root.join("storage") %>
+
+# Use rails credentials:edit to set the AWS secrets (as aws:access_key_id|secret_access_key)
+# amazon:
+# service: S3
+# access_key_id: <%= Rails.application.credentials.dig(:aws, :access_key_id) %>
+# secret_access_key: <%= Rails.application.credentials.dig(:aws, :secret_access_key) %>
+# region: us-east-1
+# bucket: your_own_bucket
+
+# Remember not to checkin your GCS keyfile to a repository
+# google:
+# service: GCS
+# project: your_project
+# credentials: <%= Rails.root.join("path/to/gcs.keyfile") %>
+# bucket: your_own_bucket
+
+# Use rails credentials:edit to set the Azure Storage secret (as azure_storage:storage_access_key)
+# microsoft:
+# service: AzureStorage
+# storage_account_name: your_account_name
+# storage_access_key: <%= Rails.application.credentials.dig(:azure_storage, :storage_access_key) %>
+# container: your_container_name
+
+# mirror:
+# service: Mirror
+# primary: local
+# mirrors: [ amazon, google, microsoft ]
diff --git a/config/webpack/development.js b/config/webpack/development.js
new file mode 100644
index 000000000..c5edff94a
--- /dev/null
+++ b/config/webpack/development.js
@@ -0,0 +1,5 @@
+process.env.NODE_ENV = process.env.NODE_ENV || 'development'
+
+const environment = require('./environment')
+
+module.exports = environment.toWebpackConfig()
diff --git a/config/webpack/environment.js b/config/webpack/environment.js
new file mode 100644
index 000000000..1a4f73eec
--- /dev/null
+++ b/config/webpack/environment.js
@@ -0,0 +1,13 @@
+const { environment } = require('@rails/webpacker')
+
+module.exports = environment
+
+const webpack = require('webpack')
+environment.plugins.append(
+ 'Provide',
+ new webpack.ProvidePlugin({
+ $: 'jquery',
+ jQuery: 'jquery',
+ Popper: ['popper.js', 'default']
+ })
+)
diff --git a/config/webpack/production.js b/config/webpack/production.js
new file mode 100644
index 000000000..be0f53aac
--- /dev/null
+++ b/config/webpack/production.js
@@ -0,0 +1,5 @@
+process.env.NODE_ENV = process.env.NODE_ENV || 'production'
+
+const environment = require('./environment')
+
+module.exports = environment.toWebpackConfig()
diff --git a/config/webpack/test.js b/config/webpack/test.js
new file mode 100644
index 000000000..c5edff94a
--- /dev/null
+++ b/config/webpack/test.js
@@ -0,0 +1,5 @@
+process.env.NODE_ENV = process.env.NODE_ENV || 'development'
+
+const environment = require('./environment')
+
+module.exports = environment.toWebpackConfig()
diff --git a/config/webpacker.yml b/config/webpacker.yml
new file mode 100644
index 000000000..8581ac047
--- /dev/null
+++ b/config/webpacker.yml
@@ -0,0 +1,96 @@
+# Note: You must restart bin/webpack-dev-server for changes to take effect
+
+default: &default
+ source_path: app/javascript
+ source_entry_path: packs
+ public_root_path: public
+ public_output_path: packs
+ cache_path: tmp/cache/webpacker
+ check_yarn_integrity: false
+ webpack_compile_output: true
+
+ # Additional paths webpack should lookup modules
+ # ['app/assets', 'engine/foo/app/assets']
+ resolved_paths: []
+
+ # Reload manifest.json on all requests so we reload latest compiled packs
+ cache_manifest: false
+
+ # Extract and emit a css file
+ extract_css: false
+
+ static_assets_extensions:
+ - .jpg
+ - .jpeg
+ - .png
+ - .gif
+ - .tiff
+ - .ico
+ - .svg
+ - .eot
+ - .otf
+ - .ttf
+ - .woff
+ - .woff2
+
+ extensions:
+ - .mjs
+ - .js
+ - .sass
+ - .scss
+ - .css
+ - .module.sass
+ - .module.scss
+ - .module.css
+ - .png
+ - .svg
+ - .gif
+ - .jpeg
+ - .jpg
+
+development:
+ <<: *default
+ compile: true
+
+ # Verifies that correct packages and versions are installed by inspecting package.json, yarn.lock, and node_modules
+ check_yarn_integrity: true
+
+ # Reference: https://webpack.js.org/configuration/dev-server/
+ dev_server:
+ https: false
+ host: localhost
+ port: 3035
+ public: localhost:3035
+ hmr: false
+ # Inline should be set to true if using HMR
+ inline: true
+ overlay: true
+ compress: true
+ disable_host_check: true
+ use_local_ip: false
+ quiet: false
+ pretty: false
+ headers:
+ 'Access-Control-Allow-Origin': '*'
+ watch_options:
+ ignored: '**/node_modules/**'
+
+
+test:
+ <<: *default
+ compile: true
+
+ # Compile test packs to a separate directory
+ public_output_path: packs-test
+
+production:
+ <<: *default
+
+ # Production depends on precompilation of packs prior to booting for performance.
+ compile: false
+
+ # Extract and emit a css file
+ extract_css: true
+
+ # Cache manifest.json for performance
+ cache_manifest: true
diff --git a/db/migrate/20200429234130_create_tasks.rb b/db/migrate/20200429234130_create_tasks.rb
new file mode 100644
index 000000000..2b277b0e9
--- /dev/null
+++ b/db/migrate/20200429234130_create_tasks.rb
@@ -0,0 +1,11 @@
+class CreateTasks < ActiveRecord::Migration[6.0]
+ def change
+ create_table :tasks do |t|
+ t.string :name
+ t.string :description
+ t.string :completed_at
+
+ t.timestamps
+ end
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
new file mode 100644
index 000000000..dfaad08d9
--- /dev/null
+++ b/db/schema.rb
@@ -0,0 +1,26 @@
+# This file is auto-generated from the current state of the database. Instead
+# of editing this file, please use the migrations feature of Active Record to
+# incrementally modify your database, and then regenerate this schema definition.
+#
+# This file is the source Rails uses to define your schema when running `rails
+# db:schema:load`. When creating a new database, `rails db:schema:load` tends to
+# be faster and is potentially less error prone than running all of your
+# migrations from scratch. Old migrations may fail to apply correctly if those
+# migrations use external dependencies or application code.
+#
+# It's strongly recommended that you check this file into your version control system.
+
+ActiveRecord::Schema.define(version: 2020_04_29_234130) do
+
+ # These are extensions that must be enabled in order to support this database
+ enable_extension "plpgsql"
+
+ create_table "tasks", force: :cascade do |t|
+ t.string "name"
+ t.string "description"
+ t.string "completed_at"
+ t.datetime "created_at", precision: 6, null: false
+ t.datetime "updated_at", precision: 6, null: false
+ end
+
+end
diff --git a/db/seeds.rb b/db/seeds.rb
new file mode 100644
index 000000000..1beea2acc
--- /dev/null
+++ b/db/seeds.rb
@@ -0,0 +1,7 @@
+# This file should contain all the record creation needed to seed the database with its default values.
+# The data can then be loaded with the rails db:seed command (or created alongside the database with db:setup).
+#
+# Examples:
+#
+# movies = Movie.create([{ name: 'Star Wars' }, { name: 'Lord of the Rings' }])
+# Character.create(name: 'Luke', movie: movies.first)
diff --git a/lib/assets/.keep b/lib/assets/.keep
new file mode 100644
index 000000000..e69de29bb
diff --git a/lib/tasks/.keep b/lib/tasks/.keep
new file mode 100644
index 000000000..e69de29bb
diff --git a/log/.keep b/log/.keep
new file mode 100644
index 000000000..e69de29bb
diff --git a/package.json b/package.json
new file mode 100644
index 000000000..2b1dde130
--- /dev/null
+++ b/package.json
@@ -0,0 +1,18 @@
+{
+ "name": "task_list",
+ "private": true,
+ "dependencies": {
+ "@rails/actioncable": "^6.0.0",
+ "@rails/activestorage": "^6.0.0",
+ "@rails/ujs": "^6.0.0",
+ "@rails/webpacker": "4.2.2",
+ "bootstrap": "^4.4.1",
+ "jquery": "^3.5.0",
+ "popper.js": "^1.16.1",
+ "turbolinks": "^5.2.0"
+ },
+ "version": "0.1.0",
+ "devDependencies": {
+ "webpack-dev-server": "^3.10.3"
+ }
+}
diff --git a/postcss.config.js b/postcss.config.js
new file mode 100644
index 000000000..aa5998a80
--- /dev/null
+++ b/postcss.config.js
@@ -0,0 +1,12 @@
+module.exports = {
+ plugins: [
+ require('postcss-import'),
+ require('postcss-flexbugs-fixes'),
+ require('postcss-preset-env')({
+ autoprefixer: {
+ flexbox: 'no-2009'
+ },
+ stage: 3
+ })
+ ]
+}
diff --git a/public/404.html b/public/404.html
new file mode 100644
index 000000000..2be3af26f
--- /dev/null
+++ b/public/404.html
@@ -0,0 +1,67 @@
+
+
+
+ The page you were looking for doesn't exist (404)
+
+
+
+
+
+
+
+
+
The page you were looking for doesn't exist.
+
You may have mistyped the address or the page may have moved.
+
+
If you are the application owner check the logs for more information.
+
+
+
diff --git a/public/422.html b/public/422.html
new file mode 100644
index 000000000..c08eac0d1
--- /dev/null
+++ b/public/422.html
@@ -0,0 +1,67 @@
+
+
+
+ The change you wanted was rejected (422)
+
+
+
+
+
+
+
+
+
The change you wanted was rejected.
+
Maybe you tried to change something you didn't have access to.
+
+
If you are the application owner check the logs for more information.
+
+
+
diff --git a/public/500.html b/public/500.html
new file mode 100644
index 000000000..78a030af2
--- /dev/null
+++ b/public/500.html
@@ -0,0 +1,66 @@
+
+
+
+ We're sorry, but something went wrong (500)
+
+
+
+
+
+
+
+
+
We're sorry, but something went wrong.
+
+
If you are the application owner check the logs for more information.
+
+
+
diff --git a/public/apple-touch-icon-precomposed.png b/public/apple-touch-icon-precomposed.png
new file mode 100644
index 000000000..e69de29bb
diff --git a/public/apple-touch-icon.png b/public/apple-touch-icon.png
new file mode 100644
index 000000000..e69de29bb
diff --git a/public/favicon.ico b/public/favicon.ico
new file mode 100644
index 000000000..e69de29bb
diff --git a/public/packs-test/js/application-42f0493b7deee40ed4b3.js b/public/packs-test/js/application-42f0493b7deee40ed4b3.js
new file mode 100644
index 000000000..d926f13f2
--- /dev/null
+++ b/public/packs-test/js/application-42f0493b7deee40ed4b3.js
@@ -0,0 +1,19890 @@
+/******/ (function(modules) { // webpackBootstrap
+/******/ // The module cache
+/******/ var installedModules = {};
+/******/
+/******/ // The require function
+/******/ function __webpack_require__(moduleId) {
+/******/
+/******/ // Check if module is in cache
+/******/ if(installedModules[moduleId]) {
+/******/ return installedModules[moduleId].exports;
+/******/ }
+/******/ // Create a new module (and put it into the cache)
+/******/ var module = installedModules[moduleId] = {
+/******/ i: moduleId,
+/******/ l: false,
+/******/ exports: {}
+/******/ };
+/******/
+/******/ // Execute the module function
+/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
+/******/
+/******/ // Flag the module as loaded
+/******/ module.l = true;
+/******/
+/******/ // Return the exports of the module
+/******/ return module.exports;
+/******/ }
+/******/
+/******/
+/******/ // expose the modules object (__webpack_modules__)
+/******/ __webpack_require__.m = modules;
+/******/
+/******/ // expose the module cache
+/******/ __webpack_require__.c = installedModules;
+/******/
+/******/ // define getter function for harmony exports
+/******/ __webpack_require__.d = function(exports, name, getter) {
+/******/ if(!__webpack_require__.o(exports, name)) {
+/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter });
+/******/ }
+/******/ };
+/******/
+/******/ // define __esModule on exports
+/******/ __webpack_require__.r = function(exports) {
+/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
+/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
+/******/ }
+/******/ Object.defineProperty(exports, '__esModule', { value: true });
+/******/ };
+/******/
+/******/ // create a fake namespace object
+/******/ // mode & 1: value is a module id, require it
+/******/ // mode & 2: merge all properties of value into the ns
+/******/ // mode & 4: return value when already ns object
+/******/ // mode & 8|1: behave like require
+/******/ __webpack_require__.t = function(value, mode) {
+/******/ if(mode & 1) value = __webpack_require__(value);
+/******/ if(mode & 8) return value;
+/******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
+/******/ var ns = Object.create(null);
+/******/ __webpack_require__.r(ns);
+/******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value });
+/******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
+/******/ return ns;
+/******/ };
+/******/
+/******/ // getDefaultExport function for compatibility with non-harmony modules
+/******/ __webpack_require__.n = function(module) {
+/******/ var getter = module && module.__esModule ?
+/******/ function getDefault() { return module['default']; } :
+/******/ function getModuleExports() { return module; };
+/******/ __webpack_require__.d(getter, 'a', getter);
+/******/ return getter;
+/******/ };
+/******/
+/******/ // Object.prototype.hasOwnProperty.call
+/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
+/******/
+/******/ // __webpack_public_path__
+/******/ __webpack_require__.p = "/packs-test/";
+/******/
+/******/
+/******/ // Load entry module and return exports
+/******/ return __webpack_require__(__webpack_require__.s = "./app/javascript/packs/application.js");
+/******/ })
+/************************************************************************/
+/******/ ({
+
+/***/ "./app/javascript/channels sync recursive _channel\\.js$":
+/*!****************************************************!*\
+ !*** ./app/javascript/channels sync _channel\.js$ ***!
+ \****************************************************/
+/*! no static exports found */
+/***/ (function(module, exports) {
+
+function webpackEmptyContext(req) {
+ var e = new Error("Cannot find module '" + req + "'");
+ e.code = 'MODULE_NOT_FOUND';
+ throw e;
+}
+webpackEmptyContext.keys = function() { return []; };
+webpackEmptyContext.resolve = webpackEmptyContext;
+module.exports = webpackEmptyContext;
+webpackEmptyContext.id = "./app/javascript/channels sync recursive _channel\\.js$";
+
+/***/ }),
+
+/***/ "./app/javascript/channels/index.js":
+/*!******************************************!*\
+ !*** ./app/javascript/channels/index.js ***!
+ \******************************************/
+/*! no static exports found */
+/***/ (function(module, exports, __webpack_require__) {
+
+// Load all the channels within this directory and all subdirectories.
+// Channel files must be named *_channel.js.
+var channels = __webpack_require__("./app/javascript/channels sync recursive _channel\\.js$");
+
+channels.keys().forEach(channels);
+
+/***/ }),
+
+/***/ "./app/javascript/packs/application.js":
+/*!*********************************************!*\
+ !*** ./app/javascript/packs/application.js ***!
+ \*********************************************/
+/*! no exports provided */
+/***/ (function(module, __webpack_exports__, __webpack_require__) {
+
+"use strict";
+__webpack_require__.r(__webpack_exports__);
+/* harmony import */ var bootstrap__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! bootstrap */ "./node_modules/bootstrap/dist/js/bootstrap.js");
+/* harmony import */ var bootstrap__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(bootstrap__WEBPACK_IMPORTED_MODULE_0__);
+// This file is automatically compiled by Webpack, along with any other files
+// present in this directory. You're encouraged to place your actual application logic in
+// a relevant structure within app/javascript and only use these pack files to reference
+// that code so it'll be compiled.
+__webpack_require__(/*! @rails/ujs */ "./node_modules/@rails/ujs/lib/assets/compiled/rails-ujs.js").start();
+
+__webpack_require__(/*! turbolinks */ "./node_modules/turbolinks/dist/turbolinks.js").start();
+
+__webpack_require__(/*! @rails/activestorage */ "./node_modules/@rails/activestorage/app/assets/javascripts/activestorage.js").start();
+
+__webpack_require__(/*! channels */ "./app/javascript/channels/index.js");
+
+ // Uncomment to copy all static images under ../images to the output folder and reference
+// them with the image_pack_tag helper in views (e.g <%= image_pack_tag 'rails.png' %>)
+// or the `imagePath` JavaScript helper below.
+//
+// const images = require.context('../images', true)
+// const imagePath = (name) => images(name, true)
+
+/***/ }),
+
+/***/ "./node_modules/@rails/activestorage/app/assets/javascripts/activestorage.js":
+/*!***********************************************************************************!*\
+ !*** ./node_modules/@rails/activestorage/app/assets/javascripts/activestorage.js ***!
+ \***********************************************************************************/
+/*! no static exports found */
+/***/ (function(module, exports, __webpack_require__) {
+
+var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
+
+(function (global, factory) {
+ ( false ? undefined : _typeof(exports)) === "object" && typeof module !== "undefined" ? factory(exports) : true ? !(__WEBPACK_AMD_DEFINE_ARRAY__ = [exports], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory),
+ __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ?
+ (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__),
+ __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)) : undefined;
+})(this, function (exports) {
+ "use strict";
+
+ function createCommonjsModule(fn, module) {
+ return module = {
+ exports: {}
+ }, fn(module, module.exports), module.exports;
+ }
+
+ var sparkMd5 = createCommonjsModule(function (module, exports) {
+ (function (factory) {
+ {
+ module.exports = factory();
+ }
+ })(function (undefined) {
+ var hex_chr = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"];
+
+ function md5cycle(x, k) {
+ var a = x[0],
+ b = x[1],
+ c = x[2],
+ d = x[3];
+ a += (b & c | ~b & d) + k[0] - 680876936 | 0;
+ a = (a << 7 | a >>> 25) + b | 0;
+ d += (a & b | ~a & c) + k[1] - 389564586 | 0;
+ d = (d << 12 | d >>> 20) + a | 0;
+ c += (d & a | ~d & b) + k[2] + 606105819 | 0;
+ c = (c << 17 | c >>> 15) + d | 0;
+ b += (c & d | ~c & a) + k[3] - 1044525330 | 0;
+ b = (b << 22 | b >>> 10) + c | 0;
+ a += (b & c | ~b & d) + k[4] - 176418897 | 0;
+ a = (a << 7 | a >>> 25) + b | 0;
+ d += (a & b | ~a & c) + k[5] + 1200080426 | 0;
+ d = (d << 12 | d >>> 20) + a | 0;
+ c += (d & a | ~d & b) + k[6] - 1473231341 | 0;
+ c = (c << 17 | c >>> 15) + d | 0;
+ b += (c & d | ~c & a) + k[7] - 45705983 | 0;
+ b = (b << 22 | b >>> 10) + c | 0;
+ a += (b & c | ~b & d) + k[8] + 1770035416 | 0;
+ a = (a << 7 | a >>> 25) + b | 0;
+ d += (a & b | ~a & c) + k[9] - 1958414417 | 0;
+ d = (d << 12 | d >>> 20) + a | 0;
+ c += (d & a | ~d & b) + k[10] - 42063 | 0;
+ c = (c << 17 | c >>> 15) + d | 0;
+ b += (c & d | ~c & a) + k[11] - 1990404162 | 0;
+ b = (b << 22 | b >>> 10) + c | 0;
+ a += (b & c | ~b & d) + k[12] + 1804603682 | 0;
+ a = (a << 7 | a >>> 25) + b | 0;
+ d += (a & b | ~a & c) + k[13] - 40341101 | 0;
+ d = (d << 12 | d >>> 20) + a | 0;
+ c += (d & a | ~d & b) + k[14] - 1502002290 | 0;
+ c = (c << 17 | c >>> 15) + d | 0;
+ b += (c & d | ~c & a) + k[15] + 1236535329 | 0;
+ b = (b << 22 | b >>> 10) + c | 0;
+ a += (b & d | c & ~d) + k[1] - 165796510 | 0;
+ a = (a << 5 | a >>> 27) + b | 0;
+ d += (a & c | b & ~c) + k[6] - 1069501632 | 0;
+ d = (d << 9 | d >>> 23) + a | 0;
+ c += (d & b | a & ~b) + k[11] + 643717713 | 0;
+ c = (c << 14 | c >>> 18) + d | 0;
+ b += (c & a | d & ~a) + k[0] - 373897302 | 0;
+ b = (b << 20 | b >>> 12) + c | 0;
+ a += (b & d | c & ~d) + k[5] - 701558691 | 0;
+ a = (a << 5 | a >>> 27) + b | 0;
+ d += (a & c | b & ~c) + k[10] + 38016083 | 0;
+ d = (d << 9 | d >>> 23) + a | 0;
+ c += (d & b | a & ~b) + k[15] - 660478335 | 0;
+ c = (c << 14 | c >>> 18) + d | 0;
+ b += (c & a | d & ~a) + k[4] - 405537848 | 0;
+ b = (b << 20 | b >>> 12) + c | 0;
+ a += (b & d | c & ~d) + k[9] + 568446438 | 0;
+ a = (a << 5 | a >>> 27) + b | 0;
+ d += (a & c | b & ~c) + k[14] - 1019803690 | 0;
+ d = (d << 9 | d >>> 23) + a | 0;
+ c += (d & b | a & ~b) + k[3] - 187363961 | 0;
+ c = (c << 14 | c >>> 18) + d | 0;
+ b += (c & a | d & ~a) + k[8] + 1163531501 | 0;
+ b = (b << 20 | b >>> 12) + c | 0;
+ a += (b & d | c & ~d) + k[13] - 1444681467 | 0;
+ a = (a << 5 | a >>> 27) + b | 0;
+ d += (a & c | b & ~c) + k[2] - 51403784 | 0;
+ d = (d << 9 | d >>> 23) + a | 0;
+ c += (d & b | a & ~b) + k[7] + 1735328473 | 0;
+ c = (c << 14 | c >>> 18) + d | 0;
+ b += (c & a | d & ~a) + k[12] - 1926607734 | 0;
+ b = (b << 20 | b >>> 12) + c | 0;
+ a += (b ^ c ^ d) + k[5] - 378558 | 0;
+ a = (a << 4 | a >>> 28) + b | 0;
+ d += (a ^ b ^ c) + k[8] - 2022574463 | 0;
+ d = (d << 11 | d >>> 21) + a | 0;
+ c += (d ^ a ^ b) + k[11] + 1839030562 | 0;
+ c = (c << 16 | c >>> 16) + d | 0;
+ b += (c ^ d ^ a) + k[14] - 35309556 | 0;
+ b = (b << 23 | b >>> 9) + c | 0;
+ a += (b ^ c ^ d) + k[1] - 1530992060 | 0;
+ a = (a << 4 | a >>> 28) + b | 0;
+ d += (a ^ b ^ c) + k[4] + 1272893353 | 0;
+ d = (d << 11 | d >>> 21) + a | 0;
+ c += (d ^ a ^ b) + k[7] - 155497632 | 0;
+ c = (c << 16 | c >>> 16) + d | 0;
+ b += (c ^ d ^ a) + k[10] - 1094730640 | 0;
+ b = (b << 23 | b >>> 9) + c | 0;
+ a += (b ^ c ^ d) + k[13] + 681279174 | 0;
+ a = (a << 4 | a >>> 28) + b | 0;
+ d += (a ^ b ^ c) + k[0] - 358537222 | 0;
+ d = (d << 11 | d >>> 21) + a | 0;
+ c += (d ^ a ^ b) + k[3] - 722521979 | 0;
+ c = (c << 16 | c >>> 16) + d | 0;
+ b += (c ^ d ^ a) + k[6] + 76029189 | 0;
+ b = (b << 23 | b >>> 9) + c | 0;
+ a += (b ^ c ^ d) + k[9] - 640364487 | 0;
+ a = (a << 4 | a >>> 28) + b | 0;
+ d += (a ^ b ^ c) + k[12] - 421815835 | 0;
+ d = (d << 11 | d >>> 21) + a | 0;
+ c += (d ^ a ^ b) + k[15] + 530742520 | 0;
+ c = (c << 16 | c >>> 16) + d | 0;
+ b += (c ^ d ^ a) + k[2] - 995338651 | 0;
+ b = (b << 23 | b >>> 9) + c | 0;
+ a += (c ^ (b | ~d)) + k[0] - 198630844 | 0;
+ a = (a << 6 | a >>> 26) + b | 0;
+ d += (b ^ (a | ~c)) + k[7] + 1126891415 | 0;
+ d = (d << 10 | d >>> 22) + a | 0;
+ c += (a ^ (d | ~b)) + k[14] - 1416354905 | 0;
+ c = (c << 15 | c >>> 17) + d | 0;
+ b += (d ^ (c | ~a)) + k[5] - 57434055 | 0;
+ b = (b << 21 | b >>> 11) + c | 0;
+ a += (c ^ (b | ~d)) + k[12] + 1700485571 | 0;
+ a = (a << 6 | a >>> 26) + b | 0;
+ d += (b ^ (a | ~c)) + k[3] - 1894986606 | 0;
+ d = (d << 10 | d >>> 22) + a | 0;
+ c += (a ^ (d | ~b)) + k[10] - 1051523 | 0;
+ c = (c << 15 | c >>> 17) + d | 0;
+ b += (d ^ (c | ~a)) + k[1] - 2054922799 | 0;
+ b = (b << 21 | b >>> 11) + c | 0;
+ a += (c ^ (b | ~d)) + k[8] + 1873313359 | 0;
+ a = (a << 6 | a >>> 26) + b | 0;
+ d += (b ^ (a | ~c)) + k[15] - 30611744 | 0;
+ d = (d << 10 | d >>> 22) + a | 0;
+ c += (a ^ (d | ~b)) + k[6] - 1560198380 | 0;
+ c = (c << 15 | c >>> 17) + d | 0;
+ b += (d ^ (c | ~a)) + k[13] + 1309151649 | 0;
+ b = (b << 21 | b >>> 11) + c | 0;
+ a += (c ^ (b | ~d)) + k[4] - 145523070 | 0;
+ a = (a << 6 | a >>> 26) + b | 0;
+ d += (b ^ (a | ~c)) + k[11] - 1120210379 | 0;
+ d = (d << 10 | d >>> 22) + a | 0;
+ c += (a ^ (d | ~b)) + k[2] + 718787259 | 0;
+ c = (c << 15 | c >>> 17) + d | 0;
+ b += (d ^ (c | ~a)) + k[9] - 343485551 | 0;
+ b = (b << 21 | b >>> 11) + c | 0;
+ x[0] = a + x[0] | 0;
+ x[1] = b + x[1] | 0;
+ x[2] = c + x[2] | 0;
+ x[3] = d + x[3] | 0;
+ }
+
+ function md5blk(s) {
+ var md5blks = [],
+ i;
+
+ for (i = 0; i < 64; i += 4) {
+ md5blks[i >> 2] = s.charCodeAt(i) + (s.charCodeAt(i + 1) << 8) + (s.charCodeAt(i + 2) << 16) + (s.charCodeAt(i + 3) << 24);
+ }
+
+ return md5blks;
+ }
+
+ function md5blk_array(a) {
+ var md5blks = [],
+ i;
+
+ for (i = 0; i < 64; i += 4) {
+ md5blks[i >> 2] = a[i] + (a[i + 1] << 8) + (a[i + 2] << 16) + (a[i + 3] << 24);
+ }
+
+ return md5blks;
+ }
+
+ function md51(s) {
+ var n = s.length,
+ state = [1732584193, -271733879, -1732584194, 271733878],
+ i,
+ length,
+ tail,
+ tmp,
+ lo,
+ hi;
+
+ for (i = 64; i <= n; i += 64) {
+ md5cycle(state, md5blk(s.substring(i - 64, i)));
+ }
+
+ s = s.substring(i - 64);
+ length = s.length;
+ tail = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
+
+ for (i = 0; i < length; i += 1) {
+ tail[i >> 2] |= s.charCodeAt(i) << (i % 4 << 3);
+ }
+
+ tail[i >> 2] |= 128 << (i % 4 << 3);
+
+ if (i > 55) {
+ md5cycle(state, tail);
+
+ for (i = 0; i < 16; i += 1) {
+ tail[i] = 0;
+ }
+ }
+
+ tmp = n * 8;
+ tmp = tmp.toString(16).match(/(.*?)(.{0,8})$/);
+ lo = parseInt(tmp[2], 16);
+ hi = parseInt(tmp[1], 16) || 0;
+ tail[14] = lo;
+ tail[15] = hi;
+ md5cycle(state, tail);
+ return state;
+ }
+
+ function md51_array(a) {
+ var n = a.length,
+ state = [1732584193, -271733879, -1732584194, 271733878],
+ i,
+ length,
+ tail,
+ tmp,
+ lo,
+ hi;
+
+ for (i = 64; i <= n; i += 64) {
+ md5cycle(state, md5blk_array(a.subarray(i - 64, i)));
+ }
+
+ a = i - 64 < n ? a.subarray(i - 64) : new Uint8Array(0);
+ length = a.length;
+ tail = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
+
+ for (i = 0; i < length; i += 1) {
+ tail[i >> 2] |= a[i] << (i % 4 << 3);
+ }
+
+ tail[i >> 2] |= 128 << (i % 4 << 3);
+
+ if (i > 55) {
+ md5cycle(state, tail);
+
+ for (i = 0; i < 16; i += 1) {
+ tail[i] = 0;
+ }
+ }
+
+ tmp = n * 8;
+ tmp = tmp.toString(16).match(/(.*?)(.{0,8})$/);
+ lo = parseInt(tmp[2], 16);
+ hi = parseInt(tmp[1], 16) || 0;
+ tail[14] = lo;
+ tail[15] = hi;
+ md5cycle(state, tail);
+ return state;
+ }
+
+ function rhex(n) {
+ var s = "",
+ j;
+
+ for (j = 0; j < 4; j += 1) {
+ s += hex_chr[n >> j * 8 + 4 & 15] + hex_chr[n >> j * 8 & 15];
+ }
+
+ return s;
+ }
+
+ function hex(x) {
+ var i;
+
+ for (i = 0; i < x.length; i += 1) {
+ x[i] = rhex(x[i]);
+ }
+
+ return x.join("");
+ }
+
+ if (hex(md51("hello")) !== "5d41402abc4b2a76b9719d911017c592") ;
+
+ if (typeof ArrayBuffer !== "undefined" && !ArrayBuffer.prototype.slice) {
+ (function () {
+ function clamp(val, length) {
+ val = val | 0 || 0;
+
+ if (val < 0) {
+ return Math.max(val + length, 0);
+ }
+
+ return Math.min(val, length);
+ }
+
+ ArrayBuffer.prototype.slice = function (from, to) {
+ var length = this.byteLength,
+ begin = clamp(from, length),
+ end = length,
+ num,
+ target,
+ targetArray,
+ sourceArray;
+
+ if (to !== undefined) {
+ end = clamp(to, length);
+ }
+
+ if (begin > end) {
+ return new ArrayBuffer(0);
+ }
+
+ num = end - begin;
+ target = new ArrayBuffer(num);
+ targetArray = new Uint8Array(target);
+ sourceArray = new Uint8Array(this, begin, num);
+ targetArray.set(sourceArray);
+ return target;
+ };
+ })();
+ }
+
+ function toUtf8(str) {
+ if (/[\u0080-\uFFFF]/.test(str)) {
+ str = unescape(encodeURIComponent(str));
+ }
+
+ return str;
+ }
+
+ function utf8Str2ArrayBuffer(str, returnUInt8Array) {
+ var length = str.length,
+ buff = new ArrayBuffer(length),
+ arr = new Uint8Array(buff),
+ i;
+
+ for (i = 0; i < length; i += 1) {
+ arr[i] = str.charCodeAt(i);
+ }
+
+ return returnUInt8Array ? arr : buff;
+ }
+
+ function arrayBuffer2Utf8Str(buff) {
+ return String.fromCharCode.apply(null, new Uint8Array(buff));
+ }
+
+ function concatenateArrayBuffers(first, second, returnUInt8Array) {
+ var result = new Uint8Array(first.byteLength + second.byteLength);
+ result.set(new Uint8Array(first));
+ result.set(new Uint8Array(second), first.byteLength);
+ return returnUInt8Array ? result : result.buffer;
+ }
+
+ function hexToBinaryString(hex) {
+ var bytes = [],
+ length = hex.length,
+ x;
+
+ for (x = 0; x < length - 1; x += 2) {
+ bytes.push(parseInt(hex.substr(x, 2), 16));
+ }
+
+ return String.fromCharCode.apply(String, bytes);
+ }
+
+ function SparkMD5() {
+ this.reset();
+ }
+
+ SparkMD5.prototype.append = function (str) {
+ this.appendBinary(toUtf8(str));
+ return this;
+ };
+
+ SparkMD5.prototype.appendBinary = function (contents) {
+ this._buff += contents;
+ this._length += contents.length;
+ var length = this._buff.length,
+ i;
+
+ for (i = 64; i <= length; i += 64) {
+ md5cycle(this._hash, md5blk(this._buff.substring(i - 64, i)));
+ }
+
+ this._buff = this._buff.substring(i - 64);
+ return this;
+ };
+
+ SparkMD5.prototype.end = function (raw) {
+ var buff = this._buff,
+ length = buff.length,
+ i,
+ tail = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+ ret;
+
+ for (i = 0; i < length; i += 1) {
+ tail[i >> 2] |= buff.charCodeAt(i) << (i % 4 << 3);
+ }
+
+ this._finish(tail, length);
+
+ ret = hex(this._hash);
+
+ if (raw) {
+ ret = hexToBinaryString(ret);
+ }
+
+ this.reset();
+ return ret;
+ };
+
+ SparkMD5.prototype.reset = function () {
+ this._buff = "";
+ this._length = 0;
+ this._hash = [1732584193, -271733879, -1732584194, 271733878];
+ return this;
+ };
+
+ SparkMD5.prototype.getState = function () {
+ return {
+ buff: this._buff,
+ length: this._length,
+ hash: this._hash
+ };
+ };
+
+ SparkMD5.prototype.setState = function (state) {
+ this._buff = state.buff;
+ this._length = state.length;
+ this._hash = state.hash;
+ return this;
+ };
+
+ SparkMD5.prototype.destroy = function () {
+ delete this._hash;
+ delete this._buff;
+ delete this._length;
+ };
+
+ SparkMD5.prototype._finish = function (tail, length) {
+ var i = length,
+ tmp,
+ lo,
+ hi;
+ tail[i >> 2] |= 128 << (i % 4 << 3);
+
+ if (i > 55) {
+ md5cycle(this._hash, tail);
+
+ for (i = 0; i < 16; i += 1) {
+ tail[i] = 0;
+ }
+ }
+
+ tmp = this._length * 8;
+ tmp = tmp.toString(16).match(/(.*?)(.{0,8})$/);
+ lo = parseInt(tmp[2], 16);
+ hi = parseInt(tmp[1], 16) || 0;
+ tail[14] = lo;
+ tail[15] = hi;
+ md5cycle(this._hash, tail);
+ };
+
+ SparkMD5.hash = function (str, raw) {
+ return SparkMD5.hashBinary(toUtf8(str), raw);
+ };
+
+ SparkMD5.hashBinary = function (content, raw) {
+ var hash = md51(content),
+ ret = hex(hash);
+ return raw ? hexToBinaryString(ret) : ret;
+ };
+
+ SparkMD5.ArrayBuffer = function () {
+ this.reset();
+ };
+
+ SparkMD5.ArrayBuffer.prototype.append = function (arr) {
+ var buff = concatenateArrayBuffers(this._buff.buffer, arr, true),
+ length = buff.length,
+ i;
+ this._length += arr.byteLength;
+
+ for (i = 64; i <= length; i += 64) {
+ md5cycle(this._hash, md5blk_array(buff.subarray(i - 64, i)));
+ }
+
+ this._buff = i - 64 < length ? new Uint8Array(buff.buffer.slice(i - 64)) : new Uint8Array(0);
+ return this;
+ };
+
+ SparkMD5.ArrayBuffer.prototype.end = function (raw) {
+ var buff = this._buff,
+ length = buff.length,
+ tail = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+ i,
+ ret;
+
+ for (i = 0; i < length; i += 1) {
+ tail[i >> 2] |= buff[i] << (i % 4 << 3);
+ }
+
+ this._finish(tail, length);
+
+ ret = hex(this._hash);
+
+ if (raw) {
+ ret = hexToBinaryString(ret);
+ }
+
+ this.reset();
+ return ret;
+ };
+
+ SparkMD5.ArrayBuffer.prototype.reset = function () {
+ this._buff = new Uint8Array(0);
+ this._length = 0;
+ this._hash = [1732584193, -271733879, -1732584194, 271733878];
+ return this;
+ };
+
+ SparkMD5.ArrayBuffer.prototype.getState = function () {
+ var state = SparkMD5.prototype.getState.call(this);
+ state.buff = arrayBuffer2Utf8Str(state.buff);
+ return state;
+ };
+
+ SparkMD5.ArrayBuffer.prototype.setState = function (state) {
+ state.buff = utf8Str2ArrayBuffer(state.buff, true);
+ return SparkMD5.prototype.setState.call(this, state);
+ };
+
+ SparkMD5.ArrayBuffer.prototype.destroy = SparkMD5.prototype.destroy;
+ SparkMD5.ArrayBuffer.prototype._finish = SparkMD5.prototype._finish;
+
+ SparkMD5.ArrayBuffer.hash = function (arr, raw) {
+ var hash = md51_array(new Uint8Array(arr)),
+ ret = hex(hash);
+ return raw ? hexToBinaryString(ret) : ret;
+ };
+
+ return SparkMD5;
+ });
+ });
+
+ var classCallCheck = function classCallCheck(instance, Constructor) {
+ if (!(instance instanceof Constructor)) {
+ throw new TypeError("Cannot call a class as a function");
+ }
+ };
+
+ var createClass = function () {
+ function defineProperties(target, props) {
+ for (var i = 0; i < props.length; i++) {
+ var descriptor = props[i];
+ descriptor.enumerable = descriptor.enumerable || false;
+ descriptor.configurable = true;
+ if ("value" in descriptor) descriptor.writable = true;
+ Object.defineProperty(target, descriptor.key, descriptor);
+ }
+ }
+
+ return function (Constructor, protoProps, staticProps) {
+ if (protoProps) defineProperties(Constructor.prototype, protoProps);
+ if (staticProps) defineProperties(Constructor, staticProps);
+ return Constructor;
+ };
+ }();
+
+ var fileSlice = File.prototype.slice || File.prototype.mozSlice || File.prototype.webkitSlice;
+
+ var FileChecksum = function () {
+ createClass(FileChecksum, null, [{
+ key: "create",
+ value: function create(file, callback) {
+ var instance = new FileChecksum(file);
+ instance.create(callback);
+ }
+ }]);
+
+ function FileChecksum(file) {
+ classCallCheck(this, FileChecksum);
+ this.file = file;
+ this.chunkSize = 2097152;
+ this.chunkCount = Math.ceil(this.file.size / this.chunkSize);
+ this.chunkIndex = 0;
+ }
+
+ createClass(FileChecksum, [{
+ key: "create",
+ value: function create(callback) {
+ var _this = this;
+
+ this.callback = callback;
+ this.md5Buffer = new sparkMd5.ArrayBuffer();
+ this.fileReader = new FileReader();
+ this.fileReader.addEventListener("load", function (event) {
+ return _this.fileReaderDidLoad(event);
+ });
+ this.fileReader.addEventListener("error", function (event) {
+ return _this.fileReaderDidError(event);
+ });
+ this.readNextChunk();
+ }
+ }, {
+ key: "fileReaderDidLoad",
+ value: function fileReaderDidLoad(event) {
+ this.md5Buffer.append(event.target.result);
+
+ if (!this.readNextChunk()) {
+ var binaryDigest = this.md5Buffer.end(true);
+ var base64digest = btoa(binaryDigest);
+ this.callback(null, base64digest);
+ }
+ }
+ }, {
+ key: "fileReaderDidError",
+ value: function fileReaderDidError(event) {
+ this.callback("Error reading " + this.file.name);
+ }
+ }, {
+ key: "readNextChunk",
+ value: function readNextChunk() {
+ if (this.chunkIndex < this.chunkCount || this.chunkIndex == 0 && this.chunkCount == 0) {
+ var start = this.chunkIndex * this.chunkSize;
+ var end = Math.min(start + this.chunkSize, this.file.size);
+ var bytes = fileSlice.call(this.file, start, end);
+ this.fileReader.readAsArrayBuffer(bytes);
+ this.chunkIndex++;
+ return true;
+ } else {
+ return false;
+ }
+ }
+ }]);
+ return FileChecksum;
+ }();
+
+ function getMetaValue(name) {
+ var element = findElement(document.head, 'meta[name="' + name + '"]');
+
+ if (element) {
+ return element.getAttribute("content");
+ }
+ }
+
+ function findElements(root, selector) {
+ if (typeof root == "string") {
+ selector = root;
+ root = document;
+ }
+
+ var elements = root.querySelectorAll(selector);
+ return toArray$1(elements);
+ }
+
+ function findElement(root, selector) {
+ if (typeof root == "string") {
+ selector = root;
+ root = document;
+ }
+
+ return root.querySelector(selector);
+ }
+
+ function dispatchEvent(element, type) {
+ var eventInit = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
+ var disabled = element.disabled;
+ var bubbles = eventInit.bubbles,
+ cancelable = eventInit.cancelable,
+ detail = eventInit.detail;
+ var event = document.createEvent("Event");
+ event.initEvent(type, bubbles || true, cancelable || true);
+ event.detail = detail || {};
+
+ try {
+ element.disabled = false;
+ element.dispatchEvent(event);
+ } finally {
+ element.disabled = disabled;
+ }
+
+ return event;
+ }
+
+ function toArray$1(value) {
+ if (Array.isArray(value)) {
+ return value;
+ } else if (Array.from) {
+ return Array.from(value);
+ } else {
+ return [].slice.call(value);
+ }
+ }
+
+ var BlobRecord = function () {
+ function BlobRecord(file, checksum, url) {
+ var _this = this;
+
+ classCallCheck(this, BlobRecord);
+ this.file = file;
+ this.attributes = {
+ filename: file.name,
+ content_type: file.type,
+ byte_size: file.size,
+ checksum: checksum
+ };
+ this.xhr = new XMLHttpRequest();
+ this.xhr.open("POST", url, true);
+ this.xhr.responseType = "json";
+ this.xhr.setRequestHeader("Content-Type", "application/json");
+ this.xhr.setRequestHeader("Accept", "application/json");
+ this.xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
+ var csrfToken = getMetaValue("csrf-token");
+
+ if (csrfToken != undefined) {
+ this.xhr.setRequestHeader("X-CSRF-Token", csrfToken);
+ }
+
+ this.xhr.addEventListener("load", function (event) {
+ return _this.requestDidLoad(event);
+ });
+ this.xhr.addEventListener("error", function (event) {
+ return _this.requestDidError(event);
+ });
+ }
+
+ createClass(BlobRecord, [{
+ key: "create",
+ value: function create(callback) {
+ this.callback = callback;
+ this.xhr.send(JSON.stringify({
+ blob: this.attributes
+ }));
+ }
+ }, {
+ key: "requestDidLoad",
+ value: function requestDidLoad(event) {
+ if (this.status >= 200 && this.status < 300) {
+ var response = this.response;
+ var direct_upload = response.direct_upload;
+ delete response.direct_upload;
+ this.attributes = response;
+ this.directUploadData = direct_upload;
+ this.callback(null, this.toJSON());
+ } else {
+ this.requestDidError(event);
+ }
+ }
+ }, {
+ key: "requestDidError",
+ value: function requestDidError(event) {
+ this.callback('Error creating Blob for "' + this.file.name + '". Status: ' + this.status);
+ }
+ }, {
+ key: "toJSON",
+ value: function toJSON() {
+ var result = {};
+
+ for (var key in this.attributes) {
+ result[key] = this.attributes[key];
+ }
+
+ return result;
+ }
+ }, {
+ key: "status",
+ get: function get$$1() {
+ return this.xhr.status;
+ }
+ }, {
+ key: "response",
+ get: function get$$1() {
+ var _xhr = this.xhr,
+ responseType = _xhr.responseType,
+ response = _xhr.response;
+
+ if (responseType == "json") {
+ return response;
+ } else {
+ return JSON.parse(response);
+ }
+ }
+ }]);
+ return BlobRecord;
+ }();
+
+ var BlobUpload = function () {
+ function BlobUpload(blob) {
+ var _this = this;
+
+ classCallCheck(this, BlobUpload);
+ this.blob = blob;
+ this.file = blob.file;
+ var _blob$directUploadDat = blob.directUploadData,
+ url = _blob$directUploadDat.url,
+ headers = _blob$directUploadDat.headers;
+ this.xhr = new XMLHttpRequest();
+ this.xhr.open("PUT", url, true);
+ this.xhr.responseType = "text";
+
+ for (var key in headers) {
+ this.xhr.setRequestHeader(key, headers[key]);
+ }
+
+ this.xhr.addEventListener("load", function (event) {
+ return _this.requestDidLoad(event);
+ });
+ this.xhr.addEventListener("error", function (event) {
+ return _this.requestDidError(event);
+ });
+ }
+
+ createClass(BlobUpload, [{
+ key: "create",
+ value: function create(callback) {
+ this.callback = callback;
+ this.xhr.send(this.file.slice());
+ }
+ }, {
+ key: "requestDidLoad",
+ value: function requestDidLoad(event) {
+ var _xhr = this.xhr,
+ status = _xhr.status,
+ response = _xhr.response;
+
+ if (status >= 200 && status < 300) {
+ this.callback(null, response);
+ } else {
+ this.requestDidError(event);
+ }
+ }
+ }, {
+ key: "requestDidError",
+ value: function requestDidError(event) {
+ this.callback('Error storing "' + this.file.name + '". Status: ' + this.xhr.status);
+ }
+ }]);
+ return BlobUpload;
+ }();
+
+ var id = 0;
+
+ var DirectUpload = function () {
+ function DirectUpload(file, url, delegate) {
+ classCallCheck(this, DirectUpload);
+ this.id = ++id;
+ this.file = file;
+ this.url = url;
+ this.delegate = delegate;
+ }
+
+ createClass(DirectUpload, [{
+ key: "create",
+ value: function create(callback) {
+ var _this = this;
+
+ FileChecksum.create(this.file, function (error, checksum) {
+ if (error) {
+ callback(error);
+ return;
+ }
+
+ var blob = new BlobRecord(_this.file, checksum, _this.url);
+ notify(_this.delegate, "directUploadWillCreateBlobWithXHR", blob.xhr);
+ blob.create(function (error) {
+ if (error) {
+ callback(error);
+ } else {
+ var upload = new BlobUpload(blob);
+ notify(_this.delegate, "directUploadWillStoreFileWithXHR", upload.xhr);
+ upload.create(function (error) {
+ if (error) {
+ callback(error);
+ } else {
+ callback(null, blob.toJSON());
+ }
+ });
+ }
+ });
+ });
+ }
+ }]);
+ return DirectUpload;
+ }();
+
+ function notify(object, methodName) {
+ if (object && typeof object[methodName] == "function") {
+ for (var _len = arguments.length, messages = Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
+ messages[_key - 2] = arguments[_key];
+ }
+
+ return object[methodName].apply(object, messages);
+ }
+ }
+
+ var DirectUploadController = function () {
+ function DirectUploadController(input, file) {
+ classCallCheck(this, DirectUploadController);
+ this.input = input;
+ this.file = file;
+ this.directUpload = new DirectUpload(this.file, this.url, this);
+ this.dispatch("initialize");
+ }
+
+ createClass(DirectUploadController, [{
+ key: "start",
+ value: function start(callback) {
+ var _this = this;
+
+ var hiddenInput = document.createElement("input");
+ hiddenInput.type = "hidden";
+ hiddenInput.name = this.input.name;
+ this.input.insertAdjacentElement("beforebegin", hiddenInput);
+ this.dispatch("start");
+ this.directUpload.create(function (error, attributes) {
+ if (error) {
+ hiddenInput.parentNode.removeChild(hiddenInput);
+
+ _this.dispatchError(error);
+ } else {
+ hiddenInput.value = attributes.signed_id;
+ }
+
+ _this.dispatch("end");
+
+ callback(error);
+ });
+ }
+ }, {
+ key: "uploadRequestDidProgress",
+ value: function uploadRequestDidProgress(event) {
+ var progress = event.loaded / event.total * 100;
+
+ if (progress) {
+ this.dispatch("progress", {
+ progress: progress
+ });
+ }
+ }
+ }, {
+ key: "dispatch",
+ value: function dispatch(name) {
+ var detail = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
+ detail.file = this.file;
+ detail.id = this.directUpload.id;
+ return dispatchEvent(this.input, "direct-upload:" + name, {
+ detail: detail
+ });
+ }
+ }, {
+ key: "dispatchError",
+ value: function dispatchError(error) {
+ var event = this.dispatch("error", {
+ error: error
+ });
+
+ if (!event.defaultPrevented) {
+ alert(error);
+ }
+ }
+ }, {
+ key: "directUploadWillCreateBlobWithXHR",
+ value: function directUploadWillCreateBlobWithXHR(xhr) {
+ this.dispatch("before-blob-request", {
+ xhr: xhr
+ });
+ }
+ }, {
+ key: "directUploadWillStoreFileWithXHR",
+ value: function directUploadWillStoreFileWithXHR(xhr) {
+ var _this2 = this;
+
+ this.dispatch("before-storage-request", {
+ xhr: xhr
+ });
+ xhr.upload.addEventListener("progress", function (event) {
+ return _this2.uploadRequestDidProgress(event);
+ });
+ }
+ }, {
+ key: "url",
+ get: function get$$1() {
+ return this.input.getAttribute("data-direct-upload-url");
+ }
+ }]);
+ return DirectUploadController;
+ }();
+
+ var inputSelector = "input[type=file][data-direct-upload-url]:not([disabled])";
+
+ var DirectUploadsController = function () {
+ function DirectUploadsController(form) {
+ classCallCheck(this, DirectUploadsController);
+ this.form = form;
+ this.inputs = findElements(form, inputSelector).filter(function (input) {
+ return input.files.length;
+ });
+ }
+
+ createClass(DirectUploadsController, [{
+ key: "start",
+ value: function start(callback) {
+ var _this = this;
+
+ var controllers = this.createDirectUploadControllers();
+
+ var startNextController = function startNextController() {
+ var controller = controllers.shift();
+
+ if (controller) {
+ controller.start(function (error) {
+ if (error) {
+ callback(error);
+
+ _this.dispatch("end");
+ } else {
+ startNextController();
+ }
+ });
+ } else {
+ callback();
+
+ _this.dispatch("end");
+ }
+ };
+
+ this.dispatch("start");
+ startNextController();
+ }
+ }, {
+ key: "createDirectUploadControllers",
+ value: function createDirectUploadControllers() {
+ var controllers = [];
+ this.inputs.forEach(function (input) {
+ toArray$1(input.files).forEach(function (file) {
+ var controller = new DirectUploadController(input, file);
+ controllers.push(controller);
+ });
+ });
+ return controllers;
+ }
+ }, {
+ key: "dispatch",
+ value: function dispatch(name) {
+ var detail = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
+ return dispatchEvent(this.form, "direct-uploads:" + name, {
+ detail: detail
+ });
+ }
+ }]);
+ return DirectUploadsController;
+ }();
+
+ var processingAttribute = "data-direct-uploads-processing";
+ var submitButtonsByForm = new WeakMap();
+ var started = false;
+
+ function start() {
+ if (!started) {
+ started = true;
+ document.addEventListener("click", didClick, true);
+ document.addEventListener("submit", didSubmitForm);
+ document.addEventListener("ajax:before", didSubmitRemoteElement);
+ }
+ }
+
+ function didClick(event) {
+ var target = event.target;
+
+ if ((target.tagName == "INPUT" || target.tagName == "BUTTON") && target.type == "submit" && target.form) {
+ submitButtonsByForm.set(target.form, target);
+ }
+ }
+
+ function didSubmitForm(event) {
+ handleFormSubmissionEvent(event);
+ }
+
+ function didSubmitRemoteElement(event) {
+ if (event.target.tagName == "FORM") {
+ handleFormSubmissionEvent(event);
+ }
+ }
+
+ function handleFormSubmissionEvent(event) {
+ var form = event.target;
+
+ if (form.hasAttribute(processingAttribute)) {
+ event.preventDefault();
+ return;
+ }
+
+ var controller = new DirectUploadsController(form);
+ var inputs = controller.inputs;
+
+ if (inputs.length) {
+ event.preventDefault();
+ form.setAttribute(processingAttribute, "");
+ inputs.forEach(disable);
+ controller.start(function (error) {
+ form.removeAttribute(processingAttribute);
+
+ if (error) {
+ inputs.forEach(enable);
+ } else {
+ submitForm(form);
+ }
+ });
+ }
+ }
+
+ function submitForm(form) {
+ var button = submitButtonsByForm.get(form) || findElement(form, "input[type=submit], button[type=submit]");
+
+ if (button) {
+ var _button = button,
+ disabled = _button.disabled;
+ button.disabled = false;
+ button.focus();
+ button.click();
+ button.disabled = disabled;
+ } else {
+ button = document.createElement("input");
+ button.type = "submit";
+ button.style.display = "none";
+ form.appendChild(button);
+ button.click();
+ form.removeChild(button);
+ }
+
+ submitButtonsByForm["delete"](form);
+ }
+
+ function disable(input) {
+ input.disabled = true;
+ }
+
+ function enable(input) {
+ input.disabled = false;
+ }
+
+ function autostart() {
+ if (window.ActiveStorage) {
+ start();
+ }
+ }
+
+ setTimeout(autostart, 1);
+ exports.start = start;
+ exports.DirectUpload = DirectUpload;
+ Object.defineProperty(exports, "__esModule", {
+ value: true
+ });
+});
+
+/***/ }),
+
+/***/ "./node_modules/@rails/ujs/lib/assets/compiled/rails-ujs.js":
+/*!******************************************************************!*\
+ !*** ./node_modules/@rails/ujs/lib/assets/compiled/rails-ujs.js ***!
+ \******************************************************************/
+/*! no static exports found */
+/***/ (function(module, exports, __webpack_require__) {
+
+/* WEBPACK VAR INJECTION */(function(jQuery, module) {var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_RESULT__;function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
+
+/*
+Unobtrusive JavaScript
+https://github.com/rails/rails/blob/master/actionview/app/assets/javascripts
+Released under the MIT license
+ */
+;
+(function () {
+ var context = this;
+ (function () {
+ (function () {
+ this.Rails = {
+ linkClickSelector: 'a[data-confirm], a[data-method], a[data-remote]:not([disabled]), a[data-disable-with], a[data-disable]',
+ buttonClickSelector: {
+ selector: 'button[data-remote]:not([form]), button[data-confirm]:not([form])',
+ exclude: 'form button'
+ },
+ inputChangeSelector: 'select[data-remote], input[data-remote], textarea[data-remote]',
+ formSubmitSelector: 'form',
+ formInputClickSelector: 'form input[type=submit], form input[type=image], form button[type=submit], form button:not([type]), input[type=submit][form], input[type=image][form], button[type=submit][form], button[form]:not([type])',
+ formDisableSelector: 'input[data-disable-with]:enabled, button[data-disable-with]:enabled, textarea[data-disable-with]:enabled, input[data-disable]:enabled, button[data-disable]:enabled, textarea[data-disable]:enabled',
+ formEnableSelector: 'input[data-disable-with]:disabled, button[data-disable-with]:disabled, textarea[data-disable-with]:disabled, input[data-disable]:disabled, button[data-disable]:disabled, textarea[data-disable]:disabled',
+ fileInputSelector: 'input[name][type=file]:not([disabled])',
+ linkDisableSelector: 'a[data-disable-with], a[data-disable]',
+ buttonDisableSelector: 'button[data-remote][data-disable-with], button[data-remote][data-disable]'
+ };
+ }).call(this);
+ }).call(context);
+ var Rails = context.Rails;
+ (function () {
+ (function () {
+ var nonce;
+ nonce = null;
+
+ Rails.loadCSPNonce = function () {
+ var ref;
+ return nonce = (ref = document.querySelector("meta[name=csp-nonce]")) != null ? ref.content : void 0;
+ };
+
+ Rails.cspNonce = function () {
+ return nonce != null ? nonce : Rails.loadCSPNonce();
+ };
+ }).call(this);
+ (function () {
+ var expando, m;
+ m = Element.prototype.matches || Element.prototype.matchesSelector || Element.prototype.mozMatchesSelector || Element.prototype.msMatchesSelector || Element.prototype.oMatchesSelector || Element.prototype.webkitMatchesSelector;
+
+ Rails.matches = function (element, selector) {
+ if (selector.exclude != null) {
+ return m.call(element, selector.selector) && !m.call(element, selector.exclude);
+ } else {
+ return m.call(element, selector);
+ }
+ };
+
+ expando = '_ujsData';
+
+ Rails.getData = function (element, key) {
+ var ref;
+ return (ref = element[expando]) != null ? ref[key] : void 0;
+ };
+
+ Rails.setData = function (element, key, value) {
+ if (element[expando] == null) {
+ element[expando] = {};
+ }
+
+ return element[expando][key] = value;
+ };
+
+ Rails.$ = function (selector) {
+ return Array.prototype.slice.call(document.querySelectorAll(selector));
+ };
+ }).call(this);
+ (function () {
+ var $, csrfParam, csrfToken;
+ $ = Rails.$;
+
+ csrfToken = Rails.csrfToken = function () {
+ var meta;
+ meta = document.querySelector('meta[name=csrf-token]');
+ return meta && meta.content;
+ };
+
+ csrfParam = Rails.csrfParam = function () {
+ var meta;
+ meta = document.querySelector('meta[name=csrf-param]');
+ return meta && meta.content;
+ };
+
+ Rails.CSRFProtection = function (xhr) {
+ var token;
+ token = csrfToken();
+
+ if (token != null) {
+ return xhr.setRequestHeader('X-CSRF-Token', token);
+ }
+ };
+
+ Rails.refreshCSRFTokens = function () {
+ var param, token;
+ token = csrfToken();
+ param = csrfParam();
+
+ if (token != null && param != null) {
+ return $('form input[name="' + param + '"]').forEach(function (input) {
+ return input.value = token;
+ });
+ }
+ };
+ }).call(this);
+ (function () {
+ var CustomEvent, fire, matches, preventDefault;
+ matches = Rails.matches;
+ CustomEvent = window.CustomEvent;
+
+ if (typeof CustomEvent !== 'function') {
+ CustomEvent = function CustomEvent(event, params) {
+ var evt;
+ evt = document.createEvent('CustomEvent');
+ evt.initCustomEvent(event, params.bubbles, params.cancelable, params.detail);
+ return evt;
+ };
+
+ CustomEvent.prototype = window.Event.prototype;
+ preventDefault = CustomEvent.prototype.preventDefault;
+
+ CustomEvent.prototype.preventDefault = function () {
+ var result;
+ result = preventDefault.call(this);
+
+ if (this.cancelable && !this.defaultPrevented) {
+ Object.defineProperty(this, 'defaultPrevented', {
+ get: function get() {
+ return true;
+ }
+ });
+ }
+
+ return result;
+ };
+ }
+
+ fire = Rails.fire = function (obj, name, data) {
+ var event;
+ event = new CustomEvent(name, {
+ bubbles: true,
+ cancelable: true,
+ detail: data
+ });
+ obj.dispatchEvent(event);
+ return !event.defaultPrevented;
+ };
+
+ Rails.stopEverything = function (e) {
+ fire(e.target, 'ujs:everythingStopped');
+ e.preventDefault();
+ e.stopPropagation();
+ return e.stopImmediatePropagation();
+ };
+
+ Rails.delegate = function (element, selector, eventType, handler) {
+ return element.addEventListener(eventType, function (e) {
+ var target;
+ target = e.target;
+
+ while (!(!(target instanceof Element) || matches(target, selector))) {
+ target = target.parentNode;
+ }
+
+ if (target instanceof Element && handler.call(target, e) === false) {
+ e.preventDefault();
+ return e.stopPropagation();
+ }
+ });
+ };
+ }).call(this);
+ (function () {
+ var AcceptHeaders, CSRFProtection, createXHR, cspNonce, fire, prepareOptions, processResponse;
+ cspNonce = Rails.cspNonce, CSRFProtection = Rails.CSRFProtection, fire = Rails.fire;
+ AcceptHeaders = {
+ '*': '*/*',
+ text: 'text/plain',
+ html: 'text/html',
+ xml: 'application/xml, text/xml',
+ json: 'application/json, text/javascript',
+ script: 'text/javascript, application/javascript, application/ecmascript, application/x-ecmascript'
+ };
+
+ Rails.ajax = function (options) {
+ var xhr;
+ options = prepareOptions(options);
+ xhr = createXHR(options, function () {
+ var ref, response;
+ response = processResponse((ref = xhr.response) != null ? ref : xhr.responseText, xhr.getResponseHeader('Content-Type'));
+
+ if (Math.floor(xhr.status / 100) === 2) {
+ if (typeof options.success === "function") {
+ options.success(response, xhr.statusText, xhr);
+ }
+ } else {
+ if (typeof options.error === "function") {
+ options.error(response, xhr.statusText, xhr);
+ }
+ }
+
+ return typeof options.complete === "function" ? options.complete(xhr, xhr.statusText) : void 0;
+ });
+
+ if (options.beforeSend != null && !options.beforeSend(xhr, options)) {
+ return false;
+ }
+
+ if (xhr.readyState === XMLHttpRequest.OPENED) {
+ return xhr.send(options.data);
+ }
+ };
+
+ prepareOptions = function prepareOptions(options) {
+ options.url = options.url || location.href;
+ options.type = options.type.toUpperCase();
+
+ if (options.type === 'GET' && options.data) {
+ if (options.url.indexOf('?') < 0) {
+ options.url += '?' + options.data;
+ } else {
+ options.url += '&' + options.data;
+ }
+ }
+
+ if (AcceptHeaders[options.dataType] == null) {
+ options.dataType = '*';
+ }
+
+ options.accept = AcceptHeaders[options.dataType];
+
+ if (options.dataType !== '*') {
+ options.accept += ', */*; q=0.01';
+ }
+
+ return options;
+ };
+
+ createXHR = function createXHR(options, done) {
+ var xhr;
+ xhr = new XMLHttpRequest();
+ xhr.open(options.type, options.url, true);
+ xhr.setRequestHeader('Accept', options.accept);
+
+ if (typeof options.data === 'string') {
+ xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
+ }
+
+ if (!options.crossDomain) {
+ xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
+ }
+
+ CSRFProtection(xhr);
+ xhr.withCredentials = !!options.withCredentials;
+
+ xhr.onreadystatechange = function () {
+ if (xhr.readyState === XMLHttpRequest.DONE) {
+ return done(xhr);
+ }
+ };
+
+ return xhr;
+ };
+
+ processResponse = function processResponse(response, type) {
+ var parser, script;
+
+ if (typeof response === 'string' && typeof type === 'string') {
+ if (type.match(/\bjson\b/)) {
+ try {
+ response = JSON.parse(response);
+ } catch (error) {}
+ } else if (type.match(/\b(?:java|ecma)script\b/)) {
+ script = document.createElement('script');
+ script.setAttribute('nonce', cspNonce());
+ script.text = response;
+ document.head.appendChild(script).parentNode.removeChild(script);
+ } else if (type.match(/\b(xml|html|svg)\b/)) {
+ parser = new DOMParser();
+ type = type.replace(/;.+/, '');
+
+ try {
+ response = parser.parseFromString(response, type);
+ } catch (error) {}
+ }
+ }
+
+ return response;
+ };
+
+ Rails.href = function (element) {
+ return element.href;
+ };
+
+ Rails.isCrossDomain = function (url) {
+ var e, originAnchor, urlAnchor;
+ originAnchor = document.createElement('a');
+ originAnchor.href = location.href;
+ urlAnchor = document.createElement('a');
+
+ try {
+ urlAnchor.href = url;
+ return !((!urlAnchor.protocol || urlAnchor.protocol === ':') && !urlAnchor.host || originAnchor.protocol + '//' + originAnchor.host === urlAnchor.protocol + '//' + urlAnchor.host);
+ } catch (error) {
+ e = error;
+ return true;
+ }
+ };
+ }).call(this);
+ (function () {
+ var matches, toArray;
+ matches = Rails.matches;
+
+ toArray = function toArray(e) {
+ return Array.prototype.slice.call(e);
+ };
+
+ Rails.serializeElement = function (element, additionalParam) {
+ var inputs, params;
+ inputs = [element];
+
+ if (matches(element, 'form')) {
+ inputs = toArray(element.elements);
+ }
+
+ params = [];
+ inputs.forEach(function (input) {
+ if (!input.name || input.disabled) {
+ return;
+ }
+
+ if (matches(input, 'fieldset[disabled] *')) {
+ return;
+ }
+
+ if (matches(input, 'select')) {
+ return toArray(input.options).forEach(function (option) {
+ if (option.selected) {
+ return params.push({
+ name: input.name,
+ value: option.value
+ });
+ }
+ });
+ } else if (input.checked || ['radio', 'checkbox', 'submit'].indexOf(input.type) === -1) {
+ return params.push({
+ name: input.name,
+ value: input.value
+ });
+ }
+ });
+
+ if (additionalParam) {
+ params.push(additionalParam);
+ }
+
+ return params.map(function (param) {
+ if (param.name != null) {
+ return encodeURIComponent(param.name) + "=" + encodeURIComponent(param.value);
+ } else {
+ return param;
+ }
+ }).join('&');
+ };
+
+ Rails.formElements = function (form, selector) {
+ if (matches(form, 'form')) {
+ return toArray(form.elements).filter(function (el) {
+ return matches(el, selector);
+ });
+ } else {
+ return toArray(form.querySelectorAll(selector));
+ }
+ };
+ }).call(this);
+ (function () {
+ var allowAction, fire, stopEverything;
+ fire = Rails.fire, stopEverything = Rails.stopEverything;
+
+ Rails.handleConfirm = function (e) {
+ if (!allowAction(this)) {
+ return stopEverything(e);
+ }
+ };
+
+ Rails.confirm = function (message, element) {
+ return confirm(message);
+ };
+
+ allowAction = function allowAction(element) {
+ var answer, callback, message;
+ message = element.getAttribute('data-confirm');
+
+ if (!message) {
+ return true;
+ }
+
+ answer = false;
+
+ if (fire(element, 'confirm')) {
+ try {
+ answer = Rails.confirm(message, element);
+ } catch (error) {}
+
+ callback = fire(element, 'confirm:complete', [answer]);
+ }
+
+ return answer && callback;
+ };
+ }).call(this);
+ (function () {
+ var disableFormElement, disableFormElements, disableLinkElement, enableFormElement, enableFormElements, enableLinkElement, formElements, getData, isXhrRedirect, matches, setData, stopEverything;
+ matches = Rails.matches, getData = Rails.getData, setData = Rails.setData, stopEverything = Rails.stopEverything, formElements = Rails.formElements;
+
+ Rails.handleDisabledElement = function (e) {
+ var element;
+ element = this;
+
+ if (element.disabled) {
+ return stopEverything(e);
+ }
+ };
+
+ Rails.enableElement = function (e) {
+ var element;
+
+ if (e instanceof Event) {
+ if (isXhrRedirect(e)) {
+ return;
+ }
+
+ element = e.target;
+ } else {
+ element = e;
+ }
+
+ if (matches(element, Rails.linkDisableSelector)) {
+ return enableLinkElement(element);
+ } else if (matches(element, Rails.buttonDisableSelector) || matches(element, Rails.formEnableSelector)) {
+ return enableFormElement(element);
+ } else if (matches(element, Rails.formSubmitSelector)) {
+ return enableFormElements(element);
+ }
+ };
+
+ Rails.disableElement = function (e) {
+ var element;
+ element = e instanceof Event ? e.target : e;
+
+ if (matches(element, Rails.linkDisableSelector)) {
+ return disableLinkElement(element);
+ } else if (matches(element, Rails.buttonDisableSelector) || matches(element, Rails.formDisableSelector)) {
+ return disableFormElement(element);
+ } else if (matches(element, Rails.formSubmitSelector)) {
+ return disableFormElements(element);
+ }
+ };
+
+ disableLinkElement = function disableLinkElement(element) {
+ var replacement;
+
+ if (getData(element, 'ujs:disabled')) {
+ return;
+ }
+
+ replacement = element.getAttribute('data-disable-with');
+
+ if (replacement != null) {
+ setData(element, 'ujs:enable-with', element.innerHTML);
+ element.innerHTML = replacement;
+ }
+
+ element.addEventListener('click', stopEverything);
+ return setData(element, 'ujs:disabled', true);
+ };
+
+ enableLinkElement = function enableLinkElement(element) {
+ var originalText;
+ originalText = getData(element, 'ujs:enable-with');
+
+ if (originalText != null) {
+ element.innerHTML = originalText;
+ setData(element, 'ujs:enable-with', null);
+ }
+
+ element.removeEventListener('click', stopEverything);
+ return setData(element, 'ujs:disabled', null);
+ };
+
+ disableFormElements = function disableFormElements(form) {
+ return formElements(form, Rails.formDisableSelector).forEach(disableFormElement);
+ };
+
+ disableFormElement = function disableFormElement(element) {
+ var replacement;
+
+ if (getData(element, 'ujs:disabled')) {
+ return;
+ }
+
+ replacement = element.getAttribute('data-disable-with');
+
+ if (replacement != null) {
+ if (matches(element, 'button')) {
+ setData(element, 'ujs:enable-with', element.innerHTML);
+ element.innerHTML = replacement;
+ } else {
+ setData(element, 'ujs:enable-with', element.value);
+ element.value = replacement;
+ }
+ }
+
+ element.disabled = true;
+ return setData(element, 'ujs:disabled', true);
+ };
+
+ enableFormElements = function enableFormElements(form) {
+ return formElements(form, Rails.formEnableSelector).forEach(enableFormElement);
+ };
+
+ enableFormElement = function enableFormElement(element) {
+ var originalText;
+ originalText = getData(element, 'ujs:enable-with');
+
+ if (originalText != null) {
+ if (matches(element, 'button')) {
+ element.innerHTML = originalText;
+ } else {
+ element.value = originalText;
+ }
+
+ setData(element, 'ujs:enable-with', null);
+ }
+
+ element.disabled = false;
+ return setData(element, 'ujs:disabled', null);
+ };
+
+ isXhrRedirect = function isXhrRedirect(event) {
+ var ref, xhr;
+ xhr = (ref = event.detail) != null ? ref[0] : void 0;
+ return (xhr != null ? xhr.getResponseHeader("X-Xhr-Redirect") : void 0) != null;
+ };
+ }).call(this);
+ (function () {
+ var stopEverything;
+ stopEverything = Rails.stopEverything;
+
+ Rails.handleMethod = function (e) {
+ var csrfParam, csrfToken, form, formContent, href, link, method;
+ link = this;
+ method = link.getAttribute('data-method');
+
+ if (!method) {
+ return;
+ }
+
+ href = Rails.href(link);
+ csrfToken = Rails.csrfToken();
+ csrfParam = Rails.csrfParam();
+ form = document.createElement('form');
+ formContent = " ";
+
+ if (csrfParam != null && csrfToken != null && !Rails.isCrossDomain(href)) {
+ formContent += " ";
+ }
+
+ formContent += ' ';
+ form.method = 'post';
+ form.action = href;
+ form.target = link.target;
+ form.innerHTML = formContent;
+ form.style.display = 'none';
+ document.body.appendChild(form);
+ form.querySelector('[type="submit"]').click();
+ return stopEverything(e);
+ };
+ }).call(this);
+ (function () {
+ var ajax,
+ fire,
+ getData,
+ isCrossDomain,
+ isRemote,
+ matches,
+ serializeElement,
+ setData,
+ stopEverything,
+ slice = [].slice;
+ matches = Rails.matches, getData = Rails.getData, setData = Rails.setData, fire = Rails.fire, stopEverything = Rails.stopEverything, ajax = Rails.ajax, isCrossDomain = Rails.isCrossDomain, serializeElement = Rails.serializeElement;
+
+ isRemote = function isRemote(element) {
+ var value;
+ value = element.getAttribute('data-remote');
+ return value != null && value !== 'false';
+ };
+
+ Rails.handleRemote = function (e) {
+ var button, data, dataType, element, method, url, withCredentials;
+ element = this;
+
+ if (!isRemote(element)) {
+ return true;
+ }
+
+ if (!fire(element, 'ajax:before')) {
+ fire(element, 'ajax:stopped');
+ return false;
+ }
+
+ withCredentials = element.getAttribute('data-with-credentials');
+ dataType = element.getAttribute('data-type') || 'script';
+
+ if (matches(element, Rails.formSubmitSelector)) {
+ button = getData(element, 'ujs:submit-button');
+ method = getData(element, 'ujs:submit-button-formmethod') || element.method;
+ url = getData(element, 'ujs:submit-button-formaction') || element.getAttribute('action') || location.href;
+
+ if (method.toUpperCase() === 'GET') {
+ url = url.replace(/\?.*$/, '');
+ }
+
+ if (element.enctype === 'multipart/form-data') {
+ data = new FormData(element);
+
+ if (button != null) {
+ data.append(button.name, button.value);
+ }
+ } else {
+ data = serializeElement(element, button);
+ }
+
+ setData(element, 'ujs:submit-button', null);
+ setData(element, 'ujs:submit-button-formmethod', null);
+ setData(element, 'ujs:submit-button-formaction', null);
+ } else if (matches(element, Rails.buttonClickSelector) || matches(element, Rails.inputChangeSelector)) {
+ method = element.getAttribute('data-method');
+ url = element.getAttribute('data-url');
+ data = serializeElement(element, element.getAttribute('data-params'));
+ } else {
+ method = element.getAttribute('data-method');
+ url = Rails.href(element);
+ data = element.getAttribute('data-params');
+ }
+
+ ajax({
+ type: method || 'GET',
+ url: url,
+ data: data,
+ dataType: dataType,
+ beforeSend: function beforeSend(xhr, options) {
+ if (fire(element, 'ajax:beforeSend', [xhr, options])) {
+ return fire(element, 'ajax:send', [xhr]);
+ } else {
+ fire(element, 'ajax:stopped');
+ return false;
+ }
+ },
+ success: function success() {
+ var args;
+ args = 1 <= arguments.length ? slice.call(arguments, 0) : [];
+ return fire(element, 'ajax:success', args);
+ },
+ error: function error() {
+ var args;
+ args = 1 <= arguments.length ? slice.call(arguments, 0) : [];
+ return fire(element, 'ajax:error', args);
+ },
+ complete: function complete() {
+ var args;
+ args = 1 <= arguments.length ? slice.call(arguments, 0) : [];
+ return fire(element, 'ajax:complete', args);
+ },
+ crossDomain: isCrossDomain(url),
+ withCredentials: withCredentials != null && withCredentials !== 'false'
+ });
+ return stopEverything(e);
+ };
+
+ Rails.formSubmitButtonClick = function (e) {
+ var button, form;
+ button = this;
+ form = button.form;
+
+ if (!form) {
+ return;
+ }
+
+ if (button.name) {
+ setData(form, 'ujs:submit-button', {
+ name: button.name,
+ value: button.value
+ });
+ }
+
+ setData(form, 'ujs:formnovalidate-button', button.formNoValidate);
+ setData(form, 'ujs:submit-button-formaction', button.getAttribute('formaction'));
+ return setData(form, 'ujs:submit-button-formmethod', button.getAttribute('formmethod'));
+ };
+
+ Rails.preventInsignificantClick = function (e) {
+ var data, insignificantMetaClick, link, metaClick, method, nonPrimaryMouseClick;
+ link = this;
+ method = (link.getAttribute('data-method') || 'GET').toUpperCase();
+ data = link.getAttribute('data-params');
+ metaClick = e.metaKey || e.ctrlKey;
+ insignificantMetaClick = metaClick && method === 'GET' && !data;
+ nonPrimaryMouseClick = e.button != null && e.button !== 0;
+
+ if (nonPrimaryMouseClick || insignificantMetaClick) {
+ return e.stopImmediatePropagation();
+ }
+ };
+ }).call(this);
+ (function () {
+ var $, CSRFProtection, delegate, disableElement, enableElement, fire, formSubmitButtonClick, getData, handleConfirm, handleDisabledElement, handleMethod, handleRemote, loadCSPNonce, preventInsignificantClick, refreshCSRFTokens;
+ fire = Rails.fire, delegate = Rails.delegate, getData = Rails.getData, $ = Rails.$, refreshCSRFTokens = Rails.refreshCSRFTokens, CSRFProtection = Rails.CSRFProtection, loadCSPNonce = Rails.loadCSPNonce, enableElement = Rails.enableElement, disableElement = Rails.disableElement, handleDisabledElement = Rails.handleDisabledElement, handleConfirm = Rails.handleConfirm, preventInsignificantClick = Rails.preventInsignificantClick, handleRemote = Rails.handleRemote, formSubmitButtonClick = Rails.formSubmitButtonClick, handleMethod = Rails.handleMethod;
+
+ if (typeof jQuery !== "undefined" && jQuery !== null && jQuery.ajax != null) {
+ if (jQuery.rails) {
+ throw new Error('If you load both jquery_ujs and rails-ujs, use rails-ujs only.');
+ }
+
+ jQuery.rails = Rails;
+ jQuery.ajaxPrefilter(function (options, originalOptions, xhr) {
+ if (!options.crossDomain) {
+ return CSRFProtection(xhr);
+ }
+ });
+ }
+
+ Rails.start = function () {
+ if (window._rails_loaded) {
+ throw new Error('rails-ujs has already been loaded!');
+ }
+
+ window.addEventListener('pageshow', function () {
+ $(Rails.formEnableSelector).forEach(function (el) {
+ if (getData(el, 'ujs:disabled')) {
+ return enableElement(el);
+ }
+ });
+ return $(Rails.linkDisableSelector).forEach(function (el) {
+ if (getData(el, 'ujs:disabled')) {
+ return enableElement(el);
+ }
+ });
+ });
+ delegate(document, Rails.linkDisableSelector, 'ajax:complete', enableElement);
+ delegate(document, Rails.linkDisableSelector, 'ajax:stopped', enableElement);
+ delegate(document, Rails.buttonDisableSelector, 'ajax:complete', enableElement);
+ delegate(document, Rails.buttonDisableSelector, 'ajax:stopped', enableElement);
+ delegate(document, Rails.linkClickSelector, 'click', preventInsignificantClick);
+ delegate(document, Rails.linkClickSelector, 'click', handleDisabledElement);
+ delegate(document, Rails.linkClickSelector, 'click', handleConfirm);
+ delegate(document, Rails.linkClickSelector, 'click', disableElement);
+ delegate(document, Rails.linkClickSelector, 'click', handleRemote);
+ delegate(document, Rails.linkClickSelector, 'click', handleMethod);
+ delegate(document, Rails.buttonClickSelector, 'click', preventInsignificantClick);
+ delegate(document, Rails.buttonClickSelector, 'click', handleDisabledElement);
+ delegate(document, Rails.buttonClickSelector, 'click', handleConfirm);
+ delegate(document, Rails.buttonClickSelector, 'click', disableElement);
+ delegate(document, Rails.buttonClickSelector, 'click', handleRemote);
+ delegate(document, Rails.inputChangeSelector, 'change', handleDisabledElement);
+ delegate(document, Rails.inputChangeSelector, 'change', handleConfirm);
+ delegate(document, Rails.inputChangeSelector, 'change', handleRemote);
+ delegate(document, Rails.formSubmitSelector, 'submit', handleDisabledElement);
+ delegate(document, Rails.formSubmitSelector, 'submit', handleConfirm);
+ delegate(document, Rails.formSubmitSelector, 'submit', handleRemote);
+ delegate(document, Rails.formSubmitSelector, 'submit', function (e) {
+ return setTimeout(function () {
+ return disableElement(e);
+ }, 13);
+ });
+ delegate(document, Rails.formSubmitSelector, 'ajax:send', disableElement);
+ delegate(document, Rails.formSubmitSelector, 'ajax:complete', enableElement);
+ delegate(document, Rails.formInputClickSelector, 'click', preventInsignificantClick);
+ delegate(document, Rails.formInputClickSelector, 'click', handleDisabledElement);
+ delegate(document, Rails.formInputClickSelector, 'click', handleConfirm);
+ delegate(document, Rails.formInputClickSelector, 'click', formSubmitButtonClick);
+ document.addEventListener('DOMContentLoaded', refreshCSRFTokens);
+ document.addEventListener('DOMContentLoaded', loadCSPNonce);
+ return window._rails_loaded = true;
+ };
+
+ if (window.Rails === Rails && fire(document, 'rails:attachBindings')) {
+ Rails.start();
+ }
+ }).call(this);
+ }).call(this);
+
+ if (( false ? undefined : _typeof(module)) === "object" && module.exports) {
+ module.exports = Rails;
+ } else if (true) {
+ !(__WEBPACK_AMD_DEFINE_FACTORY__ = (Rails),
+ __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ?
+ (__WEBPACK_AMD_DEFINE_FACTORY__.call(exports, __webpack_require__, exports, module)) :
+ __WEBPACK_AMD_DEFINE_FACTORY__),
+ __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
+ }
+}).call(this);
+/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! jquery */ "./node_modules/jquery/dist/jquery.js"), __webpack_require__(/*! ./../../../../../webpack/buildin/module.js */ "./node_modules/webpack/buildin/module.js")(module)))
+
+/***/ }),
+
+/***/ "./node_modules/bootstrap/dist/js/bootstrap.js":
+/*!*****************************************************!*\
+ !*** ./node_modules/bootstrap/dist/js/bootstrap.js ***!
+ \*****************************************************/
+/*! no static exports found */
+/***/ (function(module, exports, __webpack_require__) {
+
+var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
+
+/*!
+ * Bootstrap v4.4.1 (https://getbootstrap.com/)
+ * Copyright 2011-2019 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ */
+(function (global, factory) {
+ ( false ? undefined : _typeof(exports)) === 'object' && typeof module !== 'undefined' ? factory(exports, __webpack_require__(/*! jquery */ "./node_modules/jquery/dist/jquery.js"), __webpack_require__(/*! popper.js */ "./node_modules/popper.js/dist/esm/popper.js")) : true ? !(__WEBPACK_AMD_DEFINE_ARRAY__ = [exports, __webpack_require__(/*! jquery */ "./node_modules/jquery/dist/jquery.js"), __webpack_require__(/*! popper.js */ "./node_modules/popper.js/dist/esm/popper.js")], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory),
+ __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ?
+ (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__),
+ __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)) : (undefined);
+})(this, function (exports, $, Popper) {
+ 'use strict';
+
+ $ = $ && $.hasOwnProperty('default') ? $['default'] : $;
+ Popper = Popper && Popper.hasOwnProperty('default') ? Popper['default'] : Popper;
+
+ function _defineProperties(target, props) {
+ for (var i = 0; i < props.length; i++) {
+ var descriptor = props[i];
+ descriptor.enumerable = descriptor.enumerable || false;
+ descriptor.configurable = true;
+ if ("value" in descriptor) descriptor.writable = true;
+ Object.defineProperty(target, descriptor.key, descriptor);
+ }
+ }
+
+ function _createClass(Constructor, protoProps, staticProps) {
+ if (protoProps) _defineProperties(Constructor.prototype, protoProps);
+ if (staticProps) _defineProperties(Constructor, staticProps);
+ return Constructor;
+ }
+
+ function _defineProperty(obj, key, value) {
+ if (key in obj) {
+ Object.defineProperty(obj, key, {
+ value: value,
+ enumerable: true,
+ configurable: true,
+ writable: true
+ });
+ } else {
+ obj[key] = value;
+ }
+
+ return obj;
+ }
+
+ function ownKeys(object, enumerableOnly) {
+ var keys = Object.keys(object);
+
+ if (Object.getOwnPropertySymbols) {
+ var symbols = Object.getOwnPropertySymbols(object);
+ if (enumerableOnly) symbols = symbols.filter(function (sym) {
+ return Object.getOwnPropertyDescriptor(object, sym).enumerable;
+ });
+ keys.push.apply(keys, symbols);
+ }
+
+ return keys;
+ }
+
+ function _objectSpread2(target) {
+ for (var i = 1; i < arguments.length; i++) {
+ var source = arguments[i] != null ? arguments[i] : {};
+
+ if (i % 2) {
+ ownKeys(Object(source), true).forEach(function (key) {
+ _defineProperty(target, key, source[key]);
+ });
+ } else if (Object.getOwnPropertyDescriptors) {
+ Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
+ } else {
+ ownKeys(Object(source)).forEach(function (key) {
+ Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
+ });
+ }
+ }
+
+ return target;
+ }
+
+ function _inheritsLoose(subClass, superClass) {
+ subClass.prototype = Object.create(superClass.prototype);
+ subClass.prototype.constructor = subClass;
+ subClass.__proto__ = superClass;
+ }
+ /**
+ * --------------------------------------------------------------------------
+ * Bootstrap (v4.4.1): util.js
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * --------------------------------------------------------------------------
+ */
+
+ /**
+ * ------------------------------------------------------------------------
+ * Private TransitionEnd Helpers
+ * ------------------------------------------------------------------------
+ */
+
+
+ var TRANSITION_END = 'transitionend';
+ var MAX_UID = 1000000;
+ var MILLISECONDS_MULTIPLIER = 1000; // Shoutout AngusCroll (https://goo.gl/pxwQGp)
+
+ function toType(obj) {
+ return {}.toString.call(obj).match(/\s([a-z]+)/i)[1].toLowerCase();
+ }
+
+ function getSpecialTransitionEndEvent() {
+ return {
+ bindType: TRANSITION_END,
+ delegateType: TRANSITION_END,
+ handle: function handle(event) {
+ if ($(event.target).is(this)) {
+ return event.handleObj.handler.apply(this, arguments); // eslint-disable-line prefer-rest-params
+ }
+
+ return undefined; // eslint-disable-line no-undefined
+ }
+ };
+ }
+
+ function transitionEndEmulator(duration) {
+ var _this = this;
+
+ var called = false;
+ $(this).one(Util.TRANSITION_END, function () {
+ called = true;
+ });
+ setTimeout(function () {
+ if (!called) {
+ Util.triggerTransitionEnd(_this);
+ }
+ }, duration);
+ return this;
+ }
+
+ function setTransitionEndSupport() {
+ $.fn.emulateTransitionEnd = transitionEndEmulator;
+ $.event.special[Util.TRANSITION_END] = getSpecialTransitionEndEvent();
+ }
+ /**
+ * --------------------------------------------------------------------------
+ * Public Util Api
+ * --------------------------------------------------------------------------
+ */
+
+
+ var Util = {
+ TRANSITION_END: 'bsTransitionEnd',
+ getUID: function getUID(prefix) {
+ do {
+ // eslint-disable-next-line no-bitwise
+ prefix += ~~(Math.random() * MAX_UID); // "~~" acts like a faster Math.floor() here
+ } while (document.getElementById(prefix));
+
+ return prefix;
+ },
+ getSelectorFromElement: function getSelectorFromElement(element) {
+ var selector = element.getAttribute('data-target');
+
+ if (!selector || selector === '#') {
+ var hrefAttr = element.getAttribute('href');
+ selector = hrefAttr && hrefAttr !== '#' ? hrefAttr.trim() : '';
+ }
+
+ try {
+ return document.querySelector(selector) ? selector : null;
+ } catch (err) {
+ return null;
+ }
+ },
+ getTransitionDurationFromElement: function getTransitionDurationFromElement(element) {
+ if (!element) {
+ return 0;
+ } // Get transition-duration of the element
+
+
+ var transitionDuration = $(element).css('transition-duration');
+ var transitionDelay = $(element).css('transition-delay');
+ var floatTransitionDuration = parseFloat(transitionDuration);
+ var floatTransitionDelay = parseFloat(transitionDelay); // Return 0 if element or transition duration is not found
+
+ if (!floatTransitionDuration && !floatTransitionDelay) {
+ return 0;
+ } // If multiple durations are defined, take the first
+
+
+ transitionDuration = transitionDuration.split(',')[0];
+ transitionDelay = transitionDelay.split(',')[0];
+ return (parseFloat(transitionDuration) + parseFloat(transitionDelay)) * MILLISECONDS_MULTIPLIER;
+ },
+ reflow: function reflow(element) {
+ return element.offsetHeight;
+ },
+ triggerTransitionEnd: function triggerTransitionEnd(element) {
+ $(element).trigger(TRANSITION_END);
+ },
+ // TODO: Remove in v5
+ supportsTransitionEnd: function supportsTransitionEnd() {
+ return Boolean(TRANSITION_END);
+ },
+ isElement: function isElement(obj) {
+ return (obj[0] || obj).nodeType;
+ },
+ typeCheckConfig: function typeCheckConfig(componentName, config, configTypes) {
+ for (var property in configTypes) {
+ if (Object.prototype.hasOwnProperty.call(configTypes, property)) {
+ var expectedTypes = configTypes[property];
+ var value = config[property];
+ var valueType = value && Util.isElement(value) ? 'element' : toType(value);
+
+ if (!new RegExp(expectedTypes).test(valueType)) {
+ throw new Error(componentName.toUpperCase() + ": " + ("Option \"" + property + "\" provided type \"" + valueType + "\" ") + ("but expected type \"" + expectedTypes + "\"."));
+ }
+ }
+ }
+ },
+ findShadowRoot: function findShadowRoot(element) {
+ if (!document.documentElement.attachShadow) {
+ return null;
+ } // Can find the shadow root otherwise it'll return the document
+
+
+ if (typeof element.getRootNode === 'function') {
+ var root = element.getRootNode();
+ return root instanceof ShadowRoot ? root : null;
+ }
+
+ if (element instanceof ShadowRoot) {
+ return element;
+ } // when we don't find a shadow root
+
+
+ if (!element.parentNode) {
+ return null;
+ }
+
+ return Util.findShadowRoot(element.parentNode);
+ },
+ jQueryDetection: function jQueryDetection() {
+ if (typeof $ === 'undefined') {
+ throw new TypeError('Bootstrap\'s JavaScript requires jQuery. jQuery must be included before Bootstrap\'s JavaScript.');
+ }
+
+ var version = $.fn.jquery.split(' ')[0].split('.');
+ var minMajor = 1;
+ var ltMajor = 2;
+ var minMinor = 9;
+ var minPatch = 1;
+ var maxMajor = 4;
+
+ if (version[0] < ltMajor && version[1] < minMinor || version[0] === minMajor && version[1] === minMinor && version[2] < minPatch || version[0] >= maxMajor) {
+ throw new Error('Bootstrap\'s JavaScript requires at least jQuery v1.9.1 but less than v4.0.0');
+ }
+ }
+ };
+ Util.jQueryDetection();
+ setTransitionEndSupport();
+ /**
+ * ------------------------------------------------------------------------
+ * Constants
+ * ------------------------------------------------------------------------
+ */
+
+ var NAME = 'alert';
+ var VERSION = '4.4.1';
+ var DATA_KEY = 'bs.alert';
+ var EVENT_KEY = "." + DATA_KEY;
+ var DATA_API_KEY = '.data-api';
+ var JQUERY_NO_CONFLICT = $.fn[NAME];
+ var Selector = {
+ DISMISS: '[data-dismiss="alert"]'
+ };
+ var Event = {
+ CLOSE: "close" + EVENT_KEY,
+ CLOSED: "closed" + EVENT_KEY,
+ CLICK_DATA_API: "click" + EVENT_KEY + DATA_API_KEY
+ };
+ var ClassName = {
+ ALERT: 'alert',
+ FADE: 'fade',
+ SHOW: 'show'
+ };
+ /**
+ * ------------------------------------------------------------------------
+ * Class Definition
+ * ------------------------------------------------------------------------
+ */
+
+ var Alert = /*#__PURE__*/function () {
+ function Alert(element) {
+ this._element = element;
+ } // Getters
+
+
+ var _proto = Alert.prototype; // Public
+
+ _proto.close = function close(element) {
+ var rootElement = this._element;
+
+ if (element) {
+ rootElement = this._getRootElement(element);
+ }
+
+ var customEvent = this._triggerCloseEvent(rootElement);
+
+ if (customEvent.isDefaultPrevented()) {
+ return;
+ }
+
+ this._removeElement(rootElement);
+ };
+
+ _proto.dispose = function dispose() {
+ $.removeData(this._element, DATA_KEY);
+ this._element = null;
+ } // Private
+ ;
+
+ _proto._getRootElement = function _getRootElement(element) {
+ var selector = Util.getSelectorFromElement(element);
+ var parent = false;
+
+ if (selector) {
+ parent = document.querySelector(selector);
+ }
+
+ if (!parent) {
+ parent = $(element).closest("." + ClassName.ALERT)[0];
+ }
+
+ return parent;
+ };
+
+ _proto._triggerCloseEvent = function _triggerCloseEvent(element) {
+ var closeEvent = $.Event(Event.CLOSE);
+ $(element).trigger(closeEvent);
+ return closeEvent;
+ };
+
+ _proto._removeElement = function _removeElement(element) {
+ var _this = this;
+
+ $(element).removeClass(ClassName.SHOW);
+
+ if (!$(element).hasClass(ClassName.FADE)) {
+ this._destroyElement(element);
+
+ return;
+ }
+
+ var transitionDuration = Util.getTransitionDurationFromElement(element);
+ $(element).one(Util.TRANSITION_END, function (event) {
+ return _this._destroyElement(element, event);
+ }).emulateTransitionEnd(transitionDuration);
+ };
+
+ _proto._destroyElement = function _destroyElement(element) {
+ $(element).detach().trigger(Event.CLOSED).remove();
+ } // Static
+ ;
+
+ Alert._jQueryInterface = function _jQueryInterface(config) {
+ return this.each(function () {
+ var $element = $(this);
+ var data = $element.data(DATA_KEY);
+
+ if (!data) {
+ data = new Alert(this);
+ $element.data(DATA_KEY, data);
+ }
+
+ if (config === 'close') {
+ data[config](this);
+ }
+ });
+ };
+
+ Alert._handleDismiss = function _handleDismiss(alertInstance) {
+ return function (event) {
+ if (event) {
+ event.preventDefault();
+ }
+
+ alertInstance.close(this);
+ };
+ };
+
+ _createClass(Alert, null, [{
+ key: "VERSION",
+ get: function get() {
+ return VERSION;
+ }
+ }]);
+
+ return Alert;
+ }();
+ /**
+ * ------------------------------------------------------------------------
+ * Data Api implementation
+ * ------------------------------------------------------------------------
+ */
+
+
+ $(document).on(Event.CLICK_DATA_API, Selector.DISMISS, Alert._handleDismiss(new Alert()));
+ /**
+ * ------------------------------------------------------------------------
+ * jQuery
+ * ------------------------------------------------------------------------
+ */
+
+ $.fn[NAME] = Alert._jQueryInterface;
+ $.fn[NAME].Constructor = Alert;
+
+ $.fn[NAME].noConflict = function () {
+ $.fn[NAME] = JQUERY_NO_CONFLICT;
+ return Alert._jQueryInterface;
+ };
+ /**
+ * ------------------------------------------------------------------------
+ * Constants
+ * ------------------------------------------------------------------------
+ */
+
+
+ var NAME$1 = 'button';
+ var VERSION$1 = '4.4.1';
+ var DATA_KEY$1 = 'bs.button';
+ var EVENT_KEY$1 = "." + DATA_KEY$1;
+ var DATA_API_KEY$1 = '.data-api';
+ var JQUERY_NO_CONFLICT$1 = $.fn[NAME$1];
+ var ClassName$1 = {
+ ACTIVE: 'active',
+ BUTTON: 'btn',
+ FOCUS: 'focus'
+ };
+ var Selector$1 = {
+ DATA_TOGGLE_CARROT: '[data-toggle^="button"]',
+ DATA_TOGGLES: '[data-toggle="buttons"]',
+ DATA_TOGGLE: '[data-toggle="button"]',
+ DATA_TOGGLES_BUTTONS: '[data-toggle="buttons"] .btn',
+ INPUT: 'input:not([type="hidden"])',
+ ACTIVE: '.active',
+ BUTTON: '.btn'
+ };
+ var Event$1 = {
+ CLICK_DATA_API: "click" + EVENT_KEY$1 + DATA_API_KEY$1,
+ FOCUS_BLUR_DATA_API: "focus" + EVENT_KEY$1 + DATA_API_KEY$1 + " " + ("blur" + EVENT_KEY$1 + DATA_API_KEY$1),
+ LOAD_DATA_API: "load" + EVENT_KEY$1 + DATA_API_KEY$1
+ };
+ /**
+ * ------------------------------------------------------------------------
+ * Class Definition
+ * ------------------------------------------------------------------------
+ */
+
+ var Button = /*#__PURE__*/function () {
+ function Button(element) {
+ this._element = element;
+ } // Getters
+
+
+ var _proto = Button.prototype; // Public
+
+ _proto.toggle = function toggle() {
+ var triggerChangeEvent = true;
+ var addAriaPressed = true;
+ var rootElement = $(this._element).closest(Selector$1.DATA_TOGGLES)[0];
+
+ if (rootElement) {
+ var input = this._element.querySelector(Selector$1.INPUT);
+
+ if (input) {
+ if (input.type === 'radio') {
+ if (input.checked && this._element.classList.contains(ClassName$1.ACTIVE)) {
+ triggerChangeEvent = false;
+ } else {
+ var activeElement = rootElement.querySelector(Selector$1.ACTIVE);
+
+ if (activeElement) {
+ $(activeElement).removeClass(ClassName$1.ACTIVE);
+ }
+ }
+ } else if (input.type === 'checkbox') {
+ if (this._element.tagName === 'LABEL' && input.checked === this._element.classList.contains(ClassName$1.ACTIVE)) {
+ triggerChangeEvent = false;
+ }
+ } else {
+ // if it's not a radio button or checkbox don't add a pointless/invalid checked property to the input
+ triggerChangeEvent = false;
+ }
+
+ if (triggerChangeEvent) {
+ input.checked = !this._element.classList.contains(ClassName$1.ACTIVE);
+ $(input).trigger('change');
+ }
+
+ input.focus();
+ addAriaPressed = false;
+ }
+ }
+
+ if (!(this._element.hasAttribute('disabled') || this._element.classList.contains('disabled'))) {
+ if (addAriaPressed) {
+ this._element.setAttribute('aria-pressed', !this._element.classList.contains(ClassName$1.ACTIVE));
+ }
+
+ if (triggerChangeEvent) {
+ $(this._element).toggleClass(ClassName$1.ACTIVE);
+ }
+ }
+ };
+
+ _proto.dispose = function dispose() {
+ $.removeData(this._element, DATA_KEY$1);
+ this._element = null;
+ } // Static
+ ;
+
+ Button._jQueryInterface = function _jQueryInterface(config) {
+ return this.each(function () {
+ var data = $(this).data(DATA_KEY$1);
+
+ if (!data) {
+ data = new Button(this);
+ $(this).data(DATA_KEY$1, data);
+ }
+
+ if (config === 'toggle') {
+ data[config]();
+ }
+ });
+ };
+
+ _createClass(Button, null, [{
+ key: "VERSION",
+ get: function get() {
+ return VERSION$1;
+ }
+ }]);
+
+ return Button;
+ }();
+ /**
+ * ------------------------------------------------------------------------
+ * Data Api implementation
+ * ------------------------------------------------------------------------
+ */
+
+
+ $(document).on(Event$1.CLICK_DATA_API, Selector$1.DATA_TOGGLE_CARROT, function (event) {
+ var button = event.target;
+
+ if (!$(button).hasClass(ClassName$1.BUTTON)) {
+ button = $(button).closest(Selector$1.BUTTON)[0];
+ }
+
+ if (!button || button.hasAttribute('disabled') || button.classList.contains('disabled')) {
+ event.preventDefault(); // work around Firefox bug #1540995
+ } else {
+ var inputBtn = button.querySelector(Selector$1.INPUT);
+
+ if (inputBtn && (inputBtn.hasAttribute('disabled') || inputBtn.classList.contains('disabled'))) {
+ event.preventDefault(); // work around Firefox bug #1540995
+
+ return;
+ }
+
+ Button._jQueryInterface.call($(button), 'toggle');
+ }
+ }).on(Event$1.FOCUS_BLUR_DATA_API, Selector$1.DATA_TOGGLE_CARROT, function (event) {
+ var button = $(event.target).closest(Selector$1.BUTTON)[0];
+ $(button).toggleClass(ClassName$1.FOCUS, /^focus(in)?$/.test(event.type));
+ });
+ $(window).on(Event$1.LOAD_DATA_API, function () {
+ // ensure correct active class is set to match the controls' actual values/states
+ // find all checkboxes/readio buttons inside data-toggle groups
+ var buttons = [].slice.call(document.querySelectorAll(Selector$1.DATA_TOGGLES_BUTTONS));
+
+ for (var i = 0, len = buttons.length; i < len; i++) {
+ var button = buttons[i];
+ var input = button.querySelector(Selector$1.INPUT);
+
+ if (input.checked || input.hasAttribute('checked')) {
+ button.classList.add(ClassName$1.ACTIVE);
+ } else {
+ button.classList.remove(ClassName$1.ACTIVE);
+ }
+ } // find all button toggles
+
+
+ buttons = [].slice.call(document.querySelectorAll(Selector$1.DATA_TOGGLE));
+
+ for (var _i = 0, _len = buttons.length; _i < _len; _i++) {
+ var _button = buttons[_i];
+
+ if (_button.getAttribute('aria-pressed') === 'true') {
+ _button.classList.add(ClassName$1.ACTIVE);
+ } else {
+ _button.classList.remove(ClassName$1.ACTIVE);
+ }
+ }
+ });
+ /**
+ * ------------------------------------------------------------------------
+ * jQuery
+ * ------------------------------------------------------------------------
+ */
+
+ $.fn[NAME$1] = Button._jQueryInterface;
+ $.fn[NAME$1].Constructor = Button;
+
+ $.fn[NAME$1].noConflict = function () {
+ $.fn[NAME$1] = JQUERY_NO_CONFLICT$1;
+ return Button._jQueryInterface;
+ };
+ /**
+ * ------------------------------------------------------------------------
+ * Constants
+ * ------------------------------------------------------------------------
+ */
+
+
+ var NAME$2 = 'carousel';
+ var VERSION$2 = '4.4.1';
+ var DATA_KEY$2 = 'bs.carousel';
+ var EVENT_KEY$2 = "." + DATA_KEY$2;
+ var DATA_API_KEY$2 = '.data-api';
+ var JQUERY_NO_CONFLICT$2 = $.fn[NAME$2];
+ var ARROW_LEFT_KEYCODE = 37; // KeyboardEvent.which value for left arrow key
+
+ var ARROW_RIGHT_KEYCODE = 39; // KeyboardEvent.which value for right arrow key
+
+ var TOUCHEVENT_COMPAT_WAIT = 500; // Time for mouse compat events to fire after touch
+
+ var SWIPE_THRESHOLD = 40;
+ var Default = {
+ interval: 5000,
+ keyboard: true,
+ slide: false,
+ pause: 'hover',
+ wrap: true,
+ touch: true
+ };
+ var DefaultType = {
+ interval: '(number|boolean)',
+ keyboard: 'boolean',
+ slide: '(boolean|string)',
+ pause: '(string|boolean)',
+ wrap: 'boolean',
+ touch: 'boolean'
+ };
+ var Direction = {
+ NEXT: 'next',
+ PREV: 'prev',
+ LEFT: 'left',
+ RIGHT: 'right'
+ };
+ var Event$2 = {
+ SLIDE: "slide" + EVENT_KEY$2,
+ SLID: "slid" + EVENT_KEY$2,
+ KEYDOWN: "keydown" + EVENT_KEY$2,
+ MOUSEENTER: "mouseenter" + EVENT_KEY$2,
+ MOUSELEAVE: "mouseleave" + EVENT_KEY$2,
+ TOUCHSTART: "touchstart" + EVENT_KEY$2,
+ TOUCHMOVE: "touchmove" + EVENT_KEY$2,
+ TOUCHEND: "touchend" + EVENT_KEY$2,
+ POINTERDOWN: "pointerdown" + EVENT_KEY$2,
+ POINTERUP: "pointerup" + EVENT_KEY$2,
+ DRAG_START: "dragstart" + EVENT_KEY$2,
+ LOAD_DATA_API: "load" + EVENT_KEY$2 + DATA_API_KEY$2,
+ CLICK_DATA_API: "click" + EVENT_KEY$2 + DATA_API_KEY$2
+ };
+ var ClassName$2 = {
+ CAROUSEL: 'carousel',
+ ACTIVE: 'active',
+ SLIDE: 'slide',
+ RIGHT: 'carousel-item-right',
+ LEFT: 'carousel-item-left',
+ NEXT: 'carousel-item-next',
+ PREV: 'carousel-item-prev',
+ ITEM: 'carousel-item',
+ POINTER_EVENT: 'pointer-event'
+ };
+ var Selector$2 = {
+ ACTIVE: '.active',
+ ACTIVE_ITEM: '.active.carousel-item',
+ ITEM: '.carousel-item',
+ ITEM_IMG: '.carousel-item img',
+ NEXT_PREV: '.carousel-item-next, .carousel-item-prev',
+ INDICATORS: '.carousel-indicators',
+ DATA_SLIDE: '[data-slide], [data-slide-to]',
+ DATA_RIDE: '[data-ride="carousel"]'
+ };
+ var PointerType = {
+ TOUCH: 'touch',
+ PEN: 'pen'
+ };
+ /**
+ * ------------------------------------------------------------------------
+ * Class Definition
+ * ------------------------------------------------------------------------
+ */
+
+ var Carousel = /*#__PURE__*/function () {
+ function Carousel(element, config) {
+ this._items = null;
+ this._interval = null;
+ this._activeElement = null;
+ this._isPaused = false;
+ this._isSliding = false;
+ this.touchTimeout = null;
+ this.touchStartX = 0;
+ this.touchDeltaX = 0;
+ this._config = this._getConfig(config);
+ this._element = element;
+ this._indicatorsElement = this._element.querySelector(Selector$2.INDICATORS);
+ this._touchSupported = 'ontouchstart' in document.documentElement || navigator.maxTouchPoints > 0;
+ this._pointerEvent = Boolean(window.PointerEvent || window.MSPointerEvent);
+
+ this._addEventListeners();
+ } // Getters
+
+
+ var _proto = Carousel.prototype; // Public
+
+ _proto.next = function next() {
+ if (!this._isSliding) {
+ this._slide(Direction.NEXT);
+ }
+ };
+
+ _proto.nextWhenVisible = function nextWhenVisible() {
+ // Don't call next when the page isn't visible
+ // or the carousel or its parent isn't visible
+ if (!document.hidden && $(this._element).is(':visible') && $(this._element).css('visibility') !== 'hidden') {
+ this.next();
+ }
+ };
+
+ _proto.prev = function prev() {
+ if (!this._isSliding) {
+ this._slide(Direction.PREV);
+ }
+ };
+
+ _proto.pause = function pause(event) {
+ if (!event) {
+ this._isPaused = true;
+ }
+
+ if (this._element.querySelector(Selector$2.NEXT_PREV)) {
+ Util.triggerTransitionEnd(this._element);
+ this.cycle(true);
+ }
+
+ clearInterval(this._interval);
+ this._interval = null;
+ };
+
+ _proto.cycle = function cycle(event) {
+ if (!event) {
+ this._isPaused = false;
+ }
+
+ if (this._interval) {
+ clearInterval(this._interval);
+ this._interval = null;
+ }
+
+ if (this._config.interval && !this._isPaused) {
+ this._interval = setInterval((document.visibilityState ? this.nextWhenVisible : this.next).bind(this), this._config.interval);
+ }
+ };
+
+ _proto.to = function to(index) {
+ var _this = this;
+
+ this._activeElement = this._element.querySelector(Selector$2.ACTIVE_ITEM);
+
+ var activeIndex = this._getItemIndex(this._activeElement);
+
+ if (index > this._items.length - 1 || index < 0) {
+ return;
+ }
+
+ if (this._isSliding) {
+ $(this._element).one(Event$2.SLID, function () {
+ return _this.to(index);
+ });
+ return;
+ }
+
+ if (activeIndex === index) {
+ this.pause();
+ this.cycle();
+ return;
+ }
+
+ var direction = index > activeIndex ? Direction.NEXT : Direction.PREV;
+
+ this._slide(direction, this._items[index]);
+ };
+
+ _proto.dispose = function dispose() {
+ $(this._element).off(EVENT_KEY$2);
+ $.removeData(this._element, DATA_KEY$2);
+ this._items = null;
+ this._config = null;
+ this._element = null;
+ this._interval = null;
+ this._isPaused = null;
+ this._isSliding = null;
+ this._activeElement = null;
+ this._indicatorsElement = null;
+ } // Private
+ ;
+
+ _proto._getConfig = function _getConfig(config) {
+ config = _objectSpread2({}, Default, {}, config);
+ Util.typeCheckConfig(NAME$2, config, DefaultType);
+ return config;
+ };
+
+ _proto._handleSwipe = function _handleSwipe() {
+ var absDeltax = Math.abs(this.touchDeltaX);
+
+ if (absDeltax <= SWIPE_THRESHOLD) {
+ return;
+ }
+
+ var direction = absDeltax / this.touchDeltaX;
+ this.touchDeltaX = 0; // swipe left
+
+ if (direction > 0) {
+ this.prev();
+ } // swipe right
+
+
+ if (direction < 0) {
+ this.next();
+ }
+ };
+
+ _proto._addEventListeners = function _addEventListeners() {
+ var _this2 = this;
+
+ if (this._config.keyboard) {
+ $(this._element).on(Event$2.KEYDOWN, function (event) {
+ return _this2._keydown(event);
+ });
+ }
+
+ if (this._config.pause === 'hover') {
+ $(this._element).on(Event$2.MOUSEENTER, function (event) {
+ return _this2.pause(event);
+ }).on(Event$2.MOUSELEAVE, function (event) {
+ return _this2.cycle(event);
+ });
+ }
+
+ if (this._config.touch) {
+ this._addTouchEventListeners();
+ }
+ };
+
+ _proto._addTouchEventListeners = function _addTouchEventListeners() {
+ var _this3 = this;
+
+ if (!this._touchSupported) {
+ return;
+ }
+
+ var start = function start(event) {
+ if (_this3._pointerEvent && PointerType[event.originalEvent.pointerType.toUpperCase()]) {
+ _this3.touchStartX = event.originalEvent.clientX;
+ } else if (!_this3._pointerEvent) {
+ _this3.touchStartX = event.originalEvent.touches[0].clientX;
+ }
+ };
+
+ var move = function move(event) {
+ // ensure swiping with one touch and not pinching
+ if (event.originalEvent.touches && event.originalEvent.touches.length > 1) {
+ _this3.touchDeltaX = 0;
+ } else {
+ _this3.touchDeltaX = event.originalEvent.touches[0].clientX - _this3.touchStartX;
+ }
+ };
+
+ var end = function end(event) {
+ if (_this3._pointerEvent && PointerType[event.originalEvent.pointerType.toUpperCase()]) {
+ _this3.touchDeltaX = event.originalEvent.clientX - _this3.touchStartX;
+ }
+
+ _this3._handleSwipe();
+
+ if (_this3._config.pause === 'hover') {
+ // If it's a touch-enabled device, mouseenter/leave are fired as
+ // part of the mouse compatibility events on first tap - the carousel
+ // would stop cycling until user tapped out of it;
+ // here, we listen for touchend, explicitly pause the carousel
+ // (as if it's the second time we tap on it, mouseenter compat event
+ // is NOT fired) and after a timeout (to allow for mouse compatibility
+ // events to fire) we explicitly restart cycling
+ _this3.pause();
+
+ if (_this3.touchTimeout) {
+ clearTimeout(_this3.touchTimeout);
+ }
+
+ _this3.touchTimeout = setTimeout(function (event) {
+ return _this3.cycle(event);
+ }, TOUCHEVENT_COMPAT_WAIT + _this3._config.interval);
+ }
+ };
+
+ $(this._element.querySelectorAll(Selector$2.ITEM_IMG)).on(Event$2.DRAG_START, function (e) {
+ return e.preventDefault();
+ });
+
+ if (this._pointerEvent) {
+ $(this._element).on(Event$2.POINTERDOWN, function (event) {
+ return start(event);
+ });
+ $(this._element).on(Event$2.POINTERUP, function (event) {
+ return end(event);
+ });
+
+ this._element.classList.add(ClassName$2.POINTER_EVENT);
+ } else {
+ $(this._element).on(Event$2.TOUCHSTART, function (event) {
+ return start(event);
+ });
+ $(this._element).on(Event$2.TOUCHMOVE, function (event) {
+ return move(event);
+ });
+ $(this._element).on(Event$2.TOUCHEND, function (event) {
+ return end(event);
+ });
+ }
+ };
+
+ _proto._keydown = function _keydown(event) {
+ if (/input|textarea/i.test(event.target.tagName)) {
+ return;
+ }
+
+ switch (event.which) {
+ case ARROW_LEFT_KEYCODE:
+ event.preventDefault();
+ this.prev();
+ break;
+
+ case ARROW_RIGHT_KEYCODE:
+ event.preventDefault();
+ this.next();
+ break;
+ }
+ };
+
+ _proto._getItemIndex = function _getItemIndex(element) {
+ this._items = element && element.parentNode ? [].slice.call(element.parentNode.querySelectorAll(Selector$2.ITEM)) : [];
+ return this._items.indexOf(element);
+ };
+
+ _proto._getItemByDirection = function _getItemByDirection(direction, activeElement) {
+ var isNextDirection = direction === Direction.NEXT;
+ var isPrevDirection = direction === Direction.PREV;
+
+ var activeIndex = this._getItemIndex(activeElement);
+
+ var lastItemIndex = this._items.length - 1;
+ var isGoingToWrap = isPrevDirection && activeIndex === 0 || isNextDirection && activeIndex === lastItemIndex;
+
+ if (isGoingToWrap && !this._config.wrap) {
+ return activeElement;
+ }
+
+ var delta = direction === Direction.PREV ? -1 : 1;
+ var itemIndex = (activeIndex + delta) % this._items.length;
+ return itemIndex === -1 ? this._items[this._items.length - 1] : this._items[itemIndex];
+ };
+
+ _proto._triggerSlideEvent = function _triggerSlideEvent(relatedTarget, eventDirectionName) {
+ var targetIndex = this._getItemIndex(relatedTarget);
+
+ var fromIndex = this._getItemIndex(this._element.querySelector(Selector$2.ACTIVE_ITEM));
+
+ var slideEvent = $.Event(Event$2.SLIDE, {
+ relatedTarget: relatedTarget,
+ direction: eventDirectionName,
+ from: fromIndex,
+ to: targetIndex
+ });
+ $(this._element).trigger(slideEvent);
+ return slideEvent;
+ };
+
+ _proto._setActiveIndicatorElement = function _setActiveIndicatorElement(element) {
+ if (this._indicatorsElement) {
+ var indicators = [].slice.call(this._indicatorsElement.querySelectorAll(Selector$2.ACTIVE));
+ $(indicators).removeClass(ClassName$2.ACTIVE);
+
+ var nextIndicator = this._indicatorsElement.children[this._getItemIndex(element)];
+
+ if (nextIndicator) {
+ $(nextIndicator).addClass(ClassName$2.ACTIVE);
+ }
+ }
+ };
+
+ _proto._slide = function _slide(direction, element) {
+ var _this4 = this;
+
+ var activeElement = this._element.querySelector(Selector$2.ACTIVE_ITEM);
+
+ var activeElementIndex = this._getItemIndex(activeElement);
+
+ var nextElement = element || activeElement && this._getItemByDirection(direction, activeElement);
+
+ var nextElementIndex = this._getItemIndex(nextElement);
+
+ var isCycling = Boolean(this._interval);
+ var directionalClassName;
+ var orderClassName;
+ var eventDirectionName;
+
+ if (direction === Direction.NEXT) {
+ directionalClassName = ClassName$2.LEFT;
+ orderClassName = ClassName$2.NEXT;
+ eventDirectionName = Direction.LEFT;
+ } else {
+ directionalClassName = ClassName$2.RIGHT;
+ orderClassName = ClassName$2.PREV;
+ eventDirectionName = Direction.RIGHT;
+ }
+
+ if (nextElement && $(nextElement).hasClass(ClassName$2.ACTIVE)) {
+ this._isSliding = false;
+ return;
+ }
+
+ var slideEvent = this._triggerSlideEvent(nextElement, eventDirectionName);
+
+ if (slideEvent.isDefaultPrevented()) {
+ return;
+ }
+
+ if (!activeElement || !nextElement) {
+ // Some weirdness is happening, so we bail
+ return;
+ }
+
+ this._isSliding = true;
+
+ if (isCycling) {
+ this.pause();
+ }
+
+ this._setActiveIndicatorElement(nextElement);
+
+ var slidEvent = $.Event(Event$2.SLID, {
+ relatedTarget: nextElement,
+ direction: eventDirectionName,
+ from: activeElementIndex,
+ to: nextElementIndex
+ });
+
+ if ($(this._element).hasClass(ClassName$2.SLIDE)) {
+ $(nextElement).addClass(orderClassName);
+ Util.reflow(nextElement);
+ $(activeElement).addClass(directionalClassName);
+ $(nextElement).addClass(directionalClassName);
+ var nextElementInterval = parseInt(nextElement.getAttribute('data-interval'), 10);
+
+ if (nextElementInterval) {
+ this._config.defaultInterval = this._config.defaultInterval || this._config.interval;
+ this._config.interval = nextElementInterval;
+ } else {
+ this._config.interval = this._config.defaultInterval || this._config.interval;
+ }
+
+ var transitionDuration = Util.getTransitionDurationFromElement(activeElement);
+ $(activeElement).one(Util.TRANSITION_END, function () {
+ $(nextElement).removeClass(directionalClassName + " " + orderClassName).addClass(ClassName$2.ACTIVE);
+ $(activeElement).removeClass(ClassName$2.ACTIVE + " " + orderClassName + " " + directionalClassName);
+ _this4._isSliding = false;
+ setTimeout(function () {
+ return $(_this4._element).trigger(slidEvent);
+ }, 0);
+ }).emulateTransitionEnd(transitionDuration);
+ } else {
+ $(activeElement).removeClass(ClassName$2.ACTIVE);
+ $(nextElement).addClass(ClassName$2.ACTIVE);
+ this._isSliding = false;
+ $(this._element).trigger(slidEvent);
+ }
+
+ if (isCycling) {
+ this.cycle();
+ }
+ } // Static
+ ;
+
+ Carousel._jQueryInterface = function _jQueryInterface(config) {
+ return this.each(function () {
+ var data = $(this).data(DATA_KEY$2);
+
+ var _config = _objectSpread2({}, Default, {}, $(this).data());
+
+ if (_typeof(config) === 'object') {
+ _config = _objectSpread2({}, _config, {}, config);
+ }
+
+ var action = typeof config === 'string' ? config : _config.slide;
+
+ if (!data) {
+ data = new Carousel(this, _config);
+ $(this).data(DATA_KEY$2, data);
+ }
+
+ if (typeof config === 'number') {
+ data.to(config);
+ } else if (typeof action === 'string') {
+ if (typeof data[action] === 'undefined') {
+ throw new TypeError("No method named \"" + action + "\"");
+ }
+
+ data[action]();
+ } else if (_config.interval && _config.ride) {
+ data.pause();
+ data.cycle();
+ }
+ });
+ };
+
+ Carousel._dataApiClickHandler = function _dataApiClickHandler(event) {
+ var selector = Util.getSelectorFromElement(this);
+
+ if (!selector) {
+ return;
+ }
+
+ var target = $(selector)[0];
+
+ if (!target || !$(target).hasClass(ClassName$2.CAROUSEL)) {
+ return;
+ }
+
+ var config = _objectSpread2({}, $(target).data(), {}, $(this).data());
+
+ var slideIndex = this.getAttribute('data-slide-to');
+
+ if (slideIndex) {
+ config.interval = false;
+ }
+
+ Carousel._jQueryInterface.call($(target), config);
+
+ if (slideIndex) {
+ $(target).data(DATA_KEY$2).to(slideIndex);
+ }
+
+ event.preventDefault();
+ };
+
+ _createClass(Carousel, null, [{
+ key: "VERSION",
+ get: function get() {
+ return VERSION$2;
+ }
+ }, {
+ key: "Default",
+ get: function get() {
+ return Default;
+ }
+ }]);
+
+ return Carousel;
+ }();
+ /**
+ * ------------------------------------------------------------------------
+ * Data Api implementation
+ * ------------------------------------------------------------------------
+ */
+
+
+ $(document).on(Event$2.CLICK_DATA_API, Selector$2.DATA_SLIDE, Carousel._dataApiClickHandler);
+ $(window).on(Event$2.LOAD_DATA_API, function () {
+ var carousels = [].slice.call(document.querySelectorAll(Selector$2.DATA_RIDE));
+
+ for (var i = 0, len = carousels.length; i < len; i++) {
+ var $carousel = $(carousels[i]);
+
+ Carousel._jQueryInterface.call($carousel, $carousel.data());
+ }
+ });
+ /**
+ * ------------------------------------------------------------------------
+ * jQuery
+ * ------------------------------------------------------------------------
+ */
+
+ $.fn[NAME$2] = Carousel._jQueryInterface;
+ $.fn[NAME$2].Constructor = Carousel;
+
+ $.fn[NAME$2].noConflict = function () {
+ $.fn[NAME$2] = JQUERY_NO_CONFLICT$2;
+ return Carousel._jQueryInterface;
+ };
+ /**
+ * ------------------------------------------------------------------------
+ * Constants
+ * ------------------------------------------------------------------------
+ */
+
+
+ var NAME$3 = 'collapse';
+ var VERSION$3 = '4.4.1';
+ var DATA_KEY$3 = 'bs.collapse';
+ var EVENT_KEY$3 = "." + DATA_KEY$3;
+ var DATA_API_KEY$3 = '.data-api';
+ var JQUERY_NO_CONFLICT$3 = $.fn[NAME$3];
+ var Default$1 = {
+ toggle: true,
+ parent: ''
+ };
+ var DefaultType$1 = {
+ toggle: 'boolean',
+ parent: '(string|element)'
+ };
+ var Event$3 = {
+ SHOW: "show" + EVENT_KEY$3,
+ SHOWN: "shown" + EVENT_KEY$3,
+ HIDE: "hide" + EVENT_KEY$3,
+ HIDDEN: "hidden" + EVENT_KEY$3,
+ CLICK_DATA_API: "click" + EVENT_KEY$3 + DATA_API_KEY$3
+ };
+ var ClassName$3 = {
+ SHOW: 'show',
+ COLLAPSE: 'collapse',
+ COLLAPSING: 'collapsing',
+ COLLAPSED: 'collapsed'
+ };
+ var Dimension = {
+ WIDTH: 'width',
+ HEIGHT: 'height'
+ };
+ var Selector$3 = {
+ ACTIVES: '.show, .collapsing',
+ DATA_TOGGLE: '[data-toggle="collapse"]'
+ };
+ /**
+ * ------------------------------------------------------------------------
+ * Class Definition
+ * ------------------------------------------------------------------------
+ */
+
+ var Collapse = /*#__PURE__*/function () {
+ function Collapse(element, config) {
+ this._isTransitioning = false;
+ this._element = element;
+ this._config = this._getConfig(config);
+ this._triggerArray = [].slice.call(document.querySelectorAll("[data-toggle=\"collapse\"][href=\"#" + element.id + "\"]," + ("[data-toggle=\"collapse\"][data-target=\"#" + element.id + "\"]")));
+ var toggleList = [].slice.call(document.querySelectorAll(Selector$3.DATA_TOGGLE));
+
+ for (var i = 0, len = toggleList.length; i < len; i++) {
+ var elem = toggleList[i];
+ var selector = Util.getSelectorFromElement(elem);
+ var filterElement = [].slice.call(document.querySelectorAll(selector)).filter(function (foundElem) {
+ return foundElem === element;
+ });
+
+ if (selector !== null && filterElement.length > 0) {
+ this._selector = selector;
+
+ this._triggerArray.push(elem);
+ }
+ }
+
+ this._parent = this._config.parent ? this._getParent() : null;
+
+ if (!this._config.parent) {
+ this._addAriaAndCollapsedClass(this._element, this._triggerArray);
+ }
+
+ if (this._config.toggle) {
+ this.toggle();
+ }
+ } // Getters
+
+
+ var _proto = Collapse.prototype; // Public
+
+ _proto.toggle = function toggle() {
+ if ($(this._element).hasClass(ClassName$3.SHOW)) {
+ this.hide();
+ } else {
+ this.show();
+ }
+ };
+
+ _proto.show = function show() {
+ var _this = this;
+
+ if (this._isTransitioning || $(this._element).hasClass(ClassName$3.SHOW)) {
+ return;
+ }
+
+ var actives;
+ var activesData;
+
+ if (this._parent) {
+ actives = [].slice.call(this._parent.querySelectorAll(Selector$3.ACTIVES)).filter(function (elem) {
+ if (typeof _this._config.parent === 'string') {
+ return elem.getAttribute('data-parent') === _this._config.parent;
+ }
+
+ return elem.classList.contains(ClassName$3.COLLAPSE);
+ });
+
+ if (actives.length === 0) {
+ actives = null;
+ }
+ }
+
+ if (actives) {
+ activesData = $(actives).not(this._selector).data(DATA_KEY$3);
+
+ if (activesData && activesData._isTransitioning) {
+ return;
+ }
+ }
+
+ var startEvent = $.Event(Event$3.SHOW);
+ $(this._element).trigger(startEvent);
+
+ if (startEvent.isDefaultPrevented()) {
+ return;
+ }
+
+ if (actives) {
+ Collapse._jQueryInterface.call($(actives).not(this._selector), 'hide');
+
+ if (!activesData) {
+ $(actives).data(DATA_KEY$3, null);
+ }
+ }
+
+ var dimension = this._getDimension();
+
+ $(this._element).removeClass(ClassName$3.COLLAPSE).addClass(ClassName$3.COLLAPSING);
+ this._element.style[dimension] = 0;
+
+ if (this._triggerArray.length) {
+ $(this._triggerArray).removeClass(ClassName$3.COLLAPSED).attr('aria-expanded', true);
+ }
+
+ this.setTransitioning(true);
+
+ var complete = function complete() {
+ $(_this._element).removeClass(ClassName$3.COLLAPSING).addClass(ClassName$3.COLLAPSE).addClass(ClassName$3.SHOW);
+ _this._element.style[dimension] = '';
+
+ _this.setTransitioning(false);
+
+ $(_this._element).trigger(Event$3.SHOWN);
+ };
+
+ var capitalizedDimension = dimension[0].toUpperCase() + dimension.slice(1);
+ var scrollSize = "scroll" + capitalizedDimension;
+ var transitionDuration = Util.getTransitionDurationFromElement(this._element);
+ $(this._element).one(Util.TRANSITION_END, complete).emulateTransitionEnd(transitionDuration);
+ this._element.style[dimension] = this._element[scrollSize] + "px";
+ };
+
+ _proto.hide = function hide() {
+ var _this2 = this;
+
+ if (this._isTransitioning || !$(this._element).hasClass(ClassName$3.SHOW)) {
+ return;
+ }
+
+ var startEvent = $.Event(Event$3.HIDE);
+ $(this._element).trigger(startEvent);
+
+ if (startEvent.isDefaultPrevented()) {
+ return;
+ }
+
+ var dimension = this._getDimension();
+
+ this._element.style[dimension] = this._element.getBoundingClientRect()[dimension] + "px";
+ Util.reflow(this._element);
+ $(this._element).addClass(ClassName$3.COLLAPSING).removeClass(ClassName$3.COLLAPSE).removeClass(ClassName$3.SHOW);
+ var triggerArrayLength = this._triggerArray.length;
+
+ if (triggerArrayLength > 0) {
+ for (var i = 0; i < triggerArrayLength; i++) {
+ var trigger = this._triggerArray[i];
+ var selector = Util.getSelectorFromElement(trigger);
+
+ if (selector !== null) {
+ var $elem = $([].slice.call(document.querySelectorAll(selector)));
+
+ if (!$elem.hasClass(ClassName$3.SHOW)) {
+ $(trigger).addClass(ClassName$3.COLLAPSED).attr('aria-expanded', false);
+ }
+ }
+ }
+ }
+
+ this.setTransitioning(true);
+
+ var complete = function complete() {
+ _this2.setTransitioning(false);
+
+ $(_this2._element).removeClass(ClassName$3.COLLAPSING).addClass(ClassName$3.COLLAPSE).trigger(Event$3.HIDDEN);
+ };
+
+ this._element.style[dimension] = '';
+ var transitionDuration = Util.getTransitionDurationFromElement(this._element);
+ $(this._element).one(Util.TRANSITION_END, complete).emulateTransitionEnd(transitionDuration);
+ };
+
+ _proto.setTransitioning = function setTransitioning(isTransitioning) {
+ this._isTransitioning = isTransitioning;
+ };
+
+ _proto.dispose = function dispose() {
+ $.removeData(this._element, DATA_KEY$3);
+ this._config = null;
+ this._parent = null;
+ this._element = null;
+ this._triggerArray = null;
+ this._isTransitioning = null;
+ } // Private
+ ;
+
+ _proto._getConfig = function _getConfig(config) {
+ config = _objectSpread2({}, Default$1, {}, config);
+ config.toggle = Boolean(config.toggle); // Coerce string values
+
+ Util.typeCheckConfig(NAME$3, config, DefaultType$1);
+ return config;
+ };
+
+ _proto._getDimension = function _getDimension() {
+ var hasWidth = $(this._element).hasClass(Dimension.WIDTH);
+ return hasWidth ? Dimension.WIDTH : Dimension.HEIGHT;
+ };
+
+ _proto._getParent = function _getParent() {
+ var _this3 = this;
+
+ var parent;
+
+ if (Util.isElement(this._config.parent)) {
+ parent = this._config.parent; // It's a jQuery object
+
+ if (typeof this._config.parent.jquery !== 'undefined') {
+ parent = this._config.parent[0];
+ }
+ } else {
+ parent = document.querySelector(this._config.parent);
+ }
+
+ var selector = "[data-toggle=\"collapse\"][data-parent=\"" + this._config.parent + "\"]";
+ var children = [].slice.call(parent.querySelectorAll(selector));
+ $(children).each(function (i, element) {
+ _this3._addAriaAndCollapsedClass(Collapse._getTargetFromElement(element), [element]);
+ });
+ return parent;
+ };
+
+ _proto._addAriaAndCollapsedClass = function _addAriaAndCollapsedClass(element, triggerArray) {
+ var isOpen = $(element).hasClass(ClassName$3.SHOW);
+
+ if (triggerArray.length) {
+ $(triggerArray).toggleClass(ClassName$3.COLLAPSED, !isOpen).attr('aria-expanded', isOpen);
+ }
+ } // Static
+ ;
+
+ Collapse._getTargetFromElement = function _getTargetFromElement(element) {
+ var selector = Util.getSelectorFromElement(element);
+ return selector ? document.querySelector(selector) : null;
+ };
+
+ Collapse._jQueryInterface = function _jQueryInterface(config) {
+ return this.each(function () {
+ var $this = $(this);
+ var data = $this.data(DATA_KEY$3);
+
+ var _config = _objectSpread2({}, Default$1, {}, $this.data(), {}, _typeof(config) === 'object' && config ? config : {});
+
+ if (!data && _config.toggle && /show|hide/.test(config)) {
+ _config.toggle = false;
+ }
+
+ if (!data) {
+ data = new Collapse(this, _config);
+ $this.data(DATA_KEY$3, data);
+ }
+
+ if (typeof config === 'string') {
+ if (typeof data[config] === 'undefined') {
+ throw new TypeError("No method named \"" + config + "\"");
+ }
+
+ data[config]();
+ }
+ });
+ };
+
+ _createClass(Collapse, null, [{
+ key: "VERSION",
+ get: function get() {
+ return VERSION$3;
+ }
+ }, {
+ key: "Default",
+ get: function get() {
+ return Default$1;
+ }
+ }]);
+
+ return Collapse;
+ }();
+ /**
+ * ------------------------------------------------------------------------
+ * Data Api implementation
+ * ------------------------------------------------------------------------
+ */
+
+
+ $(document).on(Event$3.CLICK_DATA_API, Selector$3.DATA_TOGGLE, function (event) {
+ // preventDefault only for elements (which change the URL) not inside the collapsible element
+ if (event.currentTarget.tagName === 'A') {
+ event.preventDefault();
+ }
+
+ var $trigger = $(this);
+ var selector = Util.getSelectorFromElement(this);
+ var selectors = [].slice.call(document.querySelectorAll(selector));
+ $(selectors).each(function () {
+ var $target = $(this);
+ var data = $target.data(DATA_KEY$3);
+ var config = data ? 'toggle' : $trigger.data();
+
+ Collapse._jQueryInterface.call($target, config);
+ });
+ });
+ /**
+ * ------------------------------------------------------------------------
+ * jQuery
+ * ------------------------------------------------------------------------
+ */
+
+ $.fn[NAME$3] = Collapse._jQueryInterface;
+ $.fn[NAME$3].Constructor = Collapse;
+
+ $.fn[NAME$3].noConflict = function () {
+ $.fn[NAME$3] = JQUERY_NO_CONFLICT$3;
+ return Collapse._jQueryInterface;
+ };
+ /**
+ * ------------------------------------------------------------------------
+ * Constants
+ * ------------------------------------------------------------------------
+ */
+
+
+ var NAME$4 = 'dropdown';
+ var VERSION$4 = '4.4.1';
+ var DATA_KEY$4 = 'bs.dropdown';
+ var EVENT_KEY$4 = "." + DATA_KEY$4;
+ var DATA_API_KEY$4 = '.data-api';
+ var JQUERY_NO_CONFLICT$4 = $.fn[NAME$4];
+ var ESCAPE_KEYCODE = 27; // KeyboardEvent.which value for Escape (Esc) key
+
+ var SPACE_KEYCODE = 32; // KeyboardEvent.which value for space key
+
+ var TAB_KEYCODE = 9; // KeyboardEvent.which value for tab key
+
+ var ARROW_UP_KEYCODE = 38; // KeyboardEvent.which value for up arrow key
+
+ var ARROW_DOWN_KEYCODE = 40; // KeyboardEvent.which value for down arrow key
+
+ var RIGHT_MOUSE_BUTTON_WHICH = 3; // MouseEvent.which value for the right button (assuming a right-handed mouse)
+
+ var REGEXP_KEYDOWN = new RegExp(ARROW_UP_KEYCODE + "|" + ARROW_DOWN_KEYCODE + "|" + ESCAPE_KEYCODE);
+ var Event$4 = {
+ HIDE: "hide" + EVENT_KEY$4,
+ HIDDEN: "hidden" + EVENT_KEY$4,
+ SHOW: "show" + EVENT_KEY$4,
+ SHOWN: "shown" + EVENT_KEY$4,
+ CLICK: "click" + EVENT_KEY$4,
+ CLICK_DATA_API: "click" + EVENT_KEY$4 + DATA_API_KEY$4,
+ KEYDOWN_DATA_API: "keydown" + EVENT_KEY$4 + DATA_API_KEY$4,
+ KEYUP_DATA_API: "keyup" + EVENT_KEY$4 + DATA_API_KEY$4
+ };
+ var ClassName$4 = {
+ DISABLED: 'disabled',
+ SHOW: 'show',
+ DROPUP: 'dropup',
+ DROPRIGHT: 'dropright',
+ DROPLEFT: 'dropleft',
+ MENURIGHT: 'dropdown-menu-right',
+ MENULEFT: 'dropdown-menu-left',
+ POSITION_STATIC: 'position-static'
+ };
+ var Selector$4 = {
+ DATA_TOGGLE: '[data-toggle="dropdown"]',
+ FORM_CHILD: '.dropdown form',
+ MENU: '.dropdown-menu',
+ NAVBAR_NAV: '.navbar-nav',
+ VISIBLE_ITEMS: '.dropdown-menu .dropdown-item:not(.disabled):not(:disabled)'
+ };
+ var AttachmentMap = {
+ TOP: 'top-start',
+ TOPEND: 'top-end',
+ BOTTOM: 'bottom-start',
+ BOTTOMEND: 'bottom-end',
+ RIGHT: 'right-start',
+ RIGHTEND: 'right-end',
+ LEFT: 'left-start',
+ LEFTEND: 'left-end'
+ };
+ var Default$2 = {
+ offset: 0,
+ flip: true,
+ boundary: 'scrollParent',
+ reference: 'toggle',
+ display: 'dynamic',
+ popperConfig: null
+ };
+ var DefaultType$2 = {
+ offset: '(number|string|function)',
+ flip: 'boolean',
+ boundary: '(string|element)',
+ reference: '(string|element)',
+ display: 'string',
+ popperConfig: '(null|object)'
+ };
+ /**
+ * ------------------------------------------------------------------------
+ * Class Definition
+ * ------------------------------------------------------------------------
+ */
+
+ var Dropdown = /*#__PURE__*/function () {
+ function Dropdown(element, config) {
+ this._element = element;
+ this._popper = null;
+ this._config = this._getConfig(config);
+ this._menu = this._getMenuElement();
+ this._inNavbar = this._detectNavbar();
+
+ this._addEventListeners();
+ } // Getters
+
+
+ var _proto = Dropdown.prototype; // Public
+
+ _proto.toggle = function toggle() {
+ if (this._element.disabled || $(this._element).hasClass(ClassName$4.DISABLED)) {
+ return;
+ }
+
+ var isActive = $(this._menu).hasClass(ClassName$4.SHOW);
+
+ Dropdown._clearMenus();
+
+ if (isActive) {
+ return;
+ }
+
+ this.show(true);
+ };
+
+ _proto.show = function show(usePopper) {
+ if (usePopper === void 0) {
+ usePopper = false;
+ }
+
+ if (this._element.disabled || $(this._element).hasClass(ClassName$4.DISABLED) || $(this._menu).hasClass(ClassName$4.SHOW)) {
+ return;
+ }
+
+ var relatedTarget = {
+ relatedTarget: this._element
+ };
+ var showEvent = $.Event(Event$4.SHOW, relatedTarget);
+
+ var parent = Dropdown._getParentFromElement(this._element);
+
+ $(parent).trigger(showEvent);
+
+ if (showEvent.isDefaultPrevented()) {
+ return;
+ } // Disable totally Popper.js for Dropdown in Navbar
+
+
+ if (!this._inNavbar && usePopper) {
+ /**
+ * Check for Popper dependency
+ * Popper - https://popper.js.org
+ */
+ if (typeof Popper === 'undefined') {
+ throw new TypeError('Bootstrap\'s dropdowns require Popper.js (https://popper.js.org/)');
+ }
+
+ var referenceElement = this._element;
+
+ if (this._config.reference === 'parent') {
+ referenceElement = parent;
+ } else if (Util.isElement(this._config.reference)) {
+ referenceElement = this._config.reference; // Check if it's jQuery element
+
+ if (typeof this._config.reference.jquery !== 'undefined') {
+ referenceElement = this._config.reference[0];
+ }
+ } // If boundary is not `scrollParent`, then set position to `static`
+ // to allow the menu to "escape" the scroll parent's boundaries
+ // https://github.com/twbs/bootstrap/issues/24251
+
+
+ if (this._config.boundary !== 'scrollParent') {
+ $(parent).addClass(ClassName$4.POSITION_STATIC);
+ }
+
+ this._popper = new Popper(referenceElement, this._menu, this._getPopperConfig());
+ } // If this is a touch-enabled device we add extra
+ // empty mouseover listeners to the body's immediate children;
+ // only needed because of broken event delegation on iOS
+ // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html
+
+
+ if ('ontouchstart' in document.documentElement && $(parent).closest(Selector$4.NAVBAR_NAV).length === 0) {
+ $(document.body).children().on('mouseover', null, $.noop);
+ }
+
+ this._element.focus();
+
+ this._element.setAttribute('aria-expanded', true);
+
+ $(this._menu).toggleClass(ClassName$4.SHOW);
+ $(parent).toggleClass(ClassName$4.SHOW).trigger($.Event(Event$4.SHOWN, relatedTarget));
+ };
+
+ _proto.hide = function hide() {
+ if (this._element.disabled || $(this._element).hasClass(ClassName$4.DISABLED) || !$(this._menu).hasClass(ClassName$4.SHOW)) {
+ return;
+ }
+
+ var relatedTarget = {
+ relatedTarget: this._element
+ };
+ var hideEvent = $.Event(Event$4.HIDE, relatedTarget);
+
+ var parent = Dropdown._getParentFromElement(this._element);
+
+ $(parent).trigger(hideEvent);
+
+ if (hideEvent.isDefaultPrevented()) {
+ return;
+ }
+
+ if (this._popper) {
+ this._popper.destroy();
+ }
+
+ $(this._menu).toggleClass(ClassName$4.SHOW);
+ $(parent).toggleClass(ClassName$4.SHOW).trigger($.Event(Event$4.HIDDEN, relatedTarget));
+ };
+
+ _proto.dispose = function dispose() {
+ $.removeData(this._element, DATA_KEY$4);
+ $(this._element).off(EVENT_KEY$4);
+ this._element = null;
+ this._menu = null;
+
+ if (this._popper !== null) {
+ this._popper.destroy();
+
+ this._popper = null;
+ }
+ };
+
+ _proto.update = function update() {
+ this._inNavbar = this._detectNavbar();
+
+ if (this._popper !== null) {
+ this._popper.scheduleUpdate();
+ }
+ } // Private
+ ;
+
+ _proto._addEventListeners = function _addEventListeners() {
+ var _this = this;
+
+ $(this._element).on(Event$4.CLICK, function (event) {
+ event.preventDefault();
+ event.stopPropagation();
+
+ _this.toggle();
+ });
+ };
+
+ _proto._getConfig = function _getConfig(config) {
+ config = _objectSpread2({}, this.constructor.Default, {}, $(this._element).data(), {}, config);
+ Util.typeCheckConfig(NAME$4, config, this.constructor.DefaultType);
+ return config;
+ };
+
+ _proto._getMenuElement = function _getMenuElement() {
+ if (!this._menu) {
+ var parent = Dropdown._getParentFromElement(this._element);
+
+ if (parent) {
+ this._menu = parent.querySelector(Selector$4.MENU);
+ }
+ }
+
+ return this._menu;
+ };
+
+ _proto._getPlacement = function _getPlacement() {
+ var $parentDropdown = $(this._element.parentNode);
+ var placement = AttachmentMap.BOTTOM; // Handle dropup
+
+ if ($parentDropdown.hasClass(ClassName$4.DROPUP)) {
+ placement = AttachmentMap.TOP;
+
+ if ($(this._menu).hasClass(ClassName$4.MENURIGHT)) {
+ placement = AttachmentMap.TOPEND;
+ }
+ } else if ($parentDropdown.hasClass(ClassName$4.DROPRIGHT)) {
+ placement = AttachmentMap.RIGHT;
+ } else if ($parentDropdown.hasClass(ClassName$4.DROPLEFT)) {
+ placement = AttachmentMap.LEFT;
+ } else if ($(this._menu).hasClass(ClassName$4.MENURIGHT)) {
+ placement = AttachmentMap.BOTTOMEND;
+ }
+
+ return placement;
+ };
+
+ _proto._detectNavbar = function _detectNavbar() {
+ return $(this._element).closest('.navbar').length > 0;
+ };
+
+ _proto._getOffset = function _getOffset() {
+ var _this2 = this;
+
+ var offset = {};
+
+ if (typeof this._config.offset === 'function') {
+ offset.fn = function (data) {
+ data.offsets = _objectSpread2({}, data.offsets, {}, _this2._config.offset(data.offsets, _this2._element) || {});
+ return data;
+ };
+ } else {
+ offset.offset = this._config.offset;
+ }
+
+ return offset;
+ };
+
+ _proto._getPopperConfig = function _getPopperConfig() {
+ var popperConfig = {
+ placement: this._getPlacement(),
+ modifiers: {
+ offset: this._getOffset(),
+ flip: {
+ enabled: this._config.flip
+ },
+ preventOverflow: {
+ boundariesElement: this._config.boundary
+ }
+ }
+ }; // Disable Popper.js if we have a static display
+
+ if (this._config.display === 'static') {
+ popperConfig.modifiers.applyStyle = {
+ enabled: false
+ };
+ }
+
+ return _objectSpread2({}, popperConfig, {}, this._config.popperConfig);
+ } // Static
+ ;
+
+ Dropdown._jQueryInterface = function _jQueryInterface(config) {
+ return this.each(function () {
+ var data = $(this).data(DATA_KEY$4);
+
+ var _config = _typeof(config) === 'object' ? config : null;
+
+ if (!data) {
+ data = new Dropdown(this, _config);
+ $(this).data(DATA_KEY$4, data);
+ }
+
+ if (typeof config === 'string') {
+ if (typeof data[config] === 'undefined') {
+ throw new TypeError("No method named \"" + config + "\"");
+ }
+
+ data[config]();
+ }
+ });
+ };
+
+ Dropdown._clearMenus = function _clearMenus(event) {
+ if (event && (event.which === RIGHT_MOUSE_BUTTON_WHICH || event.type === 'keyup' && event.which !== TAB_KEYCODE)) {
+ return;
+ }
+
+ var toggles = [].slice.call(document.querySelectorAll(Selector$4.DATA_TOGGLE));
+
+ for (var i = 0, len = toggles.length; i < len; i++) {
+ var parent = Dropdown._getParentFromElement(toggles[i]);
+
+ var context = $(toggles[i]).data(DATA_KEY$4);
+ var relatedTarget = {
+ relatedTarget: toggles[i]
+ };
+
+ if (event && event.type === 'click') {
+ relatedTarget.clickEvent = event;
+ }
+
+ if (!context) {
+ continue;
+ }
+
+ var dropdownMenu = context._menu;
+
+ if (!$(parent).hasClass(ClassName$4.SHOW)) {
+ continue;
+ }
+
+ if (event && (event.type === 'click' && /input|textarea/i.test(event.target.tagName) || event.type === 'keyup' && event.which === TAB_KEYCODE) && $.contains(parent, event.target)) {
+ continue;
+ }
+
+ var hideEvent = $.Event(Event$4.HIDE, relatedTarget);
+ $(parent).trigger(hideEvent);
+
+ if (hideEvent.isDefaultPrevented()) {
+ continue;
+ } // If this is a touch-enabled device we remove the extra
+ // empty mouseover listeners we added for iOS support
+
+
+ if ('ontouchstart' in document.documentElement) {
+ $(document.body).children().off('mouseover', null, $.noop);
+ }
+
+ toggles[i].setAttribute('aria-expanded', 'false');
+
+ if (context._popper) {
+ context._popper.destroy();
+ }
+
+ $(dropdownMenu).removeClass(ClassName$4.SHOW);
+ $(parent).removeClass(ClassName$4.SHOW).trigger($.Event(Event$4.HIDDEN, relatedTarget));
+ }
+ };
+
+ Dropdown._getParentFromElement = function _getParentFromElement(element) {
+ var parent;
+ var selector = Util.getSelectorFromElement(element);
+
+ if (selector) {
+ parent = document.querySelector(selector);
+ }
+
+ return parent || element.parentNode;
+ } // eslint-disable-next-line complexity
+ ;
+
+ Dropdown._dataApiKeydownHandler = function _dataApiKeydownHandler(event) {
+ // If not input/textarea:
+ // - And not a key in REGEXP_KEYDOWN => not a dropdown command
+ // If input/textarea:
+ // - If space key => not a dropdown command
+ // - If key is other than escape
+ // - If key is not up or down => not a dropdown command
+ // - If trigger inside the menu => not a dropdown command
+ if (/input|textarea/i.test(event.target.tagName) ? event.which === SPACE_KEYCODE || event.which !== ESCAPE_KEYCODE && (event.which !== ARROW_DOWN_KEYCODE && event.which !== ARROW_UP_KEYCODE || $(event.target).closest(Selector$4.MENU).length) : !REGEXP_KEYDOWN.test(event.which)) {
+ return;
+ }
+
+ event.preventDefault();
+ event.stopPropagation();
+
+ if (this.disabled || $(this).hasClass(ClassName$4.DISABLED)) {
+ return;
+ }
+
+ var parent = Dropdown._getParentFromElement(this);
+
+ var isActive = $(parent).hasClass(ClassName$4.SHOW);
+
+ if (!isActive && event.which === ESCAPE_KEYCODE) {
+ return;
+ }
+
+ if (!isActive || isActive && (event.which === ESCAPE_KEYCODE || event.which === SPACE_KEYCODE)) {
+ if (event.which === ESCAPE_KEYCODE) {
+ var toggle = parent.querySelector(Selector$4.DATA_TOGGLE);
+ $(toggle).trigger('focus');
+ }
+
+ $(this).trigger('click');
+ return;
+ }
+
+ var items = [].slice.call(parent.querySelectorAll(Selector$4.VISIBLE_ITEMS)).filter(function (item) {
+ return $(item).is(':visible');
+ });
+
+ if (items.length === 0) {
+ return;
+ }
+
+ var index = items.indexOf(event.target);
+
+ if (event.which === ARROW_UP_KEYCODE && index > 0) {
+ // Up
+ index--;
+ }
+
+ if (event.which === ARROW_DOWN_KEYCODE && index < items.length - 1) {
+ // Down
+ index++;
+ }
+
+ if (index < 0) {
+ index = 0;
+ }
+
+ items[index].focus();
+ };
+
+ _createClass(Dropdown, null, [{
+ key: "VERSION",
+ get: function get() {
+ return VERSION$4;
+ }
+ }, {
+ key: "Default",
+ get: function get() {
+ return Default$2;
+ }
+ }, {
+ key: "DefaultType",
+ get: function get() {
+ return DefaultType$2;
+ }
+ }]);
+
+ return Dropdown;
+ }();
+ /**
+ * ------------------------------------------------------------------------
+ * Data Api implementation
+ * ------------------------------------------------------------------------
+ */
+
+
+ $(document).on(Event$4.KEYDOWN_DATA_API, Selector$4.DATA_TOGGLE, Dropdown._dataApiKeydownHandler).on(Event$4.KEYDOWN_DATA_API, Selector$4.MENU, Dropdown._dataApiKeydownHandler).on(Event$4.CLICK_DATA_API + " " + Event$4.KEYUP_DATA_API, Dropdown._clearMenus).on(Event$4.CLICK_DATA_API, Selector$4.DATA_TOGGLE, function (event) {
+ event.preventDefault();
+ event.stopPropagation();
+
+ Dropdown._jQueryInterface.call($(this), 'toggle');
+ }).on(Event$4.CLICK_DATA_API, Selector$4.FORM_CHILD, function (e) {
+ e.stopPropagation();
+ });
+ /**
+ * ------------------------------------------------------------------------
+ * jQuery
+ * ------------------------------------------------------------------------
+ */
+
+ $.fn[NAME$4] = Dropdown._jQueryInterface;
+ $.fn[NAME$4].Constructor = Dropdown;
+
+ $.fn[NAME$4].noConflict = function () {
+ $.fn[NAME$4] = JQUERY_NO_CONFLICT$4;
+ return Dropdown._jQueryInterface;
+ };
+ /**
+ * ------------------------------------------------------------------------
+ * Constants
+ * ------------------------------------------------------------------------
+ */
+
+
+ var NAME$5 = 'modal';
+ var VERSION$5 = '4.4.1';
+ var DATA_KEY$5 = 'bs.modal';
+ var EVENT_KEY$5 = "." + DATA_KEY$5;
+ var DATA_API_KEY$5 = '.data-api';
+ var JQUERY_NO_CONFLICT$5 = $.fn[NAME$5];
+ var ESCAPE_KEYCODE$1 = 27; // KeyboardEvent.which value for Escape (Esc) key
+
+ var Default$3 = {
+ backdrop: true,
+ keyboard: true,
+ focus: true,
+ show: true
+ };
+ var DefaultType$3 = {
+ backdrop: '(boolean|string)',
+ keyboard: 'boolean',
+ focus: 'boolean',
+ show: 'boolean'
+ };
+ var Event$5 = {
+ HIDE: "hide" + EVENT_KEY$5,
+ HIDE_PREVENTED: "hidePrevented" + EVENT_KEY$5,
+ HIDDEN: "hidden" + EVENT_KEY$5,
+ SHOW: "show" + EVENT_KEY$5,
+ SHOWN: "shown" + EVENT_KEY$5,
+ FOCUSIN: "focusin" + EVENT_KEY$5,
+ RESIZE: "resize" + EVENT_KEY$5,
+ CLICK_DISMISS: "click.dismiss" + EVENT_KEY$5,
+ KEYDOWN_DISMISS: "keydown.dismiss" + EVENT_KEY$5,
+ MOUSEUP_DISMISS: "mouseup.dismiss" + EVENT_KEY$5,
+ MOUSEDOWN_DISMISS: "mousedown.dismiss" + EVENT_KEY$5,
+ CLICK_DATA_API: "click" + EVENT_KEY$5 + DATA_API_KEY$5
+ };
+ var ClassName$5 = {
+ SCROLLABLE: 'modal-dialog-scrollable',
+ SCROLLBAR_MEASURER: 'modal-scrollbar-measure',
+ BACKDROP: 'modal-backdrop',
+ OPEN: 'modal-open',
+ FADE: 'fade',
+ SHOW: 'show',
+ STATIC: 'modal-static'
+ };
+ var Selector$5 = {
+ DIALOG: '.modal-dialog',
+ MODAL_BODY: '.modal-body',
+ DATA_TOGGLE: '[data-toggle="modal"]',
+ DATA_DISMISS: '[data-dismiss="modal"]',
+ FIXED_CONTENT: '.fixed-top, .fixed-bottom, .is-fixed, .sticky-top',
+ STICKY_CONTENT: '.sticky-top'
+ };
+ /**
+ * ------------------------------------------------------------------------
+ * Class Definition
+ * ------------------------------------------------------------------------
+ */
+
+ var Modal = /*#__PURE__*/function () {
+ function Modal(element, config) {
+ this._config = this._getConfig(config);
+ this._element = element;
+ this._dialog = element.querySelector(Selector$5.DIALOG);
+ this._backdrop = null;
+ this._isShown = false;
+ this._isBodyOverflowing = false;
+ this._ignoreBackdropClick = false;
+ this._isTransitioning = false;
+ this._scrollbarWidth = 0;
+ } // Getters
+
+
+ var _proto = Modal.prototype; // Public
+
+ _proto.toggle = function toggle(relatedTarget) {
+ return this._isShown ? this.hide() : this.show(relatedTarget);
+ };
+
+ _proto.show = function show(relatedTarget) {
+ var _this = this;
+
+ if (this._isShown || this._isTransitioning) {
+ return;
+ }
+
+ if ($(this._element).hasClass(ClassName$5.FADE)) {
+ this._isTransitioning = true;
+ }
+
+ var showEvent = $.Event(Event$5.SHOW, {
+ relatedTarget: relatedTarget
+ });
+ $(this._element).trigger(showEvent);
+
+ if (this._isShown || showEvent.isDefaultPrevented()) {
+ return;
+ }
+
+ this._isShown = true;
+
+ this._checkScrollbar();
+
+ this._setScrollbar();
+
+ this._adjustDialog();
+
+ this._setEscapeEvent();
+
+ this._setResizeEvent();
+
+ $(this._element).on(Event$5.CLICK_DISMISS, Selector$5.DATA_DISMISS, function (event) {
+ return _this.hide(event);
+ });
+ $(this._dialog).on(Event$5.MOUSEDOWN_DISMISS, function () {
+ $(_this._element).one(Event$5.MOUSEUP_DISMISS, function (event) {
+ if ($(event.target).is(_this._element)) {
+ _this._ignoreBackdropClick = true;
+ }
+ });
+ });
+
+ this._showBackdrop(function () {
+ return _this._showElement(relatedTarget);
+ });
+ };
+
+ _proto.hide = function hide(event) {
+ var _this2 = this;
+
+ if (event) {
+ event.preventDefault();
+ }
+
+ if (!this._isShown || this._isTransitioning) {
+ return;
+ }
+
+ var hideEvent = $.Event(Event$5.HIDE);
+ $(this._element).trigger(hideEvent);
+
+ if (!this._isShown || hideEvent.isDefaultPrevented()) {
+ return;
+ }
+
+ this._isShown = false;
+ var transition = $(this._element).hasClass(ClassName$5.FADE);
+
+ if (transition) {
+ this._isTransitioning = true;
+ }
+
+ this._setEscapeEvent();
+
+ this._setResizeEvent();
+
+ $(document).off(Event$5.FOCUSIN);
+ $(this._element).removeClass(ClassName$5.SHOW);
+ $(this._element).off(Event$5.CLICK_DISMISS);
+ $(this._dialog).off(Event$5.MOUSEDOWN_DISMISS);
+
+ if (transition) {
+ var transitionDuration = Util.getTransitionDurationFromElement(this._element);
+ $(this._element).one(Util.TRANSITION_END, function (event) {
+ return _this2._hideModal(event);
+ }).emulateTransitionEnd(transitionDuration);
+ } else {
+ this._hideModal();
+ }
+ };
+
+ _proto.dispose = function dispose() {
+ [window, this._element, this._dialog].forEach(function (htmlElement) {
+ return $(htmlElement).off(EVENT_KEY$5);
+ });
+ /**
+ * `document` has 2 events `Event.FOCUSIN` and `Event.CLICK_DATA_API`
+ * Do not move `document` in `htmlElements` array
+ * It will remove `Event.CLICK_DATA_API` event that should remain
+ */
+
+ $(document).off(Event$5.FOCUSIN);
+ $.removeData(this._element, DATA_KEY$5);
+ this._config = null;
+ this._element = null;
+ this._dialog = null;
+ this._backdrop = null;
+ this._isShown = null;
+ this._isBodyOverflowing = null;
+ this._ignoreBackdropClick = null;
+ this._isTransitioning = null;
+ this._scrollbarWidth = null;
+ };
+
+ _proto.handleUpdate = function handleUpdate() {
+ this._adjustDialog();
+ } // Private
+ ;
+
+ _proto._getConfig = function _getConfig(config) {
+ config = _objectSpread2({}, Default$3, {}, config);
+ Util.typeCheckConfig(NAME$5, config, DefaultType$3);
+ return config;
+ };
+
+ _proto._triggerBackdropTransition = function _triggerBackdropTransition() {
+ var _this3 = this;
+
+ if (this._config.backdrop === 'static') {
+ var hideEventPrevented = $.Event(Event$5.HIDE_PREVENTED);
+ $(this._element).trigger(hideEventPrevented);
+
+ if (hideEventPrevented.defaultPrevented) {
+ return;
+ }
+
+ this._element.classList.add(ClassName$5.STATIC);
+
+ var modalTransitionDuration = Util.getTransitionDurationFromElement(this._element);
+ $(this._element).one(Util.TRANSITION_END, function () {
+ _this3._element.classList.remove(ClassName$5.STATIC);
+ }).emulateTransitionEnd(modalTransitionDuration);
+
+ this._element.focus();
+ } else {
+ this.hide();
+ }
+ };
+
+ _proto._showElement = function _showElement(relatedTarget) {
+ var _this4 = this;
+
+ var transition = $(this._element).hasClass(ClassName$5.FADE);
+ var modalBody = this._dialog ? this._dialog.querySelector(Selector$5.MODAL_BODY) : null;
+
+ if (!this._element.parentNode || this._element.parentNode.nodeType !== Node.ELEMENT_NODE) {
+ // Don't move modal's DOM position
+ document.body.appendChild(this._element);
+ }
+
+ this._element.style.display = 'block';
+
+ this._element.removeAttribute('aria-hidden');
+
+ this._element.setAttribute('aria-modal', true);
+
+ if ($(this._dialog).hasClass(ClassName$5.SCROLLABLE) && modalBody) {
+ modalBody.scrollTop = 0;
+ } else {
+ this._element.scrollTop = 0;
+ }
+
+ if (transition) {
+ Util.reflow(this._element);
+ }
+
+ $(this._element).addClass(ClassName$5.SHOW);
+
+ if (this._config.focus) {
+ this._enforceFocus();
+ }
+
+ var shownEvent = $.Event(Event$5.SHOWN, {
+ relatedTarget: relatedTarget
+ });
+
+ var transitionComplete = function transitionComplete() {
+ if (_this4._config.focus) {
+ _this4._element.focus();
+ }
+
+ _this4._isTransitioning = false;
+ $(_this4._element).trigger(shownEvent);
+ };
+
+ if (transition) {
+ var transitionDuration = Util.getTransitionDurationFromElement(this._dialog);
+ $(this._dialog).one(Util.TRANSITION_END, transitionComplete).emulateTransitionEnd(transitionDuration);
+ } else {
+ transitionComplete();
+ }
+ };
+
+ _proto._enforceFocus = function _enforceFocus() {
+ var _this5 = this;
+
+ $(document).off(Event$5.FOCUSIN) // Guard against infinite focus loop
+ .on(Event$5.FOCUSIN, function (event) {
+ if (document !== event.target && _this5._element !== event.target && $(_this5._element).has(event.target).length === 0) {
+ _this5._element.focus();
+ }
+ });
+ };
+
+ _proto._setEscapeEvent = function _setEscapeEvent() {
+ var _this6 = this;
+
+ if (this._isShown && this._config.keyboard) {
+ $(this._element).on(Event$5.KEYDOWN_DISMISS, function (event) {
+ if (event.which === ESCAPE_KEYCODE$1) {
+ _this6._triggerBackdropTransition();
+ }
+ });
+ } else if (!this._isShown) {
+ $(this._element).off(Event$5.KEYDOWN_DISMISS);
+ }
+ };
+
+ _proto._setResizeEvent = function _setResizeEvent() {
+ var _this7 = this;
+
+ if (this._isShown) {
+ $(window).on(Event$5.RESIZE, function (event) {
+ return _this7.handleUpdate(event);
+ });
+ } else {
+ $(window).off(Event$5.RESIZE);
+ }
+ };
+
+ _proto._hideModal = function _hideModal() {
+ var _this8 = this;
+
+ this._element.style.display = 'none';
+
+ this._element.setAttribute('aria-hidden', true);
+
+ this._element.removeAttribute('aria-modal');
+
+ this._isTransitioning = false;
+
+ this._showBackdrop(function () {
+ $(document.body).removeClass(ClassName$5.OPEN);
+
+ _this8._resetAdjustments();
+
+ _this8._resetScrollbar();
+
+ $(_this8._element).trigger(Event$5.HIDDEN);
+ });
+ };
+
+ _proto._removeBackdrop = function _removeBackdrop() {
+ if (this._backdrop) {
+ $(this._backdrop).remove();
+ this._backdrop = null;
+ }
+ };
+
+ _proto._showBackdrop = function _showBackdrop(callback) {
+ var _this9 = this;
+
+ var animate = $(this._element).hasClass(ClassName$5.FADE) ? ClassName$5.FADE : '';
+
+ if (this._isShown && this._config.backdrop) {
+ this._backdrop = document.createElement('div');
+ this._backdrop.className = ClassName$5.BACKDROP;
+
+ if (animate) {
+ this._backdrop.classList.add(animate);
+ }
+
+ $(this._backdrop).appendTo(document.body);
+ $(this._element).on(Event$5.CLICK_DISMISS, function (event) {
+ if (_this9._ignoreBackdropClick) {
+ _this9._ignoreBackdropClick = false;
+ return;
+ }
+
+ if (event.target !== event.currentTarget) {
+ return;
+ }
+
+ _this9._triggerBackdropTransition();
+ });
+
+ if (animate) {
+ Util.reflow(this._backdrop);
+ }
+
+ $(this._backdrop).addClass(ClassName$5.SHOW);
+
+ if (!callback) {
+ return;
+ }
+
+ if (!animate) {
+ callback();
+ return;
+ }
+
+ var backdropTransitionDuration = Util.getTransitionDurationFromElement(this._backdrop);
+ $(this._backdrop).one(Util.TRANSITION_END, callback).emulateTransitionEnd(backdropTransitionDuration);
+ } else if (!this._isShown && this._backdrop) {
+ $(this._backdrop).removeClass(ClassName$5.SHOW);
+
+ var callbackRemove = function callbackRemove() {
+ _this9._removeBackdrop();
+
+ if (callback) {
+ callback();
+ }
+ };
+
+ if ($(this._element).hasClass(ClassName$5.FADE)) {
+ var _backdropTransitionDuration = Util.getTransitionDurationFromElement(this._backdrop);
+
+ $(this._backdrop).one(Util.TRANSITION_END, callbackRemove).emulateTransitionEnd(_backdropTransitionDuration);
+ } else {
+ callbackRemove();
+ }
+ } else if (callback) {
+ callback();
+ }
+ } // ----------------------------------------------------------------------
+ // the following methods are used to handle overflowing modals
+ // todo (fat): these should probably be refactored out of modal.js
+ // ----------------------------------------------------------------------
+ ;
+
+ _proto._adjustDialog = function _adjustDialog() {
+ var isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight;
+
+ if (!this._isBodyOverflowing && isModalOverflowing) {
+ this._element.style.paddingLeft = this._scrollbarWidth + "px";
+ }
+
+ if (this._isBodyOverflowing && !isModalOverflowing) {
+ this._element.style.paddingRight = this._scrollbarWidth + "px";
+ }
+ };
+
+ _proto._resetAdjustments = function _resetAdjustments() {
+ this._element.style.paddingLeft = '';
+ this._element.style.paddingRight = '';
+ };
+
+ _proto._checkScrollbar = function _checkScrollbar() {
+ var rect = document.body.getBoundingClientRect();
+ this._isBodyOverflowing = rect.left + rect.right < window.innerWidth;
+ this._scrollbarWidth = this._getScrollbarWidth();
+ };
+
+ _proto._setScrollbar = function _setScrollbar() {
+ var _this10 = this;
+
+ if (this._isBodyOverflowing) {
+ // Note: DOMNode.style.paddingRight returns the actual value or '' if not set
+ // while $(DOMNode).css('padding-right') returns the calculated value or 0 if not set
+ var fixedContent = [].slice.call(document.querySelectorAll(Selector$5.FIXED_CONTENT));
+ var stickyContent = [].slice.call(document.querySelectorAll(Selector$5.STICKY_CONTENT)); // Adjust fixed content padding
+
+ $(fixedContent).each(function (index, element) {
+ var actualPadding = element.style.paddingRight;
+ var calculatedPadding = $(element).css('padding-right');
+ $(element).data('padding-right', actualPadding).css('padding-right', parseFloat(calculatedPadding) + _this10._scrollbarWidth + "px");
+ }); // Adjust sticky content margin
+
+ $(stickyContent).each(function (index, element) {
+ var actualMargin = element.style.marginRight;
+ var calculatedMargin = $(element).css('margin-right');
+ $(element).data('margin-right', actualMargin).css('margin-right', parseFloat(calculatedMargin) - _this10._scrollbarWidth + "px");
+ }); // Adjust body padding
+
+ var actualPadding = document.body.style.paddingRight;
+ var calculatedPadding = $(document.body).css('padding-right');
+ $(document.body).data('padding-right', actualPadding).css('padding-right', parseFloat(calculatedPadding) + this._scrollbarWidth + "px");
+ }
+
+ $(document.body).addClass(ClassName$5.OPEN);
+ };
+
+ _proto._resetScrollbar = function _resetScrollbar() {
+ // Restore fixed content padding
+ var fixedContent = [].slice.call(document.querySelectorAll(Selector$5.FIXED_CONTENT));
+ $(fixedContent).each(function (index, element) {
+ var padding = $(element).data('padding-right');
+ $(element).removeData('padding-right');
+ element.style.paddingRight = padding ? padding : '';
+ }); // Restore sticky content
+
+ var elements = [].slice.call(document.querySelectorAll("" + Selector$5.STICKY_CONTENT));
+ $(elements).each(function (index, element) {
+ var margin = $(element).data('margin-right');
+
+ if (typeof margin !== 'undefined') {
+ $(element).css('margin-right', margin).removeData('margin-right');
+ }
+ }); // Restore body padding
+
+ var padding = $(document.body).data('padding-right');
+ $(document.body).removeData('padding-right');
+ document.body.style.paddingRight = padding ? padding : '';
+ };
+
+ _proto._getScrollbarWidth = function _getScrollbarWidth() {
+ // thx d.walsh
+ var scrollDiv = document.createElement('div');
+ scrollDiv.className = ClassName$5.SCROLLBAR_MEASURER;
+ document.body.appendChild(scrollDiv);
+ var scrollbarWidth = scrollDiv.getBoundingClientRect().width - scrollDiv.clientWidth;
+ document.body.removeChild(scrollDiv);
+ return scrollbarWidth;
+ } // Static
+ ;
+
+ Modal._jQueryInterface = function _jQueryInterface(config, relatedTarget) {
+ return this.each(function () {
+ var data = $(this).data(DATA_KEY$5);
+
+ var _config = _objectSpread2({}, Default$3, {}, $(this).data(), {}, _typeof(config) === 'object' && config ? config : {});
+
+ if (!data) {
+ data = new Modal(this, _config);
+ $(this).data(DATA_KEY$5, data);
+ }
+
+ if (typeof config === 'string') {
+ if (typeof data[config] === 'undefined') {
+ throw new TypeError("No method named \"" + config + "\"");
+ }
+
+ data[config](relatedTarget);
+ } else if (_config.show) {
+ data.show(relatedTarget);
+ }
+ });
+ };
+
+ _createClass(Modal, null, [{
+ key: "VERSION",
+ get: function get() {
+ return VERSION$5;
+ }
+ }, {
+ key: "Default",
+ get: function get() {
+ return Default$3;
+ }
+ }]);
+
+ return Modal;
+ }();
+ /**
+ * ------------------------------------------------------------------------
+ * Data Api implementation
+ * ------------------------------------------------------------------------
+ */
+
+
+ $(document).on(Event$5.CLICK_DATA_API, Selector$5.DATA_TOGGLE, function (event) {
+ var _this11 = this;
+
+ var target;
+ var selector = Util.getSelectorFromElement(this);
+
+ if (selector) {
+ target = document.querySelector(selector);
+ }
+
+ var config = $(target).data(DATA_KEY$5) ? 'toggle' : _objectSpread2({}, $(target).data(), {}, $(this).data());
+
+ if (this.tagName === 'A' || this.tagName === 'AREA') {
+ event.preventDefault();
+ }
+
+ var $target = $(target).one(Event$5.SHOW, function (showEvent) {
+ if (showEvent.isDefaultPrevented()) {
+ // Only register focus restorer if modal will actually get shown
+ return;
+ }
+
+ $target.one(Event$5.HIDDEN, function () {
+ if ($(_this11).is(':visible')) {
+ _this11.focus();
+ }
+ });
+ });
+
+ Modal._jQueryInterface.call($(target), config, this);
+ });
+ /**
+ * ------------------------------------------------------------------------
+ * jQuery
+ * ------------------------------------------------------------------------
+ */
+
+ $.fn[NAME$5] = Modal._jQueryInterface;
+ $.fn[NAME$5].Constructor = Modal;
+
+ $.fn[NAME$5].noConflict = function () {
+ $.fn[NAME$5] = JQUERY_NO_CONFLICT$5;
+ return Modal._jQueryInterface;
+ };
+ /**
+ * --------------------------------------------------------------------------
+ * Bootstrap (v4.4.1): tools/sanitizer.js
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * --------------------------------------------------------------------------
+ */
+
+
+ var uriAttrs = ['background', 'cite', 'href', 'itemtype', 'longdesc', 'poster', 'src', 'xlink:href'];
+ var ARIA_ATTRIBUTE_PATTERN = /^aria-[\w-]*$/i;
+ var DefaultWhitelist = {
+ // Global attributes allowed on any supplied element below.
+ '*': ['class', 'dir', 'id', 'lang', 'role', ARIA_ATTRIBUTE_PATTERN],
+ a: ['target', 'href', 'title', 'rel'],
+ area: [],
+ b: [],
+ br: [],
+ col: [],
+ code: [],
+ div: [],
+ em: [],
+ hr: [],
+ h1: [],
+ h2: [],
+ h3: [],
+ h4: [],
+ h5: [],
+ h6: [],
+ i: [],
+ img: ['src', 'alt', 'title', 'width', 'height'],
+ li: [],
+ ol: [],
+ p: [],
+ pre: [],
+ s: [],
+ small: [],
+ span: [],
+ sub: [],
+ sup: [],
+ strong: [],
+ u: [],
+ ul: []
+ };
+ /**
+ * A pattern that recognizes a commonly useful subset of URLs that are safe.
+ *
+ * Shoutout to Angular 7 https://github.com/angular/angular/blob/7.2.4/packages/core/src/sanitization/url_sanitizer.ts
+ */
+
+ var SAFE_URL_PATTERN = /^(?:(?:https?|mailto|ftp|tel|file):|[^&:/?#]*(?:[/?#]|$))/gi;
+ /**
+ * A pattern that matches safe data URLs. Only matches image, video and audio types.
+ *
+ * Shoutout to Angular 7 https://github.com/angular/angular/blob/7.2.4/packages/core/src/sanitization/url_sanitizer.ts
+ */
+
+ var DATA_URL_PATTERN = /^data:(?:image\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\/(?:mpeg|mp4|ogg|webm)|audio\/(?:mp3|oga|ogg|opus));base64,[a-z0-9+/]+=*$/i;
+
+ function allowedAttribute(attr, allowedAttributeList) {
+ var attrName = attr.nodeName.toLowerCase();
+
+ if (allowedAttributeList.indexOf(attrName) !== -1) {
+ if (uriAttrs.indexOf(attrName) !== -1) {
+ return Boolean(attr.nodeValue.match(SAFE_URL_PATTERN) || attr.nodeValue.match(DATA_URL_PATTERN));
+ }
+
+ return true;
+ }
+
+ var regExp = allowedAttributeList.filter(function (attrRegex) {
+ return attrRegex instanceof RegExp;
+ }); // Check if a regular expression validates the attribute.
+
+ for (var i = 0, l = regExp.length; i < l; i++) {
+ if (attrName.match(regExp[i])) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ function sanitizeHtml(unsafeHtml, whiteList, sanitizeFn) {
+ if (unsafeHtml.length === 0) {
+ return unsafeHtml;
+ }
+
+ if (sanitizeFn && typeof sanitizeFn === 'function') {
+ return sanitizeFn(unsafeHtml);
+ }
+
+ var domParser = new window.DOMParser();
+ var createdDocument = domParser.parseFromString(unsafeHtml, 'text/html');
+ var whitelistKeys = Object.keys(whiteList);
+ var elements = [].slice.call(createdDocument.body.querySelectorAll('*'));
+
+ var _loop = function _loop(i, len) {
+ var el = elements[i];
+ var elName = el.nodeName.toLowerCase();
+
+ if (whitelistKeys.indexOf(el.nodeName.toLowerCase()) === -1) {
+ el.parentNode.removeChild(el);
+ return "continue";
+ }
+
+ var attributeList = [].slice.call(el.attributes);
+ var whitelistedAttributes = [].concat(whiteList['*'] || [], whiteList[elName] || []);
+ attributeList.forEach(function (attr) {
+ if (!allowedAttribute(attr, whitelistedAttributes)) {
+ el.removeAttribute(attr.nodeName);
+ }
+ });
+ };
+
+ for (var i = 0, len = elements.length; i < len; i++) {
+ var _ret = _loop(i);
+
+ if (_ret === "continue") continue;
+ }
+
+ return createdDocument.body.innerHTML;
+ }
+ /**
+ * ------------------------------------------------------------------------
+ * Constants
+ * ------------------------------------------------------------------------
+ */
+
+
+ var NAME$6 = 'tooltip';
+ var VERSION$6 = '4.4.1';
+ var DATA_KEY$6 = 'bs.tooltip';
+ var EVENT_KEY$6 = "." + DATA_KEY$6;
+ var JQUERY_NO_CONFLICT$6 = $.fn[NAME$6];
+ var CLASS_PREFIX = 'bs-tooltip';
+ var BSCLS_PREFIX_REGEX = new RegExp("(^|\\s)" + CLASS_PREFIX + "\\S+", 'g');
+ var DISALLOWED_ATTRIBUTES = ['sanitize', 'whiteList', 'sanitizeFn'];
+ var DefaultType$4 = {
+ animation: 'boolean',
+ template: 'string',
+ title: '(string|element|function)',
+ trigger: 'string',
+ delay: '(number|object)',
+ html: 'boolean',
+ selector: '(string|boolean)',
+ placement: '(string|function)',
+ offset: '(number|string|function)',
+ container: '(string|element|boolean)',
+ fallbackPlacement: '(string|array)',
+ boundary: '(string|element)',
+ sanitize: 'boolean',
+ sanitizeFn: '(null|function)',
+ whiteList: 'object',
+ popperConfig: '(null|object)'
+ };
+ var AttachmentMap$1 = {
+ AUTO: 'auto',
+ TOP: 'top',
+ RIGHT: 'right',
+ BOTTOM: 'bottom',
+ LEFT: 'left'
+ };
+ var Default$4 = {
+ animation: true,
+ template: '',
+ trigger: 'hover focus',
+ title: '',
+ delay: 0,
+ html: false,
+ selector: false,
+ placement: 'top',
+ offset: 0,
+ container: false,
+ fallbackPlacement: 'flip',
+ boundary: 'scrollParent',
+ sanitize: true,
+ sanitizeFn: null,
+ whiteList: DefaultWhitelist,
+ popperConfig: null
+ };
+ var HoverState = {
+ SHOW: 'show',
+ OUT: 'out'
+ };
+ var Event$6 = {
+ HIDE: "hide" + EVENT_KEY$6,
+ HIDDEN: "hidden" + EVENT_KEY$6,
+ SHOW: "show" + EVENT_KEY$6,
+ SHOWN: "shown" + EVENT_KEY$6,
+ INSERTED: "inserted" + EVENT_KEY$6,
+ CLICK: "click" + EVENT_KEY$6,
+ FOCUSIN: "focusin" + EVENT_KEY$6,
+ FOCUSOUT: "focusout" + EVENT_KEY$6,
+ MOUSEENTER: "mouseenter" + EVENT_KEY$6,
+ MOUSELEAVE: "mouseleave" + EVENT_KEY$6
+ };
+ var ClassName$6 = {
+ FADE: 'fade',
+ SHOW: 'show'
+ };
+ var Selector$6 = {
+ TOOLTIP: '.tooltip',
+ TOOLTIP_INNER: '.tooltip-inner',
+ ARROW: '.arrow'
+ };
+ var Trigger = {
+ HOVER: 'hover',
+ FOCUS: 'focus',
+ CLICK: 'click',
+ MANUAL: 'manual'
+ };
+ /**
+ * ------------------------------------------------------------------------
+ * Class Definition
+ * ------------------------------------------------------------------------
+ */
+
+ var Tooltip = /*#__PURE__*/function () {
+ function Tooltip(element, config) {
+ if (typeof Popper === 'undefined') {
+ throw new TypeError('Bootstrap\'s tooltips require Popper.js (https://popper.js.org/)');
+ } // private
+
+
+ this._isEnabled = true;
+ this._timeout = 0;
+ this._hoverState = '';
+ this._activeTrigger = {};
+ this._popper = null; // Protected
+
+ this.element = element;
+ this.config = this._getConfig(config);
+ this.tip = null;
+
+ this._setListeners();
+ } // Getters
+
+
+ var _proto = Tooltip.prototype; // Public
+
+ _proto.enable = function enable() {
+ this._isEnabled = true;
+ };
+
+ _proto.disable = function disable() {
+ this._isEnabled = false;
+ };
+
+ _proto.toggleEnabled = function toggleEnabled() {
+ this._isEnabled = !this._isEnabled;
+ };
+
+ _proto.toggle = function toggle(event) {
+ if (!this._isEnabled) {
+ return;
+ }
+
+ if (event) {
+ var dataKey = this.constructor.DATA_KEY;
+ var context = $(event.currentTarget).data(dataKey);
+
+ if (!context) {
+ context = new this.constructor(event.currentTarget, this._getDelegateConfig());
+ $(event.currentTarget).data(dataKey, context);
+ }
+
+ context._activeTrigger.click = !context._activeTrigger.click;
+
+ if (context._isWithActiveTrigger()) {
+ context._enter(null, context);
+ } else {
+ context._leave(null, context);
+ }
+ } else {
+ if ($(this.getTipElement()).hasClass(ClassName$6.SHOW)) {
+ this._leave(null, this);
+
+ return;
+ }
+
+ this._enter(null, this);
+ }
+ };
+
+ _proto.dispose = function dispose() {
+ clearTimeout(this._timeout);
+ $.removeData(this.element, this.constructor.DATA_KEY);
+ $(this.element).off(this.constructor.EVENT_KEY);
+ $(this.element).closest('.modal').off('hide.bs.modal', this._hideModalHandler);
+
+ if (this.tip) {
+ $(this.tip).remove();
+ }
+
+ this._isEnabled = null;
+ this._timeout = null;
+ this._hoverState = null;
+ this._activeTrigger = null;
+
+ if (this._popper) {
+ this._popper.destroy();
+ }
+
+ this._popper = null;
+ this.element = null;
+ this.config = null;
+ this.tip = null;
+ };
+
+ _proto.show = function show() {
+ var _this = this;
+
+ if ($(this.element).css('display') === 'none') {
+ throw new Error('Please use show on visible elements');
+ }
+
+ var showEvent = $.Event(this.constructor.Event.SHOW);
+
+ if (this.isWithContent() && this._isEnabled) {
+ $(this.element).trigger(showEvent);
+ var shadowRoot = Util.findShadowRoot(this.element);
+ var isInTheDom = $.contains(shadowRoot !== null ? shadowRoot : this.element.ownerDocument.documentElement, this.element);
+
+ if (showEvent.isDefaultPrevented() || !isInTheDom) {
+ return;
+ }
+
+ var tip = this.getTipElement();
+ var tipId = Util.getUID(this.constructor.NAME);
+ tip.setAttribute('id', tipId);
+ this.element.setAttribute('aria-describedby', tipId);
+ this.setContent();
+
+ if (this.config.animation) {
+ $(tip).addClass(ClassName$6.FADE);
+ }
+
+ var placement = typeof this.config.placement === 'function' ? this.config.placement.call(this, tip, this.element) : this.config.placement;
+
+ var attachment = this._getAttachment(placement);
+
+ this.addAttachmentClass(attachment);
+
+ var container = this._getContainer();
+
+ $(tip).data(this.constructor.DATA_KEY, this);
+
+ if (!$.contains(this.element.ownerDocument.documentElement, this.tip)) {
+ $(tip).appendTo(container);
+ }
+
+ $(this.element).trigger(this.constructor.Event.INSERTED);
+ this._popper = new Popper(this.element, tip, this._getPopperConfig(attachment));
+ $(tip).addClass(ClassName$6.SHOW); // If this is a touch-enabled device we add extra
+ // empty mouseover listeners to the body's immediate children;
+ // only needed because of broken event delegation on iOS
+ // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html
+
+ if ('ontouchstart' in document.documentElement) {
+ $(document.body).children().on('mouseover', null, $.noop);
+ }
+
+ var complete = function complete() {
+ if (_this.config.animation) {
+ _this._fixTransition();
+ }
+
+ var prevHoverState = _this._hoverState;
+ _this._hoverState = null;
+ $(_this.element).trigger(_this.constructor.Event.SHOWN);
+
+ if (prevHoverState === HoverState.OUT) {
+ _this._leave(null, _this);
+ }
+ };
+
+ if ($(this.tip).hasClass(ClassName$6.FADE)) {
+ var transitionDuration = Util.getTransitionDurationFromElement(this.tip);
+ $(this.tip).one(Util.TRANSITION_END, complete).emulateTransitionEnd(transitionDuration);
+ } else {
+ complete();
+ }
+ }
+ };
+
+ _proto.hide = function hide(callback) {
+ var _this2 = this;
+
+ var tip = this.getTipElement();
+ var hideEvent = $.Event(this.constructor.Event.HIDE);
+
+ var complete = function complete() {
+ if (_this2._hoverState !== HoverState.SHOW && tip.parentNode) {
+ tip.parentNode.removeChild(tip);
+ }
+
+ _this2._cleanTipClass();
+
+ _this2.element.removeAttribute('aria-describedby');
+
+ $(_this2.element).trigger(_this2.constructor.Event.HIDDEN);
+
+ if (_this2._popper !== null) {
+ _this2._popper.destroy();
+ }
+
+ if (callback) {
+ callback();
+ }
+ };
+
+ $(this.element).trigger(hideEvent);
+
+ if (hideEvent.isDefaultPrevented()) {
+ return;
+ }
+
+ $(tip).removeClass(ClassName$6.SHOW); // If this is a touch-enabled device we remove the extra
+ // empty mouseover listeners we added for iOS support
+
+ if ('ontouchstart' in document.documentElement) {
+ $(document.body).children().off('mouseover', null, $.noop);
+ }
+
+ this._activeTrigger[Trigger.CLICK] = false;
+ this._activeTrigger[Trigger.FOCUS] = false;
+ this._activeTrigger[Trigger.HOVER] = false;
+
+ if ($(this.tip).hasClass(ClassName$6.FADE)) {
+ var transitionDuration = Util.getTransitionDurationFromElement(tip);
+ $(tip).one(Util.TRANSITION_END, complete).emulateTransitionEnd(transitionDuration);
+ } else {
+ complete();
+ }
+
+ this._hoverState = '';
+ };
+
+ _proto.update = function update() {
+ if (this._popper !== null) {
+ this._popper.scheduleUpdate();
+ }
+ } // Protected
+ ;
+
+ _proto.isWithContent = function isWithContent() {
+ return Boolean(this.getTitle());
+ };
+
+ _proto.addAttachmentClass = function addAttachmentClass(attachment) {
+ $(this.getTipElement()).addClass(CLASS_PREFIX + "-" + attachment);
+ };
+
+ _proto.getTipElement = function getTipElement() {
+ this.tip = this.tip || $(this.config.template)[0];
+ return this.tip;
+ };
+
+ _proto.setContent = function setContent() {
+ var tip = this.getTipElement();
+ this.setElementContent($(tip.querySelectorAll(Selector$6.TOOLTIP_INNER)), this.getTitle());
+ $(tip).removeClass(ClassName$6.FADE + " " + ClassName$6.SHOW);
+ };
+
+ _proto.setElementContent = function setElementContent($element, content) {
+ if (_typeof(content) === 'object' && (content.nodeType || content.jquery)) {
+ // Content is a DOM node or a jQuery
+ if (this.config.html) {
+ if (!$(content).parent().is($element)) {
+ $element.empty().append(content);
+ }
+ } else {
+ $element.text($(content).text());
+ }
+
+ return;
+ }
+
+ if (this.config.html) {
+ if (this.config.sanitize) {
+ content = sanitizeHtml(content, this.config.whiteList, this.config.sanitizeFn);
+ }
+
+ $element.html(content);
+ } else {
+ $element.text(content);
+ }
+ };
+
+ _proto.getTitle = function getTitle() {
+ var title = this.element.getAttribute('data-original-title');
+
+ if (!title) {
+ title = typeof this.config.title === 'function' ? this.config.title.call(this.element) : this.config.title;
+ }
+
+ return title;
+ } // Private
+ ;
+
+ _proto._getPopperConfig = function _getPopperConfig(attachment) {
+ var _this3 = this;
+
+ var defaultBsConfig = {
+ placement: attachment,
+ modifiers: {
+ offset: this._getOffset(),
+ flip: {
+ behavior: this.config.fallbackPlacement
+ },
+ arrow: {
+ element: Selector$6.ARROW
+ },
+ preventOverflow: {
+ boundariesElement: this.config.boundary
+ }
+ },
+ onCreate: function onCreate(data) {
+ if (data.originalPlacement !== data.placement) {
+ _this3._handlePopperPlacementChange(data);
+ }
+ },
+ onUpdate: function onUpdate(data) {
+ return _this3._handlePopperPlacementChange(data);
+ }
+ };
+ return _objectSpread2({}, defaultBsConfig, {}, this.config.popperConfig);
+ };
+
+ _proto._getOffset = function _getOffset() {
+ var _this4 = this;
+
+ var offset = {};
+
+ if (typeof this.config.offset === 'function') {
+ offset.fn = function (data) {
+ data.offsets = _objectSpread2({}, data.offsets, {}, _this4.config.offset(data.offsets, _this4.element) || {});
+ return data;
+ };
+ } else {
+ offset.offset = this.config.offset;
+ }
+
+ return offset;
+ };
+
+ _proto._getContainer = function _getContainer() {
+ if (this.config.container === false) {
+ return document.body;
+ }
+
+ if (Util.isElement(this.config.container)) {
+ return $(this.config.container);
+ }
+
+ return $(document).find(this.config.container);
+ };
+
+ _proto._getAttachment = function _getAttachment(placement) {
+ return AttachmentMap$1[placement.toUpperCase()];
+ };
+
+ _proto._setListeners = function _setListeners() {
+ var _this5 = this;
+
+ var triggers = this.config.trigger.split(' ');
+ triggers.forEach(function (trigger) {
+ if (trigger === 'click') {
+ $(_this5.element).on(_this5.constructor.Event.CLICK, _this5.config.selector, function (event) {
+ return _this5.toggle(event);
+ });
+ } else if (trigger !== Trigger.MANUAL) {
+ var eventIn = trigger === Trigger.HOVER ? _this5.constructor.Event.MOUSEENTER : _this5.constructor.Event.FOCUSIN;
+ var eventOut = trigger === Trigger.HOVER ? _this5.constructor.Event.MOUSELEAVE : _this5.constructor.Event.FOCUSOUT;
+ $(_this5.element).on(eventIn, _this5.config.selector, function (event) {
+ return _this5._enter(event);
+ }).on(eventOut, _this5.config.selector, function (event) {
+ return _this5._leave(event);
+ });
+ }
+ });
+
+ this._hideModalHandler = function () {
+ if (_this5.element) {
+ _this5.hide();
+ }
+ };
+
+ $(this.element).closest('.modal').on('hide.bs.modal', this._hideModalHandler);
+
+ if (this.config.selector) {
+ this.config = _objectSpread2({}, this.config, {
+ trigger: 'manual',
+ selector: ''
+ });
+ } else {
+ this._fixTitle();
+ }
+ };
+
+ _proto._fixTitle = function _fixTitle() {
+ var titleType = _typeof(this.element.getAttribute('data-original-title'));
+
+ if (this.element.getAttribute('title') || titleType !== 'string') {
+ this.element.setAttribute('data-original-title', this.element.getAttribute('title') || '');
+ this.element.setAttribute('title', '');
+ }
+ };
+
+ _proto._enter = function _enter(event, context) {
+ var dataKey = this.constructor.DATA_KEY;
+ context = context || $(event.currentTarget).data(dataKey);
+
+ if (!context) {
+ context = new this.constructor(event.currentTarget, this._getDelegateConfig());
+ $(event.currentTarget).data(dataKey, context);
+ }
+
+ if (event) {
+ context._activeTrigger[event.type === 'focusin' ? Trigger.FOCUS : Trigger.HOVER] = true;
+ }
+
+ if ($(context.getTipElement()).hasClass(ClassName$6.SHOW) || context._hoverState === HoverState.SHOW) {
+ context._hoverState = HoverState.SHOW;
+ return;
+ }
+
+ clearTimeout(context._timeout);
+ context._hoverState = HoverState.SHOW;
+
+ if (!context.config.delay || !context.config.delay.show) {
+ context.show();
+ return;
+ }
+
+ context._timeout = setTimeout(function () {
+ if (context._hoverState === HoverState.SHOW) {
+ context.show();
+ }
+ }, context.config.delay.show);
+ };
+
+ _proto._leave = function _leave(event, context) {
+ var dataKey = this.constructor.DATA_KEY;
+ context = context || $(event.currentTarget).data(dataKey);
+
+ if (!context) {
+ context = new this.constructor(event.currentTarget, this._getDelegateConfig());
+ $(event.currentTarget).data(dataKey, context);
+ }
+
+ if (event) {
+ context._activeTrigger[event.type === 'focusout' ? Trigger.FOCUS : Trigger.HOVER] = false;
+ }
+
+ if (context._isWithActiveTrigger()) {
+ return;
+ }
+
+ clearTimeout(context._timeout);
+ context._hoverState = HoverState.OUT;
+
+ if (!context.config.delay || !context.config.delay.hide) {
+ context.hide();
+ return;
+ }
+
+ context._timeout = setTimeout(function () {
+ if (context._hoverState === HoverState.OUT) {
+ context.hide();
+ }
+ }, context.config.delay.hide);
+ };
+
+ _proto._isWithActiveTrigger = function _isWithActiveTrigger() {
+ for (var trigger in this._activeTrigger) {
+ if (this._activeTrigger[trigger]) {
+ return true;
+ }
+ }
+
+ return false;
+ };
+
+ _proto._getConfig = function _getConfig(config) {
+ var dataAttributes = $(this.element).data();
+ Object.keys(dataAttributes).forEach(function (dataAttr) {
+ if (DISALLOWED_ATTRIBUTES.indexOf(dataAttr) !== -1) {
+ delete dataAttributes[dataAttr];
+ }
+ });
+ config = _objectSpread2({}, this.constructor.Default, {}, dataAttributes, {}, _typeof(config) === 'object' && config ? config : {});
+
+ if (typeof config.delay === 'number') {
+ config.delay = {
+ show: config.delay,
+ hide: config.delay
+ };
+ }
+
+ if (typeof config.title === 'number') {
+ config.title = config.title.toString();
+ }
+
+ if (typeof config.content === 'number') {
+ config.content = config.content.toString();
+ }
+
+ Util.typeCheckConfig(NAME$6, config, this.constructor.DefaultType);
+
+ if (config.sanitize) {
+ config.template = sanitizeHtml(config.template, config.whiteList, config.sanitizeFn);
+ }
+
+ return config;
+ };
+
+ _proto._getDelegateConfig = function _getDelegateConfig() {
+ var config = {};
+
+ if (this.config) {
+ for (var key in this.config) {
+ if (this.constructor.Default[key] !== this.config[key]) {
+ config[key] = this.config[key];
+ }
+ }
+ }
+
+ return config;
+ };
+
+ _proto._cleanTipClass = function _cleanTipClass() {
+ var $tip = $(this.getTipElement());
+ var tabClass = $tip.attr('class').match(BSCLS_PREFIX_REGEX);
+
+ if (tabClass !== null && tabClass.length) {
+ $tip.removeClass(tabClass.join(''));
+ }
+ };
+
+ _proto._handlePopperPlacementChange = function _handlePopperPlacementChange(popperData) {
+ var popperInstance = popperData.instance;
+ this.tip = popperInstance.popper;
+
+ this._cleanTipClass();
+
+ this.addAttachmentClass(this._getAttachment(popperData.placement));
+ };
+
+ _proto._fixTransition = function _fixTransition() {
+ var tip = this.getTipElement();
+ var initConfigAnimation = this.config.animation;
+
+ if (tip.getAttribute('x-placement') !== null) {
+ return;
+ }
+
+ $(tip).removeClass(ClassName$6.FADE);
+ this.config.animation = false;
+ this.hide();
+ this.show();
+ this.config.animation = initConfigAnimation;
+ } // Static
+ ;
+
+ Tooltip._jQueryInterface = function _jQueryInterface(config) {
+ return this.each(function () {
+ var data = $(this).data(DATA_KEY$6);
+
+ var _config = _typeof(config) === 'object' && config;
+
+ if (!data && /dispose|hide/.test(config)) {
+ return;
+ }
+
+ if (!data) {
+ data = new Tooltip(this, _config);
+ $(this).data(DATA_KEY$6, data);
+ }
+
+ if (typeof config === 'string') {
+ if (typeof data[config] === 'undefined') {
+ throw new TypeError("No method named \"" + config + "\"");
+ }
+
+ data[config]();
+ }
+ });
+ };
+
+ _createClass(Tooltip, null, [{
+ key: "VERSION",
+ get: function get() {
+ return VERSION$6;
+ }
+ }, {
+ key: "Default",
+ get: function get() {
+ return Default$4;
+ }
+ }, {
+ key: "NAME",
+ get: function get() {
+ return NAME$6;
+ }
+ }, {
+ key: "DATA_KEY",
+ get: function get() {
+ return DATA_KEY$6;
+ }
+ }, {
+ key: "Event",
+ get: function get() {
+ return Event$6;
+ }
+ }, {
+ key: "EVENT_KEY",
+ get: function get() {
+ return EVENT_KEY$6;
+ }
+ }, {
+ key: "DefaultType",
+ get: function get() {
+ return DefaultType$4;
+ }
+ }]);
+
+ return Tooltip;
+ }();
+ /**
+ * ------------------------------------------------------------------------
+ * jQuery
+ * ------------------------------------------------------------------------
+ */
+
+
+ $.fn[NAME$6] = Tooltip._jQueryInterface;
+ $.fn[NAME$6].Constructor = Tooltip;
+
+ $.fn[NAME$6].noConflict = function () {
+ $.fn[NAME$6] = JQUERY_NO_CONFLICT$6;
+ return Tooltip._jQueryInterface;
+ };
+ /**
+ * ------------------------------------------------------------------------
+ * Constants
+ * ------------------------------------------------------------------------
+ */
+
+
+ var NAME$7 = 'popover';
+ var VERSION$7 = '4.4.1';
+ var DATA_KEY$7 = 'bs.popover';
+ var EVENT_KEY$7 = "." + DATA_KEY$7;
+ var JQUERY_NO_CONFLICT$7 = $.fn[NAME$7];
+ var CLASS_PREFIX$1 = 'bs-popover';
+ var BSCLS_PREFIX_REGEX$1 = new RegExp("(^|\\s)" + CLASS_PREFIX$1 + "\\S+", 'g');
+
+ var Default$5 = _objectSpread2({}, Tooltip.Default, {
+ placement: 'right',
+ trigger: 'click',
+ content: '',
+ template: ''
+ });
+
+ var DefaultType$5 = _objectSpread2({}, Tooltip.DefaultType, {
+ content: '(string|element|function)'
+ });
+
+ var ClassName$7 = {
+ FADE: 'fade',
+ SHOW: 'show'
+ };
+ var Selector$7 = {
+ TITLE: '.popover-header',
+ CONTENT: '.popover-body'
+ };
+ var Event$7 = {
+ HIDE: "hide" + EVENT_KEY$7,
+ HIDDEN: "hidden" + EVENT_KEY$7,
+ SHOW: "show" + EVENT_KEY$7,
+ SHOWN: "shown" + EVENT_KEY$7,
+ INSERTED: "inserted" + EVENT_KEY$7,
+ CLICK: "click" + EVENT_KEY$7,
+ FOCUSIN: "focusin" + EVENT_KEY$7,
+ FOCUSOUT: "focusout" + EVENT_KEY$7,
+ MOUSEENTER: "mouseenter" + EVENT_KEY$7,
+ MOUSELEAVE: "mouseleave" + EVENT_KEY$7
+ };
+ /**
+ * ------------------------------------------------------------------------
+ * Class Definition
+ * ------------------------------------------------------------------------
+ */
+
+ var Popover = /*#__PURE__*/function (_Tooltip) {
+ _inheritsLoose(Popover, _Tooltip);
+
+ function Popover() {
+ return _Tooltip.apply(this, arguments) || this;
+ }
+
+ var _proto = Popover.prototype; // Overrides
+
+ _proto.isWithContent = function isWithContent() {
+ return this.getTitle() || this._getContent();
+ };
+
+ _proto.addAttachmentClass = function addAttachmentClass(attachment) {
+ $(this.getTipElement()).addClass(CLASS_PREFIX$1 + "-" + attachment);
+ };
+
+ _proto.getTipElement = function getTipElement() {
+ this.tip = this.tip || $(this.config.template)[0];
+ return this.tip;
+ };
+
+ _proto.setContent = function setContent() {
+ var $tip = $(this.getTipElement()); // We use append for html objects to maintain js events
+
+ this.setElementContent($tip.find(Selector$7.TITLE), this.getTitle());
+
+ var content = this._getContent();
+
+ if (typeof content === 'function') {
+ content = content.call(this.element);
+ }
+
+ this.setElementContent($tip.find(Selector$7.CONTENT), content);
+ $tip.removeClass(ClassName$7.FADE + " " + ClassName$7.SHOW);
+ } // Private
+ ;
+
+ _proto._getContent = function _getContent() {
+ return this.element.getAttribute('data-content') || this.config.content;
+ };
+
+ _proto._cleanTipClass = function _cleanTipClass() {
+ var $tip = $(this.getTipElement());
+ var tabClass = $tip.attr('class').match(BSCLS_PREFIX_REGEX$1);
+
+ if (tabClass !== null && tabClass.length > 0) {
+ $tip.removeClass(tabClass.join(''));
+ }
+ } // Static
+ ;
+
+ Popover._jQueryInterface = function _jQueryInterface(config) {
+ return this.each(function () {
+ var data = $(this).data(DATA_KEY$7);
+
+ var _config = _typeof(config) === 'object' ? config : null;
+
+ if (!data && /dispose|hide/.test(config)) {
+ return;
+ }
+
+ if (!data) {
+ data = new Popover(this, _config);
+ $(this).data(DATA_KEY$7, data);
+ }
+
+ if (typeof config === 'string') {
+ if (typeof data[config] === 'undefined') {
+ throw new TypeError("No method named \"" + config + "\"");
+ }
+
+ data[config]();
+ }
+ });
+ };
+
+ _createClass(Popover, null, [{
+ key: "VERSION",
+ // Getters
+ get: function get() {
+ return VERSION$7;
+ }
+ }, {
+ key: "Default",
+ get: function get() {
+ return Default$5;
+ }
+ }, {
+ key: "NAME",
+ get: function get() {
+ return NAME$7;
+ }
+ }, {
+ key: "DATA_KEY",
+ get: function get() {
+ return DATA_KEY$7;
+ }
+ }, {
+ key: "Event",
+ get: function get() {
+ return Event$7;
+ }
+ }, {
+ key: "EVENT_KEY",
+ get: function get() {
+ return EVENT_KEY$7;
+ }
+ }, {
+ key: "DefaultType",
+ get: function get() {
+ return DefaultType$5;
+ }
+ }]);
+
+ return Popover;
+ }(Tooltip);
+ /**
+ * ------------------------------------------------------------------------
+ * jQuery
+ * ------------------------------------------------------------------------
+ */
+
+
+ $.fn[NAME$7] = Popover._jQueryInterface;
+ $.fn[NAME$7].Constructor = Popover;
+
+ $.fn[NAME$7].noConflict = function () {
+ $.fn[NAME$7] = JQUERY_NO_CONFLICT$7;
+ return Popover._jQueryInterface;
+ };
+ /**
+ * ------------------------------------------------------------------------
+ * Constants
+ * ------------------------------------------------------------------------
+ */
+
+
+ var NAME$8 = 'scrollspy';
+ var VERSION$8 = '4.4.1';
+ var DATA_KEY$8 = 'bs.scrollspy';
+ var EVENT_KEY$8 = "." + DATA_KEY$8;
+ var DATA_API_KEY$6 = '.data-api';
+ var JQUERY_NO_CONFLICT$8 = $.fn[NAME$8];
+ var Default$6 = {
+ offset: 10,
+ method: 'auto',
+ target: ''
+ };
+ var DefaultType$6 = {
+ offset: 'number',
+ method: 'string',
+ target: '(string|element)'
+ };
+ var Event$8 = {
+ ACTIVATE: "activate" + EVENT_KEY$8,
+ SCROLL: "scroll" + EVENT_KEY$8,
+ LOAD_DATA_API: "load" + EVENT_KEY$8 + DATA_API_KEY$6
+ };
+ var ClassName$8 = {
+ DROPDOWN_ITEM: 'dropdown-item',
+ DROPDOWN_MENU: 'dropdown-menu',
+ ACTIVE: 'active'
+ };
+ var Selector$8 = {
+ DATA_SPY: '[data-spy="scroll"]',
+ ACTIVE: '.active',
+ NAV_LIST_GROUP: '.nav, .list-group',
+ NAV_LINKS: '.nav-link',
+ NAV_ITEMS: '.nav-item',
+ LIST_ITEMS: '.list-group-item',
+ DROPDOWN: '.dropdown',
+ DROPDOWN_ITEMS: '.dropdown-item',
+ DROPDOWN_TOGGLE: '.dropdown-toggle'
+ };
+ var OffsetMethod = {
+ OFFSET: 'offset',
+ POSITION: 'position'
+ };
+ /**
+ * ------------------------------------------------------------------------
+ * Class Definition
+ * ------------------------------------------------------------------------
+ */
+
+ var ScrollSpy = /*#__PURE__*/function () {
+ function ScrollSpy(element, config) {
+ var _this = this;
+
+ this._element = element;
+ this._scrollElement = element.tagName === 'BODY' ? window : element;
+ this._config = this._getConfig(config);
+ this._selector = this._config.target + " " + Selector$8.NAV_LINKS + "," + (this._config.target + " " + Selector$8.LIST_ITEMS + ",") + (this._config.target + " " + Selector$8.DROPDOWN_ITEMS);
+ this._offsets = [];
+ this._targets = [];
+ this._activeTarget = null;
+ this._scrollHeight = 0;
+ $(this._scrollElement).on(Event$8.SCROLL, function (event) {
+ return _this._process(event);
+ });
+ this.refresh();
+
+ this._process();
+ } // Getters
+
+
+ var _proto = ScrollSpy.prototype; // Public
+
+ _proto.refresh = function refresh() {
+ var _this2 = this;
+
+ var autoMethod = this._scrollElement === this._scrollElement.window ? OffsetMethod.OFFSET : OffsetMethod.POSITION;
+ var offsetMethod = this._config.method === 'auto' ? autoMethod : this._config.method;
+ var offsetBase = offsetMethod === OffsetMethod.POSITION ? this._getScrollTop() : 0;
+ this._offsets = [];
+ this._targets = [];
+ this._scrollHeight = this._getScrollHeight();
+ var targets = [].slice.call(document.querySelectorAll(this._selector));
+ targets.map(function (element) {
+ var target;
+ var targetSelector = Util.getSelectorFromElement(element);
+
+ if (targetSelector) {
+ target = document.querySelector(targetSelector);
+ }
+
+ if (target) {
+ var targetBCR = target.getBoundingClientRect();
+
+ if (targetBCR.width || targetBCR.height) {
+ // TODO (fat): remove sketch reliance on jQuery position/offset
+ return [$(target)[offsetMethod]().top + offsetBase, targetSelector];
+ }
+ }
+
+ return null;
+ }).filter(function (item) {
+ return item;
+ }).sort(function (a, b) {
+ return a[0] - b[0];
+ }).forEach(function (item) {
+ _this2._offsets.push(item[0]);
+
+ _this2._targets.push(item[1]);
+ });
+ };
+
+ _proto.dispose = function dispose() {
+ $.removeData(this._element, DATA_KEY$8);
+ $(this._scrollElement).off(EVENT_KEY$8);
+ this._element = null;
+ this._scrollElement = null;
+ this._config = null;
+ this._selector = null;
+ this._offsets = null;
+ this._targets = null;
+ this._activeTarget = null;
+ this._scrollHeight = null;
+ } // Private
+ ;
+
+ _proto._getConfig = function _getConfig(config) {
+ config = _objectSpread2({}, Default$6, {}, _typeof(config) === 'object' && config ? config : {});
+
+ if (typeof config.target !== 'string') {
+ var id = $(config.target).attr('id');
+
+ if (!id) {
+ id = Util.getUID(NAME$8);
+ $(config.target).attr('id', id);
+ }
+
+ config.target = "#" + id;
+ }
+
+ Util.typeCheckConfig(NAME$8, config, DefaultType$6);
+ return config;
+ };
+
+ _proto._getScrollTop = function _getScrollTop() {
+ return this._scrollElement === window ? this._scrollElement.pageYOffset : this._scrollElement.scrollTop;
+ };
+
+ _proto._getScrollHeight = function _getScrollHeight() {
+ return this._scrollElement.scrollHeight || Math.max(document.body.scrollHeight, document.documentElement.scrollHeight);
+ };
+
+ _proto._getOffsetHeight = function _getOffsetHeight() {
+ return this._scrollElement === window ? window.innerHeight : this._scrollElement.getBoundingClientRect().height;
+ };
+
+ _proto._process = function _process() {
+ var scrollTop = this._getScrollTop() + this._config.offset;
+
+ var scrollHeight = this._getScrollHeight();
+
+ var maxScroll = this._config.offset + scrollHeight - this._getOffsetHeight();
+
+ if (this._scrollHeight !== scrollHeight) {
+ this.refresh();
+ }
+
+ if (scrollTop >= maxScroll) {
+ var target = this._targets[this._targets.length - 1];
+
+ if (this._activeTarget !== target) {
+ this._activate(target);
+ }
+
+ return;
+ }
+
+ if (this._activeTarget && scrollTop < this._offsets[0] && this._offsets[0] > 0) {
+ this._activeTarget = null;
+
+ this._clear();
+
+ return;
+ }
+
+ var offsetLength = this._offsets.length;
+
+ for (var i = offsetLength; i--;) {
+ var isActiveTarget = this._activeTarget !== this._targets[i] && scrollTop >= this._offsets[i] && (typeof this._offsets[i + 1] === 'undefined' || scrollTop < this._offsets[i + 1]);
+
+ if (isActiveTarget) {
+ this._activate(this._targets[i]);
+ }
+ }
+ };
+
+ _proto._activate = function _activate(target) {
+ this._activeTarget = target;
+
+ this._clear();
+
+ var queries = this._selector.split(',').map(function (selector) {
+ return selector + "[data-target=\"" + target + "\"]," + selector + "[href=\"" + target + "\"]";
+ });
+
+ var $link = $([].slice.call(document.querySelectorAll(queries.join(','))));
+
+ if ($link.hasClass(ClassName$8.DROPDOWN_ITEM)) {
+ $link.closest(Selector$8.DROPDOWN).find(Selector$8.DROPDOWN_TOGGLE).addClass(ClassName$8.ACTIVE);
+ $link.addClass(ClassName$8.ACTIVE);
+ } else {
+ // Set triggered link as active
+ $link.addClass(ClassName$8.ACTIVE); // Set triggered links parents as active
+ // With both and markup a parent is the previous sibling of any nav ancestor
+
+ $link.parents(Selector$8.NAV_LIST_GROUP).prev(Selector$8.NAV_LINKS + ", " + Selector$8.LIST_ITEMS).addClass(ClassName$8.ACTIVE); // Handle special case when .nav-link is inside .nav-item
+
+ $link.parents(Selector$8.NAV_LIST_GROUP).prev(Selector$8.NAV_ITEMS).children(Selector$8.NAV_LINKS).addClass(ClassName$8.ACTIVE);
+ }
+
+ $(this._scrollElement).trigger(Event$8.ACTIVATE, {
+ relatedTarget: target
+ });
+ };
+
+ _proto._clear = function _clear() {
+ [].slice.call(document.querySelectorAll(this._selector)).filter(function (node) {
+ return node.classList.contains(ClassName$8.ACTIVE);
+ }).forEach(function (node) {
+ return node.classList.remove(ClassName$8.ACTIVE);
+ });
+ } // Static
+ ;
+
+ ScrollSpy._jQueryInterface = function _jQueryInterface(config) {
+ return this.each(function () {
+ var data = $(this).data(DATA_KEY$8);
+
+ var _config = _typeof(config) === 'object' && config;
+
+ if (!data) {
+ data = new ScrollSpy(this, _config);
+ $(this).data(DATA_KEY$8, data);
+ }
+
+ if (typeof config === 'string') {
+ if (typeof data[config] === 'undefined') {
+ throw new TypeError("No method named \"" + config + "\"");
+ }
+
+ data[config]();
+ }
+ });
+ };
+
+ _createClass(ScrollSpy, null, [{
+ key: "VERSION",
+ get: function get() {
+ return VERSION$8;
+ }
+ }, {
+ key: "Default",
+ get: function get() {
+ return Default$6;
+ }
+ }]);
+
+ return ScrollSpy;
+ }();
+ /**
+ * ------------------------------------------------------------------------
+ * Data Api implementation
+ * ------------------------------------------------------------------------
+ */
+
+
+ $(window).on(Event$8.LOAD_DATA_API, function () {
+ var scrollSpys = [].slice.call(document.querySelectorAll(Selector$8.DATA_SPY));
+ var scrollSpysLength = scrollSpys.length;
+
+ for (var i = scrollSpysLength; i--;) {
+ var $spy = $(scrollSpys[i]);
+
+ ScrollSpy._jQueryInterface.call($spy, $spy.data());
+ }
+ });
+ /**
+ * ------------------------------------------------------------------------
+ * jQuery
+ * ------------------------------------------------------------------------
+ */
+
+ $.fn[NAME$8] = ScrollSpy._jQueryInterface;
+ $.fn[NAME$8].Constructor = ScrollSpy;
+
+ $.fn[NAME$8].noConflict = function () {
+ $.fn[NAME$8] = JQUERY_NO_CONFLICT$8;
+ return ScrollSpy._jQueryInterface;
+ };
+ /**
+ * ------------------------------------------------------------------------
+ * Constants
+ * ------------------------------------------------------------------------
+ */
+
+
+ var NAME$9 = 'tab';
+ var VERSION$9 = '4.4.1';
+ var DATA_KEY$9 = 'bs.tab';
+ var EVENT_KEY$9 = "." + DATA_KEY$9;
+ var DATA_API_KEY$7 = '.data-api';
+ var JQUERY_NO_CONFLICT$9 = $.fn[NAME$9];
+ var Event$9 = {
+ HIDE: "hide" + EVENT_KEY$9,
+ HIDDEN: "hidden" + EVENT_KEY$9,
+ SHOW: "show" + EVENT_KEY$9,
+ SHOWN: "shown" + EVENT_KEY$9,
+ CLICK_DATA_API: "click" + EVENT_KEY$9 + DATA_API_KEY$7
+ };
+ var ClassName$9 = {
+ DROPDOWN_MENU: 'dropdown-menu',
+ ACTIVE: 'active',
+ DISABLED: 'disabled',
+ FADE: 'fade',
+ SHOW: 'show'
+ };
+ var Selector$9 = {
+ DROPDOWN: '.dropdown',
+ NAV_LIST_GROUP: '.nav, .list-group',
+ ACTIVE: '.active',
+ ACTIVE_UL: '> li > .active',
+ DATA_TOGGLE: '[data-toggle="tab"], [data-toggle="pill"], [data-toggle="list"]',
+ DROPDOWN_TOGGLE: '.dropdown-toggle',
+ DROPDOWN_ACTIVE_CHILD: '> .dropdown-menu .active'
+ };
+ /**
+ * ------------------------------------------------------------------------
+ * Class Definition
+ * ------------------------------------------------------------------------
+ */
+
+ var Tab = /*#__PURE__*/function () {
+ function Tab(element) {
+ this._element = element;
+ } // Getters
+
+
+ var _proto = Tab.prototype; // Public
+
+ _proto.show = function show() {
+ var _this = this;
+
+ if (this._element.parentNode && this._element.parentNode.nodeType === Node.ELEMENT_NODE && $(this._element).hasClass(ClassName$9.ACTIVE) || $(this._element).hasClass(ClassName$9.DISABLED)) {
+ return;
+ }
+
+ var target;
+ var previous;
+ var listElement = $(this._element).closest(Selector$9.NAV_LIST_GROUP)[0];
+ var selector = Util.getSelectorFromElement(this._element);
+
+ if (listElement) {
+ var itemSelector = listElement.nodeName === 'UL' || listElement.nodeName === 'OL' ? Selector$9.ACTIVE_UL : Selector$9.ACTIVE;
+ previous = $.makeArray($(listElement).find(itemSelector));
+ previous = previous[previous.length - 1];
+ }
+
+ var hideEvent = $.Event(Event$9.HIDE, {
+ relatedTarget: this._element
+ });
+ var showEvent = $.Event(Event$9.SHOW, {
+ relatedTarget: previous
+ });
+
+ if (previous) {
+ $(previous).trigger(hideEvent);
+ }
+
+ $(this._element).trigger(showEvent);
+
+ if (showEvent.isDefaultPrevented() || hideEvent.isDefaultPrevented()) {
+ return;
+ }
+
+ if (selector) {
+ target = document.querySelector(selector);
+ }
+
+ this._activate(this._element, listElement);
+
+ var complete = function complete() {
+ var hiddenEvent = $.Event(Event$9.HIDDEN, {
+ relatedTarget: _this._element
+ });
+ var shownEvent = $.Event(Event$9.SHOWN, {
+ relatedTarget: previous
+ });
+ $(previous).trigger(hiddenEvent);
+ $(_this._element).trigger(shownEvent);
+ };
+
+ if (target) {
+ this._activate(target, target.parentNode, complete);
+ } else {
+ complete();
+ }
+ };
+
+ _proto.dispose = function dispose() {
+ $.removeData(this._element, DATA_KEY$9);
+ this._element = null;
+ } // Private
+ ;
+
+ _proto._activate = function _activate(element, container, callback) {
+ var _this2 = this;
+
+ var activeElements = container && (container.nodeName === 'UL' || container.nodeName === 'OL') ? $(container).find(Selector$9.ACTIVE_UL) : $(container).children(Selector$9.ACTIVE);
+ var active = activeElements[0];
+ var isTransitioning = callback && active && $(active).hasClass(ClassName$9.FADE);
+
+ var complete = function complete() {
+ return _this2._transitionComplete(element, active, callback);
+ };
+
+ if (active && isTransitioning) {
+ var transitionDuration = Util.getTransitionDurationFromElement(active);
+ $(active).removeClass(ClassName$9.SHOW).one(Util.TRANSITION_END, complete).emulateTransitionEnd(transitionDuration);
+ } else {
+ complete();
+ }
+ };
+
+ _proto._transitionComplete = function _transitionComplete(element, active, callback) {
+ if (active) {
+ $(active).removeClass(ClassName$9.ACTIVE);
+ var dropdownChild = $(active.parentNode).find(Selector$9.DROPDOWN_ACTIVE_CHILD)[0];
+
+ if (dropdownChild) {
+ $(dropdownChild).removeClass(ClassName$9.ACTIVE);
+ }
+
+ if (active.getAttribute('role') === 'tab') {
+ active.setAttribute('aria-selected', false);
+ }
+ }
+
+ $(element).addClass(ClassName$9.ACTIVE);
+
+ if (element.getAttribute('role') === 'tab') {
+ element.setAttribute('aria-selected', true);
+ }
+
+ Util.reflow(element);
+
+ if (element.classList.contains(ClassName$9.FADE)) {
+ element.classList.add(ClassName$9.SHOW);
+ }
+
+ if (element.parentNode && $(element.parentNode).hasClass(ClassName$9.DROPDOWN_MENU)) {
+ var dropdownElement = $(element).closest(Selector$9.DROPDOWN)[0];
+
+ if (dropdownElement) {
+ var dropdownToggleList = [].slice.call(dropdownElement.querySelectorAll(Selector$9.DROPDOWN_TOGGLE));
+ $(dropdownToggleList).addClass(ClassName$9.ACTIVE);
+ }
+
+ element.setAttribute('aria-expanded', true);
+ }
+
+ if (callback) {
+ callback();
+ }
+ } // Static
+ ;
+
+ Tab._jQueryInterface = function _jQueryInterface(config) {
+ return this.each(function () {
+ var $this = $(this);
+ var data = $this.data(DATA_KEY$9);
+
+ if (!data) {
+ data = new Tab(this);
+ $this.data(DATA_KEY$9, data);
+ }
+
+ if (typeof config === 'string') {
+ if (typeof data[config] === 'undefined') {
+ throw new TypeError("No method named \"" + config + "\"");
+ }
+
+ data[config]();
+ }
+ });
+ };
+
+ _createClass(Tab, null, [{
+ key: "VERSION",
+ get: function get() {
+ return VERSION$9;
+ }
+ }]);
+
+ return Tab;
+ }();
+ /**
+ * ------------------------------------------------------------------------
+ * Data Api implementation
+ * ------------------------------------------------------------------------
+ */
+
+
+ $(document).on(Event$9.CLICK_DATA_API, Selector$9.DATA_TOGGLE, function (event) {
+ event.preventDefault();
+
+ Tab._jQueryInterface.call($(this), 'show');
+ });
+ /**
+ * ------------------------------------------------------------------------
+ * jQuery
+ * ------------------------------------------------------------------------
+ */
+
+ $.fn[NAME$9] = Tab._jQueryInterface;
+ $.fn[NAME$9].Constructor = Tab;
+
+ $.fn[NAME$9].noConflict = function () {
+ $.fn[NAME$9] = JQUERY_NO_CONFLICT$9;
+ return Tab._jQueryInterface;
+ };
+ /**
+ * ------------------------------------------------------------------------
+ * Constants
+ * ------------------------------------------------------------------------
+ */
+
+
+ var NAME$a = 'toast';
+ var VERSION$a = '4.4.1';
+ var DATA_KEY$a = 'bs.toast';
+ var EVENT_KEY$a = "." + DATA_KEY$a;
+ var JQUERY_NO_CONFLICT$a = $.fn[NAME$a];
+ var Event$a = {
+ CLICK_DISMISS: "click.dismiss" + EVENT_KEY$a,
+ HIDE: "hide" + EVENT_KEY$a,
+ HIDDEN: "hidden" + EVENT_KEY$a,
+ SHOW: "show" + EVENT_KEY$a,
+ SHOWN: "shown" + EVENT_KEY$a
+ };
+ var ClassName$a = {
+ FADE: 'fade',
+ HIDE: 'hide',
+ SHOW: 'show',
+ SHOWING: 'showing'
+ };
+ var DefaultType$7 = {
+ animation: 'boolean',
+ autohide: 'boolean',
+ delay: 'number'
+ };
+ var Default$7 = {
+ animation: true,
+ autohide: true,
+ delay: 500
+ };
+ var Selector$a = {
+ DATA_DISMISS: '[data-dismiss="toast"]'
+ };
+ /**
+ * ------------------------------------------------------------------------
+ * Class Definition
+ * ------------------------------------------------------------------------
+ */
+
+ var Toast = /*#__PURE__*/function () {
+ function Toast(element, config) {
+ this._element = element;
+ this._config = this._getConfig(config);
+ this._timeout = null;
+
+ this._setListeners();
+ } // Getters
+
+
+ var _proto = Toast.prototype; // Public
+
+ _proto.show = function show() {
+ var _this = this;
+
+ var showEvent = $.Event(Event$a.SHOW);
+ $(this._element).trigger(showEvent);
+
+ if (showEvent.isDefaultPrevented()) {
+ return;
+ }
+
+ if (this._config.animation) {
+ this._element.classList.add(ClassName$a.FADE);
+ }
+
+ var complete = function complete() {
+ _this._element.classList.remove(ClassName$a.SHOWING);
+
+ _this._element.classList.add(ClassName$a.SHOW);
+
+ $(_this._element).trigger(Event$a.SHOWN);
+
+ if (_this._config.autohide) {
+ _this._timeout = setTimeout(function () {
+ _this.hide();
+ }, _this._config.delay);
+ }
+ };
+
+ this._element.classList.remove(ClassName$a.HIDE);
+
+ Util.reflow(this._element);
+
+ this._element.classList.add(ClassName$a.SHOWING);
+
+ if (this._config.animation) {
+ var transitionDuration = Util.getTransitionDurationFromElement(this._element);
+ $(this._element).one(Util.TRANSITION_END, complete).emulateTransitionEnd(transitionDuration);
+ } else {
+ complete();
+ }
+ };
+
+ _proto.hide = function hide() {
+ if (!this._element.classList.contains(ClassName$a.SHOW)) {
+ return;
+ }
+
+ var hideEvent = $.Event(Event$a.HIDE);
+ $(this._element).trigger(hideEvent);
+
+ if (hideEvent.isDefaultPrevented()) {
+ return;
+ }
+
+ this._close();
+ };
+
+ _proto.dispose = function dispose() {
+ clearTimeout(this._timeout);
+ this._timeout = null;
+
+ if (this._element.classList.contains(ClassName$a.SHOW)) {
+ this._element.classList.remove(ClassName$a.SHOW);
+ }
+
+ $(this._element).off(Event$a.CLICK_DISMISS);
+ $.removeData(this._element, DATA_KEY$a);
+ this._element = null;
+ this._config = null;
+ } // Private
+ ;
+
+ _proto._getConfig = function _getConfig(config) {
+ config = _objectSpread2({}, Default$7, {}, $(this._element).data(), {}, _typeof(config) === 'object' && config ? config : {});
+ Util.typeCheckConfig(NAME$a, config, this.constructor.DefaultType);
+ return config;
+ };
+
+ _proto._setListeners = function _setListeners() {
+ var _this2 = this;
+
+ $(this._element).on(Event$a.CLICK_DISMISS, Selector$a.DATA_DISMISS, function () {
+ return _this2.hide();
+ });
+ };
+
+ _proto._close = function _close() {
+ var _this3 = this;
+
+ var complete = function complete() {
+ _this3._element.classList.add(ClassName$a.HIDE);
+
+ $(_this3._element).trigger(Event$a.HIDDEN);
+ };
+
+ this._element.classList.remove(ClassName$a.SHOW);
+
+ if (this._config.animation) {
+ var transitionDuration = Util.getTransitionDurationFromElement(this._element);
+ $(this._element).one(Util.TRANSITION_END, complete).emulateTransitionEnd(transitionDuration);
+ } else {
+ complete();
+ }
+ } // Static
+ ;
+
+ Toast._jQueryInterface = function _jQueryInterface(config) {
+ return this.each(function () {
+ var $element = $(this);
+ var data = $element.data(DATA_KEY$a);
+
+ var _config = _typeof(config) === 'object' && config;
+
+ if (!data) {
+ data = new Toast(this, _config);
+ $element.data(DATA_KEY$a, data);
+ }
+
+ if (typeof config === 'string') {
+ if (typeof data[config] === 'undefined') {
+ throw new TypeError("No method named \"" + config + "\"");
+ }
+
+ data[config](this);
+ }
+ });
+ };
+
+ _createClass(Toast, null, [{
+ key: "VERSION",
+ get: function get() {
+ return VERSION$a;
+ }
+ }, {
+ key: "DefaultType",
+ get: function get() {
+ return DefaultType$7;
+ }
+ }, {
+ key: "Default",
+ get: function get() {
+ return Default$7;
+ }
+ }]);
+
+ return Toast;
+ }();
+ /**
+ * ------------------------------------------------------------------------
+ * jQuery
+ * ------------------------------------------------------------------------
+ */
+
+
+ $.fn[NAME$a] = Toast._jQueryInterface;
+ $.fn[NAME$a].Constructor = Toast;
+
+ $.fn[NAME$a].noConflict = function () {
+ $.fn[NAME$a] = JQUERY_NO_CONFLICT$a;
+ return Toast._jQueryInterface;
+ };
+
+ exports.Alert = Alert;
+ exports.Button = Button;
+ exports.Carousel = Carousel;
+ exports.Collapse = Collapse;
+ exports.Dropdown = Dropdown;
+ exports.Modal = Modal;
+ exports.Popover = Popover;
+ exports.Scrollspy = ScrollSpy;
+ exports.Tab = Tab;
+ exports.Toast = Toast;
+ exports.Tooltip = Tooltip;
+ exports.Util = Util;
+ Object.defineProperty(exports, '__esModule', {
+ value: true
+ });
+});
+
+/***/ }),
+
+/***/ "./node_modules/jquery/dist/jquery.js":
+/*!********************************************!*\
+ !*** ./node_modules/jquery/dist/jquery.js ***!
+ \********************************************/
+/*! no static exports found */
+/***/ (function(module, exports, __webpack_require__) {
+
+/* WEBPACK VAR INJECTION */(function(module) {var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
+
+/*!
+ * jQuery JavaScript Library v3.5.0
+ * https://jquery.com/
+ *
+ * Includes Sizzle.js
+ * https://sizzlejs.com/
+ *
+ * Copyright JS Foundation and other contributors
+ * Released under the MIT license
+ * https://jquery.org/license
+ *
+ * Date: 2020-04-10T15:07Z
+ */
+(function (global, factory) {
+ "use strict";
+
+ if (( false ? undefined : _typeof(module)) === "object" && _typeof(module.exports) === "object") {
+ // For CommonJS and CommonJS-like environments where a proper `window`
+ // is present, execute the factory and get jQuery.
+ // For environments that do not have a `window` with a `document`
+ // (such as Node.js), expose a factory as module.exports.
+ // This accentuates the need for the creation of a real `window`.
+ // e.g. var jQuery = require("jquery")(window);
+ // See ticket #14549 for more info.
+ module.exports = global.document ? factory(global, true) : function (w) {
+ if (!w.document) {
+ throw new Error("jQuery requires a window with a document");
+ }
+
+ return factory(w);
+ };
+ } else {
+ factory(global);
+ } // Pass this if window is not defined yet
+
+})(typeof window !== "undefined" ? window : this, function (window, noGlobal) {
+ // Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1
+ // throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode
+ // arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), strict mode should be common
+ // enough that all such attempts are guarded in a try block.
+ "use strict";
+
+ var arr = [];
+ var getProto = Object.getPrototypeOf;
+ var _slice = arr.slice;
+ var flat = arr.flat ? function (array) {
+ return arr.flat.call(array);
+ } : function (array) {
+ return arr.concat.apply([], array);
+ };
+ var push = arr.push;
+ var indexOf = arr.indexOf;
+ var class2type = {};
+ var toString = class2type.toString;
+ var hasOwn = class2type.hasOwnProperty;
+ var fnToString = hasOwn.toString;
+ var ObjectFunctionString = fnToString.call(Object);
+ var support = {};
+
+ var isFunction = function isFunction(obj) {
+ // Support: Chrome <=57, Firefox <=52
+ // In some browsers, typeof returns "function" for HTML elements
+ // (i.e., `typeof document.createElement( "object" ) === "function"`).
+ // We don't want to classify *any* DOM node as a function.
+ return typeof obj === "function" && typeof obj.nodeType !== "number";
+ };
+
+ var isWindow = function isWindow(obj) {
+ return obj != null && obj === obj.window;
+ };
+
+ var document = window.document;
+ var preservedScriptAttributes = {
+ type: true,
+ src: true,
+ nonce: true,
+ noModule: true
+ };
+
+ function DOMEval(code, node, doc) {
+ doc = doc || document;
+ var i,
+ val,
+ script = doc.createElement("script");
+ script.text = code;
+
+ if (node) {
+ for (i in preservedScriptAttributes) {
+ // Support: Firefox 64+, Edge 18+
+ // Some browsers don't support the "nonce" property on scripts.
+ // On the other hand, just using `getAttribute` is not enough as
+ // the `nonce` attribute is reset to an empty string whenever it
+ // becomes browsing-context connected.
+ // See https://github.com/whatwg/html/issues/2369
+ // See https://html.spec.whatwg.org/#nonce-attributes
+ // The `node.getAttribute` check was added for the sake of
+ // `jQuery.globalEval` so that it can fake a nonce-containing node
+ // via an object.
+ val = node[i] || node.getAttribute && node.getAttribute(i);
+
+ if (val) {
+ script.setAttribute(i, val);
+ }
+ }
+ }
+
+ doc.head.appendChild(script).parentNode.removeChild(script);
+ }
+
+ function toType(obj) {
+ if (obj == null) {
+ return obj + "";
+ } // Support: Android <=2.3 only (functionish RegExp)
+
+
+ return _typeof(obj) === "object" || typeof obj === "function" ? class2type[toString.call(obj)] || "object" : _typeof(obj);
+ }
+ /* global Symbol */
+ // Defining this global in .eslintrc.json would create a danger of using the global
+ // unguarded in another place, it seems safer to define global only for this module
+
+
+ var version = "3.5.0",
+ // Define a local copy of jQuery
+ jQuery = function jQuery(selector, context) {
+ // The jQuery object is actually just the init constructor 'enhanced'
+ // Need init if jQuery is called (just allow error to be thrown if not included)
+ return new jQuery.fn.init(selector, context);
+ };
+
+ jQuery.fn = jQuery.prototype = {
+ // The current version of jQuery being used
+ jquery: version,
+ constructor: jQuery,
+ // The default length of a jQuery object is 0
+ length: 0,
+ toArray: function toArray() {
+ return _slice.call(this);
+ },
+ // Get the Nth element in the matched element set OR
+ // Get the whole matched element set as a clean array
+ get: function get(num) {
+ // Return all the elements in a clean array
+ if (num == null) {
+ return _slice.call(this);
+ } // Return just the one element from the set
+
+
+ return num < 0 ? this[num + this.length] : this[num];
+ },
+ // Take an array of elements and push it onto the stack
+ // (returning the new matched element set)
+ pushStack: function pushStack(elems) {
+ // Build a new jQuery matched element set
+ var ret = jQuery.merge(this.constructor(), elems); // Add the old object onto the stack (as a reference)
+
+ ret.prevObject = this; // Return the newly-formed element set
+
+ return ret;
+ },
+ // Execute a callback for every element in the matched set.
+ each: function each(callback) {
+ return jQuery.each(this, callback);
+ },
+ map: function map(callback) {
+ return this.pushStack(jQuery.map(this, function (elem, i) {
+ return callback.call(elem, i, elem);
+ }));
+ },
+ slice: function slice() {
+ return this.pushStack(_slice.apply(this, arguments));
+ },
+ first: function first() {
+ return this.eq(0);
+ },
+ last: function last() {
+ return this.eq(-1);
+ },
+ even: function even() {
+ return this.pushStack(jQuery.grep(this, function (_elem, i) {
+ return (i + 1) % 2;
+ }));
+ },
+ odd: function odd() {
+ return this.pushStack(jQuery.grep(this, function (_elem, i) {
+ return i % 2;
+ }));
+ },
+ eq: function eq(i) {
+ var len = this.length,
+ j = +i + (i < 0 ? len : 0);
+ return this.pushStack(j >= 0 && j < len ? [this[j]] : []);
+ },
+ end: function end() {
+ return this.prevObject || this.constructor();
+ },
+ // For internal use only.
+ // Behaves like an Array's method, not like a jQuery method.
+ push: push,
+ sort: arr.sort,
+ splice: arr.splice
+ };
+
+ jQuery.extend = jQuery.fn.extend = function () {
+ var options,
+ name,
+ src,
+ copy,
+ copyIsArray,
+ clone,
+ target = arguments[0] || {},
+ i = 1,
+ length = arguments.length,
+ deep = false; // Handle a deep copy situation
+
+ if (typeof target === "boolean") {
+ deep = target; // Skip the boolean and the target
+
+ target = arguments[i] || {};
+ i++;
+ } // Handle case when target is a string or something (possible in deep copy)
+
+
+ if (_typeof(target) !== "object" && !isFunction(target)) {
+ target = {};
+ } // Extend jQuery itself if only one argument is passed
+
+
+ if (i === length) {
+ target = this;
+ i--;
+ }
+
+ for (; i < length; i++) {
+ // Only deal with non-null/undefined values
+ if ((options = arguments[i]) != null) {
+ // Extend the base object
+ for (name in options) {
+ copy = options[name]; // Prevent Object.prototype pollution
+ // Prevent never-ending loop
+
+ if (name === "__proto__" || target === copy) {
+ continue;
+ } // Recurse if we're merging plain objects or arrays
+
+
+ if (deep && copy && (jQuery.isPlainObject(copy) || (copyIsArray = Array.isArray(copy)))) {
+ src = target[name]; // Ensure proper type for the source value
+
+ if (copyIsArray && !Array.isArray(src)) {
+ clone = [];
+ } else if (!copyIsArray && !jQuery.isPlainObject(src)) {
+ clone = {};
+ } else {
+ clone = src;
+ }
+
+ copyIsArray = false; // Never move original objects, clone them
+
+ target[name] = jQuery.extend(deep, clone, copy); // Don't bring in undefined values
+ } else if (copy !== undefined) {
+ target[name] = copy;
+ }
+ }
+ }
+ } // Return the modified object
+
+
+ return target;
+ };
+
+ jQuery.extend({
+ // Unique for each copy of jQuery on the page
+ expando: "jQuery" + (version + Math.random()).replace(/\D/g, ""),
+ // Assume jQuery is ready without the ready module
+ isReady: true,
+ error: function error(msg) {
+ throw new Error(msg);
+ },
+ noop: function noop() {},
+ isPlainObject: function isPlainObject(obj) {
+ var proto, Ctor; // Detect obvious negatives
+ // Use toString instead of jQuery.type to catch host objects
+
+ if (!obj || toString.call(obj) !== "[object Object]") {
+ return false;
+ }
+
+ proto = getProto(obj); // Objects with no prototype (e.g., `Object.create( null )`) are plain
+
+ if (!proto) {
+ return true;
+ } // Objects with prototype are plain iff they were constructed by a global Object function
+
+
+ Ctor = hasOwn.call(proto, "constructor") && proto.constructor;
+ return typeof Ctor === "function" && fnToString.call(Ctor) === ObjectFunctionString;
+ },
+ isEmptyObject: function isEmptyObject(obj) {
+ var name;
+
+ for (name in obj) {
+ return false;
+ }
+
+ return true;
+ },
+ // Evaluates a script in a provided context; falls back to the global one
+ // if not specified.
+ globalEval: function globalEval(code, options, doc) {
+ DOMEval(code, {
+ nonce: options && options.nonce
+ }, doc);
+ },
+ each: function each(obj, callback) {
+ var length,
+ i = 0;
+
+ if (isArrayLike(obj)) {
+ length = obj.length;
+
+ for (; i < length; i++) {
+ if (callback.call(obj[i], i, obj[i]) === false) {
+ break;
+ }
+ }
+ } else {
+ for (i in obj) {
+ if (callback.call(obj[i], i, obj[i]) === false) {
+ break;
+ }
+ }
+ }
+
+ return obj;
+ },
+ // results is for internal usage only
+ makeArray: function makeArray(arr, results) {
+ var ret = results || [];
+
+ if (arr != null) {
+ if (isArrayLike(Object(arr))) {
+ jQuery.merge(ret, typeof arr === "string" ? [arr] : arr);
+ } else {
+ push.call(ret, arr);
+ }
+ }
+
+ return ret;
+ },
+ inArray: function inArray(elem, arr, i) {
+ return arr == null ? -1 : indexOf.call(arr, elem, i);
+ },
+ // Support: Android <=4.0 only, PhantomJS 1 only
+ // push.apply(_, arraylike) throws on ancient WebKit
+ merge: function merge(first, second) {
+ var len = +second.length,
+ j = 0,
+ i = first.length;
+
+ for (; j < len; j++) {
+ first[i++] = second[j];
+ }
+
+ first.length = i;
+ return first;
+ },
+ grep: function grep(elems, callback, invert) {
+ var callbackInverse,
+ matches = [],
+ i = 0,
+ length = elems.length,
+ callbackExpect = !invert; // Go through the array, only saving the items
+ // that pass the validator function
+
+ for (; i < length; i++) {
+ callbackInverse = !callback(elems[i], i);
+
+ if (callbackInverse !== callbackExpect) {
+ matches.push(elems[i]);
+ }
+ }
+
+ return matches;
+ },
+ // arg is for internal usage only
+ map: function map(elems, callback, arg) {
+ var length,
+ value,
+ i = 0,
+ ret = []; // Go through the array, translating each of the items to their new values
+
+ if (isArrayLike(elems)) {
+ length = elems.length;
+
+ for (; i < length; i++) {
+ value = callback(elems[i], i, arg);
+
+ if (value != null) {
+ ret.push(value);
+ }
+ } // Go through every key on the object,
+
+ } else {
+ for (i in elems) {
+ value = callback(elems[i], i, arg);
+
+ if (value != null) {
+ ret.push(value);
+ }
+ }
+ } // Flatten any nested arrays
+
+
+ return flat(ret);
+ },
+ // A global GUID counter for objects
+ guid: 1,
+ // jQuery.support is not used in Core but other projects attach their
+ // properties to it so it needs to exist.
+ support: support
+ });
+
+ if (typeof Symbol === "function") {
+ jQuery.fn[Symbol.iterator] = arr[Symbol.iterator];
+ } // Populate the class2type map
+
+
+ jQuery.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "), function (_i, name) {
+ class2type["[object " + name + "]"] = name.toLowerCase();
+ });
+
+ function isArrayLike(obj) {
+ // Support: real iOS 8.2 only (not reproducible in simulator)
+ // `in` check used to prevent JIT error (gh-2145)
+ // hasOwn isn't used here due to false negatives
+ // regarding Nodelist length in IE
+ var length = !!obj && "length" in obj && obj.length,
+ type = toType(obj);
+
+ if (isFunction(obj) || isWindow(obj)) {
+ return false;
+ }
+
+ return type === "array" || length === 0 || typeof length === "number" && length > 0 && length - 1 in obj;
+ }
+
+ var Sizzle =
+ /*!
+ * Sizzle CSS Selector Engine v2.3.5
+ * https://sizzlejs.com/
+ *
+ * Copyright JS Foundation and other contributors
+ * Released under the MIT license
+ * https://js.foundation/
+ *
+ * Date: 2020-03-14
+ */
+ function (window) {
+ var i,
+ support,
+ Expr,
+ getText,
+ isXML,
+ tokenize,
+ compile,
+ select,
+ outermostContext,
+ sortInput,
+ hasDuplicate,
+ // Local document vars
+ setDocument,
+ document,
+ docElem,
+ documentIsHTML,
+ rbuggyQSA,
+ rbuggyMatches,
+ matches,
+ contains,
+ // Instance-specific data
+ expando = "sizzle" + 1 * new Date(),
+ preferredDoc = window.document,
+ dirruns = 0,
+ done = 0,
+ classCache = createCache(),
+ tokenCache = createCache(),
+ compilerCache = createCache(),
+ nonnativeSelectorCache = createCache(),
+ sortOrder = function sortOrder(a, b) {
+ if (a === b) {
+ hasDuplicate = true;
+ }
+
+ return 0;
+ },
+ // Instance methods
+ hasOwn = {}.hasOwnProperty,
+ arr = [],
+ pop = arr.pop,
+ pushNative = arr.push,
+ push = arr.push,
+ slice = arr.slice,
+ // Use a stripped-down indexOf as it's faster than native
+ // https://jsperf.com/thor-indexof-vs-for/5
+ indexOf = function indexOf(list, elem) {
+ var i = 0,
+ len = list.length;
+
+ for (; i < len; i++) {
+ if (list[i] === elem) {
+ return i;
+ }
+ }
+
+ return -1;
+ },
+ booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|" + "ismap|loop|multiple|open|readonly|required|scoped",
+ // Regular expressions
+ // http://www.w3.org/TR/css3-selectors/#whitespace
+ whitespace = "[\\x20\\t\\r\\n\\f]",
+ // https://www.w3.org/TR/css-syntax-3/#ident-token-diagram
+ identifier = "(?:\\\\[\\da-fA-F]{1,6}" + whitespace + "?|\\\\[^\\r\\n\\f]|[\\w-]|[^\0-\\x7f])+",
+ // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors
+ attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace + // Operator (capture 2)
+ "*([*^$|!~]?=)" + whitespace + // "Attribute values must be CSS identifiers [capture 5]
+ // or strings [capture 3 or capture 4]"
+ "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace + "*\\]",
+ pseudos = ":(" + identifier + ")(?:\\((" + // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments:
+ // 1. quoted (capture 3; capture 4 or capture 5)
+ "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" + // 2. simple (capture 6)
+ "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" + // 3. anything else (capture 2)
+ ".*" + ")\\)|)",
+ // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter
+ rwhitespace = new RegExp(whitespace + "+", "g"),
+ rtrim = new RegExp("^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g"),
+ rcomma = new RegExp("^" + whitespace + "*," + whitespace + "*"),
+ rcombinators = new RegExp("^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*"),
+ rdescend = new RegExp(whitespace + "|>"),
+ rpseudo = new RegExp(pseudos),
+ ridentifier = new RegExp("^" + identifier + "$"),
+ matchExpr = {
+ "ID": new RegExp("^#(" + identifier + ")"),
+ "CLASS": new RegExp("^\\.(" + identifier + ")"),
+ "TAG": new RegExp("^(" + identifier + "|[*])"),
+ "ATTR": new RegExp("^" + attributes),
+ "PSEUDO": new RegExp("^" + pseudos),
+ "CHILD": new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace + "*(\\d+)|))" + whitespace + "*\\)|)", "i"),
+ "bool": new RegExp("^(?:" + booleans + ")$", "i"),
+ // For use in libraries implementing .is()
+ // We use this for POS matching in `select`
+ "needsContext": new RegExp("^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i")
+ },
+ rhtml = /HTML$/i,
+ rinputs = /^(?:input|select|textarea|button)$/i,
+ rheader = /^h\d$/i,
+ rnative = /^[^{]+\{\s*\[native \w/,
+ // Easily-parseable/retrievable ID or TAG or CLASS selectors
+ rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,
+ rsibling = /[+~]/,
+ // CSS escapes
+ // http://www.w3.org/TR/CSS21/syndata.html#escaped-characters
+ runescape = new RegExp("\\\\[\\da-fA-F]{1,6}" + whitespace + "?|\\\\([^\\r\\n\\f])", "g"),
+ funescape = function funescape(escape, nonHex) {
+ var high = "0x" + escape.slice(1) - 0x10000;
+ return nonHex ? // Strip the backslash prefix from a non-hex escape sequence
+ nonHex : // Replace a hexadecimal escape sequence with the encoded Unicode code point
+ // Support: IE <=11+
+ // For values outside the Basic Multilingual Plane (BMP), manually construct a
+ // surrogate pair
+ high < 0 ? String.fromCharCode(high + 0x10000) : String.fromCharCode(high >> 10 | 0xD800, high & 0x3FF | 0xDC00);
+ },
+ // CSS string/identifier serialization
+ // https://drafts.csswg.org/cssom/#common-serializing-idioms
+ rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,
+ fcssescape = function fcssescape(ch, asCodePoint) {
+ if (asCodePoint) {
+ // U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER
+ if (ch === "\0") {
+ return "\uFFFD";
+ } // Control characters and (dependent upon position) numbers get escaped as code points
+
+
+ return ch.slice(0, -1) + "\\" + ch.charCodeAt(ch.length - 1).toString(16) + " ";
+ } // Other potentially-special ASCII characters get backslash-escaped
+
+
+ return "\\" + ch;
+ },
+ // Used for iframes
+ // See setDocument()
+ // Removing the function wrapper causes a "Permission Denied"
+ // error in IE
+ unloadHandler = function unloadHandler() {
+ setDocument();
+ },
+ inDisabledFieldset = addCombinator(function (elem) {
+ return elem.disabled === true && elem.nodeName.toLowerCase() === "fieldset";
+ }, {
+ dir: "parentNode",
+ next: "legend"
+ }); // Optimize for push.apply( _, NodeList )
+
+
+ try {
+ push.apply(arr = slice.call(preferredDoc.childNodes), preferredDoc.childNodes); // Support: Android<4.0
+ // Detect silently failing push.apply
+ // eslint-disable-next-line no-unused-expressions
+
+ arr[preferredDoc.childNodes.length].nodeType;
+ } catch (e) {
+ push = {
+ apply: arr.length ? // Leverage slice if possible
+ function (target, els) {
+ pushNative.apply(target, slice.call(els));
+ } : // Support: IE<9
+ // Otherwise append directly
+ function (target, els) {
+ var j = target.length,
+ i = 0; // Can't trust NodeList.length
+
+ while (target[j++] = els[i++]) {}
+
+ target.length = j - 1;
+ }
+ };
+ }
+
+ function Sizzle(selector, context, results, seed) {
+ var m,
+ i,
+ elem,
+ nid,
+ match,
+ groups,
+ newSelector,
+ newContext = context && context.ownerDocument,
+ // nodeType defaults to 9, since context defaults to document
+ nodeType = context ? context.nodeType : 9;
+ results = results || []; // Return early from calls with invalid selector or context
+
+ if (typeof selector !== "string" || !selector || nodeType !== 1 && nodeType !== 9 && nodeType !== 11) {
+ return results;
+ } // Try to shortcut find operations (as opposed to filters) in HTML documents
+
+
+ if (!seed) {
+ setDocument(context);
+ context = context || document;
+
+ if (documentIsHTML) {
+ // If the selector is sufficiently simple, try using a "get*By*" DOM method
+ // (excepting DocumentFragment context, where the methods don't exist)
+ if (nodeType !== 11 && (match = rquickExpr.exec(selector))) {
+ // ID selector
+ if (m = match[1]) {
+ // Document context
+ if (nodeType === 9) {
+ if (elem = context.getElementById(m)) {
+ // Support: IE, Opera, Webkit
+ // TODO: identify versions
+ // getElementById can match elements by name instead of ID
+ if (elem.id === m) {
+ results.push(elem);
+ return results;
+ }
+ } else {
+ return results;
+ } // Element context
+
+ } else {
+ // Support: IE, Opera, Webkit
+ // TODO: identify versions
+ // getElementById can match elements by name instead of ID
+ if (newContext && (elem = newContext.getElementById(m)) && contains(context, elem) && elem.id === m) {
+ results.push(elem);
+ return results;
+ }
+ } // Type selector
+
+ } else if (match[2]) {
+ push.apply(results, context.getElementsByTagName(selector));
+ return results; // Class selector
+ } else if ((m = match[3]) && support.getElementsByClassName && context.getElementsByClassName) {
+ push.apply(results, context.getElementsByClassName(m));
+ return results;
+ }
+ } // Take advantage of querySelectorAll
+
+
+ if (support.qsa && !nonnativeSelectorCache[selector + " "] && (!rbuggyQSA || !rbuggyQSA.test(selector)) && ( // Support: IE 8 only
+ // Exclude object elements
+ nodeType !== 1 || context.nodeName.toLowerCase() !== "object")) {
+ newSelector = selector;
+ newContext = context; // qSA considers elements outside a scoping root when evaluating child or
+ // descendant combinators, which is not what we want.
+ // In such cases, we work around the behavior by prefixing every selector in the
+ // list with an ID selector referencing the scope context.
+ // The technique has to be used as well when a leading combinator is used
+ // as such selectors are not recognized by querySelectorAll.
+ // Thanks to Andrew Dupont for this technique.
+
+ if (nodeType === 1 && (rdescend.test(selector) || rcombinators.test(selector))) {
+ // Expand context for sibling selectors
+ newContext = rsibling.test(selector) && testContext(context.parentNode) || context; // We can use :scope instead of the ID hack if the browser
+ // supports it & if we're not changing the context.
+
+ if (newContext !== context || !support.scope) {
+ // Capture the context ID, setting it first if necessary
+ if (nid = context.getAttribute("id")) {
+ nid = nid.replace(rcssescape, fcssescape);
+ } else {
+ context.setAttribute("id", nid = expando);
+ }
+ } // Prefix every selector in the list
+
+
+ groups = tokenize(selector);
+ i = groups.length;
+
+ while (i--) {
+ groups[i] = (nid ? "#" + nid : ":scope") + " " + toSelector(groups[i]);
+ }
+
+ newSelector = groups.join(",");
+ }
+
+ try {
+ push.apply(results, newContext.querySelectorAll(newSelector));
+ return results;
+ } catch (qsaError) {
+ nonnativeSelectorCache(selector, true);
+ } finally {
+ if (nid === expando) {
+ context.removeAttribute("id");
+ }
+ }
+ }
+ }
+ } // All others
+
+
+ return select(selector.replace(rtrim, "$1"), context, results, seed);
+ }
+ /**
+ * Create key-value caches of limited size
+ * @returns {function(string, object)} Returns the Object data after storing it on itself with
+ * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)
+ * deleting the oldest entry
+ */
+
+
+ function createCache() {
+ var keys = [];
+
+ function cache(key, value) {
+ // Use (key + " ") to avoid collision with native prototype properties (see Issue #157)
+ if (keys.push(key + " ") > Expr.cacheLength) {
+ // Only keep the most recent entries
+ delete cache[keys.shift()];
+ }
+
+ return cache[key + " "] = value;
+ }
+
+ return cache;
+ }
+ /**
+ * Mark a function for special use by Sizzle
+ * @param {Function} fn The function to mark
+ */
+
+
+ function markFunction(fn) {
+ fn[expando] = true;
+ return fn;
+ }
+ /**
+ * Support testing using an element
+ * @param {Function} fn Passed the created element and returns a boolean result
+ */
+
+
+ function assert(fn) {
+ var el = document.createElement("fieldset");
+
+ try {
+ return !!fn(el);
+ } catch (e) {
+ return false;
+ } finally {
+ // Remove from its parent by default
+ if (el.parentNode) {
+ el.parentNode.removeChild(el);
+ } // release memory in IE
+
+
+ el = null;
+ }
+ }
+ /**
+ * Adds the same handler for all of the specified attrs
+ * @param {String} attrs Pipe-separated list of attributes
+ * @param {Function} handler The method that will be applied
+ */
+
+
+ function addHandle(attrs, handler) {
+ var arr = attrs.split("|"),
+ i = arr.length;
+
+ while (i--) {
+ Expr.attrHandle[arr[i]] = handler;
+ }
+ }
+ /**
+ * Checks document order of two siblings
+ * @param {Element} a
+ * @param {Element} b
+ * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b
+ */
+
+
+ function siblingCheck(a, b) {
+ var cur = b && a,
+ diff = cur && a.nodeType === 1 && b.nodeType === 1 && a.sourceIndex - b.sourceIndex; // Use IE sourceIndex if available on both nodes
+
+ if (diff) {
+ return diff;
+ } // Check if b follows a
+
+
+ if (cur) {
+ while (cur = cur.nextSibling) {
+ if (cur === b) {
+ return -1;
+ }
+ }
+ }
+
+ return a ? 1 : -1;
+ }
+ /**
+ * Returns a function to use in pseudos for input types
+ * @param {String} type
+ */
+
+
+ function createInputPseudo(type) {
+ return function (elem) {
+ var name = elem.nodeName.toLowerCase();
+ return name === "input" && elem.type === type;
+ };
+ }
+ /**
+ * Returns a function to use in pseudos for buttons
+ * @param {String} type
+ */
+
+
+ function createButtonPseudo(type) {
+ return function (elem) {
+ var name = elem.nodeName.toLowerCase();
+ return (name === "input" || name === "button") && elem.type === type;
+ };
+ }
+ /**
+ * Returns a function to use in pseudos for :enabled/:disabled
+ * @param {Boolean} disabled true for :disabled; false for :enabled
+ */
+
+
+ function createDisabledPseudo(disabled) {
+ // Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable
+ return function (elem) {
+ // Only certain elements can match :enabled or :disabled
+ // https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled
+ // https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled
+ if ("form" in elem) {
+ // Check for inherited disabledness on relevant non-disabled elements:
+ // * listed form-associated elements in a disabled fieldset
+ // https://html.spec.whatwg.org/multipage/forms.html#category-listed
+ // https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled
+ // * option elements in a disabled optgroup
+ // https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled
+ // All such elements have a "form" property.
+ if (elem.parentNode && elem.disabled === false) {
+ // Option elements defer to a parent optgroup if present
+ if ("label" in elem) {
+ if ("label" in elem.parentNode) {
+ return elem.parentNode.disabled === disabled;
+ } else {
+ return elem.disabled === disabled;
+ }
+ } // Support: IE 6 - 11
+ // Use the isDisabled shortcut property to check for disabled fieldset ancestors
+
+
+ return elem.isDisabled === disabled || // Where there is no isDisabled, check manually
+
+ /* jshint -W018 */
+ elem.isDisabled !== !disabled && inDisabledFieldset(elem) === disabled;
+ }
+
+ return elem.disabled === disabled; // Try to winnow out elements that can't be disabled before trusting the disabled property.
+ // Some victims get caught in our net (label, legend, menu, track), but it shouldn't
+ // even exist on them, let alone have a boolean value.
+ } else if ("label" in elem) {
+ return elem.disabled === disabled;
+ } // Remaining elements are neither :enabled nor :disabled
+
+
+ return false;
+ };
+ }
+ /**
+ * Returns a function to use in pseudos for positionals
+ * @param {Function} fn
+ */
+
+
+ function createPositionalPseudo(fn) {
+ return markFunction(function (argument) {
+ argument = +argument;
+ return markFunction(function (seed, matches) {
+ var j,
+ matchIndexes = fn([], seed.length, argument),
+ i = matchIndexes.length; // Match elements found at the specified indexes
+
+ while (i--) {
+ if (seed[j = matchIndexes[i]]) {
+ seed[j] = !(matches[j] = seed[j]);
+ }
+ }
+ });
+ });
+ }
+ /**
+ * Checks a node for validity as a Sizzle context
+ * @param {Element|Object=} context
+ * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value
+ */
+
+
+ function testContext(context) {
+ return context && typeof context.getElementsByTagName !== "undefined" && context;
+ } // Expose support vars for convenience
+
+
+ support = Sizzle.support = {};
+ /**
+ * Detects XML nodes
+ * @param {Element|Object} elem An element or a document
+ * @returns {Boolean} True iff elem is a non-HTML XML node
+ */
+
+ isXML = Sizzle.isXML = function (elem) {
+ var namespace = elem.namespaceURI,
+ docElem = (elem.ownerDocument || elem).documentElement; // Support: IE <=8
+ // Assume HTML when documentElement doesn't yet exist, such as inside loading iframes
+ // https://bugs.jquery.com/ticket/4833
+
+ return !rhtml.test(namespace || docElem && docElem.nodeName || "HTML");
+ };
+ /**
+ * Sets document-related variables once based on the current document
+ * @param {Element|Object} [doc] An element or document object to use to set the document
+ * @returns {Object} Returns the current document
+ */
+
+
+ setDocument = Sizzle.setDocument = function (node) {
+ var hasCompare,
+ subWindow,
+ doc = node ? node.ownerDocument || node : preferredDoc; // Return early if doc is invalid or already selected
+ // Support: IE 11+, Edge 17 - 18+
+ // IE/Edge sometimes throw a "Permission denied" error when strict-comparing
+ // two documents; shallow comparisons work.
+ // eslint-disable-next-line eqeqeq
+
+ if (doc == document || doc.nodeType !== 9 || !doc.documentElement) {
+ return document;
+ } // Update global variables
+
+
+ document = doc;
+ docElem = document.documentElement;
+ documentIsHTML = !isXML(document); // Support: IE 9 - 11+, Edge 12 - 18+
+ // Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936)
+ // Support: IE 11+, Edge 17 - 18+
+ // IE/Edge sometimes throw a "Permission denied" error when strict-comparing
+ // two documents; shallow comparisons work.
+ // eslint-disable-next-line eqeqeq
+
+ if (preferredDoc != document && (subWindow = document.defaultView) && subWindow.top !== subWindow) {
+ // Support: IE 11, Edge
+ if (subWindow.addEventListener) {
+ subWindow.addEventListener("unload", unloadHandler, false); // Support: IE 9 - 10 only
+ } else if (subWindow.attachEvent) {
+ subWindow.attachEvent("onunload", unloadHandler);
+ }
+ } // Support: IE 8 - 11+, Edge 12 - 18+, Chrome <=16 - 25 only, Firefox <=3.6 - 31 only,
+ // Safari 4 - 5 only, Opera <=11.6 - 12.x only
+ // IE/Edge & older browsers don't support the :scope pseudo-class.
+ // Support: Safari 6.0 only
+ // Safari 6.0 supports :scope but it's an alias of :root there.
+
+
+ support.scope = assert(function (el) {
+ docElem.appendChild(el).appendChild(document.createElement("div"));
+ return typeof el.querySelectorAll !== "undefined" && !el.querySelectorAll(":scope fieldset div").length;
+ });
+ /* Attributes
+ ---------------------------------------------------------------------- */
+ // Support: IE<8
+ // Verify that getAttribute really returns attributes and not properties
+ // (excepting IE8 booleans)
+
+ support.attributes = assert(function (el) {
+ el.className = "i";
+ return !el.getAttribute("className");
+ });
+ /* getElement(s)By*
+ ---------------------------------------------------------------------- */
+ // Check if getElementsByTagName("*") returns only elements
+
+ support.getElementsByTagName = assert(function (el) {
+ el.appendChild(document.createComment(""));
+ return !el.getElementsByTagName("*").length;
+ }); // Support: IE<9
+
+ support.getElementsByClassName = rnative.test(document.getElementsByClassName); // Support: IE<10
+ // Check if getElementById returns elements by name
+ // The broken getElementById methods don't pick up programmatically-set names,
+ // so use a roundabout getElementsByName test
+
+ support.getById = assert(function (el) {
+ docElem.appendChild(el).id = expando;
+ return !document.getElementsByName || !document.getElementsByName(expando).length;
+ }); // ID filter and find
+
+ if (support.getById) {
+ Expr.filter["ID"] = function (id) {
+ var attrId = id.replace(runescape, funescape);
+ return function (elem) {
+ return elem.getAttribute("id") === attrId;
+ };
+ };
+
+ Expr.find["ID"] = function (id, context) {
+ if (typeof context.getElementById !== "undefined" && documentIsHTML) {
+ var elem = context.getElementById(id);
+ return elem ? [elem] : [];
+ }
+ };
+ } else {
+ Expr.filter["ID"] = function (id) {
+ var attrId = id.replace(runescape, funescape);
+ return function (elem) {
+ var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id");
+ return node && node.value === attrId;
+ };
+ }; // Support: IE 6 - 7 only
+ // getElementById is not reliable as a find shortcut
+
+
+ Expr.find["ID"] = function (id, context) {
+ if (typeof context.getElementById !== "undefined" && documentIsHTML) {
+ var node,
+ i,
+ elems,
+ elem = context.getElementById(id);
+
+ if (elem) {
+ // Verify the id attribute
+ node = elem.getAttributeNode("id");
+
+ if (node && node.value === id) {
+ return [elem];
+ } // Fall back on getElementsByName
+
+
+ elems = context.getElementsByName(id);
+ i = 0;
+
+ while (elem = elems[i++]) {
+ node = elem.getAttributeNode("id");
+
+ if (node && node.value === id) {
+ return [elem];
+ }
+ }
+ }
+
+ return [];
+ }
+ };
+ } // Tag
+
+
+ Expr.find["TAG"] = support.getElementsByTagName ? function (tag, context) {
+ if (typeof context.getElementsByTagName !== "undefined") {
+ return context.getElementsByTagName(tag); // DocumentFragment nodes don't have gEBTN
+ } else if (support.qsa) {
+ return context.querySelectorAll(tag);
+ }
+ } : function (tag, context) {
+ var elem,
+ tmp = [],
+ i = 0,
+ // By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too
+ results = context.getElementsByTagName(tag); // Filter out possible comments
+
+ if (tag === "*") {
+ while (elem = results[i++]) {
+ if (elem.nodeType === 1) {
+ tmp.push(elem);
+ }
+ }
+
+ return tmp;
+ }
+
+ return results;
+ }; // Class
+
+ Expr.find["CLASS"] = support.getElementsByClassName && function (className, context) {
+ if (typeof context.getElementsByClassName !== "undefined" && documentIsHTML) {
+ return context.getElementsByClassName(className);
+ }
+ };
+ /* QSA/matchesSelector
+ ---------------------------------------------------------------------- */
+ // QSA and matchesSelector support
+ // matchesSelector(:active) reports false when true (IE9/Opera 11.5)
+
+
+ rbuggyMatches = []; // qSa(:focus) reports false when true (Chrome 21)
+ // We allow this because of a bug in IE8/9 that throws an error
+ // whenever `document.activeElement` is accessed on an iframe
+ // So, we allow :focus to pass through QSA all the time to avoid the IE error
+ // See https://bugs.jquery.com/ticket/13378
+
+ rbuggyQSA = [];
+
+ if (support.qsa = rnative.test(document.querySelectorAll)) {
+ // Build QSA regex
+ // Regex strategy adopted from Diego Perini
+ assert(function (el) {
+ var input; // Select is set to empty string on purpose
+ // This is to test IE's treatment of not explicitly
+ // setting a boolean content attribute,
+ // since its presence should be enough
+ // https://bugs.jquery.com/ticket/12359
+
+ docElem.appendChild(el).innerHTML = " " + "" + " "; // Support: IE8, Opera 11-12.16
+ // Nothing should be selected when empty strings follow ^= or $= or *=
+ // The test attribute must be unknown in Opera but "safe" for WinRT
+ // https://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section
+
+ if (el.querySelectorAll("[msallowcapture^='']").length) {
+ rbuggyQSA.push("[*^$]=" + whitespace + "*(?:''|\"\")");
+ } // Support: IE8
+ // Boolean attributes and "value" are not treated correctly
+
+
+ if (!el.querySelectorAll("[selected]").length) {
+ rbuggyQSA.push("\\[" + whitespace + "*(?:value|" + booleans + ")");
+ } // Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+
+
+
+ if (!el.querySelectorAll("[id~=" + expando + "-]").length) {
+ rbuggyQSA.push("~=");
+ } // Support: IE 11+, Edge 15 - 18+
+ // IE 11/Edge don't find elements on a `[name='']` query in some cases.
+ // Adding a temporary attribute to the document before the selection works
+ // around the issue.
+ // Interestingly, IE 10 & older don't seem to have the issue.
+
+
+ input = document.createElement("input");
+ input.setAttribute("name", "");
+ el.appendChild(input);
+
+ if (!el.querySelectorAll("[name='']").length) {
+ rbuggyQSA.push("\\[" + whitespace + "*name" + whitespace + "*=" + whitespace + "*(?:''|\"\")");
+ } // Webkit/Opera - :checked should return selected option elements
+ // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
+ // IE8 throws error here and will not see later tests
+
+
+ if (!el.querySelectorAll(":checked").length) {
+ rbuggyQSA.push(":checked");
+ } // Support: Safari 8+, iOS 8+
+ // https://bugs.webkit.org/show_bug.cgi?id=136851
+ // In-page `selector#id sibling-combinator selector` fails
+
+
+ if (!el.querySelectorAll("a#" + expando + "+*").length) {
+ rbuggyQSA.push(".#.+[+~]");
+ } // Support: Firefox <=3.6 - 5 only
+ // Old Firefox doesn't throw on a badly-escaped identifier.
+
+
+ el.querySelectorAll("\\\f");
+ rbuggyQSA.push("[\\r\\n\\f]");
+ });
+ assert(function (el) {
+ el.innerHTML = " " + " "; // Support: Windows 8 Native Apps
+ // The type and name attributes are restricted during .innerHTML assignment
+
+ var input = document.createElement("input");
+ input.setAttribute("type", "hidden");
+ el.appendChild(input).setAttribute("name", "D"); // Support: IE8
+ // Enforce case-sensitivity of name attribute
+
+ if (el.querySelectorAll("[name=d]").length) {
+ rbuggyQSA.push("name" + whitespace + "*[*^$|!~]?=");
+ } // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)
+ // IE8 throws error here and will not see later tests
+
+
+ if (el.querySelectorAll(":enabled").length !== 2) {
+ rbuggyQSA.push(":enabled", ":disabled");
+ } // Support: IE9-11+
+ // IE's :disabled selector does not pick up the children of disabled fieldsets
+
+
+ docElem.appendChild(el).disabled = true;
+
+ if (el.querySelectorAll(":disabled").length !== 2) {
+ rbuggyQSA.push(":enabled", ":disabled");
+ } // Support: Opera 10 - 11 only
+ // Opera 10-11 does not throw on post-comma invalid pseudos
+
+
+ el.querySelectorAll("*,:x");
+ rbuggyQSA.push(",.*:");
+ });
+ }
+
+ if (support.matchesSelector = rnative.test(matches = docElem.matches || docElem.webkitMatchesSelector || docElem.mozMatchesSelector || docElem.oMatchesSelector || docElem.msMatchesSelector)) {
+ assert(function (el) {
+ // Check to see if it's possible to do matchesSelector
+ // on a disconnected node (IE 9)
+ support.disconnectedMatch = matches.call(el, "*"); // This should fail with an exception
+ // Gecko does not error, returns false instead
+
+ matches.call(el, "[s!='']:x");
+ rbuggyMatches.push("!=", pseudos);
+ });
+ }
+
+ rbuggyQSA = rbuggyQSA.length && new RegExp(rbuggyQSA.join("|"));
+ rbuggyMatches = rbuggyMatches.length && new RegExp(rbuggyMatches.join("|"));
+ /* Contains
+ ---------------------------------------------------------------------- */
+
+ hasCompare = rnative.test(docElem.compareDocumentPosition); // Element contains another
+ // Purposefully self-exclusive
+ // As in, an element does not contain itself
+
+ contains = hasCompare || rnative.test(docElem.contains) ? function (a, b) {
+ var adown = a.nodeType === 9 ? a.documentElement : a,
+ bup = b && b.parentNode;
+ return a === bup || !!(bup && bup.nodeType === 1 && (adown.contains ? adown.contains(bup) : a.compareDocumentPosition && a.compareDocumentPosition(bup) & 16));
+ } : function (a, b) {
+ if (b) {
+ while (b = b.parentNode) {
+ if (b === a) {
+ return true;
+ }
+ }
+ }
+
+ return false;
+ };
+ /* Sorting
+ ---------------------------------------------------------------------- */
+ // Document order sorting
+
+ sortOrder = hasCompare ? function (a, b) {
+ // Flag for duplicate removal
+ if (a === b) {
+ hasDuplicate = true;
+ return 0;
+ } // Sort on method existence if only one input has compareDocumentPosition
+
+
+ var compare = !a.compareDocumentPosition - !b.compareDocumentPosition;
+
+ if (compare) {
+ return compare;
+ } // Calculate position if both inputs belong to the same document
+ // Support: IE 11+, Edge 17 - 18+
+ // IE/Edge sometimes throw a "Permission denied" error when strict-comparing
+ // two documents; shallow comparisons work.
+ // eslint-disable-next-line eqeqeq
+
+
+ compare = (a.ownerDocument || a) == (b.ownerDocument || b) ? a.compareDocumentPosition(b) : // Otherwise we know they are disconnected
+ 1; // Disconnected nodes
+
+ if (compare & 1 || !support.sortDetached && b.compareDocumentPosition(a) === compare) {
+ // Choose the first element that is related to our preferred document
+ // Support: IE 11+, Edge 17 - 18+
+ // IE/Edge sometimes throw a "Permission denied" error when strict-comparing
+ // two documents; shallow comparisons work.
+ // eslint-disable-next-line eqeqeq
+ if (a == document || a.ownerDocument == preferredDoc && contains(preferredDoc, a)) {
+ return -1;
+ } // Support: IE 11+, Edge 17 - 18+
+ // IE/Edge sometimes throw a "Permission denied" error when strict-comparing
+ // two documents; shallow comparisons work.
+ // eslint-disable-next-line eqeqeq
+
+
+ if (b == document || b.ownerDocument == preferredDoc && contains(preferredDoc, b)) {
+ return 1;
+ } // Maintain original order
+
+
+ return sortInput ? indexOf(sortInput, a) - indexOf(sortInput, b) : 0;
+ }
+
+ return compare & 4 ? -1 : 1;
+ } : function (a, b) {
+ // Exit early if the nodes are identical
+ if (a === b) {
+ hasDuplicate = true;
+ return 0;
+ }
+
+ var cur,
+ i = 0,
+ aup = a.parentNode,
+ bup = b.parentNode,
+ ap = [a],
+ bp = [b]; // Parentless nodes are either documents or disconnected
+
+ if (!aup || !bup) {
+ // Support: IE 11+, Edge 17 - 18+
+ // IE/Edge sometimes throw a "Permission denied" error when strict-comparing
+ // two documents; shallow comparisons work.
+
+ /* eslint-disable eqeqeq */
+ return a == document ? -1 : b == document ? 1 :
+ /* eslint-enable eqeqeq */
+ aup ? -1 : bup ? 1 : sortInput ? indexOf(sortInput, a) - indexOf(sortInput, b) : 0; // If the nodes are siblings, we can do a quick check
+ } else if (aup === bup) {
+ return siblingCheck(a, b);
+ } // Otherwise we need full lists of their ancestors for comparison
+
+
+ cur = a;
+
+ while (cur = cur.parentNode) {
+ ap.unshift(cur);
+ }
+
+ cur = b;
+
+ while (cur = cur.parentNode) {
+ bp.unshift(cur);
+ } // Walk down the tree looking for a discrepancy
+
+
+ while (ap[i] === bp[i]) {
+ i++;
+ }
+
+ return i ? // Do a sibling check if the nodes have a common ancestor
+ siblingCheck(ap[i], bp[i]) : // Otherwise nodes in our document sort first
+ // Support: IE 11+, Edge 17 - 18+
+ // IE/Edge sometimes throw a "Permission denied" error when strict-comparing
+ // two documents; shallow comparisons work.
+
+ /* eslint-disable eqeqeq */
+ ap[i] == preferredDoc ? -1 : bp[i] == preferredDoc ? 1 :
+ /* eslint-enable eqeqeq */
+ 0;
+ };
+ return document;
+ };
+
+ Sizzle.matches = function (expr, elements) {
+ return Sizzle(expr, null, null, elements);
+ };
+
+ Sizzle.matchesSelector = function (elem, expr) {
+ setDocument(elem);
+
+ if (support.matchesSelector && documentIsHTML && !nonnativeSelectorCache[expr + " "] && (!rbuggyMatches || !rbuggyMatches.test(expr)) && (!rbuggyQSA || !rbuggyQSA.test(expr))) {
+ try {
+ var ret = matches.call(elem, expr); // IE 9's matchesSelector returns false on disconnected nodes
+
+ if (ret || support.disconnectedMatch || // As well, disconnected nodes are said to be in a document
+ // fragment in IE 9
+ elem.document && elem.document.nodeType !== 11) {
+ return ret;
+ }
+ } catch (e) {
+ nonnativeSelectorCache(expr, true);
+ }
+ }
+
+ return Sizzle(expr, document, null, [elem]).length > 0;
+ };
+
+ Sizzle.contains = function (context, elem) {
+ // Set document vars if needed
+ // Support: IE 11+, Edge 17 - 18+
+ // IE/Edge sometimes throw a "Permission denied" error when strict-comparing
+ // two documents; shallow comparisons work.
+ // eslint-disable-next-line eqeqeq
+ if ((context.ownerDocument || context) != document) {
+ setDocument(context);
+ }
+
+ return contains(context, elem);
+ };
+
+ Sizzle.attr = function (elem, name) {
+ // Set document vars if needed
+ // Support: IE 11+, Edge 17 - 18+
+ // IE/Edge sometimes throw a "Permission denied" error when strict-comparing
+ // two documents; shallow comparisons work.
+ // eslint-disable-next-line eqeqeq
+ if ((elem.ownerDocument || elem) != document) {
+ setDocument(elem);
+ }
+
+ var fn = Expr.attrHandle[name.toLowerCase()],
+ // Don't get fooled by Object.prototype properties (jQuery #13807)
+ val = fn && hasOwn.call(Expr.attrHandle, name.toLowerCase()) ? fn(elem, name, !documentIsHTML) : undefined;
+ return val !== undefined ? val : support.attributes || !documentIsHTML ? elem.getAttribute(name) : (val = elem.getAttributeNode(name)) && val.specified ? val.value : null;
+ };
+
+ Sizzle.escape = function (sel) {
+ return (sel + "").replace(rcssescape, fcssescape);
+ };
+
+ Sizzle.error = function (msg) {
+ throw new Error("Syntax error, unrecognized expression: " + msg);
+ };
+ /**
+ * Document sorting and removing duplicates
+ * @param {ArrayLike} results
+ */
+
+
+ Sizzle.uniqueSort = function (results) {
+ var elem,
+ duplicates = [],
+ j = 0,
+ i = 0; // Unless we *know* we can detect duplicates, assume their presence
+
+ hasDuplicate = !support.detectDuplicates;
+ sortInput = !support.sortStable && results.slice(0);
+ results.sort(sortOrder);
+
+ if (hasDuplicate) {
+ while (elem = results[i++]) {
+ if (elem === results[i]) {
+ j = duplicates.push(i);
+ }
+ }
+
+ while (j--) {
+ results.splice(duplicates[j], 1);
+ }
+ } // Clear input after sorting to release objects
+ // See https://github.com/jquery/sizzle/pull/225
+
+
+ sortInput = null;
+ return results;
+ };
+ /**
+ * Utility function for retrieving the text value of an array of DOM nodes
+ * @param {Array|Element} elem
+ */
+
+
+ getText = Sizzle.getText = function (elem) {
+ var node,
+ ret = "",
+ i = 0,
+ nodeType = elem.nodeType;
+
+ if (!nodeType) {
+ // If no nodeType, this is expected to be an array
+ while (node = elem[i++]) {
+ // Do not traverse comment nodes
+ ret += getText(node);
+ }
+ } else if (nodeType === 1 || nodeType === 9 || nodeType === 11) {
+ // Use textContent for elements
+ // innerText usage removed for consistency of new lines (jQuery #11153)
+ if (typeof elem.textContent === "string") {
+ return elem.textContent;
+ } else {
+ // Traverse its children
+ for (elem = elem.firstChild; elem; elem = elem.nextSibling) {
+ ret += getText(elem);
+ }
+ }
+ } else if (nodeType === 3 || nodeType === 4) {
+ return elem.nodeValue;
+ } // Do not include comment or processing instruction nodes
+
+
+ return ret;
+ };
+
+ Expr = Sizzle.selectors = {
+ // Can be adjusted by the user
+ cacheLength: 50,
+ createPseudo: markFunction,
+ match: matchExpr,
+ attrHandle: {},
+ find: {},
+ relative: {
+ ">": {
+ dir: "parentNode",
+ first: true
+ },
+ " ": {
+ dir: "parentNode"
+ },
+ "+": {
+ dir: "previousSibling",
+ first: true
+ },
+ "~": {
+ dir: "previousSibling"
+ }
+ },
+ preFilter: {
+ "ATTR": function ATTR(match) {
+ match[1] = match[1].replace(runescape, funescape); // Move the given value to match[3] whether quoted or unquoted
+
+ match[3] = (match[3] || match[4] || match[5] || "").replace(runescape, funescape);
+
+ if (match[2] === "~=") {
+ match[3] = " " + match[3] + " ";
+ }
+
+ return match.slice(0, 4);
+ },
+ "CHILD": function CHILD(match) {
+ /* matches from matchExpr["CHILD"]
+ 1 type (only|nth|...)
+ 2 what (child|of-type)
+ 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...)
+ 4 xn-component of xn+y argument ([+-]?\d*n|)
+ 5 sign of xn-component
+ 6 x of xn-component
+ 7 sign of y-component
+ 8 y of y-component
+ */
+ match[1] = match[1].toLowerCase();
+
+ if (match[1].slice(0, 3) === "nth") {
+ // nth-* requires argument
+ if (!match[3]) {
+ Sizzle.error(match[0]);
+ } // numeric x and y parameters for Expr.filter.CHILD
+ // remember that false/true cast respectively to 0/1
+
+
+ match[4] = +(match[4] ? match[5] + (match[6] || 1) : 2 * (match[3] === "even" || match[3] === "odd"));
+ match[5] = +(match[7] + match[8] || match[3] === "odd"); // other types prohibit arguments
+ } else if (match[3]) {
+ Sizzle.error(match[0]);
+ }
+
+ return match;
+ },
+ "PSEUDO": function PSEUDO(match) {
+ var excess,
+ unquoted = !match[6] && match[2];
+
+ if (matchExpr["CHILD"].test(match[0])) {
+ return null;
+ } // Accept quoted arguments as-is
+
+
+ if (match[3]) {
+ match[2] = match[4] || match[5] || ""; // Strip excess characters from unquoted arguments
+ } else if (unquoted && rpseudo.test(unquoted) && ( // Get excess from tokenize (recursively)
+ excess = tokenize(unquoted, true)) && ( // advance to the next closing parenthesis
+ excess = unquoted.indexOf(")", unquoted.length - excess) - unquoted.length)) {
+ // excess is a negative index
+ match[0] = match[0].slice(0, excess);
+ match[2] = unquoted.slice(0, excess);
+ } // Return only captures needed by the pseudo filter method (type and argument)
+
+
+ return match.slice(0, 3);
+ }
+ },
+ filter: {
+ "TAG": function TAG(nodeNameSelector) {
+ var nodeName = nodeNameSelector.replace(runescape, funescape).toLowerCase();
+ return nodeNameSelector === "*" ? function () {
+ return true;
+ } : function (elem) {
+ return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;
+ };
+ },
+ "CLASS": function CLASS(className) {
+ var pattern = classCache[className + " "];
+ return pattern || (pattern = new RegExp("(^|" + whitespace + ")" + className + "(" + whitespace + "|$)")) && classCache(className, function (elem) {
+ return pattern.test(typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== "undefined" && elem.getAttribute("class") || "");
+ });
+ },
+ "ATTR": function ATTR(name, operator, check) {
+ return function (elem) {
+ var result = Sizzle.attr(elem, name);
+
+ if (result == null) {
+ return operator === "!=";
+ }
+
+ if (!operator) {
+ return true;
+ }
+
+ result += "";
+ /* eslint-disable max-len */
+
+ return operator === "=" ? result === check : operator === "!=" ? result !== check : operator === "^=" ? check && result.indexOf(check) === 0 : operator === "*=" ? check && result.indexOf(check) > -1 : operator === "$=" ? check && result.slice(-check.length) === check : operator === "~=" ? (" " + result.replace(rwhitespace, " ") + " ").indexOf(check) > -1 : operator === "|=" ? result === check || result.slice(0, check.length + 1) === check + "-" : false;
+ /* eslint-enable max-len */
+ };
+ },
+ "CHILD": function CHILD(type, what, _argument, first, last) {
+ var simple = type.slice(0, 3) !== "nth",
+ forward = type.slice(-4) !== "last",
+ ofType = what === "of-type";
+ return first === 1 && last === 0 ? // Shortcut for :nth-*(n)
+ function (elem) {
+ return !!elem.parentNode;
+ } : function (elem, _context, xml) {
+ var cache,
+ uniqueCache,
+ outerCache,
+ node,
+ nodeIndex,
+ start,
+ dir = simple !== forward ? "nextSibling" : "previousSibling",
+ parent = elem.parentNode,
+ name = ofType && elem.nodeName.toLowerCase(),
+ useCache = !xml && !ofType,
+ diff = false;
+
+ if (parent) {
+ // :(first|last|only)-(child|of-type)
+ if (simple) {
+ while (dir) {
+ node = elem;
+
+ while (node = node[dir]) {
+ if (ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1) {
+ return false;
+ }
+ } // Reverse direction for :only-* (if we haven't yet done so)
+
+
+ start = dir = type === "only" && !start && "nextSibling";
+ }
+
+ return true;
+ }
+
+ start = [forward ? parent.firstChild : parent.lastChild]; // non-xml :nth-child(...) stores cache data on `parent`
+
+ if (forward && useCache) {
+ // Seek `elem` from a previously-cached index
+ // ...in a gzip-friendly way
+ node = parent;
+ outerCache = node[expando] || (node[expando] = {}); // Support: IE <9 only
+ // Defend against cloned attroperties (jQuery gh-1709)
+
+ uniqueCache = outerCache[node.uniqueID] || (outerCache[node.uniqueID] = {});
+ cache = uniqueCache[type] || [];
+ nodeIndex = cache[0] === dirruns && cache[1];
+ diff = nodeIndex && cache[2];
+ node = nodeIndex && parent.childNodes[nodeIndex];
+
+ while (node = ++nodeIndex && node && node[dir] || ( // Fallback to seeking `elem` from the start
+ diff = nodeIndex = 0) || start.pop()) {
+ // When found, cache indexes on `parent` and break
+ if (node.nodeType === 1 && ++diff && node === elem) {
+ uniqueCache[type] = [dirruns, nodeIndex, diff];
+ break;
+ }
+ }
+ } else {
+ // Use previously-cached element index if available
+ if (useCache) {
+ // ...in a gzip-friendly way
+ node = elem;
+ outerCache = node[expando] || (node[expando] = {}); // Support: IE <9 only
+ // Defend against cloned attroperties (jQuery gh-1709)
+
+ uniqueCache = outerCache[node.uniqueID] || (outerCache[node.uniqueID] = {});
+ cache = uniqueCache[type] || [];
+ nodeIndex = cache[0] === dirruns && cache[1];
+ diff = nodeIndex;
+ } // xml :nth-child(...)
+ // or :nth-last-child(...) or :nth(-last)?-of-type(...)
+
+
+ if (diff === false) {
+ // Use the same loop as above to seek `elem` from the start
+ while (node = ++nodeIndex && node && node[dir] || (diff = nodeIndex = 0) || start.pop()) {
+ if ((ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1) && ++diff) {
+ // Cache the index of each encountered element
+ if (useCache) {
+ outerCache = node[expando] || (node[expando] = {}); // Support: IE <9 only
+ // Defend against cloned attroperties (jQuery gh-1709)
+
+ uniqueCache = outerCache[node.uniqueID] || (outerCache[node.uniqueID] = {});
+ uniqueCache[type] = [dirruns, diff];
+ }
+
+ if (node === elem) {
+ break;
+ }
+ }
+ }
+ }
+ } // Incorporate the offset, then check against cycle size
+
+
+ diff -= last;
+ return diff === first || diff % first === 0 && diff / first >= 0;
+ }
+ };
+ },
+ "PSEUDO": function PSEUDO(pseudo, argument) {
+ // pseudo-class names are case-insensitive
+ // http://www.w3.org/TR/selectors/#pseudo-classes
+ // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters
+ // Remember that setFilters inherits from pseudos
+ var args,
+ fn = Expr.pseudos[pseudo] || Expr.setFilters[pseudo.toLowerCase()] || Sizzle.error("unsupported pseudo: " + pseudo); // The user may use createPseudo to indicate that
+ // arguments are needed to create the filter function
+ // just as Sizzle does
+
+ if (fn[expando]) {
+ return fn(argument);
+ } // But maintain support for old signatures
+
+
+ if (fn.length > 1) {
+ args = [pseudo, pseudo, "", argument];
+ return Expr.setFilters.hasOwnProperty(pseudo.toLowerCase()) ? markFunction(function (seed, matches) {
+ var idx,
+ matched = fn(seed, argument),
+ i = matched.length;
+
+ while (i--) {
+ idx = indexOf(seed, matched[i]);
+ seed[idx] = !(matches[idx] = matched[i]);
+ }
+ }) : function (elem) {
+ return fn(elem, 0, args);
+ };
+ }
+
+ return fn;
+ }
+ },
+ pseudos: {
+ // Potentially complex pseudos
+ "not": markFunction(function (selector) {
+ // Trim the selector passed to compile
+ // to avoid treating leading and trailing
+ // spaces as combinators
+ var input = [],
+ results = [],
+ matcher = compile(selector.replace(rtrim, "$1"));
+ return matcher[expando] ? markFunction(function (seed, matches, _context, xml) {
+ var elem,
+ unmatched = matcher(seed, null, xml, []),
+ i = seed.length; // Match elements unmatched by `matcher`
+
+ while (i--) {
+ if (elem = unmatched[i]) {
+ seed[i] = !(matches[i] = elem);
+ }
+ }
+ }) : function (elem, _context, xml) {
+ input[0] = elem;
+ matcher(input, null, xml, results); // Don't keep the element (issue #299)
+
+ input[0] = null;
+ return !results.pop();
+ };
+ }),
+ "has": markFunction(function (selector) {
+ return function (elem) {
+ return Sizzle(selector, elem).length > 0;
+ };
+ }),
+ "contains": markFunction(function (text) {
+ text = text.replace(runescape, funescape);
+ return function (elem) {
+ return (elem.textContent || getText(elem)).indexOf(text) > -1;
+ };
+ }),
+ // "Whether an element is represented by a :lang() selector
+ // is based solely on the element's language value
+ // being equal to the identifier C,
+ // or beginning with the identifier C immediately followed by "-".
+ // The matching of C against the element's language value is performed case-insensitively.
+ // The identifier C does not have to be a valid language name."
+ // http://www.w3.org/TR/selectors/#lang-pseudo
+ "lang": markFunction(function (lang) {
+ // lang value must be a valid identifier
+ if (!ridentifier.test(lang || "")) {
+ Sizzle.error("unsupported lang: " + lang);
+ }
+
+ lang = lang.replace(runescape, funescape).toLowerCase();
+ return function (elem) {
+ var elemLang;
+
+ do {
+ if (elemLang = documentIsHTML ? elem.lang : elem.getAttribute("xml:lang") || elem.getAttribute("lang")) {
+ elemLang = elemLang.toLowerCase();
+ return elemLang === lang || elemLang.indexOf(lang + "-") === 0;
+ }
+ } while ((elem = elem.parentNode) && elem.nodeType === 1);
+
+ return false;
+ };
+ }),
+ // Miscellaneous
+ "target": function target(elem) {
+ var hash = window.location && window.location.hash;
+ return hash && hash.slice(1) === elem.id;
+ },
+ "root": function root(elem) {
+ return elem === docElem;
+ },
+ "focus": function focus(elem) {
+ return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);
+ },
+ // Boolean properties
+ "enabled": createDisabledPseudo(false),
+ "disabled": createDisabledPseudo(true),
+ "checked": function checked(elem) {
+ // In CSS3, :checked should return both checked and selected elements
+ // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
+ var nodeName = elem.nodeName.toLowerCase();
+ return nodeName === "input" && !!elem.checked || nodeName === "option" && !!elem.selected;
+ },
+ "selected": function selected(elem) {
+ // Accessing this property makes selected-by-default
+ // options in Safari work properly
+ if (elem.parentNode) {
+ // eslint-disable-next-line no-unused-expressions
+ elem.parentNode.selectedIndex;
+ }
+
+ return elem.selected === true;
+ },
+ // Contents
+ "empty": function empty(elem) {
+ // http://www.w3.org/TR/selectors/#empty-pseudo
+ // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5),
+ // but not by others (comment: 8; processing instruction: 7; etc.)
+ // nodeType < 6 works because attributes (2) do not appear as children
+ for (elem = elem.firstChild; elem; elem = elem.nextSibling) {
+ if (elem.nodeType < 6) {
+ return false;
+ }
+ }
+
+ return true;
+ },
+ "parent": function parent(elem) {
+ return !Expr.pseudos["empty"](elem);
+ },
+ // Element/input types
+ "header": function header(elem) {
+ return rheader.test(elem.nodeName);
+ },
+ "input": function input(elem) {
+ return rinputs.test(elem.nodeName);
+ },
+ "button": function button(elem) {
+ var name = elem.nodeName.toLowerCase();
+ return name === "input" && elem.type === "button" || name === "button";
+ },
+ "text": function text(elem) {
+ var attr;
+ return elem.nodeName.toLowerCase() === "input" && elem.type === "text" && ( // Support: IE<8
+ // New HTML5 attribute values (e.g., "search") appear with elem.type === "text"
+ (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text");
+ },
+ // Position-in-collection
+ "first": createPositionalPseudo(function () {
+ return [0];
+ }),
+ "last": createPositionalPseudo(function (_matchIndexes, length) {
+ return [length - 1];
+ }),
+ "eq": createPositionalPseudo(function (_matchIndexes, length, argument) {
+ return [argument < 0 ? argument + length : argument];
+ }),
+ "even": createPositionalPseudo(function (matchIndexes, length) {
+ var i = 0;
+
+ for (; i < length; i += 2) {
+ matchIndexes.push(i);
+ }
+
+ return matchIndexes;
+ }),
+ "odd": createPositionalPseudo(function (matchIndexes, length) {
+ var i = 1;
+
+ for (; i < length; i += 2) {
+ matchIndexes.push(i);
+ }
+
+ return matchIndexes;
+ }),
+ "lt": createPositionalPseudo(function (matchIndexes, length, argument) {
+ var i = argument < 0 ? argument + length : argument > length ? length : argument;
+
+ for (; --i >= 0;) {
+ matchIndexes.push(i);
+ }
+
+ return matchIndexes;
+ }),
+ "gt": createPositionalPseudo(function (matchIndexes, length, argument) {
+ var i = argument < 0 ? argument + length : argument;
+
+ for (; ++i < length;) {
+ matchIndexes.push(i);
+ }
+
+ return matchIndexes;
+ })
+ }
+ };
+ Expr.pseudos["nth"] = Expr.pseudos["eq"]; // Add button/input type pseudos
+
+ for (i in {
+ radio: true,
+ checkbox: true,
+ file: true,
+ password: true,
+ image: true
+ }) {
+ Expr.pseudos[i] = createInputPseudo(i);
+ }
+
+ for (i in {
+ submit: true,
+ reset: true
+ }) {
+ Expr.pseudos[i] = createButtonPseudo(i);
+ } // Easy API for creating new setFilters
+
+
+ function setFilters() {}
+
+ setFilters.prototype = Expr.filters = Expr.pseudos;
+ Expr.setFilters = new setFilters();
+
+ tokenize = Sizzle.tokenize = function (selector, parseOnly) {
+ var matched,
+ match,
+ tokens,
+ type,
+ soFar,
+ groups,
+ preFilters,
+ cached = tokenCache[selector + " "];
+
+ if (cached) {
+ return parseOnly ? 0 : cached.slice(0);
+ }
+
+ soFar = selector;
+ groups = [];
+ preFilters = Expr.preFilter;
+
+ while (soFar) {
+ // Comma and first run
+ if (!matched || (match = rcomma.exec(soFar))) {
+ if (match) {
+ // Don't consume trailing commas as valid
+ soFar = soFar.slice(match[0].length) || soFar;
+ }
+
+ groups.push(tokens = []);
+ }
+
+ matched = false; // Combinators
+
+ if (match = rcombinators.exec(soFar)) {
+ matched = match.shift();
+ tokens.push({
+ value: matched,
+ // Cast descendant combinators to space
+ type: match[0].replace(rtrim, " ")
+ });
+ soFar = soFar.slice(matched.length);
+ } // Filters
+
+
+ for (type in Expr.filter) {
+ if ((match = matchExpr[type].exec(soFar)) && (!preFilters[type] || (match = preFilters[type](match)))) {
+ matched = match.shift();
+ tokens.push({
+ value: matched,
+ type: type,
+ matches: match
+ });
+ soFar = soFar.slice(matched.length);
+ }
+ }
+
+ if (!matched) {
+ break;
+ }
+ } // Return the length of the invalid excess
+ // if we're just parsing
+ // Otherwise, throw an error or return tokens
+
+
+ return parseOnly ? soFar.length : soFar ? Sizzle.error(selector) : // Cache the tokens
+ tokenCache(selector, groups).slice(0);
+ };
+
+ function toSelector(tokens) {
+ var i = 0,
+ len = tokens.length,
+ selector = "";
+
+ for (; i < len; i++) {
+ selector += tokens[i].value;
+ }
+
+ return selector;
+ }
+
+ function addCombinator(matcher, combinator, base) {
+ var dir = combinator.dir,
+ skip = combinator.next,
+ key = skip || dir,
+ checkNonElements = base && key === "parentNode",
+ doneName = done++;
+ return combinator.first ? // Check against closest ancestor/preceding element
+ function (elem, context, xml) {
+ while (elem = elem[dir]) {
+ if (elem.nodeType === 1 || checkNonElements) {
+ return matcher(elem, context, xml);
+ }
+ }
+
+ return false;
+ } : // Check against all ancestor/preceding elements
+ function (elem, context, xml) {
+ var oldCache,
+ uniqueCache,
+ outerCache,
+ newCache = [dirruns, doneName]; // We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching
+
+ if (xml) {
+ while (elem = elem[dir]) {
+ if (elem.nodeType === 1 || checkNonElements) {
+ if (matcher(elem, context, xml)) {
+ return true;
+ }
+ }
+ }
+ } else {
+ while (elem = elem[dir]) {
+ if (elem.nodeType === 1 || checkNonElements) {
+ outerCache = elem[expando] || (elem[expando] = {}); // Support: IE <9 only
+ // Defend against cloned attroperties (jQuery gh-1709)
+
+ uniqueCache = outerCache[elem.uniqueID] || (outerCache[elem.uniqueID] = {});
+
+ if (skip && skip === elem.nodeName.toLowerCase()) {
+ elem = elem[dir] || elem;
+ } else if ((oldCache = uniqueCache[key]) && oldCache[0] === dirruns && oldCache[1] === doneName) {
+ // Assign to newCache so results back-propagate to previous elements
+ return newCache[2] = oldCache[2];
+ } else {
+ // Reuse newcache so results back-propagate to previous elements
+ uniqueCache[key] = newCache; // A match means we're done; a fail means we have to keep checking
+
+ if (newCache[2] = matcher(elem, context, xml)) {
+ return true;
+ }
+ }
+ }
+ }
+ }
+
+ return false;
+ };
+ }
+
+ function elementMatcher(matchers) {
+ return matchers.length > 1 ? function (elem, context, xml) {
+ var i = matchers.length;
+
+ while (i--) {
+ if (!matchers[i](elem, context, xml)) {
+ return false;
+ }
+ }
+
+ return true;
+ } : matchers[0];
+ }
+
+ function multipleContexts(selector, contexts, results) {
+ var i = 0,
+ len = contexts.length;
+
+ for (; i < len; i++) {
+ Sizzle(selector, contexts[i], results);
+ }
+
+ return results;
+ }
+
+ function condense(unmatched, map, filter, context, xml) {
+ var elem,
+ newUnmatched = [],
+ i = 0,
+ len = unmatched.length,
+ mapped = map != null;
+
+ for (; i < len; i++) {
+ if (elem = unmatched[i]) {
+ if (!filter || filter(elem, context, xml)) {
+ newUnmatched.push(elem);
+
+ if (mapped) {
+ map.push(i);
+ }
+ }
+ }
+ }
+
+ return newUnmatched;
+ }
+
+ function setMatcher(preFilter, selector, matcher, postFilter, postFinder, postSelector) {
+ if (postFilter && !postFilter[expando]) {
+ postFilter = setMatcher(postFilter);
+ }
+
+ if (postFinder && !postFinder[expando]) {
+ postFinder = setMatcher(postFinder, postSelector);
+ }
+
+ return markFunction(function (seed, results, context, xml) {
+ var temp,
+ i,
+ elem,
+ preMap = [],
+ postMap = [],
+ preexisting = results.length,
+ // Get initial elements from seed or context
+ elems = seed || multipleContexts(selector || "*", context.nodeType ? [context] : context, []),
+ // Prefilter to get matcher input, preserving a map for seed-results synchronization
+ matcherIn = preFilter && (seed || !selector) ? condense(elems, preMap, preFilter, context, xml) : elems,
+ matcherOut = matcher ? // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,
+ postFinder || (seed ? preFilter : preexisting || postFilter) ? // ...intermediate processing is necessary
+ [] : // ...otherwise use results directly
+ results : matcherIn; // Find primary matches
+
+ if (matcher) {
+ matcher(matcherIn, matcherOut, context, xml);
+ } // Apply postFilter
+
+
+ if (postFilter) {
+ temp = condense(matcherOut, postMap);
+ postFilter(temp, [], context, xml); // Un-match failing elements by moving them back to matcherIn
+
+ i = temp.length;
+
+ while (i--) {
+ if (elem = temp[i]) {
+ matcherOut[postMap[i]] = !(matcherIn[postMap[i]] = elem);
+ }
+ }
+ }
+
+ if (seed) {
+ if (postFinder || preFilter) {
+ if (postFinder) {
+ // Get the final matcherOut by condensing this intermediate into postFinder contexts
+ temp = [];
+ i = matcherOut.length;
+
+ while (i--) {
+ if (elem = matcherOut[i]) {
+ // Restore matcherIn since elem is not yet a final match
+ temp.push(matcherIn[i] = elem);
+ }
+ }
+
+ postFinder(null, matcherOut = [], temp, xml);
+ } // Move matched elements from seed to results to keep them synchronized
+
+
+ i = matcherOut.length;
+
+ while (i--) {
+ if ((elem = matcherOut[i]) && (temp = postFinder ? indexOf(seed, elem) : preMap[i]) > -1) {
+ seed[temp] = !(results[temp] = elem);
+ }
+ }
+ } // Add elements to results, through postFinder if defined
+
+ } else {
+ matcherOut = condense(matcherOut === results ? matcherOut.splice(preexisting, matcherOut.length) : matcherOut);
+
+ if (postFinder) {
+ postFinder(null, results, matcherOut, xml);
+ } else {
+ push.apply(results, matcherOut);
+ }
+ }
+ });
+ }
+
+ function matcherFromTokens(tokens) {
+ var checkContext,
+ matcher,
+ j,
+ len = tokens.length,
+ leadingRelative = Expr.relative[tokens[0].type],
+ implicitRelative = leadingRelative || Expr.relative[" "],
+ i = leadingRelative ? 1 : 0,
+ // The foundational matcher ensures that elements are reachable from top-level context(s)
+ matchContext = addCombinator(function (elem) {
+ return elem === checkContext;
+ }, implicitRelative, true),
+ matchAnyContext = addCombinator(function (elem) {
+ return indexOf(checkContext, elem) > -1;
+ }, implicitRelative, true),
+ matchers = [function (elem, context, xml) {
+ var ret = !leadingRelative && (xml || context !== outermostContext) || ((checkContext = context).nodeType ? matchContext(elem, context, xml) : matchAnyContext(elem, context, xml)); // Avoid hanging onto element (issue #299)
+
+ checkContext = null;
+ return ret;
+ }];
+
+ for (; i < len; i++) {
+ if (matcher = Expr.relative[tokens[i].type]) {
+ matchers = [addCombinator(elementMatcher(matchers), matcher)];
+ } else {
+ matcher = Expr.filter[tokens[i].type].apply(null, tokens[i].matches); // Return special upon seeing a positional matcher
+
+ if (matcher[expando]) {
+ // Find the next relative operator (if any) for proper handling
+ j = ++i;
+
+ for (; j < len; j++) {
+ if (Expr.relative[tokens[j].type]) {
+ break;
+ }
+ }
+
+ return setMatcher(i > 1 && elementMatcher(matchers), i > 1 && toSelector( // If the preceding token was a descendant combinator, insert an implicit any-element `*`
+ tokens.slice(0, i - 1).concat({
+ value: tokens[i - 2].type === " " ? "*" : ""
+ })).replace(rtrim, "$1"), matcher, i < j && matcherFromTokens(tokens.slice(i, j)), j < len && matcherFromTokens(tokens = tokens.slice(j)), j < len && toSelector(tokens));
+ }
+
+ matchers.push(matcher);
+ }
+ }
+
+ return elementMatcher(matchers);
+ }
+
+ function matcherFromGroupMatchers(elementMatchers, setMatchers) {
+ var bySet = setMatchers.length > 0,
+ byElement = elementMatchers.length > 0,
+ superMatcher = function superMatcher(seed, context, xml, results, outermost) {
+ var elem,
+ j,
+ matcher,
+ matchedCount = 0,
+ i = "0",
+ unmatched = seed && [],
+ setMatched = [],
+ contextBackup = outermostContext,
+ // We must always have either seed elements or outermost context
+ elems = seed || byElement && Expr.find["TAG"]("*", outermost),
+ // Use integer dirruns iff this is the outermost matcher
+ dirrunsUnique = dirruns += contextBackup == null ? 1 : Math.random() || 0.1,
+ len = elems.length;
+
+ if (outermost) {
+ // Support: IE 11+, Edge 17 - 18+
+ // IE/Edge sometimes throw a "Permission denied" error when strict-comparing
+ // two documents; shallow comparisons work.
+ // eslint-disable-next-line eqeqeq
+ outermostContext = context == document || context || outermost;
+ } // Add elements passing elementMatchers directly to results
+ // Support: IE<9, Safari
+ // Tolerate NodeList properties (IE: "length"; Safari: ) matching elements by id
+
+
+ for (; i !== len && (elem = elems[i]) != null; i++) {
+ if (byElement && elem) {
+ j = 0; // Support: IE 11+, Edge 17 - 18+
+ // IE/Edge sometimes throw a "Permission denied" error when strict-comparing
+ // two documents; shallow comparisons work.
+ // eslint-disable-next-line eqeqeq
+
+ if (!context && elem.ownerDocument != document) {
+ setDocument(elem);
+ xml = !documentIsHTML;
+ }
+
+ while (matcher = elementMatchers[j++]) {
+ if (matcher(elem, context || document, xml)) {
+ results.push(elem);
+ break;
+ }
+ }
+
+ if (outermost) {
+ dirruns = dirrunsUnique;
+ }
+ } // Track unmatched elements for set filters
+
+
+ if (bySet) {
+ // They will have gone through all possible matchers
+ if (elem = !matcher && elem) {
+ matchedCount--;
+ } // Lengthen the array for every element, matched or not
+
+
+ if (seed) {
+ unmatched.push(elem);
+ }
+ }
+ } // `i` is now the count of elements visited above, and adding it to `matchedCount`
+ // makes the latter nonnegative.
+
+
+ matchedCount += i; // Apply set filters to unmatched elements
+ // NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount`
+ // equals `i`), unless we didn't visit _any_ elements in the above loop because we have
+ // no element matchers and no seed.
+ // Incrementing an initially-string "0" `i` allows `i` to remain a string only in that
+ // case, which will result in a "00" `matchedCount` that differs from `i` but is also
+ // numerically zero.
+
+ if (bySet && i !== matchedCount) {
+ j = 0;
+
+ while (matcher = setMatchers[j++]) {
+ matcher(unmatched, setMatched, context, xml);
+ }
+
+ if (seed) {
+ // Reintegrate element matches to eliminate the need for sorting
+ if (matchedCount > 0) {
+ while (i--) {
+ if (!(unmatched[i] || setMatched[i])) {
+ setMatched[i] = pop.call(results);
+ }
+ }
+ } // Discard index placeholder values to get only actual matches
+
+
+ setMatched = condense(setMatched);
+ } // Add matches to results
+
+
+ push.apply(results, setMatched); // Seedless set matches succeeding multiple successful matchers stipulate sorting
+
+ if (outermost && !seed && setMatched.length > 0 && matchedCount + setMatchers.length > 1) {
+ Sizzle.uniqueSort(results);
+ }
+ } // Override manipulation of globals by nested matchers
+
+
+ if (outermost) {
+ dirruns = dirrunsUnique;
+ outermostContext = contextBackup;
+ }
+
+ return unmatched;
+ };
+
+ return bySet ? markFunction(superMatcher) : superMatcher;
+ }
+
+ compile = Sizzle.compile = function (selector, match
+ /* Internal Use Only */
+ ) {
+ var i,
+ setMatchers = [],
+ elementMatchers = [],
+ cached = compilerCache[selector + " "];
+
+ if (!cached) {
+ // Generate a function of recursive functions that can be used to check each element
+ if (!match) {
+ match = tokenize(selector);
+ }
+
+ i = match.length;
+
+ while (i--) {
+ cached = matcherFromTokens(match[i]);
+
+ if (cached[expando]) {
+ setMatchers.push(cached);
+ } else {
+ elementMatchers.push(cached);
+ }
+ } // Cache the compiled function
+
+
+ cached = compilerCache(selector, matcherFromGroupMatchers(elementMatchers, setMatchers)); // Save selector and tokenization
+
+ cached.selector = selector;
+ }
+
+ return cached;
+ };
+ /**
+ * A low-level selection function that works with Sizzle's compiled
+ * selector functions
+ * @param {String|Function} selector A selector or a pre-compiled
+ * selector function built with Sizzle.compile
+ * @param {Element} context
+ * @param {Array} [results]
+ * @param {Array} [seed] A set of elements to match against
+ */
+
+
+ select = Sizzle.select = function (selector, context, results, seed) {
+ var i,
+ tokens,
+ token,
+ type,
+ find,
+ compiled = typeof selector === "function" && selector,
+ match = !seed && tokenize(selector = compiled.selector || selector);
+ results = results || []; // Try to minimize operations if there is only one selector in the list and no seed
+ // (the latter of which guarantees us context)
+
+ if (match.length === 1) {
+ // Reduce context if the leading compound selector is an ID
+ tokens = match[0] = match[0].slice(0);
+
+ if (tokens.length > 2 && (token = tokens[0]).type === "ID" && context.nodeType === 9 && documentIsHTML && Expr.relative[tokens[1].type]) {
+ context = (Expr.find["ID"](token.matches[0].replace(runescape, funescape), context) || [])[0];
+
+ if (!context) {
+ return results; // Precompiled matchers will still verify ancestry, so step up a level
+ } else if (compiled) {
+ context = context.parentNode;
+ }
+
+ selector = selector.slice(tokens.shift().value.length);
+ } // Fetch a seed set for right-to-left matching
+
+
+ i = matchExpr["needsContext"].test(selector) ? 0 : tokens.length;
+
+ while (i--) {
+ token = tokens[i]; // Abort if we hit a combinator
+
+ if (Expr.relative[type = token.type]) {
+ break;
+ }
+
+ if (find = Expr.find[type]) {
+ // Search, expanding context for leading sibling combinators
+ if (seed = find(token.matches[0].replace(runescape, funescape), rsibling.test(tokens[0].type) && testContext(context.parentNode) || context)) {
+ // If seed is empty or no tokens remain, we can return early
+ tokens.splice(i, 1);
+ selector = seed.length && toSelector(tokens);
+
+ if (!selector) {
+ push.apply(results, seed);
+ return results;
+ }
+
+ break;
+ }
+ }
+ }
+ } // Compile and execute a filtering function if one is not provided
+ // Provide `match` to avoid retokenization if we modified the selector above
+
+
+ (compiled || compile(selector, match))(seed, context, !documentIsHTML, results, !context || rsibling.test(selector) && testContext(context.parentNode) || context);
+ return results;
+ }; // One-time assignments
+ // Sort stability
+
+
+ support.sortStable = expando.split("").sort(sortOrder).join("") === expando; // Support: Chrome 14-35+
+ // Always assume duplicates if they aren't passed to the comparison function
+
+ support.detectDuplicates = !!hasDuplicate; // Initialize against the default document
+
+ setDocument(); // Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)
+ // Detached nodes confoundingly follow *each other*
+
+ support.sortDetached = assert(function (el) {
+ // Should return 1, but returns 4 (following)
+ return el.compareDocumentPosition(document.createElement("fieldset")) & 1;
+ }); // Support: IE<8
+ // Prevent attribute/property "interpolation"
+ // https://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
+
+ if (!assert(function (el) {
+ el.innerHTML = " ";
+ return el.firstChild.getAttribute("href") === "#";
+ })) {
+ addHandle("type|href|height|width", function (elem, name, isXML) {
+ if (!isXML) {
+ return elem.getAttribute(name, name.toLowerCase() === "type" ? 1 : 2);
+ }
+ });
+ } // Support: IE<9
+ // Use defaultValue in place of getAttribute("value")
+
+
+ if (!support.attributes || !assert(function (el) {
+ el.innerHTML = " ";
+ el.firstChild.setAttribute("value", "");
+ return el.firstChild.getAttribute("value") === "";
+ })) {
+ addHandle("value", function (elem, _name, isXML) {
+ if (!isXML && elem.nodeName.toLowerCase() === "input") {
+ return elem.defaultValue;
+ }
+ });
+ } // Support: IE<9
+ // Use getAttributeNode to fetch booleans when getAttribute lies
+
+
+ if (!assert(function (el) {
+ return el.getAttribute("disabled") == null;
+ })) {
+ addHandle(booleans, function (elem, name, isXML) {
+ var val;
+
+ if (!isXML) {
+ return elem[name] === true ? name.toLowerCase() : (val = elem.getAttributeNode(name)) && val.specified ? val.value : null;
+ }
+ });
+ }
+
+ return Sizzle;
+ }(window);
+
+ jQuery.find = Sizzle;
+ jQuery.expr = Sizzle.selectors; // Deprecated
+
+ jQuery.expr[":"] = jQuery.expr.pseudos;
+ jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort;
+ jQuery.text = Sizzle.getText;
+ jQuery.isXMLDoc = Sizzle.isXML;
+ jQuery.contains = Sizzle.contains;
+ jQuery.escapeSelector = Sizzle.escape;
+
+ var dir = function dir(elem, _dir, until) {
+ var matched = [],
+ truncate = until !== undefined;
+
+ while ((elem = elem[_dir]) && elem.nodeType !== 9) {
+ if (elem.nodeType === 1) {
+ if (truncate && jQuery(elem).is(until)) {
+ break;
+ }
+
+ matched.push(elem);
+ }
+ }
+
+ return matched;
+ };
+
+ var _siblings = function siblings(n, elem) {
+ var matched = [];
+
+ for (; n; n = n.nextSibling) {
+ if (n.nodeType === 1 && n !== elem) {
+ matched.push(n);
+ }
+ }
+
+ return matched;
+ };
+
+ var rneedsContext = jQuery.expr.match.needsContext;
+
+ function nodeName(elem, name) {
+ return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
+ }
+
+ ;
+ var rsingleTag = /^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i; // Implement the identical functionality for filter and not
+
+ function winnow(elements, qualifier, not) {
+ if (isFunction(qualifier)) {
+ return jQuery.grep(elements, function (elem, i) {
+ return !!qualifier.call(elem, i, elem) !== not;
+ });
+ } // Single element
+
+
+ if (qualifier.nodeType) {
+ return jQuery.grep(elements, function (elem) {
+ return elem === qualifier !== not;
+ });
+ } // Arraylike of elements (jQuery, arguments, Array)
+
+
+ if (typeof qualifier !== "string") {
+ return jQuery.grep(elements, function (elem) {
+ return indexOf.call(qualifier, elem) > -1 !== not;
+ });
+ } // Filtered directly for both simple and complex selectors
+
+
+ return jQuery.filter(qualifier, elements, not);
+ }
+
+ jQuery.filter = function (expr, elems, not) {
+ var elem = elems[0];
+
+ if (not) {
+ expr = ":not(" + expr + ")";
+ }
+
+ if (elems.length === 1 && elem.nodeType === 1) {
+ return jQuery.find.matchesSelector(elem, expr) ? [elem] : [];
+ }
+
+ return jQuery.find.matches(expr, jQuery.grep(elems, function (elem) {
+ return elem.nodeType === 1;
+ }));
+ };
+
+ jQuery.fn.extend({
+ find: function find(selector) {
+ var i,
+ ret,
+ len = this.length,
+ self = this;
+
+ if (typeof selector !== "string") {
+ return this.pushStack(jQuery(selector).filter(function () {
+ for (i = 0; i < len; i++) {
+ if (jQuery.contains(self[i], this)) {
+ return true;
+ }
+ }
+ }));
+ }
+
+ ret = this.pushStack([]);
+
+ for (i = 0; i < len; i++) {
+ jQuery.find(selector, self[i], ret);
+ }
+
+ return len > 1 ? jQuery.uniqueSort(ret) : ret;
+ },
+ filter: function filter(selector) {
+ return this.pushStack(winnow(this, selector || [], false));
+ },
+ not: function not(selector) {
+ return this.pushStack(winnow(this, selector || [], true));
+ },
+ is: function is(selector) {
+ return !!winnow(this, // If this is a positional/relative selector, check membership in the returned set
+ // so $("p:first").is("p:last") won't return true for a doc with two "p".
+ typeof selector === "string" && rneedsContext.test(selector) ? jQuery(selector) : selector || [], false).length;
+ }
+ }); // Initialize a jQuery object
+ // A central reference to the root jQuery(document)
+
+ var rootjQuery,
+ // A simple way to check for HTML strings
+ // Prioritize #id over to avoid XSS via location.hash (#9521)
+ // Strict HTML recognition (#11290: must start with <)
+ // Shortcut simple #id case for speed
+ rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/,
+ init = jQuery.fn.init = function (selector, context, root) {
+ var match, elem; // HANDLE: $(""), $(null), $(undefined), $(false)
+
+ if (!selector) {
+ return this;
+ } // Method init() accepts an alternate rootjQuery
+ // so migrate can support jQuery.sub (gh-2101)
+
+
+ root = root || rootjQuery; // Handle HTML strings
+
+ if (typeof selector === "string") {
+ if (selector[0] === "<" && selector[selector.length - 1] === ">" && selector.length >= 3) {
+ // Assume that strings that start and end with <> are HTML and skip the regex check
+ match = [null, selector, null];
+ } else {
+ match = rquickExpr.exec(selector);
+ } // Match html or make sure no context is specified for #id
+
+
+ if (match && (match[1] || !context)) {
+ // HANDLE: $(html) -> $(array)
+ if (match[1]) {
+ context = context instanceof jQuery ? context[0] : context; // Option to run scripts is true for back-compat
+ // Intentionally let the error be thrown if parseHTML is not present
+
+ jQuery.merge(this, jQuery.parseHTML(match[1], context && context.nodeType ? context.ownerDocument || context : document, true)); // HANDLE: $(html, props)
+
+ if (rsingleTag.test(match[1]) && jQuery.isPlainObject(context)) {
+ for (match in context) {
+ // Properties of context are called as methods if possible
+ if (isFunction(this[match])) {
+ this[match](context[match]); // ...and otherwise set as attributes
+ } else {
+ this.attr(match, context[match]);
+ }
+ }
+ }
+
+ return this; // HANDLE: $(#id)
+ } else {
+ elem = document.getElementById(match[2]);
+
+ if (elem) {
+ // Inject the element directly into the jQuery object
+ this[0] = elem;
+ this.length = 1;
+ }
+
+ return this;
+ } // HANDLE: $(expr, $(...))
+
+ } else if (!context || context.jquery) {
+ return (context || root).find(selector); // HANDLE: $(expr, context)
+ // (which is just equivalent to: $(context).find(expr)
+ } else {
+ return this.constructor(context).find(selector);
+ } // HANDLE: $(DOMElement)
+
+ } else if (selector.nodeType) {
+ this[0] = selector;
+ this.length = 1;
+ return this; // HANDLE: $(function)
+ // Shortcut for document ready
+ } else if (isFunction(selector)) {
+ return root.ready !== undefined ? root.ready(selector) : // Execute immediately if ready is not present
+ selector(jQuery);
+ }
+
+ return jQuery.makeArray(selector, this);
+ }; // Give the init function the jQuery prototype for later instantiation
+
+
+ init.prototype = jQuery.fn; // Initialize central reference
+
+ rootjQuery = jQuery(document);
+ var rparentsprev = /^(?:parents|prev(?:Until|All))/,
+ // Methods guaranteed to produce a unique set when starting from a unique set
+ guaranteedUnique = {
+ children: true,
+ contents: true,
+ next: true,
+ prev: true
+ };
+ jQuery.fn.extend({
+ has: function has(target) {
+ var targets = jQuery(target, this),
+ l = targets.length;
+ return this.filter(function () {
+ var i = 0;
+
+ for (; i < l; i++) {
+ if (jQuery.contains(this, targets[i])) {
+ return true;
+ }
+ }
+ });
+ },
+ closest: function closest(selectors, context) {
+ var cur,
+ i = 0,
+ l = this.length,
+ matched = [],
+ targets = typeof selectors !== "string" && jQuery(selectors); // Positional selectors never match, since there's no _selection_ context
+
+ if (!rneedsContext.test(selectors)) {
+ for (; i < l; i++) {
+ for (cur = this[i]; cur && cur !== context; cur = cur.parentNode) {
+ // Always skip document fragments
+ if (cur.nodeType < 11 && (targets ? targets.index(cur) > -1 : // Don't pass non-elements to Sizzle
+ cur.nodeType === 1 && jQuery.find.matchesSelector(cur, selectors))) {
+ matched.push(cur);
+ break;
+ }
+ }
+ }
+ }
+
+ return this.pushStack(matched.length > 1 ? jQuery.uniqueSort(matched) : matched);
+ },
+ // Determine the position of an element within the set
+ index: function index(elem) {
+ // No argument, return index in parent
+ if (!elem) {
+ return this[0] && this[0].parentNode ? this.first().prevAll().length : -1;
+ } // Index in selector
+
+
+ if (typeof elem === "string") {
+ return indexOf.call(jQuery(elem), this[0]);
+ } // Locate the position of the desired element
+
+
+ return indexOf.call(this, // If it receives a jQuery object, the first element is used
+ elem.jquery ? elem[0] : elem);
+ },
+ add: function add(selector, context) {
+ return this.pushStack(jQuery.uniqueSort(jQuery.merge(this.get(), jQuery(selector, context))));
+ },
+ addBack: function addBack(selector) {
+ return this.add(selector == null ? this.prevObject : this.prevObject.filter(selector));
+ }
+ });
+
+ function sibling(cur, dir) {
+ while ((cur = cur[dir]) && cur.nodeType !== 1) {}
+
+ return cur;
+ }
+
+ jQuery.each({
+ parent: function parent(elem) {
+ var parent = elem.parentNode;
+ return parent && parent.nodeType !== 11 ? parent : null;
+ },
+ parents: function parents(elem) {
+ return dir(elem, "parentNode");
+ },
+ parentsUntil: function parentsUntil(elem, _i, until) {
+ return dir(elem, "parentNode", until);
+ },
+ next: function next(elem) {
+ return sibling(elem, "nextSibling");
+ },
+ prev: function prev(elem) {
+ return sibling(elem, "previousSibling");
+ },
+ nextAll: function nextAll(elem) {
+ return dir(elem, "nextSibling");
+ },
+ prevAll: function prevAll(elem) {
+ return dir(elem, "previousSibling");
+ },
+ nextUntil: function nextUntil(elem, _i, until) {
+ return dir(elem, "nextSibling", until);
+ },
+ prevUntil: function prevUntil(elem, _i, until) {
+ return dir(elem, "previousSibling", until);
+ },
+ siblings: function siblings(elem) {
+ return _siblings((elem.parentNode || {}).firstChild, elem);
+ },
+ children: function children(elem) {
+ return _siblings(elem.firstChild);
+ },
+ contents: function contents(elem) {
+ if (elem.contentDocument != null && // Support: IE 11+
+ // elements with no `data` attribute has an object
+ // `contentDocument` with a `null` prototype.
+ getProto(elem.contentDocument)) {
+ return elem.contentDocument;
+ } // Support: IE 9 - 11 only, iOS 7 only, Android Browser <=4.3 only
+ // Treat the template element as a regular one in browsers that
+ // don't support it.
+
+
+ if (nodeName(elem, "template")) {
+ elem = elem.content || elem;
+ }
+
+ return jQuery.merge([], elem.childNodes);
+ }
+ }, function (name, fn) {
+ jQuery.fn[name] = function (until, selector) {
+ var matched = jQuery.map(this, fn, until);
+
+ if (name.slice(-5) !== "Until") {
+ selector = until;
+ }
+
+ if (selector && typeof selector === "string") {
+ matched = jQuery.filter(selector, matched);
+ }
+
+ if (this.length > 1) {
+ // Remove duplicates
+ if (!guaranteedUnique[name]) {
+ jQuery.uniqueSort(matched);
+ } // Reverse order for parents* and prev-derivatives
+
+
+ if (rparentsprev.test(name)) {
+ matched.reverse();
+ }
+ }
+
+ return this.pushStack(matched);
+ };
+ });
+ var rnothtmlwhite = /[^\x20\t\r\n\f]+/g; // Convert String-formatted options into Object-formatted ones
+
+ function createOptions(options) {
+ var object = {};
+ jQuery.each(options.match(rnothtmlwhite) || [], function (_, flag) {
+ object[flag] = true;
+ });
+ return object;
+ }
+ /*
+ * Create a callback list using the following parameters:
+ *
+ * options: an optional list of space-separated options that will change how
+ * the callback list behaves or a more traditional option object
+ *
+ * By default a callback list will act like an event callback list and can be
+ * "fired" multiple times.
+ *
+ * Possible options:
+ *
+ * once: will ensure the callback list can only be fired once (like a Deferred)
+ *
+ * memory: will keep track of previous values and will call any callback added
+ * after the list has been fired right away with the latest "memorized"
+ * values (like a Deferred)
+ *
+ * unique: will ensure a callback can only be added once (no duplicate in the list)
+ *
+ * stopOnFalse: interrupt callings when a callback returns false
+ *
+ */
+
+
+ jQuery.Callbacks = function (options) {
+ // Convert options from String-formatted to Object-formatted if needed
+ // (we check in cache first)
+ options = typeof options === "string" ? createOptions(options) : jQuery.extend({}, options);
+
+ var // Flag to know if list is currently firing
+ firing,
+ // Last fire value for non-forgettable lists
+ memory,
+ // Flag to know if list was already fired
+ _fired,
+ // Flag to prevent firing
+ _locked,
+ // Actual callback list
+ list = [],
+ // Queue of execution data for repeatable lists
+ queue = [],
+ // Index of currently firing callback (modified by add/remove as needed)
+ firingIndex = -1,
+ // Fire callbacks
+ fire = function fire() {
+ // Enforce single-firing
+ _locked = _locked || options.once; // Execute callbacks for all pending executions,
+ // respecting firingIndex overrides and runtime changes
+
+ _fired = firing = true;
+
+ for (; queue.length; firingIndex = -1) {
+ memory = queue.shift();
+
+ while (++firingIndex < list.length) {
+ // Run callback and check for early termination
+ if (list[firingIndex].apply(memory[0], memory[1]) === false && options.stopOnFalse) {
+ // Jump to end and forget the data so .add doesn't re-fire
+ firingIndex = list.length;
+ memory = false;
+ }
+ }
+ } // Forget the data if we're done with it
+
+
+ if (!options.memory) {
+ memory = false;
+ }
+
+ firing = false; // Clean up if we're done firing for good
+
+ if (_locked) {
+ // Keep an empty list if we have data for future add calls
+ if (memory) {
+ list = []; // Otherwise, this object is spent
+ } else {
+ list = "";
+ }
+ }
+ },
+ // Actual Callbacks object
+ self = {
+ // Add a callback or a collection of callbacks to the list
+ add: function add() {
+ if (list) {
+ // If we have memory from a past run, we should fire after adding
+ if (memory && !firing) {
+ firingIndex = list.length - 1;
+ queue.push(memory);
+ }
+
+ (function add(args) {
+ jQuery.each(args, function (_, arg) {
+ if (isFunction(arg)) {
+ if (!options.unique || !self.has(arg)) {
+ list.push(arg);
+ }
+ } else if (arg && arg.length && toType(arg) !== "string") {
+ // Inspect recursively
+ add(arg);
+ }
+ });
+ })(arguments);
+
+ if (memory && !firing) {
+ fire();
+ }
+ }
+
+ return this;
+ },
+ // Remove a callback from the list
+ remove: function remove() {
+ jQuery.each(arguments, function (_, arg) {
+ var index;
+
+ while ((index = jQuery.inArray(arg, list, index)) > -1) {
+ list.splice(index, 1); // Handle firing indexes
+
+ if (index <= firingIndex) {
+ firingIndex--;
+ }
+ }
+ });
+ return this;
+ },
+ // Check if a given callback is in the list.
+ // If no argument is given, return whether or not list has callbacks attached.
+ has: function has(fn) {
+ return fn ? jQuery.inArray(fn, list) > -1 : list.length > 0;
+ },
+ // Remove all callbacks from the list
+ empty: function empty() {
+ if (list) {
+ list = [];
+ }
+
+ return this;
+ },
+ // Disable .fire and .add
+ // Abort any current/pending executions
+ // Clear all callbacks and values
+ disable: function disable() {
+ _locked = queue = [];
+ list = memory = "";
+ return this;
+ },
+ disabled: function disabled() {
+ return !list;
+ },
+ // Disable .fire
+ // Also disable .add unless we have memory (since it would have no effect)
+ // Abort any pending executions
+ lock: function lock() {
+ _locked = queue = [];
+
+ if (!memory && !firing) {
+ list = memory = "";
+ }
+
+ return this;
+ },
+ locked: function locked() {
+ return !!_locked;
+ },
+ // Call all callbacks with the given context and arguments
+ fireWith: function fireWith(context, args) {
+ if (!_locked) {
+ args = args || [];
+ args = [context, args.slice ? args.slice() : args];
+ queue.push(args);
+
+ if (!firing) {
+ fire();
+ }
+ }
+
+ return this;
+ },
+ // Call all the callbacks with the given arguments
+ fire: function fire() {
+ self.fireWith(this, arguments);
+ return this;
+ },
+ // To know if the callbacks have already been called at least once
+ fired: function fired() {
+ return !!_fired;
+ }
+ };
+
+ return self;
+ };
+
+ function Identity(v) {
+ return v;
+ }
+
+ function Thrower(ex) {
+ throw ex;
+ }
+
+ function adoptValue(value, resolve, reject, noValue) {
+ var method;
+
+ try {
+ // Check for promise aspect first to privilege synchronous behavior
+ if (value && isFunction(method = value.promise)) {
+ method.call(value).done(resolve).fail(reject); // Other thenables
+ } else if (value && isFunction(method = value.then)) {
+ method.call(value, resolve, reject); // Other non-thenables
+ } else {
+ // Control `resolve` arguments by letting Array#slice cast boolean `noValue` to integer:
+ // * false: [ value ].slice( 0 ) => resolve( value )
+ // * true: [ value ].slice( 1 ) => resolve()
+ resolve.apply(undefined, [value].slice(noValue));
+ } // For Promises/A+, convert exceptions into rejections
+ // Since jQuery.when doesn't unwrap thenables, we can skip the extra checks appearing in
+ // Deferred#then to conditionally suppress rejection.
+
+ } catch (value) {
+ // Support: Android 4.0 only
+ // Strict mode functions invoked without .call/.apply get global-object context
+ reject.apply(undefined, [value]);
+ }
+ }
+
+ jQuery.extend({
+ Deferred: function Deferred(func) {
+ var tuples = [// action, add listener, callbacks,
+ // ... .then handlers, argument index, [final state]
+ ["notify", "progress", jQuery.Callbacks("memory"), jQuery.Callbacks("memory"), 2], ["resolve", "done", jQuery.Callbacks("once memory"), jQuery.Callbacks("once memory"), 0, "resolved"], ["reject", "fail", jQuery.Callbacks("once memory"), jQuery.Callbacks("once memory"), 1, "rejected"]],
+ _state = "pending",
+ _promise = {
+ state: function state() {
+ return _state;
+ },
+ always: function always() {
+ deferred.done(arguments).fail(arguments);
+ return this;
+ },
+ "catch": function _catch(fn) {
+ return _promise.then(null, fn);
+ },
+ // Keep pipe for back-compat
+ pipe: function pipe()
+ /* fnDone, fnFail, fnProgress */
+ {
+ var fns = arguments;
+ return jQuery.Deferred(function (newDefer) {
+ jQuery.each(tuples, function (_i, tuple) {
+ // Map tuples (progress, done, fail) to arguments (done, fail, progress)
+ var fn = isFunction(fns[tuple[4]]) && fns[tuple[4]]; // deferred.progress(function() { bind to newDefer or newDefer.notify })
+ // deferred.done(function() { bind to newDefer or newDefer.resolve })
+ // deferred.fail(function() { bind to newDefer or newDefer.reject })
+
+ deferred[tuple[1]](function () {
+ var returned = fn && fn.apply(this, arguments);
+
+ if (returned && isFunction(returned.promise)) {
+ returned.promise().progress(newDefer.notify).done(newDefer.resolve).fail(newDefer.reject);
+ } else {
+ newDefer[tuple[0] + "With"](this, fn ? [returned] : arguments);
+ }
+ });
+ });
+ fns = null;
+ }).promise();
+ },
+ then: function then(onFulfilled, onRejected, onProgress) {
+ var maxDepth = 0;
+
+ function resolve(depth, deferred, handler, special) {
+ return function () {
+ var that = this,
+ args = arguments,
+ mightThrow = function mightThrow() {
+ var returned, then; // Support: Promises/A+ section 2.3.3.3.3
+ // https://promisesaplus.com/#point-59
+ // Ignore double-resolution attempts
+
+ if (depth < maxDepth) {
+ return;
+ }
+
+ returned = handler.apply(that, args); // Support: Promises/A+ section 2.3.1
+ // https://promisesaplus.com/#point-48
+
+ if (returned === deferred.promise()) {
+ throw new TypeError("Thenable self-resolution");
+ } // Support: Promises/A+ sections 2.3.3.1, 3.5
+ // https://promisesaplus.com/#point-54
+ // https://promisesaplus.com/#point-75
+ // Retrieve `then` only once
+
+
+ then = returned && ( // Support: Promises/A+ section 2.3.4
+ // https://promisesaplus.com/#point-64
+ // Only check objects and functions for thenability
+ _typeof(returned) === "object" || typeof returned === "function") && returned.then; // Handle a returned thenable
+
+ if (isFunction(then)) {
+ // Special processors (notify) just wait for resolution
+ if (special) {
+ then.call(returned, resolve(maxDepth, deferred, Identity, special), resolve(maxDepth, deferred, Thrower, special)); // Normal processors (resolve) also hook into progress
+ } else {
+ // ...and disregard older resolution values
+ maxDepth++;
+ then.call(returned, resolve(maxDepth, deferred, Identity, special), resolve(maxDepth, deferred, Thrower, special), resolve(maxDepth, deferred, Identity, deferred.notifyWith));
+ } // Handle all other returned values
+
+ } else {
+ // Only substitute handlers pass on context
+ // and multiple values (non-spec behavior)
+ if (handler !== Identity) {
+ that = undefined;
+ args = [returned];
+ } // Process the value(s)
+ // Default process is resolve
+
+
+ (special || deferred.resolveWith)(that, args);
+ }
+ },
+ // Only normal processors (resolve) catch and reject exceptions
+ process = special ? mightThrow : function () {
+ try {
+ mightThrow();
+ } catch (e) {
+ if (jQuery.Deferred.exceptionHook) {
+ jQuery.Deferred.exceptionHook(e, process.stackTrace);
+ } // Support: Promises/A+ section 2.3.3.3.4.1
+ // https://promisesaplus.com/#point-61
+ // Ignore post-resolution exceptions
+
+
+ if (depth + 1 >= maxDepth) {
+ // Only substitute handlers pass on context
+ // and multiple values (non-spec behavior)
+ if (handler !== Thrower) {
+ that = undefined;
+ args = [e];
+ }
+
+ deferred.rejectWith(that, args);
+ }
+ }
+ }; // Support: Promises/A+ section 2.3.3.3.1
+ // https://promisesaplus.com/#point-57
+ // Re-resolve promises immediately to dodge false rejection from
+ // subsequent errors
+
+
+ if (depth) {
+ process();
+ } else {
+ // Call an optional hook to record the stack, in case of exception
+ // since it's otherwise lost when execution goes async
+ if (jQuery.Deferred.getStackHook) {
+ process.stackTrace = jQuery.Deferred.getStackHook();
+ }
+
+ window.setTimeout(process);
+ }
+ };
+ }
+
+ return jQuery.Deferred(function (newDefer) {
+ // progress_handlers.add( ... )
+ tuples[0][3].add(resolve(0, newDefer, isFunction(onProgress) ? onProgress : Identity, newDefer.notifyWith)); // fulfilled_handlers.add( ... )
+
+ tuples[1][3].add(resolve(0, newDefer, isFunction(onFulfilled) ? onFulfilled : Identity)); // rejected_handlers.add( ... )
+
+ tuples[2][3].add(resolve(0, newDefer, isFunction(onRejected) ? onRejected : Thrower));
+ }).promise();
+ },
+ // Get a promise for this deferred
+ // If obj is provided, the promise aspect is added to the object
+ promise: function promise(obj) {
+ return obj != null ? jQuery.extend(obj, _promise) : _promise;
+ }
+ },
+ deferred = {}; // Add list-specific methods
+
+ jQuery.each(tuples, function (i, tuple) {
+ var list = tuple[2],
+ stateString = tuple[5]; // promise.progress = list.add
+ // promise.done = list.add
+ // promise.fail = list.add
+
+ _promise[tuple[1]] = list.add; // Handle state
+
+ if (stateString) {
+ list.add(function () {
+ // state = "resolved" (i.e., fulfilled)
+ // state = "rejected"
+ _state = stateString;
+ }, // rejected_callbacks.disable
+ // fulfilled_callbacks.disable
+ tuples[3 - i][2].disable, // rejected_handlers.disable
+ // fulfilled_handlers.disable
+ tuples[3 - i][3].disable, // progress_callbacks.lock
+ tuples[0][2].lock, // progress_handlers.lock
+ tuples[0][3].lock);
+ } // progress_handlers.fire
+ // fulfilled_handlers.fire
+ // rejected_handlers.fire
+
+
+ list.add(tuple[3].fire); // deferred.notify = function() { deferred.notifyWith(...) }
+ // deferred.resolve = function() { deferred.resolveWith(...) }
+ // deferred.reject = function() { deferred.rejectWith(...) }
+
+ deferred[tuple[0]] = function () {
+ deferred[tuple[0] + "With"](this === deferred ? undefined : this, arguments);
+ return this;
+ }; // deferred.notifyWith = list.fireWith
+ // deferred.resolveWith = list.fireWith
+ // deferred.rejectWith = list.fireWith
+
+
+ deferred[tuple[0] + "With"] = list.fireWith;
+ }); // Make the deferred a promise
+
+ _promise.promise(deferred); // Call given func if any
+
+
+ if (func) {
+ func.call(deferred, deferred);
+ } // All done!
+
+
+ return deferred;
+ },
+ // Deferred helper
+ when: function when(singleValue) {
+ var // count of uncompleted subordinates
+ remaining = arguments.length,
+ // count of unprocessed arguments
+ i = remaining,
+ // subordinate fulfillment data
+ resolveContexts = Array(i),
+ resolveValues = _slice.call(arguments),
+ // the master Deferred
+ master = jQuery.Deferred(),
+ // subordinate callback factory
+ updateFunc = function updateFunc(i) {
+ return function (value) {
+ resolveContexts[i] = this;
+ resolveValues[i] = arguments.length > 1 ? _slice.call(arguments) : value;
+
+ if (! --remaining) {
+ master.resolveWith(resolveContexts, resolveValues);
+ }
+ };
+ }; // Single- and empty arguments are adopted like Promise.resolve
+
+
+ if (remaining <= 1) {
+ adoptValue(singleValue, master.done(updateFunc(i)).resolve, master.reject, !remaining); // Use .then() to unwrap secondary thenables (cf. gh-3000)
+
+ if (master.state() === "pending" || isFunction(resolveValues[i] && resolveValues[i].then)) {
+ return master.then();
+ }
+ } // Multiple arguments are aggregated like Promise.all array elements
+
+
+ while (i--) {
+ adoptValue(resolveValues[i], updateFunc(i), master.reject);
+ }
+
+ return master.promise();
+ }
+ }); // These usually indicate a programmer mistake during development,
+ // warn about them ASAP rather than swallowing them by default.
+
+ var rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;
+
+ jQuery.Deferred.exceptionHook = function (error, stack) {
+ // Support: IE 8 - 9 only
+ // Console exists when dev tools are open, which can happen at any time
+ if (window.console && window.console.warn && error && rerrorNames.test(error.name)) {
+ window.console.warn("jQuery.Deferred exception: " + error.message, error.stack, stack);
+ }
+ };
+
+ jQuery.readyException = function (error) {
+ window.setTimeout(function () {
+ throw error;
+ });
+ }; // The deferred used on DOM ready
+
+
+ var readyList = jQuery.Deferred();
+
+ jQuery.fn.ready = function (fn) {
+ readyList.then(fn) // Wrap jQuery.readyException in a function so that the lookup
+ // happens at the time of error handling instead of callback
+ // registration.
+ ["catch"](function (error) {
+ jQuery.readyException(error);
+ });
+ return this;
+ };
+
+ jQuery.extend({
+ // Is the DOM ready to be used? Set to true once it occurs.
+ isReady: false,
+ // A counter to track how many items to wait for before
+ // the ready event fires. See #6781
+ readyWait: 1,
+ // Handle when the DOM is ready
+ ready: function ready(wait) {
+ // Abort if there are pending holds or we're already ready
+ if (wait === true ? --jQuery.readyWait : jQuery.isReady) {
+ return;
+ } // Remember that the DOM is ready
+
+
+ jQuery.isReady = true; // If a normal DOM Ready event fired, decrement, and wait if need be
+
+ if (wait !== true && --jQuery.readyWait > 0) {
+ return;
+ } // If there are functions bound, to execute
+
+
+ readyList.resolveWith(document, [jQuery]);
+ }
+ });
+ jQuery.ready.then = readyList.then; // The ready event handler and self cleanup method
+
+ function completed() {
+ document.removeEventListener("DOMContentLoaded", completed);
+ window.removeEventListener("load", completed);
+ jQuery.ready();
+ } // Catch cases where $(document).ready() is called
+ // after the browser event has already occurred.
+ // Support: IE <=9 - 10 only
+ // Older IE sometimes signals "interactive" too soon
+
+
+ if (document.readyState === "complete" || document.readyState !== "loading" && !document.documentElement.doScroll) {
+ // Handle it asynchronously to allow scripts the opportunity to delay ready
+ window.setTimeout(jQuery.ready);
+ } else {
+ // Use the handy event callback
+ document.addEventListener("DOMContentLoaded", completed); // A fallback to window.onload, that will always work
+
+ window.addEventListener("load", completed);
+ } // Multifunctional method to get and set values of a collection
+ // The value/s can optionally be executed if it's a function
+
+
+ var access = function access(elems, fn, key, value, chainable, emptyGet, raw) {
+ var i = 0,
+ len = elems.length,
+ bulk = key == null; // Sets many values
+
+ if (toType(key) === "object") {
+ chainable = true;
+
+ for (i in key) {
+ access(elems, fn, i, key[i], true, emptyGet, raw);
+ } // Sets one value
+
+ } else if (value !== undefined) {
+ chainable = true;
+
+ if (!isFunction(value)) {
+ raw = true;
+ }
+
+ if (bulk) {
+ // Bulk operations run against the entire set
+ if (raw) {
+ fn.call(elems, value);
+ fn = null; // ...except when executing function values
+ } else {
+ bulk = fn;
+
+ fn = function fn(elem, _key, value) {
+ return bulk.call(jQuery(elem), value);
+ };
+ }
+ }
+
+ if (fn) {
+ for (; i < len; i++) {
+ fn(elems[i], key, raw ? value : value.call(elems[i], i, fn(elems[i], key)));
+ }
+ }
+ }
+
+ if (chainable) {
+ return elems;
+ } // Gets
+
+
+ if (bulk) {
+ return fn.call(elems);
+ }
+
+ return len ? fn(elems[0], key) : emptyGet;
+ }; // Matches dashed string for camelizing
+
+
+ var rmsPrefix = /^-ms-/,
+ rdashAlpha = /-([a-z])/g; // Used by camelCase as callback to replace()
+
+ function fcamelCase(_all, letter) {
+ return letter.toUpperCase();
+ } // Convert dashed to camelCase; used by the css and data modules
+ // Support: IE <=9 - 11, Edge 12 - 15
+ // Microsoft forgot to hump their vendor prefix (#9572)
+
+
+ function camelCase(string) {
+ return string.replace(rmsPrefix, "ms-").replace(rdashAlpha, fcamelCase);
+ }
+
+ var acceptData = function acceptData(owner) {
+ // Accepts only:
+ // - Node
+ // - Node.ELEMENT_NODE
+ // - Node.DOCUMENT_NODE
+ // - Object
+ // - Any
+ return owner.nodeType === 1 || owner.nodeType === 9 || !+owner.nodeType;
+ };
+
+ function Data() {
+ this.expando = jQuery.expando + Data.uid++;
+ }
+
+ Data.uid = 1;
+ Data.prototype = {
+ cache: function cache(owner) {
+ // Check if the owner object already has a cache
+ var value = owner[this.expando]; // If not, create one
+
+ if (!value) {
+ value = Object.create(null); // We can accept data for non-element nodes in modern browsers,
+ // but we should not, see #8335.
+ // Always return an empty object.
+
+ if (acceptData(owner)) {
+ // If it is a node unlikely to be stringify-ed or looped over
+ // use plain assignment
+ if (owner.nodeType) {
+ owner[this.expando] = value; // Otherwise secure it in a non-enumerable property
+ // configurable must be true to allow the property to be
+ // deleted when data is removed
+ } else {
+ Object.defineProperty(owner, this.expando, {
+ value: value,
+ configurable: true
+ });
+ }
+ }
+ }
+
+ return value;
+ },
+ set: function set(owner, data, value) {
+ var prop,
+ cache = this.cache(owner); // Handle: [ owner, key, value ] args
+ // Always use camelCase key (gh-2257)
+
+ if (typeof data === "string") {
+ cache[camelCase(data)] = value; // Handle: [ owner, { properties } ] args
+ } else {
+ // Copy the properties one-by-one to the cache object
+ for (prop in data) {
+ cache[camelCase(prop)] = data[prop];
+ }
+ }
+
+ return cache;
+ },
+ get: function get(owner, key) {
+ return key === undefined ? this.cache(owner) : // Always use camelCase key (gh-2257)
+ owner[this.expando] && owner[this.expando][camelCase(key)];
+ },
+ access: function access(owner, key, value) {
+ // In cases where either:
+ //
+ // 1. No key was specified
+ // 2. A string key was specified, but no value provided
+ //
+ // Take the "read" path and allow the get method to determine
+ // which value to return, respectively either:
+ //
+ // 1. The entire cache object
+ // 2. The data stored at the key
+ //
+ if (key === undefined || key && typeof key === "string" && value === undefined) {
+ return this.get(owner, key);
+ } // When the key is not a string, or both a key and value
+ // are specified, set or extend (existing objects) with either:
+ //
+ // 1. An object of properties
+ // 2. A key and value
+ //
+
+
+ this.set(owner, key, value); // Since the "set" path can have two possible entry points
+ // return the expected data based on which path was taken[*]
+
+ return value !== undefined ? value : key;
+ },
+ remove: function remove(owner, key) {
+ var i,
+ cache = owner[this.expando];
+
+ if (cache === undefined) {
+ return;
+ }
+
+ if (key !== undefined) {
+ // Support array or space separated string of keys
+ if (Array.isArray(key)) {
+ // If key is an array of keys...
+ // We always set camelCase keys, so remove that.
+ key = key.map(camelCase);
+ } else {
+ key = camelCase(key); // If a key with the spaces exists, use it.
+ // Otherwise, create an array by matching non-whitespace
+
+ key = key in cache ? [key] : key.match(rnothtmlwhite) || [];
+ }
+
+ i = key.length;
+
+ while (i--) {
+ delete cache[key[i]];
+ }
+ } // Remove the expando if there's no more data
+
+
+ if (key === undefined || jQuery.isEmptyObject(cache)) {
+ // Support: Chrome <=35 - 45
+ // Webkit & Blink performance suffers when deleting properties
+ // from DOM nodes, so set to undefined instead
+ // https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted)
+ if (owner.nodeType) {
+ owner[this.expando] = undefined;
+ } else {
+ delete owner[this.expando];
+ }
+ }
+ },
+ hasData: function hasData(owner) {
+ var cache = owner[this.expando];
+ return cache !== undefined && !jQuery.isEmptyObject(cache);
+ }
+ };
+ var dataPriv = new Data();
+ var dataUser = new Data(); // Implementation Summary
+ //
+ // 1. Enforce API surface and semantic compatibility with 1.9.x branch
+ // 2. Improve the module's maintainability by reducing the storage
+ // paths to a single mechanism.
+ // 3. Use the same single mechanism to support "private" and "user" data.
+ // 4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData)
+ // 5. Avoid exposing implementation details on user objects (eg. expando properties)
+ // 6. Provide a clear path for implementation upgrade to WeakMap in 2014
+
+ var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,
+ rmultiDash = /[A-Z]/g;
+
+ function getData(data) {
+ if (data === "true") {
+ return true;
+ }
+
+ if (data === "false") {
+ return false;
+ }
+
+ if (data === "null") {
+ return null;
+ } // Only convert to a number if it doesn't change the string
+
+
+ if (data === +data + "") {
+ return +data;
+ }
+
+ if (rbrace.test(data)) {
+ return JSON.parse(data);
+ }
+
+ return data;
+ }
+
+ function dataAttr(elem, key, data) {
+ var name; // If nothing was found internally, try to fetch any
+ // data from the HTML5 data-* attribute
+
+ if (data === undefined && elem.nodeType === 1) {
+ name = "data-" + key.replace(rmultiDash, "-$&").toLowerCase();
+ data = elem.getAttribute(name);
+
+ if (typeof data === "string") {
+ try {
+ data = getData(data);
+ } catch (e) {} // Make sure we set the data so it isn't changed later
+
+
+ dataUser.set(elem, key, data);
+ } else {
+ data = undefined;
+ }
+ }
+
+ return data;
+ }
+
+ jQuery.extend({
+ hasData: function hasData(elem) {
+ return dataUser.hasData(elem) || dataPriv.hasData(elem);
+ },
+ data: function data(elem, name, _data) {
+ return dataUser.access(elem, name, _data);
+ },
+ removeData: function removeData(elem, name) {
+ dataUser.remove(elem, name);
+ },
+ // TODO: Now that all calls to _data and _removeData have been replaced
+ // with direct calls to dataPriv methods, these can be deprecated.
+ _data: function _data(elem, name, data) {
+ return dataPriv.access(elem, name, data);
+ },
+ _removeData: function _removeData(elem, name) {
+ dataPriv.remove(elem, name);
+ }
+ });
+ jQuery.fn.extend({
+ data: function data(key, value) {
+ var i,
+ name,
+ data,
+ elem = this[0],
+ attrs = elem && elem.attributes; // Gets all values
+
+ if (key === undefined) {
+ if (this.length) {
+ data = dataUser.get(elem);
+
+ if (elem.nodeType === 1 && !dataPriv.get(elem, "hasDataAttrs")) {
+ i = attrs.length;
+
+ while (i--) {
+ // Support: IE 11 only
+ // The attrs elements can be null (#14894)
+ if (attrs[i]) {
+ name = attrs[i].name;
+
+ if (name.indexOf("data-") === 0) {
+ name = camelCase(name.slice(5));
+ dataAttr(elem, name, data[name]);
+ }
+ }
+ }
+
+ dataPriv.set(elem, "hasDataAttrs", true);
+ }
+ }
+
+ return data;
+ } // Sets multiple values
+
+
+ if (_typeof(key) === "object") {
+ return this.each(function () {
+ dataUser.set(this, key);
+ });
+ }
+
+ return access(this, function (value) {
+ var data; // The calling jQuery object (element matches) is not empty
+ // (and therefore has an element appears at this[ 0 ]) and the
+ // `value` parameter was not undefined. An empty jQuery object
+ // will result in `undefined` for elem = this[ 0 ] which will
+ // throw an exception if an attempt to read a data cache is made.
+
+ if (elem && value === undefined) {
+ // Attempt to get data from the cache
+ // The key will always be camelCased in Data
+ data = dataUser.get(elem, key);
+
+ if (data !== undefined) {
+ return data;
+ } // Attempt to "discover" the data in
+ // HTML5 custom data-* attrs
+
+
+ data = dataAttr(elem, key);
+
+ if (data !== undefined) {
+ return data;
+ } // We tried really hard, but the data doesn't exist.
+
+
+ return;
+ } // Set the data...
+
+
+ this.each(function () {
+ // We always store the camelCased key
+ dataUser.set(this, key, value);
+ });
+ }, null, value, arguments.length > 1, null, true);
+ },
+ removeData: function removeData(key) {
+ return this.each(function () {
+ dataUser.remove(this, key);
+ });
+ }
+ });
+ jQuery.extend({
+ queue: function queue(elem, type, data) {
+ var queue;
+
+ if (elem) {
+ type = (type || "fx") + "queue";
+ queue = dataPriv.get(elem, type); // Speed up dequeue by getting out quickly if this is just a lookup
+
+ if (data) {
+ if (!queue || Array.isArray(data)) {
+ queue = dataPriv.access(elem, type, jQuery.makeArray(data));
+ } else {
+ queue.push(data);
+ }
+ }
+
+ return queue || [];
+ }
+ },
+ dequeue: function dequeue(elem, type) {
+ type = type || "fx";
+
+ var queue = jQuery.queue(elem, type),
+ startLength = queue.length,
+ fn = queue.shift(),
+ hooks = jQuery._queueHooks(elem, type),
+ next = function next() {
+ jQuery.dequeue(elem, type);
+ }; // If the fx queue is dequeued, always remove the progress sentinel
+
+
+ if (fn === "inprogress") {
+ fn = queue.shift();
+ startLength--;
+ }
+
+ if (fn) {
+ // Add a progress sentinel to prevent the fx queue from being
+ // automatically dequeued
+ if (type === "fx") {
+ queue.unshift("inprogress");
+ } // Clear up the last queue stop function
+
+
+ delete hooks.stop;
+ fn.call(elem, next, hooks);
+ }
+
+ if (!startLength && hooks) {
+ hooks.empty.fire();
+ }
+ },
+ // Not public - generate a queueHooks object, or return the current one
+ _queueHooks: function _queueHooks(elem, type) {
+ var key = type + "queueHooks";
+ return dataPriv.get(elem, key) || dataPriv.access(elem, key, {
+ empty: jQuery.Callbacks("once memory").add(function () {
+ dataPriv.remove(elem, [type + "queue", key]);
+ })
+ });
+ }
+ });
+ jQuery.fn.extend({
+ queue: function queue(type, data) {
+ var setter = 2;
+
+ if (typeof type !== "string") {
+ data = type;
+ type = "fx";
+ setter--;
+ }
+
+ if (arguments.length < setter) {
+ return jQuery.queue(this[0], type);
+ }
+
+ return data === undefined ? this : this.each(function () {
+ var queue = jQuery.queue(this, type, data); // Ensure a hooks for this queue
+
+ jQuery._queueHooks(this, type);
+
+ if (type === "fx" && queue[0] !== "inprogress") {
+ jQuery.dequeue(this, type);
+ }
+ });
+ },
+ dequeue: function dequeue(type) {
+ return this.each(function () {
+ jQuery.dequeue(this, type);
+ });
+ },
+ clearQueue: function clearQueue(type) {
+ return this.queue(type || "fx", []);
+ },
+ // Get a promise resolved when queues of a certain type
+ // are emptied (fx is the type by default)
+ promise: function promise(type, obj) {
+ var tmp,
+ count = 1,
+ defer = jQuery.Deferred(),
+ elements = this,
+ i = this.length,
+ resolve = function resolve() {
+ if (! --count) {
+ defer.resolveWith(elements, [elements]);
+ }
+ };
+
+ if (typeof type !== "string") {
+ obj = type;
+ type = undefined;
+ }
+
+ type = type || "fx";
+
+ while (i--) {
+ tmp = dataPriv.get(elements[i], type + "queueHooks");
+
+ if (tmp && tmp.empty) {
+ count++;
+ tmp.empty.add(resolve);
+ }
+ }
+
+ resolve();
+ return defer.promise(obj);
+ }
+ });
+ var pnum = /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source;
+ var rcssNum = new RegExp("^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i");
+ var cssExpand = ["Top", "Right", "Bottom", "Left"];
+ var documentElement = document.documentElement;
+
+ var isAttached = function isAttached(elem) {
+ return jQuery.contains(elem.ownerDocument, elem);
+ },
+ composed = {
+ composed: true
+ }; // Support: IE 9 - 11+, Edge 12 - 18+, iOS 10.0 - 10.2 only
+ // Check attachment across shadow DOM boundaries when possible (gh-3504)
+ // Support: iOS 10.0-10.2 only
+ // Early iOS 10 versions support `attachShadow` but not `getRootNode`,
+ // leading to errors. We need to check for `getRootNode`.
+
+
+ if (documentElement.getRootNode) {
+ isAttached = function isAttached(elem) {
+ return jQuery.contains(elem.ownerDocument, elem) || elem.getRootNode(composed) === elem.ownerDocument;
+ };
+ }
+
+ var isHiddenWithinTree = function isHiddenWithinTree(elem, el) {
+ // isHiddenWithinTree might be called from jQuery#filter function;
+ // in that case, element will be second argument
+ elem = el || elem; // Inline style trumps all
+
+ return elem.style.display === "none" || elem.style.display === "" && // Otherwise, check computed style
+ // Support: Firefox <=43 - 45
+ // Disconnected elements can have computed display: none, so first confirm that elem is
+ // in the document.
+ isAttached(elem) && jQuery.css(elem, "display") === "none";
+ };
+
+ function adjustCSS(elem, prop, valueParts, tween) {
+ var adjusted,
+ scale,
+ maxIterations = 20,
+ currentValue = tween ? function () {
+ return tween.cur();
+ } : function () {
+ return jQuery.css(elem, prop, "");
+ },
+ initial = currentValue(),
+ unit = valueParts && valueParts[3] || (jQuery.cssNumber[prop] ? "" : "px"),
+ // Starting value computation is required for potential unit mismatches
+ initialInUnit = elem.nodeType && (jQuery.cssNumber[prop] || unit !== "px" && +initial) && rcssNum.exec(jQuery.css(elem, prop));
+
+ if (initialInUnit && initialInUnit[3] !== unit) {
+ // Support: Firefox <=54
+ // Halve the iteration target value to prevent interference from CSS upper bounds (gh-2144)
+ initial = initial / 2; // Trust units reported by jQuery.css
+
+ unit = unit || initialInUnit[3]; // Iteratively approximate from a nonzero starting point
+
+ initialInUnit = +initial || 1;
+
+ while (maxIterations--) {
+ // Evaluate and update our best guess (doubling guesses that zero out).
+ // Finish if the scale equals or crosses 1 (making the old*new product non-positive).
+ jQuery.style(elem, prop, initialInUnit + unit);
+
+ if ((1 - scale) * (1 - (scale = currentValue() / initial || 0.5)) <= 0) {
+ maxIterations = 0;
+ }
+
+ initialInUnit = initialInUnit / scale;
+ }
+
+ initialInUnit = initialInUnit * 2;
+ jQuery.style(elem, prop, initialInUnit + unit); // Make sure we update the tween properties later on
+
+ valueParts = valueParts || [];
+ }
+
+ if (valueParts) {
+ initialInUnit = +initialInUnit || +initial || 0; // Apply relative offset (+=/-=) if specified
+
+ adjusted = valueParts[1] ? initialInUnit + (valueParts[1] + 1) * valueParts[2] : +valueParts[2];
+
+ if (tween) {
+ tween.unit = unit;
+ tween.start = initialInUnit;
+ tween.end = adjusted;
+ }
+ }
+
+ return adjusted;
+ }
+
+ var defaultDisplayMap = {};
+
+ function getDefaultDisplay(elem) {
+ var temp,
+ doc = elem.ownerDocument,
+ nodeName = elem.nodeName,
+ display = defaultDisplayMap[nodeName];
+
+ if (display) {
+ return display;
+ }
+
+ temp = doc.body.appendChild(doc.createElement(nodeName));
+ display = jQuery.css(temp, "display");
+ temp.parentNode.removeChild(temp);
+
+ if (display === "none") {
+ display = "block";
+ }
+
+ defaultDisplayMap[nodeName] = display;
+ return display;
+ }
+
+ function showHide(elements, show) {
+ var display,
+ elem,
+ values = [],
+ index = 0,
+ length = elements.length; // Determine new display value for elements that need to change
+
+ for (; index < length; index++) {
+ elem = elements[index];
+
+ if (!elem.style) {
+ continue;
+ }
+
+ display = elem.style.display;
+
+ if (show) {
+ // Since we force visibility upon cascade-hidden elements, an immediate (and slow)
+ // check is required in this first loop unless we have a nonempty display value (either
+ // inline or about-to-be-restored)
+ if (display === "none") {
+ values[index] = dataPriv.get(elem, "display") || null;
+
+ if (!values[index]) {
+ elem.style.display = "";
+ }
+ }
+
+ if (elem.style.display === "" && isHiddenWithinTree(elem)) {
+ values[index] = getDefaultDisplay(elem);
+ }
+ } else {
+ if (display !== "none") {
+ values[index] = "none"; // Remember what we're overwriting
+
+ dataPriv.set(elem, "display", display);
+ }
+ }
+ } // Set the display of the elements in a second loop to avoid constant reflow
+
+
+ for (index = 0; index < length; index++) {
+ if (values[index] != null) {
+ elements[index].style.display = values[index];
+ }
+ }
+
+ return elements;
+ }
+
+ jQuery.fn.extend({
+ show: function show() {
+ return showHide(this, true);
+ },
+ hide: function hide() {
+ return showHide(this);
+ },
+ toggle: function toggle(state) {
+ if (typeof state === "boolean") {
+ return state ? this.show() : this.hide();
+ }
+
+ return this.each(function () {
+ if (isHiddenWithinTree(this)) {
+ jQuery(this).show();
+ } else {
+ jQuery(this).hide();
+ }
+ });
+ }
+ });
+ var rcheckableType = /^(?:checkbox|radio)$/i;
+ var rtagName = /<([a-z][^\/\0>\x20\t\r\n\f]*)/i;
+ var rscriptType = /^$|^module$|\/(?:java|ecma)script/i;
+
+ (function () {
+ var fragment = document.createDocumentFragment(),
+ div = fragment.appendChild(document.createElement("div")),
+ input = document.createElement("input"); // Support: Android 4.0 - 4.3 only
+ // Check state lost if the name is set (#11217)
+ // Support: Windows Web Apps (WWA)
+ // `name` and `type` must use .setAttribute for WWA (#14901)
+
+ input.setAttribute("type", "radio");
+ input.setAttribute("checked", "checked");
+ input.setAttribute("name", "t");
+ div.appendChild(input); // Support: Android <=4.1 only
+ // Older WebKit doesn't clone checked state correctly in fragments
+
+ support.checkClone = div.cloneNode(true).cloneNode(true).lastChild.checked; // Support: IE <=11 only
+ // Make sure textarea (and checkbox) defaultValue is properly cloned
+
+ div.innerHTML = "";
+ support.noCloneChecked = !!div.cloneNode(true).lastChild.defaultValue; // Support: IE <=9 only
+ // IE <=9 replaces tags with their contents when inserted outside of
+ // the select element.
+
+ div.innerHTML = " ";
+ support.option = !!div.lastChild;
+ })(); // We have to close these tags to support XHTML (#13200)
+
+
+ var wrapMap = {
+ // XHTML parsers do not magically insert elements in the
+ // same way that tag soup parsers do. So we cannot shorten
+ // this by omitting or other required elements.
+ thead: [1, ""],
+ col: [2, ""],
+ tr: [2, ""],
+ td: [3, ""],
+ _default: [0, "", ""]
+ };
+ wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
+ wrapMap.th = wrapMap.td; // Support: IE <=9 only
+
+ if (!support.option) {
+ wrapMap.optgroup = wrapMap.option = [1, "", " "];
+ }
+
+ function getAll(context, tag) {
+ // Support: IE <=9 - 11 only
+ // Use typeof to avoid zero-argument method invocation on host objects (#15151)
+ var ret;
+
+ if (typeof context.getElementsByTagName !== "undefined") {
+ ret = context.getElementsByTagName(tag || "*");
+ } else if (typeof context.querySelectorAll !== "undefined") {
+ ret = context.querySelectorAll(tag || "*");
+ } else {
+ ret = [];
+ }
+
+ if (tag === undefined || tag && nodeName(context, tag)) {
+ return jQuery.merge([context], ret);
+ }
+
+ return ret;
+ } // Mark scripts as having already been evaluated
+
+
+ function setGlobalEval(elems, refElements) {
+ var i = 0,
+ l = elems.length;
+
+ for (; i < l; i++) {
+ dataPriv.set(elems[i], "globalEval", !refElements || dataPriv.get(refElements[i], "globalEval"));
+ }
+ }
+
+ var rhtml = /<|?\w+;/;
+
+ function buildFragment(elems, context, scripts, selection, ignored) {
+ var elem,
+ tmp,
+ tag,
+ wrap,
+ attached,
+ j,
+ fragment = context.createDocumentFragment(),
+ nodes = [],
+ i = 0,
+ l = elems.length;
+
+ for (; i < l; i++) {
+ elem = elems[i];
+
+ if (elem || elem === 0) {
+ // Add nodes directly
+ if (toType(elem) === "object") {
+ // Support: Android <=4.0 only, PhantomJS 1 only
+ // push.apply(_, arraylike) throws on ancient WebKit
+ jQuery.merge(nodes, elem.nodeType ? [elem] : elem); // Convert non-html into a text node
+ } else if (!rhtml.test(elem)) {
+ nodes.push(context.createTextNode(elem)); // Convert html into DOM nodes
+ } else {
+ tmp = tmp || fragment.appendChild(context.createElement("div")); // Deserialize a standard representation
+
+ tag = (rtagName.exec(elem) || ["", ""])[1].toLowerCase();
+ wrap = wrapMap[tag] || wrapMap._default;
+ tmp.innerHTML = wrap[1] + jQuery.htmlPrefilter(elem) + wrap[2]; // Descend through wrappers to the right content
+
+ j = wrap[0];
+
+ while (j--) {
+ tmp = tmp.lastChild;
+ } // Support: Android <=4.0 only, PhantomJS 1 only
+ // push.apply(_, arraylike) throws on ancient WebKit
+
+
+ jQuery.merge(nodes, tmp.childNodes); // Remember the top-level container
+
+ tmp = fragment.firstChild; // Ensure the created nodes are orphaned (#12392)
+
+ tmp.textContent = "";
+ }
+ }
+ } // Remove wrapper from fragment
+
+
+ fragment.textContent = "";
+ i = 0;
+
+ while (elem = nodes[i++]) {
+ // Skip elements already in the context collection (trac-4087)
+ if (selection && jQuery.inArray(elem, selection) > -1) {
+ if (ignored) {
+ ignored.push(elem);
+ }
+
+ continue;
+ }
+
+ attached = isAttached(elem); // Append to fragment
+
+ tmp = getAll(fragment.appendChild(elem), "script"); // Preserve script evaluation history
+
+ if (attached) {
+ setGlobalEval(tmp);
+ } // Capture executables
+
+
+ if (scripts) {
+ j = 0;
+
+ while (elem = tmp[j++]) {
+ if (rscriptType.test(elem.type || "")) {
+ scripts.push(elem);
+ }
+ }
+ }
+ }
+
+ return fragment;
+ }
+
+ var rkeyEvent = /^key/,
+ rmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/,
+ rtypenamespace = /^([^.]*)(?:\.(.+)|)/;
+
+ function returnTrue() {
+ return true;
+ }
+
+ function returnFalse() {
+ return false;
+ } // Support: IE <=9 - 11+
+ // focus() and blur() are asynchronous, except when they are no-op.
+ // So expect focus to be synchronous when the element is already active,
+ // and blur to be synchronous when the element is not already active.
+ // (focus and blur are always synchronous in other supported browsers,
+ // this just defines when we can count on it).
+
+
+ function expectSync(elem, type) {
+ return elem === safeActiveElement() === (type === "focus");
+ } // Support: IE <=9 only
+ // Accessing document.activeElement can throw unexpectedly
+ // https://bugs.jquery.com/ticket/13393
+
+
+ function safeActiveElement() {
+ try {
+ return document.activeElement;
+ } catch (err) {}
+ }
+
+ function _on(elem, types, selector, data, fn, one) {
+ var origFn, type; // Types can be a map of types/handlers
+
+ if (_typeof(types) === "object") {
+ // ( types-Object, selector, data )
+ if (typeof selector !== "string") {
+ // ( types-Object, data )
+ data = data || selector;
+ selector = undefined;
+ }
+
+ for (type in types) {
+ _on(elem, type, selector, data, types[type], one);
+ }
+
+ return elem;
+ }
+
+ if (data == null && fn == null) {
+ // ( types, fn )
+ fn = selector;
+ data = selector = undefined;
+ } else if (fn == null) {
+ if (typeof selector === "string") {
+ // ( types, selector, fn )
+ fn = data;
+ data = undefined;
+ } else {
+ // ( types, data, fn )
+ fn = data;
+ data = selector;
+ selector = undefined;
+ }
+ }
+
+ if (fn === false) {
+ fn = returnFalse;
+ } else if (!fn) {
+ return elem;
+ }
+
+ if (one === 1) {
+ origFn = fn;
+
+ fn = function fn(event) {
+ // Can use an empty set, since event contains the info
+ jQuery().off(event);
+ return origFn.apply(this, arguments);
+ }; // Use same guid so caller can remove using origFn
+
+
+ fn.guid = origFn.guid || (origFn.guid = jQuery.guid++);
+ }
+
+ return elem.each(function () {
+ jQuery.event.add(this, types, fn, data, selector);
+ });
+ }
+ /*
+ * Helper functions for managing events -- not part of the public interface.
+ * Props to Dean Edwards' addEvent library for many of the ideas.
+ */
+
+
+ jQuery.event = {
+ global: {},
+ add: function add(elem, types, handler, data, selector) {
+ var handleObjIn,
+ eventHandle,
+ tmp,
+ events,
+ t,
+ handleObj,
+ special,
+ handlers,
+ type,
+ namespaces,
+ origType,
+ elemData = dataPriv.get(elem); // Only attach events to objects that accept data
+
+ if (!acceptData(elem)) {
+ return;
+ } // Caller can pass in an object of custom data in lieu of the handler
+
+
+ if (handler.handler) {
+ handleObjIn = handler;
+ handler = handleObjIn.handler;
+ selector = handleObjIn.selector;
+ } // Ensure that invalid selectors throw exceptions at attach time
+ // Evaluate against documentElement in case elem is a non-element node (e.g., document)
+
+
+ if (selector) {
+ jQuery.find.matchesSelector(documentElement, selector);
+ } // Make sure that the handler has a unique ID, used to find/remove it later
+
+
+ if (!handler.guid) {
+ handler.guid = jQuery.guid++;
+ } // Init the element's event structure and main handler, if this is the first
+
+
+ if (!(events = elemData.events)) {
+ events = elemData.events = Object.create(null);
+ }
+
+ if (!(eventHandle = elemData.handle)) {
+ eventHandle = elemData.handle = function (e) {
+ // Discard the second event of a jQuery.event.trigger() and
+ // when an event is called after a page has unloaded
+ return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ? jQuery.event.dispatch.apply(elem, arguments) : undefined;
+ };
+ } // Handle multiple events separated by a space
+
+
+ types = (types || "").match(rnothtmlwhite) || [""];
+ t = types.length;
+
+ while (t--) {
+ tmp = rtypenamespace.exec(types[t]) || [];
+ type = origType = tmp[1];
+ namespaces = (tmp[2] || "").split(".").sort(); // There *must* be a type, no attaching namespace-only handlers
+
+ if (!type) {
+ continue;
+ } // If event changes its type, use the special event handlers for the changed type
+
+
+ special = jQuery.event.special[type] || {}; // If selector defined, determine special event api type, otherwise given type
+
+ type = (selector ? special.delegateType : special.bindType) || type; // Update special based on newly reset type
+
+ special = jQuery.event.special[type] || {}; // handleObj is passed to all event handlers
+
+ handleObj = jQuery.extend({
+ type: type,
+ origType: origType,
+ data: data,
+ handler: handler,
+ guid: handler.guid,
+ selector: selector,
+ needsContext: selector && jQuery.expr.match.needsContext.test(selector),
+ namespace: namespaces.join(".")
+ }, handleObjIn); // Init the event handler queue if we're the first
+
+ if (!(handlers = events[type])) {
+ handlers = events[type] = [];
+ handlers.delegateCount = 0; // Only use addEventListener if the special events handler returns false
+
+ if (!special.setup || special.setup.call(elem, data, namespaces, eventHandle) === false) {
+ if (elem.addEventListener) {
+ elem.addEventListener(type, eventHandle);
+ }
+ }
+ }
+
+ if (special.add) {
+ special.add.call(elem, handleObj);
+
+ if (!handleObj.handler.guid) {
+ handleObj.handler.guid = handler.guid;
+ }
+ } // Add to the element's handler list, delegates in front
+
+
+ if (selector) {
+ handlers.splice(handlers.delegateCount++, 0, handleObj);
+ } else {
+ handlers.push(handleObj);
+ } // Keep track of which events have ever been used, for event optimization
+
+
+ jQuery.event.global[type] = true;
+ }
+ },
+ // Detach an event or set of events from an element
+ remove: function remove(elem, types, handler, selector, mappedTypes) {
+ var j,
+ origCount,
+ tmp,
+ events,
+ t,
+ handleObj,
+ special,
+ handlers,
+ type,
+ namespaces,
+ origType,
+ elemData = dataPriv.hasData(elem) && dataPriv.get(elem);
+
+ if (!elemData || !(events = elemData.events)) {
+ return;
+ } // Once for each type.namespace in types; type may be omitted
+
+
+ types = (types || "").match(rnothtmlwhite) || [""];
+ t = types.length;
+
+ while (t--) {
+ tmp = rtypenamespace.exec(types[t]) || [];
+ type = origType = tmp[1];
+ namespaces = (tmp[2] || "").split(".").sort(); // Unbind all events (on this namespace, if provided) for the element
+
+ if (!type) {
+ for (type in events) {
+ jQuery.event.remove(elem, type + types[t], handler, selector, true);
+ }
+
+ continue;
+ }
+
+ special = jQuery.event.special[type] || {};
+ type = (selector ? special.delegateType : special.bindType) || type;
+ handlers = events[type] || [];
+ tmp = tmp[2] && new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)"); // Remove matching events
+
+ origCount = j = handlers.length;
+
+ while (j--) {
+ handleObj = handlers[j];
+
+ if ((mappedTypes || origType === handleObj.origType) && (!handler || handler.guid === handleObj.guid) && (!tmp || tmp.test(handleObj.namespace)) && (!selector || selector === handleObj.selector || selector === "**" && handleObj.selector)) {
+ handlers.splice(j, 1);
+
+ if (handleObj.selector) {
+ handlers.delegateCount--;
+ }
+
+ if (special.remove) {
+ special.remove.call(elem, handleObj);
+ }
+ }
+ } // Remove generic event handler if we removed something and no more handlers exist
+ // (avoids potential for endless recursion during removal of special event handlers)
+
+
+ if (origCount && !handlers.length) {
+ if (!special.teardown || special.teardown.call(elem, namespaces, elemData.handle) === false) {
+ jQuery.removeEvent(elem, type, elemData.handle);
+ }
+
+ delete events[type];
+ }
+ } // Remove data and the expando if it's no longer used
+
+
+ if (jQuery.isEmptyObject(events)) {
+ dataPriv.remove(elem, "handle events");
+ }
+ },
+ dispatch: function dispatch(nativeEvent) {
+ var i,
+ j,
+ ret,
+ matched,
+ handleObj,
+ handlerQueue,
+ args = new Array(arguments.length),
+ // Make a writable jQuery.Event from the native event object
+ event = jQuery.event.fix(nativeEvent),
+ handlers = (dataPriv.get(this, "events") || Object.create(null))[event.type] || [],
+ special = jQuery.event.special[event.type] || {}; // Use the fix-ed jQuery.Event rather than the (read-only) native event
+
+ args[0] = event;
+
+ for (i = 1; i < arguments.length; i++) {
+ args[i] = arguments[i];
+ }
+
+ event.delegateTarget = this; // Call the preDispatch hook for the mapped type, and let it bail if desired
+
+ if (special.preDispatch && special.preDispatch.call(this, event) === false) {
+ return;
+ } // Determine handlers
+
+
+ handlerQueue = jQuery.event.handlers.call(this, event, handlers); // Run delegates first; they may want to stop propagation beneath us
+
+ i = 0;
+
+ while ((matched = handlerQueue[i++]) && !event.isPropagationStopped()) {
+ event.currentTarget = matched.elem;
+ j = 0;
+
+ while ((handleObj = matched.handlers[j++]) && !event.isImmediatePropagationStopped()) {
+ // If the event is namespaced, then each handler is only invoked if it is
+ // specially universal or its namespaces are a superset of the event's.
+ if (!event.rnamespace || handleObj.namespace === false || event.rnamespace.test(handleObj.namespace)) {
+ event.handleObj = handleObj;
+ event.data = handleObj.data;
+ ret = ((jQuery.event.special[handleObj.origType] || {}).handle || handleObj.handler).apply(matched.elem, args);
+
+ if (ret !== undefined) {
+ if ((event.result = ret) === false) {
+ event.preventDefault();
+ event.stopPropagation();
+ }
+ }
+ }
+ }
+ } // Call the postDispatch hook for the mapped type
+
+
+ if (special.postDispatch) {
+ special.postDispatch.call(this, event);
+ }
+
+ return event.result;
+ },
+ handlers: function handlers(event, _handlers) {
+ var i,
+ handleObj,
+ sel,
+ matchedHandlers,
+ matchedSelectors,
+ handlerQueue = [],
+ delegateCount = _handlers.delegateCount,
+ cur = event.target; // Find delegate handlers
+
+ if (delegateCount && // Support: IE <=9
+ // Black-hole SVG instance trees (trac-13180)
+ cur.nodeType && // Support: Firefox <=42
+ // Suppress spec-violating clicks indicating a non-primary pointer button (trac-3861)
+ // https://www.w3.org/TR/DOM-Level-3-Events/#event-type-click
+ // Support: IE 11 only
+ // ...but not arrow key "clicks" of radio inputs, which can have `button` -1 (gh-2343)
+ !(event.type === "click" && event.button >= 1)) {
+ for (; cur !== this; cur = cur.parentNode || this) {
+ // Don't check non-elements (#13208)
+ // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)
+ if (cur.nodeType === 1 && !(event.type === "click" && cur.disabled === true)) {
+ matchedHandlers = [];
+ matchedSelectors = {};
+
+ for (i = 0; i < delegateCount; i++) {
+ handleObj = _handlers[i]; // Don't conflict with Object.prototype properties (#13203)
+
+ sel = handleObj.selector + " ";
+
+ if (matchedSelectors[sel] === undefined) {
+ matchedSelectors[sel] = handleObj.needsContext ? jQuery(sel, this).index(cur) > -1 : jQuery.find(sel, this, null, [cur]).length;
+ }
+
+ if (matchedSelectors[sel]) {
+ matchedHandlers.push(handleObj);
+ }
+ }
+
+ if (matchedHandlers.length) {
+ handlerQueue.push({
+ elem: cur,
+ handlers: matchedHandlers
+ });
+ }
+ }
+ }
+ } // Add the remaining (directly-bound) handlers
+
+
+ cur = this;
+
+ if (delegateCount < _handlers.length) {
+ handlerQueue.push({
+ elem: cur,
+ handlers: _handlers.slice(delegateCount)
+ });
+ }
+
+ return handlerQueue;
+ },
+ addProp: function addProp(name, hook) {
+ Object.defineProperty(jQuery.Event.prototype, name, {
+ enumerable: true,
+ configurable: true,
+ get: isFunction(hook) ? function () {
+ if (this.originalEvent) {
+ return hook(this.originalEvent);
+ }
+ } : function () {
+ if (this.originalEvent) {
+ return this.originalEvent[name];
+ }
+ },
+ set: function set(value) {
+ Object.defineProperty(this, name, {
+ enumerable: true,
+ configurable: true,
+ writable: true,
+ value: value
+ });
+ }
+ });
+ },
+ fix: function fix(originalEvent) {
+ return originalEvent[jQuery.expando] ? originalEvent : new jQuery.Event(originalEvent);
+ },
+ special: {
+ load: {
+ // Prevent triggered image.load events from bubbling to window.load
+ noBubble: true
+ },
+ click: {
+ // Utilize native event to ensure correct state for checkable inputs
+ setup: function setup(data) {
+ // For mutual compressibility with _default, replace `this` access with a local var.
+ // `|| data` is dead code meant only to preserve the variable through minification.
+ var el = this || data; // Claim the first handler
+
+ if (rcheckableType.test(el.type) && el.click && nodeName(el, "input")) {
+ // dataPriv.set( el, "click", ... )
+ leverageNative(el, "click", returnTrue);
+ } // Return false to allow normal processing in the caller
+
+
+ return false;
+ },
+ trigger: function trigger(data) {
+ // For mutual compressibility with _default, replace `this` access with a local var.
+ // `|| data` is dead code meant only to preserve the variable through minification.
+ var el = this || data; // Force setup before triggering a click
+
+ if (rcheckableType.test(el.type) && el.click && nodeName(el, "input")) {
+ leverageNative(el, "click");
+ } // Return non-false to allow normal event-path propagation
+
+
+ return true;
+ },
+ // For cross-browser consistency, suppress native .click() on links
+ // Also prevent it if we're currently inside a leveraged native-event stack
+ _default: function _default(event) {
+ var target = event.target;
+ return rcheckableType.test(target.type) && target.click && nodeName(target, "input") && dataPriv.get(target, "click") || nodeName(target, "a");
+ }
+ },
+ beforeunload: {
+ postDispatch: function postDispatch(event) {
+ // Support: Firefox 20+
+ // Firefox doesn't alert if the returnValue field is not set.
+ if (event.result !== undefined && event.originalEvent) {
+ event.originalEvent.returnValue = event.result;
+ }
+ }
+ }
+ }
+ }; // Ensure the presence of an event listener that handles manually-triggered
+ // synthetic events by interrupting progress until reinvoked in response to
+ // *native* events that it fires directly, ensuring that state changes have
+ // already occurred before other listeners are invoked.
+
+ function leverageNative(el, type, expectSync) {
+ // Missing expectSync indicates a trigger call, which must force setup through jQuery.event.add
+ if (!expectSync) {
+ if (dataPriv.get(el, type) === undefined) {
+ jQuery.event.add(el, type, returnTrue);
+ }
+
+ return;
+ } // Register the controller as a special universal handler for all event namespaces
+
+
+ dataPriv.set(el, type, false);
+ jQuery.event.add(el, type, {
+ namespace: false,
+ handler: function handler(event) {
+ var notAsync,
+ result,
+ saved = dataPriv.get(this, type);
+
+ if (event.isTrigger & 1 && this[type]) {
+ // Interrupt processing of the outer synthetic .trigger()ed event
+ // Saved data should be false in such cases, but might be a leftover capture object
+ // from an async native handler (gh-4350)
+ if (!saved.length) {
+ // Store arguments for use when handling the inner native event
+ // There will always be at least one argument (an event object), so this array
+ // will not be confused with a leftover capture object.
+ saved = _slice.call(arguments);
+ dataPriv.set(this, type, saved); // Trigger the native event and capture its result
+ // Support: IE <=9 - 11+
+ // focus() and blur() are asynchronous
+
+ notAsync = expectSync(this, type);
+ this[type]();
+ result = dataPriv.get(this, type);
+
+ if (saved !== result || notAsync) {
+ dataPriv.set(this, type, false);
+ } else {
+ result = {};
+ }
+
+ if (saved !== result) {
+ // Cancel the outer synthetic event
+ event.stopImmediatePropagation();
+ event.preventDefault();
+ return result.value;
+ } // If this is an inner synthetic event for an event with a bubbling surrogate
+ // (focus or blur), assume that the surrogate already propagated from triggering the
+ // native event and prevent that from happening again here.
+ // This technically gets the ordering wrong w.r.t. to `.trigger()` (in which the
+ // bubbling surrogate propagates *after* the non-bubbling base), but that seems
+ // less bad than duplication.
+
+ } else if ((jQuery.event.special[type] || {}).delegateType) {
+ event.stopPropagation();
+ } // If this is a native event triggered above, everything is now in order
+ // Fire an inner synthetic event with the original arguments
+
+ } else if (saved.length) {
+ // ...and capture the result
+ dataPriv.set(this, type, {
+ value: jQuery.event.trigger( // Support: IE <=9 - 11+
+ // Extend with the prototype to reset the above stopImmediatePropagation()
+ jQuery.extend(saved[0], jQuery.Event.prototype), saved.slice(1), this)
+ }); // Abort handling of the native event
+
+ event.stopImmediatePropagation();
+ }
+ }
+ });
+ }
+
+ jQuery.removeEvent = function (elem, type, handle) {
+ // This "if" is needed for plain objects
+ if (elem.removeEventListener) {
+ elem.removeEventListener(type, handle);
+ }
+ };
+
+ jQuery.Event = function (src, props) {
+ // Allow instantiation without the 'new' keyword
+ if (!(this instanceof jQuery.Event)) {
+ return new jQuery.Event(src, props);
+ } // Event object
+
+
+ if (src && src.type) {
+ this.originalEvent = src;
+ this.type = src.type; // Events bubbling up the document may have been marked as prevented
+ // by a handler lower down the tree; reflect the correct value.
+
+ this.isDefaultPrevented = src.defaultPrevented || src.defaultPrevented === undefined && // Support: Android <=2.3 only
+ src.returnValue === false ? returnTrue : returnFalse; // Create target properties
+ // Support: Safari <=6 - 7 only
+ // Target should not be a text node (#504, #13143)
+
+ this.target = src.target && src.target.nodeType === 3 ? src.target.parentNode : src.target;
+ this.currentTarget = src.currentTarget;
+ this.relatedTarget = src.relatedTarget; // Event type
+ } else {
+ this.type = src;
+ } // Put explicitly provided properties onto the event object
+
+
+ if (props) {
+ jQuery.extend(this, props);
+ } // Create a timestamp if incoming event doesn't have one
+
+
+ this.timeStamp = src && src.timeStamp || Date.now(); // Mark it as fixed
+
+ this[jQuery.expando] = true;
+ }; // jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
+ // https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
+
+
+ jQuery.Event.prototype = {
+ constructor: jQuery.Event,
+ isDefaultPrevented: returnFalse,
+ isPropagationStopped: returnFalse,
+ isImmediatePropagationStopped: returnFalse,
+ isSimulated: false,
+ preventDefault: function preventDefault() {
+ var e = this.originalEvent;
+ this.isDefaultPrevented = returnTrue;
+
+ if (e && !this.isSimulated) {
+ e.preventDefault();
+ }
+ },
+ stopPropagation: function stopPropagation() {
+ var e = this.originalEvent;
+ this.isPropagationStopped = returnTrue;
+
+ if (e && !this.isSimulated) {
+ e.stopPropagation();
+ }
+ },
+ stopImmediatePropagation: function stopImmediatePropagation() {
+ var e = this.originalEvent;
+ this.isImmediatePropagationStopped = returnTrue;
+
+ if (e && !this.isSimulated) {
+ e.stopImmediatePropagation();
+ }
+
+ this.stopPropagation();
+ }
+ }; // Includes all common event props including KeyEvent and MouseEvent specific props
+
+ jQuery.each({
+ altKey: true,
+ bubbles: true,
+ cancelable: true,
+ changedTouches: true,
+ ctrlKey: true,
+ detail: true,
+ eventPhase: true,
+ metaKey: true,
+ pageX: true,
+ pageY: true,
+ shiftKey: true,
+ view: true,
+ "char": true,
+ code: true,
+ charCode: true,
+ key: true,
+ keyCode: true,
+ button: true,
+ buttons: true,
+ clientX: true,
+ clientY: true,
+ offsetX: true,
+ offsetY: true,
+ pointerId: true,
+ pointerType: true,
+ screenX: true,
+ screenY: true,
+ targetTouches: true,
+ toElement: true,
+ touches: true,
+ which: function which(event) {
+ var button = event.button; // Add which for key events
+
+ if (event.which == null && rkeyEvent.test(event.type)) {
+ return event.charCode != null ? event.charCode : event.keyCode;
+ } // Add which for click: 1 === left; 2 === middle; 3 === right
+
+
+ if (!event.which && button !== undefined && rmouseEvent.test(event.type)) {
+ if (button & 1) {
+ return 1;
+ }
+
+ if (button & 2) {
+ return 3;
+ }
+
+ if (button & 4) {
+ return 2;
+ }
+
+ return 0;
+ }
+
+ return event.which;
+ }
+ }, jQuery.event.addProp);
+ jQuery.each({
+ focus: "focusin",
+ blur: "focusout"
+ }, function (type, delegateType) {
+ jQuery.event.special[type] = {
+ // Utilize native event if possible so blur/focus sequence is correct
+ setup: function setup() {
+ // Claim the first handler
+ // dataPriv.set( this, "focus", ... )
+ // dataPriv.set( this, "blur", ... )
+ leverageNative(this, type, expectSync); // Return false to allow normal processing in the caller
+
+ return false;
+ },
+ trigger: function trigger() {
+ // Force setup before trigger
+ leverageNative(this, type); // Return non-false to allow normal event-path propagation
+
+ return true;
+ },
+ delegateType: delegateType
+ };
+ }); // Create mouseenter/leave events using mouseover/out and event-time checks
+ // so that event delegation works in jQuery.
+ // Do the same for pointerenter/pointerleave and pointerover/pointerout
+ //
+ // Support: Safari 7 only
+ // Safari sends mouseenter too often; see:
+ // https://bugs.chromium.org/p/chromium/issues/detail?id=470258
+ // for the description of the bug (it existed in older Chrome versions as well).
+
+ jQuery.each({
+ mouseenter: "mouseover",
+ mouseleave: "mouseout",
+ pointerenter: "pointerover",
+ pointerleave: "pointerout"
+ }, function (orig, fix) {
+ jQuery.event.special[orig] = {
+ delegateType: fix,
+ bindType: fix,
+ handle: function handle(event) {
+ var ret,
+ target = this,
+ related = event.relatedTarget,
+ handleObj = event.handleObj; // For mouseenter/leave call the handler if related is outside the target.
+ // NB: No relatedTarget if the mouse left/entered the browser window
+
+ if (!related || related !== target && !jQuery.contains(target, related)) {
+ event.type = handleObj.origType;
+ ret = handleObj.handler.apply(this, arguments);
+ event.type = fix;
+ }
+
+ return ret;
+ }
+ };
+ });
+ jQuery.fn.extend({
+ on: function on(types, selector, data, fn) {
+ return _on(this, types, selector, data, fn);
+ },
+ one: function one(types, selector, data, fn) {
+ return _on(this, types, selector, data, fn, 1);
+ },
+ off: function off(types, selector, fn) {
+ var handleObj, type;
+
+ if (types && types.preventDefault && types.handleObj) {
+ // ( event ) dispatched jQuery.Event
+ handleObj = types.handleObj;
+ jQuery(types.delegateTarget).off(handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType, handleObj.selector, handleObj.handler);
+ return this;
+ }
+
+ if (_typeof(types) === "object") {
+ // ( types-object [, selector] )
+ for (type in types) {
+ this.off(type, selector, types[type]);
+ }
+
+ return this;
+ }
+
+ if (selector === false || typeof selector === "function") {
+ // ( types [, fn] )
+ fn = selector;
+ selector = undefined;
+ }
+
+ if (fn === false) {
+ fn = returnFalse;
+ }
+
+ return this.each(function () {
+ jQuery.event.remove(this, types, fn, selector);
+ });
+ }
+ });
+ var // Support: IE <=10 - 11, Edge 12 - 13 only
+ // In IE/Edge using regex groups here causes severe slowdowns.
+ // See https://connect.microsoft.com/IE/feedback/details/1736512/
+ rnoInnerhtml = /