diff --git a/CHANGELOG.md b/CHANGELOG.md index 07005e513d9..cd6d607ed77 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -48,6 +48,14 @@ More information is available in the [VersionCake README](https://github.com/bwillis/versioncake) +* Bootstrap 4.0.0-alpha.2 is included into the admin. + +* Pagination now uses an admin-specific kaminari theme, which uses the + bootstrap4 styles. If you have a custom admin page with pagination you can + use this style with the following. + + <%= paginate @collection, theme: "solidus_admin" %> + ## Solidus 1.2.0 (2016-01-26) * Admin menu has been moved from top of the page to the left side. diff --git a/backend/app/assets/javascripts/spree/backend.js b/backend/app/assets/javascripts/spree/backend.js index 8d21d3b9678..66edd0b1b52 100644 --- a/backend/app/assets/javascripts/spree/backend.js +++ b/backend/app/assets/javascripts/spree/backend.js @@ -9,6 +9,8 @@ //= require jquery.sticky-kit.min //= require underscore-min //= require backbone +//= require solidus_admin/tether +//= require solidus_admin/bootstrap //= require prism //= require spree //= require ./backend/backbone-overrides diff --git a/backend/app/assets/stylesheets/spree/backend/_bootstrap_custom.scss b/backend/app/assets/stylesheets/spree/backend/_bootstrap_custom.scss new file mode 100644 index 00000000000..3e872fa3484 --- /dev/null +++ b/backend/app/assets/stylesheets/spree/backend/_bootstrap_custom.scss @@ -0,0 +1,666 @@ +// Variables +// +// Copy settings from this file into the provided `_custom.scss` to override +// the Bootstrap defaults without modifying key, versioned files. + + +// Table of Contents +// +// Colors +// Options +// Spacing +// Body +// Links +// Grid breakpoints +// Grid containers +// Grid columns +// Fonts +// Components + +// General variable structure +// +// Variable format should follow the `$component-modifier-state-property` order. + + +// Colors +// +// Grayscale and brand colors for use across Bootstrap. + +$gray-dark: #373a3c !default; +$gray: #55595c !default; +$gray-light: #818a91 !default; +$gray-lighter: #eceeef !default; +$gray-lightest: #f7f7f9 !default; + +$brand-primary: $color-3 !default; +$brand-success: $color-2 !default; +$brand-info: #5bc0de !default; +$brand-warning: $color-6 !default; +$brand-danger: $color-5 !default; + + +// Options +// +// Quickly modify global styling by enabling or disabling optional features. + +$enable-flex: true !default; +$enable-rounded: true !default; +$enable-shadows: false !default; +$enable-gradients: false !default; +$enable-transitions: false !default; +$enable-hover-media-query: false !default; +$enable-grid-classes: false !default; + + +// Spacing +// +// Control the default styling of most Bootstrap elements by modifying these +// variables. Mostly focused on spacing. + +$spacer: 1rem !default; +$spacer-x: $spacer !default; +$spacer-y: $spacer !default; +$spacers: ( + 0: ( + x: 0, + y: 0 + ), + 1: ( + x: $spacer-x, + y: $spacer-y + ), + 2: ( + x: ($spacer-x * 1.5), + y: ($spacer-y * 1.5) + ), + 3: ( + x: ($spacer-x * 3), + y: ($spacer-y * 3) + ) +) !default; +$border-width: 1px !default; + + +// Body +// +// Settings for the `` element. + +$body-bg: #fff !default; +$body-color: $gray-dark !default; + + +// Links +// +// Style anchor elements. + +$link-color: $brand-primary !default; +$link-decoration: none !default; +$link-hover-color: darken($link-color, 15%) !default; +$link-hover-decoration: underline !default; + + +// Grid breakpoints +// +// Define the minimum and maximum dimensions at which your layout will change, +// adapting to different screen sizes, for use in media queries. + +$grid-breakpoints: ( + // Extra small screen / phone + xs: 0, + // Small screen / phone + sm: 544px, + // Medium screen / tablet + md: 768px, + // Large screen / desktop + lg: 992px, + // Extra large screen / wide desktop + xl: 1200px +) !default; + + +// Grid containers +// +// Define the maximum width of `.container` for different screen sizes. + +$container-max-widths: ( + sm: 576px, + md: 720px, + lg: 960px, /* Changed to 960 from 940 to avoid fighting with skeleton */ + xl: 1140px +) !default; + + +// Grid columns +// +// Set the number of columns and specify the width of the gutters. + +$grid-columns: 12 !default; +$grid-gutter-width: 1.875rem !default; // 30px + + +// Typography +// +// Font, line-height, and color for body text, headings, and more. + +$font-family-sans-serif: "Helvetica Neue", Helvetica, Arial, sans-serif !default; +$font-family-serif: Georgia, "Times New Roman", Times, serif !default; +$font-family-monospace: Menlo, Monaco, Consolas, "Courier New", monospace !default; +$font-family-base: $font-family-sans-serif !default; + +// Pixel value used to responsively scale all typography. Applied to the `` element. +$font-size-root: 16px !default; + +$font-size-base: 1rem !default; +$font-size-lg: 1.25rem !default; +$font-size-sm: .875rem !default; +$font-size-xs: .75rem !default; + +$font-size-h1: 2.5rem !default; +$font-size-h2: 2rem !default; +$font-size-h3: 1.75rem !default; +$font-size-h4: 1.5rem !default; +$font-size-h5: 1.25rem !default; +$font-size-h6: 1rem !default; + +$display1-size: 6rem !default; +$display2-size: 5.5rem !default; +$display3-size: 4.5rem !default; +$display4-size: 3.5rem !default; + +$display1-weight: 300 !default; +$display2-weight: 300 !default; +$display3-weight: 300 !default; +$display4-weight: 300 !default; + +$line-height: 1.5 !default; + +$headings-margin-bottom: ($spacer / 2) !default; +$headings-font-family: inherit !default; +$headings-font-weight: 500 !default; +$headings-line-height: 1.1 !default; +$headings-color: inherit !default; + +$lead-font-size: 1.25rem !default; +$lead-font-weight: 300 !default; + +$text-muted: $gray-light !default; + +$abbr-border-color: $gray-light !default; + +$blockquote-small-color: $gray-light !default; +$blockquote-font-size: ($font-size-base * 1.25) !default; +$blockquote-border-color: $gray-lighter !default; + +$hr-border-color: rgba(0,0,0,.1) !default; +$hr-border-width: $border-width !default; + +$dt-font-weight: bold !default; + +$nested-kbd-font-weight: bold !default; + +$list-inline-padding: 5px !default; + + +// Components +// +// Define common padding and border radius sizes and more. + +$line-height-lg: (4 / 3) !default; +$line-height-sm: 1.5 !default; + +$border-radius: .25rem !default; +$border-radius-lg: .3rem !default; +$border-radius-sm: .2rem !default; + +$component-active-color: #fff !default; +$component-active-bg: $brand-primary !default; + +$caret-width: .3em !default; +$caret-width-lg: $caret-width !default; + + +// Tables +// +// Customizes the `.table` component with basic values, each used across all table variations. + +$table-cell-padding: .75rem !default; +$table-sm-cell-padding: .3rem !default; + +$table-bg: transparent !default; +$table-bg-accent: #f9f9f9 !default; +$table-bg-hover: #f5f5f5 !default; +$table-bg-active: $table-bg-hover !default; + +$table-border-width: $border-width !default; +$table-border-color: $gray-lighter !default; + + +// Buttons +// +// For each of Bootstrap's buttons, define text, background and border color. + +$btn-padding-x: 1rem !default; +$btn-padding-y: .375rem !default; +$btn-font-weight: normal !default; + +$btn-primary-color: #fff !default; +$btn-primary-bg: $brand-primary !default; +$btn-primary-border: $btn-primary-bg !default; + +$btn-secondary-color: $gray-dark !default; +$btn-secondary-bg: #fff !default; +$btn-secondary-border: #ccc !default; + +$btn-info-color: #fff !default; +$btn-info-bg: $brand-info !default; +$btn-info-border: $btn-info-bg !default; + +$btn-success-color: #fff !default; +$btn-success-bg: $brand-success !default; +$btn-success-border: $btn-success-bg !default; + +$btn-warning-color: #fff !default; +$btn-warning-bg: $brand-warning !default; +$btn-warning-border: $btn-warning-bg !default; + +$btn-danger-color: #fff !default; +$btn-danger-bg: $brand-danger !default; +$btn-danger-border: $btn-danger-bg !default; + +$btn-link-disabled-color: $gray-light !default; + +$btn-padding-x-sm: .75rem !default; +$btn-padding-y-sm: .25rem !default; + +$btn-padding-x-lg: 1.25rem !default; +$btn-padding-y-lg: .75rem !default; + +// Allows for customizing button radius independently from global border radius +$btn-border-radius: $border-radius !default; +$btn-border-radius-lg: $border-radius-lg !default; +$btn-border-radius-sm: $border-radius-sm !default; + + +// Forms + +$input-padding-x: .75rem !default; +$input-padding-y: .375rem !default; + +$input-bg: #fff !default; +$input-bg-disabled: $gray-lighter !default; + +$input-color: $gray !default; +$input-border-color: #ccc !default; +$input-btn-border-width: $border-width !default; // For form controls and buttons +$input-box-shadow: inset 0 1px 1px rgba(0,0,0,.075) !default; + +$input-border-radius: $border-radius !default; +$input-border-radius-lg: $border-radius-lg !default; +$input-border-radius-sm: $border-radius-sm !default; + +$input-border-focus: #66afe9 !default; +$input-box-shadow-focus: rgba(102,175,233,.6) !default; + +$input-color-placeholder: #999 !default; + +$input-padding-x-sm: .75rem !default; +$input-padding-y-sm: .275rem !default; + +$input-padding-x-lg: 1.25rem !default; +$input-padding-y-lg: .75rem !default; + +$input-height: (($font-size-base * $line-height) + ($input-padding-y * 2)) !default; +$input-height-lg: (($font-size-lg * $line-height-lg) + ($input-padding-y-lg * 2)) !default; +$input-height-sm: (($font-size-sm * $line-height-sm) + ($input-padding-y-sm * 2)) !default; + +$form-group-margin-bottom: $spacer-y !default; + +$input-group-addon-bg: $gray-lighter !default; +$input-group-addon-border-color: $input-border-color !default; + +$cursor-disabled: not-allowed !default; + +// Form validation icons +$form-icon-success: "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA2MTIgNzkyIj48cGF0aCBmaWxsPSIjNWNiODVjIiBkPSJNMjMzLjggNjEwYy0xMy4zIDAtMjYtNi0zNC0xNi44TDkwLjUgNDQ4LjhDNzYuMyA0MzAgODAgNDAzLjMgOTguOCAzODljMTguOC0xNC4yIDQ1LjUtMTAuNCA1OS44IDguNGw3MiA5NUw0NTEuMyAyNDJjMTIuNS0yMCAzOC44LTI2LjIgNTguOC0xMy43IDIwIDEyLjQgMjYgMzguNyAxMy43IDU4LjhMMjcwIDU5MGMtNy40IDEyLTIwLjIgMTkuNC0zNC4zIDIwaC0yeiIvPjwvc3ZnPg==" !default; +$form-icon-warning: "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA2MTIgNzkyIj48cGF0aCBmaWxsPSIjZjBhZDRlIiBkPSJNNjAzIDY0MC4ybC0yNzguNS01MDljLTMuOC02LjYtMTAuOC0xMC42LTE4LjUtMTAuNnMtMTQuNyA0LTE4LjUgMTAuNkw5IDY0MC4yYy0zLjcgNi41LTMuNiAxNC40LjIgMjAuOCAzLjggNi41IDEwLjggMTAuNCAxOC4zIDEwLjRoNTU3YzcuNiAwIDE0LjYtNCAxOC40LTEwLjQgMy41LTYuNCAzLjYtMTQuNCAwLTIwLjh6bS0yNjYuNC0zMGgtNjEuMlY1NDloNjEuMnY2MS4yem0wLTEwN2gtNjEuMlYzMDRoNjEuMnYxOTl6Ii8+PC9zdmc+" !default; +$form-icon-danger: "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA2MTIgNzkyIj48cGF0aCBmaWxsPSIjZDk1MzRmIiBkPSJNNDQ3IDU0NC40Yy0xNC40IDE0LjQtMzcuNiAxNC40LTUyIDBsLTg5LTkyLjctODkgOTIuN2MtMTQuNSAxNC40LTM3LjcgMTQuNC01MiAwLTE0LjQtMTQuNC0xNC40LTM3LjYgMC01Mmw5Mi40LTk2LjMtOTIuNC05Ni4zYy0xNC40LTE0LjQtMTQuNC0zNy42IDAtNTJzMzcuNi0xNC4zIDUyIDBsODkgOTIuOCA4OS4yLTkyLjdjMTQuNC0xNC40IDM3LjYtMTQuNCA1MiAwIDE0LjMgMTQuNCAxNC4zIDM3LjYgMCA1MkwzNTQuNiAzOTZsOTIuNCA5Ni40YzE0LjQgMTQuNCAxNC40IDM3LjYgMCA1MnoiLz48L3N2Zz4=" !default; + + +// Dropdowns +// +// Dropdown menu container and contents. + +$dropdown-bg: #fff !default; +$dropdown-border-color: rgba(0,0,0,.15) !default; +$dropdown-border-width: $border-width !default; +$dropdown-divider-bg: #e5e5e5 !default; + +$dropdown-link-color: $gray-dark !default; +$dropdown-link-hover-color: darken($gray-dark, 5%) !default; +$dropdown-link-hover-bg: #f5f5f5 !default; + +$dropdown-link-active-color: $component-active-color !default; +$dropdown-link-active-bg: $component-active-bg !default; + +$dropdown-link-disabled-color: $gray-light !default; + +$dropdown-header-color: $gray-light !default; + + +// Z-index master list +// +// Warning: Avoid customizing these values. They're used for a bird's eye view +// of components dependent on the z-axis and are designed to all work together. + +$zindex-navbar: 1000 !default; +$zindex-dropdown: 1000 !default; +$zindex-popover: 1060 !default; +$zindex-tooltip: 1070 !default; +$zindex-navbar-fixed: 1030 !default; +$zindex-navbar-sticky: 1030 !default; +$zindex-modal-bg: 1040 !default; +$zindex-modal: 1050 !default; + + +// Navbar + +$navbar-border-radius: $border-radius !default; +$navbar-padding-horizontal: $spacer !default; +$navbar-padding-vertical: ($spacer / 2) !default; + +$navbar-dark-color: rgba(255,255,255,.5) !default; +$navbar-dark-hover-color: rgba(255,255,255,.75) !default; +$navbar-dark-active-color: rgba(255,255,255,1) !default; +$navbar-dark-disabled-color: rgba(255,255,255,.25) !default; + +$navbar-light-color: rgba(0,0,0,.3) !default; +$navbar-light-hover-color: rgba(0,0,0,.6) !default; +$navbar-light-active-color: rgba(0,0,0,.8) !default; +$navbar-light-disabled-color: rgba(0,0,0,.15) !default; + + +// Navs + +$nav-link-padding: .5em 1em !default; +$nav-link-hover-bg: $gray-lighter !default; + +$nav-disabled-link-color: $gray-light !default; +$nav-disabled-link-hover-color: $gray-light !default; + +$nav-tabs-border-color: #ddd !default; + +$nav-tabs-link-border-width: $border-width !default; +$nav-tabs-link-hover-border-color: $gray-lighter !default; + +$nav-tabs-active-link-hover-bg: $body-bg !default; +$nav-tabs-active-link-hover-color: $gray !default; +$nav-tabs-active-link-hover-border-color: #ddd !default; + +$nav-tabs-justified-link-border-color: #ddd !default; +$nav-tabs-justified-active-link-border-color: $body-bg !default; + +$nav-pills-border-radius: $border-radius !default; +$nav-pills-active-link-hover-bg: $component-active-bg !default; +$nav-pills-active-link-hover-color: $component-active-color !default; + + +// Pagination + +$pagination-padding-x: .75rem !default; +$pagination-padding-y: .5rem !default; +$pagination-padding-x-sm: .75rem !default; +$pagination-padding-y-sm: .275rem !default; +$pagination-padding-x-lg: 1.5rem !default; +$pagination-padding-y-lg: .75rem !default; + + +$pagination-color: $link-color !default; +$pagination-bg: #fff !default; +$pagination-border-width: $border-width !default; +$pagination-border-color: #ddd !default; + +$pagination-hover-color: $link-hover-color !default; +$pagination-hover-bg: $gray-lighter !default; +$pagination-hover-border: #ddd !default; + +$pagination-active-color: #fff !default; +$pagination-active-bg: $brand-primary !default; +$pagination-active-border: $brand-primary !default; + +$pagination-disabled-color: $gray-light !default; +$pagination-disabled-bg: #fff !default; +$pagination-disabled-border: #ddd !default; + + +// Pager + +$pager-bg: $pagination-bg !default; +$pager-border-width: $border-width !default; +$pager-border-color: $pagination-border-color !default; +$pager-border-radius: 15px !default; + +$pager-hover-bg: $pagination-hover-bg !default; + +$pager-active-bg: $pagination-active-bg !default; +$pager-active-color: $pagination-active-color !default; + +$pager-disabled-color: $pagination-disabled-color !default; + + +// Jumbotron + +$jumbotron-padding: 2rem !default; +$jumbotron-bg: $gray-lighter !default; + + +// Form states and alerts +// +// Define colors for form feedback states and, by default, alerts. + +$state-success-text: #3c763d !default; +$state-success-bg: #dff0d8 !default; +$state-success-border: darken($state-success-bg, 5%) !default; + +$state-info-text: #31708f !default; +$state-info-bg: #d9edf7 !default; +$state-info-border: darken($state-info-bg, 7%) !default; + +$state-warning-text: #8a6d3b !default; +$state-warning-bg: #fcf8e3 !default; +$state-warning-border: darken($state-warning-bg, 5%) !default; + +$state-danger-text: #a94442 !default; +$state-danger-bg: #f2dede !default; +$state-danger-border: darken($state-danger-bg, 5%) !default; + + +// Cards +$card-spacer-x: 1.25rem !default; +$card-spacer-y: .75rem !default; +$card-border-width: 1px !default; +$card-border-radius: $border-radius !default; +$card-border-color: #e5e5e5 !default; +$card-border-radius-inner: $card-border-radius !default; +$card-cap-bg: #f5f5f5 !default; +$card-bg: #fff !default; + +$card-link-hover-color: #fff !default; + + +// Tooltips + +$tooltip-max-width: 200px !default; +$tooltip-color: #fff !default; +$tooltip-bg: #000 !default; +$tooltip-opacity: .9 !default; + +$tooltip-arrow-width: 5px !default; +$tooltip-arrow-color: $tooltip-bg !default; + + +// Popovers + +$popover-bg: #fff !default; +$popover-max-width: 276px !default; +$popover-border-width: $border-width !default; +$popover-border-color: rgba(0,0,0,.2) !default; + +$popover-title-bg: darken($popover-bg, 3%) !default; + +$popover-arrow-width: 10px !default; +$popover-arrow-color: $popover-bg !default; + +$popover-arrow-outer-width: ($popover-arrow-width + 1) !default; +$popover-arrow-outer-color: fade-in($popover-border-color, 0.05) !default; + + +// Labels + +$label-default-bg: $gray-light !default; +$label-primary-bg: $brand-primary !default; +$label-success-bg: $brand-success !default; +$label-info-bg: $brand-info !default; +$label-warning-bg: $brand-warning !default; +$label-danger-bg: $brand-danger !default; + +$label-color: #fff !default; +$label-link-hover-color: #fff !default; +$label-font-weight: bold !default; + + +// Modals + +// Padding applied to the modal body +$modal-inner-padding: 15px !default; + +$modal-title-padding: 15px !default; +$modal-title-line-height: $line-height !default; + +$modal-content-bg: #fff !default; +$modal-content-border-color: rgba(0,0,0,.2) !default; + +$modal-backdrop-bg: #000 !default; +$modal-backdrop-opacity: .5 !default; +$modal-header-border-color: #e5e5e5 !default; +$modal-footer-border-color: $modal-header-border-color !default; + +$modal-lg: 900px !default; +$modal-md: 600px !default; +$modal-sm: 300px !default; + + +// Alerts +// +// Define alert colors, border radius, and padding. + +$alert-padding: 15px !default; +$alert-border-radius: $border-radius !default; +$alert-link-font-weight: bold !default; +$alert-border-width: $border-width !default; + +$alert-success-bg: $state-success-bg !default; +$alert-success-text: $state-success-text !default; +$alert-success-border: $state-success-border !default; + +$alert-info-bg: $state-info-bg !default; +$alert-info-text: $state-info-text !default; +$alert-info-border: $state-info-border !default; + +$alert-warning-bg: $state-warning-bg !default; +$alert-warning-text: $state-warning-text !default; +$alert-warning-border: $state-warning-border !default; + +$alert-danger-bg: $state-danger-bg !default; +$alert-danger-text: $state-danger-text !default; +$alert-danger-border: $state-danger-border !default; + + +// Progress bars + +$progress-bg: #f5f5f5 !default; +$progress-bar-color: #fff !default; +$progress-border-radius: $border-radius !default; + +$progress-bar-bg: $brand-primary !default; +$progress-bar-success-bg: $brand-success !default; +$progress-bar-warning-bg: $brand-warning !default; +$progress-bar-danger-bg: $brand-danger !default; +$progress-bar-info-bg: $brand-info !default; + + +// List group + +$list-group-bg: #fff !default; +$list-group-border-color: #ddd !default; +$list-group-border-width: $border-width !default; +$list-group-border-radius: $border-radius !default; + +$list-group-hover-bg: #f5f5f5 !default; +$list-group-active-color: $component-active-color !default; +$list-group-active-bg: $component-active-bg !default; +$list-group-active-border: $list-group-active-bg !default; +$list-group-active-text-color: lighten($list-group-active-bg, 40%) !default; + +$list-group-disabled-color: $gray-light !default; +$list-group-disabled-bg: $gray-lighter !default; +$list-group-disabled-text-color: $list-group-disabled-color !default; + +$list-group-link-color: #555 !default; +$list-group-link-hover-color: $list-group-link-color !default; +$list-group-link-heading-color: #333 !default; + + +// Image thumbnails + +$thumbnail-padding: .25rem !default; +$thumbnail-bg: $body-bg !default; +$thumbnail-border-width: $border-width !default; +$thumbnail-border-color: #ddd !default; +$thumbnail-border-radius: $border-radius !default; + + +// Breadcrumbs + +$breadcrumb-padding-vertical: .75rem !default; +$breadcrumb-padding-horizontal: 1rem !default; + +$breadcrumb-bg: $gray-lighter !default; +$breadcrumb-divider-color: $gray-light !default; +$breadcrumb-active-color: $gray-light !default; +$breadcrumb-divider: "/" !default; + + +// Carousel + +$carousel-text-shadow: 0 1px 2px rgba(0,0,0,.6) !default; + +$carousel-control-color: #fff !default; +$carousel-control-width: 15% !default; +$carousel-control-opacity: .5 !default; +$carousel-control-font-size: 20px !default; + +$carousel-indicator-active-bg: #fff !default; +$carousel-indicator-border-color: #fff !default; + +$carousel-caption-color: #fff !default; + + +// Close + +$close-font-weight: bold !default; +$close-color: #000 !default; +$close-text-shadow: 0 1px 0 #fff !default; + + +// Code + +$code-color: #bd4147 !default; +$code-bg: #f7f7f9 !default; + +$kbd-color: #fff !default; +$kbd-bg: #333 !default; + +$pre-bg: #f7f7f9 !default; +$pre-color: $gray-dark !default; +$pre-border-color: #ccc !default; +$pre-scrollable-max-height: 340px !default; diff --git a/backend/app/assets/stylesheets/spree/backend/components/_pagination.scss b/backend/app/assets/stylesheets/spree/backend/components/_pagination.scss deleted file mode 100644 index aba1cb09a81..00000000000 --- a/backend/app/assets/stylesheets/spree/backend/components/_pagination.scss +++ /dev/null @@ -1,17 +0,0 @@ -.pagination { - padding: 10px 0; - text-align: center; - - .page { - padding: 5px 8px; - text-align: center; - display: inline-block; - text-align: center; - - &.current { - background-color: $color-2; - border-radius: 3px; - color: $color-1; - } - } -} \ No newline at end of file diff --git a/backend/app/assets/stylesheets/spree/backend/shared/_forms.scss b/backend/app/assets/stylesheets/spree/backend/shared/_forms.scss index 68aea4c7fd3..9d7a3561f9d 100644 --- a/backend/app/assets/stylesheets/spree/backend/shared/_forms.scss +++ b/backend/app/assets/stylesheets/spree/backend/shared/_forms.scss @@ -231,6 +231,7 @@ fieldset { text-transform: uppercase; text-align: center; padding: 8px 15px; + width: auto; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; diff --git a/backend/app/assets/stylesheets/spree/backend/shared/_layout.scss b/backend/app/assets/stylesheets/spree/backend/shared/_layout.scss index ca7a1122995..a9c74315a15 100644 --- a/backend/app/assets/stylesheets/spree/backend/shared/_layout.scss +++ b/backend/app/assets/stylesheets/spree/backend/shared/_layout.scss @@ -109,6 +109,7 @@ body { .page-title { font-size: 20px; + margin: 0.67em 0; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; diff --git a/backend/app/assets/stylesheets/spree/backend/shared/_tables.scss b/backend/app/assets/stylesheets/spree/backend/shared/_tables.scss index f4e607bee1b..ac191fcd1f8 100644 --- a/backend/app/assets/stylesheets/spree/backend/shared/_tables.scss +++ b/backend/app/assets/stylesheets/spree/backend/shared/_tables.scss @@ -53,6 +53,7 @@ table { &:before { text-align: center !important; + padding: 0; width: 27px; display: inline-block; } @@ -134,6 +135,7 @@ table { border-bottom: none; background-color: $color-tbl-thead; text-transform: uppercase; + text-align: center; font-size: 85%; font-weight: $font-weight-bold; } diff --git a/backend/app/assets/stylesheets/spree/backend/shared/_typography.scss b/backend/app/assets/stylesheets/spree/backend/shared/_typography.scss index b54d0e8b677..753e03c6848 100644 --- a/backend/app/assets/stylesheets/spree/backend/shared/_typography.scss +++ b/backend/app/assets/stylesheets/spree/backend/shared/_typography.scss @@ -27,6 +27,9 @@ a { text-decoration: none; line-height: inherit; + &:active, &:hover { + text-decoration: none; + } &:visited { color: $color-link-visited; } diff --git a/backend/app/assets/stylesheets/spree/backend/spree_admin.scss b/backend/app/assets/stylesheets/spree/backend/spree_admin.scss index 2d92c870cbb..50d26d267ff 100644 --- a/backend/app/assets/stylesheets/spree/backend/spree_admin.scss +++ b/backend/app/assets/stylesheets/spree/backend/spree_admin.scss @@ -4,6 +4,9 @@ @import 'spree/backend/globals/variables_override'; @import 'spree/backend/globals/variables'; +@import 'bootstrap_custom'; +@import 'solidus_admin/bootstrap/bootstrap'; + @import 'spree/backend/globals/mixins/caret'; @import 'spree/backend/shared/skeleton'; @@ -13,14 +16,11 @@ @import 'spree/backend/shared/forms'; @import 'spree/backend/shared/layout'; -@import 'bootstrap/components/media'; - @import 'spree/backend/components/states'; @import 'spree/backend/components/actions'; @import 'spree/backend/components/date-picker'; @import 'spree/backend/components/list_group'; @import 'spree/backend/components/messages'; -@import 'spree/backend/components/pagination'; @import 'spree/backend/components/progress'; @import 'spree/backend/components/table-filter'; @import 'spree/backend/components/navigation'; diff --git a/backend/app/views/kaminari/solidus_admin/_first_page.html.erb b/backend/app/views/kaminari/solidus_admin/_first_page.html.erb new file mode 100644 index 00000000000..cc107ec6ea1 --- /dev/null +++ b/backend/app/views/kaminari/solidus_admin/_first_page.html.erb @@ -0,0 +1,3 @@ +
  • + <%= link_to_unless current_page.first?, raw(t 'views.pagination.first'), url, remote: remote, class: 'page-link' %> +
  • diff --git a/backend/app/views/kaminari/solidus_admin/_gap.html.erb b/backend/app/views/kaminari/solidus_admin/_gap.html.erb new file mode 100644 index 00000000000..6d3a1490ca4 --- /dev/null +++ b/backend/app/views/kaminari/solidus_admin/_gap.html.erb @@ -0,0 +1,3 @@ +
  • + <%= content_tag :a, raw(t 'views.pagination.truncate') %> +
  • diff --git a/backend/app/views/kaminari/solidus_admin/_last_page.html.erb b/backend/app/views/kaminari/solidus_admin/_last_page.html.erb new file mode 100644 index 00000000000..76ce130b8a2 --- /dev/null +++ b/backend/app/views/kaminari/solidus_admin/_last_page.html.erb @@ -0,0 +1,3 @@ +
  • + <%= link_to_unless current_page.last?, raw(t 'views.pagination.last'), url, { remote: remote, class: 'page-link' } %> +
  • diff --git a/backend/app/views/kaminari/solidus_admin/_next_page.html.erb b/backend/app/views/kaminari/solidus_admin/_next_page.html.erb new file mode 100644 index 00000000000..7ca72a819f7 --- /dev/null +++ b/backend/app/views/kaminari/solidus_admin/_next_page.html.erb @@ -0,0 +1,3 @@ +
  • + <%= link_to_unless current_page.last?, raw(t 'views.pagination.next'), url, rel: 'next', remote: remote, class: 'page-link' %> +
  • diff --git a/backend/app/views/kaminari/solidus_admin/_page.html.erb b/backend/app/views/kaminari/solidus_admin/_page.html.erb new file mode 100644 index 00000000000..57bc591bf7f --- /dev/null +++ b/backend/app/views/kaminari/solidus_admin/_page.html.erb @@ -0,0 +1,9 @@ +<% if page.current? %> +
  • + <%= content_tag :a, page, remote: remote, rel: (page.next? ? 'next' : (page.prev? ? 'prev' : nil)), class: 'page-link' %> +
  • +<% else %> +
  • + <%= link_to page, url, remote: remote, rel: (page.next? ? 'next' : (page.prev? ? 'prev' : nil)), class: 'page-link' %> +
  • +<% end %> diff --git a/backend/app/views/kaminari/solidus_admin/_paginator.html.erb b/backend/app/views/kaminari/solidus_admin/_paginator.html.erb new file mode 100644 index 00000000000..0f9bdec71f8 --- /dev/null +++ b/backend/app/views/kaminari/solidus_admin/_paginator.html.erb @@ -0,0 +1,15 @@ +<%= paginator.render do %> + +<% end %> diff --git a/backend/app/views/kaminari/solidus_admin/_prev_page.html.erb b/backend/app/views/kaminari/solidus_admin/_prev_page.html.erb new file mode 100644 index 00000000000..c7803fac466 --- /dev/null +++ b/backend/app/views/kaminari/solidus_admin/_prev_page.html.erb @@ -0,0 +1,3 @@ +
  • + <%= link_to_unless current_page.first?, raw(t 'views.pagination.previous'), url, rel: 'prev', remote: remote, class: 'page-link' %> +
  • diff --git a/backend/app/views/spree/admin/orders/index.html.erb b/backend/app/views/spree/admin/orders/index.html.erb index a35f13d0614..e1f21e245bf 100644 --- a/backend/app/views/spree/admin/orders/index.html.erb +++ b/backend/app/views/spree/admin/orders/index.html.erb @@ -96,7 +96,7 @@ <% end %> -<%= paginate @orders %> +<%= paginate @orders, theme: "solidus_admin" %> <% if @orders.any? %> @@ -163,4 +163,4 @@ <% end %> -<%= paginate @orders %> +<%= paginate @orders, theme: "solidus_admin" %> diff --git a/backend/app/views/spree/admin/products/index.html.erb b/backend/app/views/spree/admin/products/index.html.erb index cfddf03695e..afb460103c2 100644 --- a/backend/app/views/spree/admin/products/index.html.erb +++ b/backend/app/views/spree/admin/products/index.html.erb @@ -53,7 +53,7 @@
    -<%= paginate @collection %> +<%= paginate @collection, theme: "solidus_admin" %> <% if @collection.any? %>
    @@ -98,4 +98,4 @@ <% end %> -<%= paginate @collection %> +<%= paginate @collection, theme: "solidus_admin" %> diff --git a/backend/app/views/spree/admin/promotions/index.html.erb b/backend/app/views/spree/admin/promotions/index.html.erb index 8b66260774b..e9a3606f5a5 100644 --- a/backend/app/views/spree/admin/promotions/index.html.erb +++ b/backend/app/views/spree/admin/promotions/index.html.erb @@ -57,7 +57,7 @@ <% end %> -<%= paginate @promotions %> +<%= paginate @promotions, theme: "solidus_admin" %> <% if @promotions.any? %>
    diff --git a/backend/app/views/spree/admin/properties/index.html.erb b/backend/app/views/spree/admin/properties/index.html.erb index 716f7832e24..975404f5bc0 100644 --- a/backend/app/views/spree/admin/properties/index.html.erb +++ b/backend/app/views/spree/admin/properties/index.html.erb @@ -80,4 +80,4 @@ <% end %> -<%= paginate @collection %> +<%= paginate @collection, theme: "solidus_admin" %> diff --git a/backend/app/views/spree/admin/stock_items/_stock_management.html.erb b/backend/app/views/spree/admin/stock_items/_stock_management.html.erb index 185caa40554..7ac6db93d34 100644 --- a/backend/app/views/spree/admin/stock_items/_stock_management.html.erb +++ b/backend/app/views/spree/admin/stock_items/_stock_management.html.erb @@ -1,4 +1,4 @@ -<%= paginate @variants %> +<%= paginate @variants, theme: "solidus_admin" %>
    @@ -98,4 +98,4 @@
    -<%= paginate @variants %> +<%= paginate @variants, theme: "solidus_admin" %> diff --git a/backend/app/views/spree/admin/stock_movements/index.html.erb b/backend/app/views/spree/admin/stock_movements/index.html.erb index d124d92a705..c6d69ec132f 100644 --- a/backend/app/views/spree/admin/stock_movements/index.html.erb +++ b/backend/app/views/spree/admin/stock_movements/index.html.erb @@ -52,4 +52,4 @@ <% end %> -<%= paginate @stock_movements %> +<%= paginate @stock_movements, theme: "solidus_admin" %> diff --git a/backend/app/views/spree/admin/stock_transfers/index.html.erb b/backend/app/views/spree/admin/stock_transfers/index.html.erb index dac8e984090..3be04bff696 100644 --- a/backend/app/views/spree/admin/stock_transfers/index.html.erb +++ b/backend/app/views/spree/admin/stock_transfers/index.html.erb @@ -66,7 +66,7 @@ <% end %> -<%= paginate @stock_transfers %> +<%= paginate @stock_transfers, theme: "solidus_admin" %> <% if @stock_transfers.any? %> @@ -114,4 +114,4 @@ <% end %> -<%= paginate @stock_transfers %> +<%= paginate @stock_transfers, theme: "solidus_admin" %> diff --git a/backend/app/views/spree/admin/users/index.html.erb b/backend/app/views/spree/admin/users/index.html.erb index 985f3cfc65f..233e5dd7981 100644 --- a/backend/app/views/spree/admin/users/index.html.erb +++ b/backend/app/views/spree/admin/users/index.html.erb @@ -38,7 +38,7 @@ -<%= paginate @users %> +<%= paginate @users, theme: "solidus_admin" %> <% content_for :sidebar_title do %> <%= Spree.t(:search) %> diff --git a/backend/app/views/spree/admin/users/items.html.erb b/backend/app/views/spree/admin/users/items.html.erb index f9468a96781..44c1612286f 100644 --- a/backend/app/views/spree/admin/users/items.html.erb +++ b/backend/app/views/spree/admin/users/items.html.erb @@ -8,7 +8,7 @@
    <%= Spree.t(:"admin.user.items_purchased") %> - <%= paginate @orders %> + <%= paginate @orders, theme: "solidus_admin" %> <% if @orders.any? %> <%# TODO add search interface %> @@ -77,5 +77,5 @@ new_resource_url: spree.new_admin_order_path %> <% end %> - <%= paginate @orders %> + <%= paginate @orders, theme: "solidus_admin" %>
    diff --git a/backend/app/views/spree/admin/users/orders.html.erb b/backend/app/views/spree/admin/users/orders.html.erb index e6836b5f957..a03fa2178fb 100644 --- a/backend/app/views/spree/admin/users/orders.html.erb +++ b/backend/app/views/spree/admin/users/orders.html.erb @@ -8,7 +8,7 @@
    <%= Spree.t(:"admin.user.order_history") %> - <%= paginate @orders %> + <%= paginate @orders, theme: "solidus_admin" %> <% if @orders.any? %> <%# TODO add search interface %> @@ -60,5 +60,5 @@ <% end %> - <%= paginate @orders %> + <%= paginate @orders, theme: "solidus_admin" %>
    diff --git a/backend/app/views/spree/admin/variants/index.html.erb b/backend/app/views/spree/admin/variants/index.html.erb index 3a638240ba3..b7091f89d82 100644 --- a/backend/app/views/spree/admin/variants/index.html.erb +++ b/backend/app/views/spree/admin/variants/index.html.erb @@ -44,7 +44,7 @@ <% end %> <% if @variants.any? %> - <%= paginate @variants %> + <%= paginate @variants, theme: "solidus_admin" %> @@ -90,7 +90,7 @@ <% end %>
    - <%= paginate @variants %> + <%= paginate @variants, theme: "solidus_admin" %> <% else %>
    <%= render 'spree/admin/shared/no_objects_found', diff --git a/backend/app/views/spree/admin/zones/index.html.erb b/backend/app/views/spree/admin/zones/index.html.erb index fe0aa6b7ec9..b8c0b947dc6 100644 --- a/backend/app/views/spree/admin/zones/index.html.erb +++ b/backend/app/views/spree/admin/zones/index.html.erb @@ -12,7 +12,7 @@ <% end %> <% end %> -<%= paginate @zones %> +<%= paginate @zones, theme: "solidus_admin" %> <% if @zones.any? %> @@ -58,4 +58,4 @@ <% end %> -<%= paginate @zones %> +<%= paginate @zones, theme: "solidus_admin" %> diff --git a/backend/vendor/assets/javascripts/solidus_admin/bootstrap.js b/backend/vendor/assets/javascripts/solidus_admin/bootstrap.js new file mode 100644 index 00000000000..e6a646d6d9a --- /dev/null +++ b/backend/vendor/assets/javascripts/solidus_admin/bootstrap.js @@ -0,0 +1,3560 @@ +/*! + * Bootstrap v4.0.0-alpha.2 (http://getbootstrap.com) + * Copyright 2011-2015 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + */ + +if (typeof jQuery === 'undefined') { + throw new Error('Bootstrap\'s JavaScript requires jQuery') +} + ++function ($) { + var version = $.fn.jquery.split(' ')[0].split('.') + if ((version[0] < 2 && version[1] < 9) || (version[0] == 1 && version[1] == 9 && version[2] < 1) || (version[0] >= 3)) { + throw new Error('Bootstrap\'s JavaScript requires at least jQuery v1.9.1 but less than v3.0.0') + } +}(jQuery); + + ++function ($) { + +/** + * -------------------------------------------------------------------------- + * Bootstrap (v4.0.0-alpha.2): util.js + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * -------------------------------------------------------------------------- + */ + +'use strict'; + +var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } }; + +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; }; })(); + +function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } + +var Util = (function ($) { + + /** + * ------------------------------------------------------------------------ + * Private TransitionEnd Helpers + * ------------------------------------------------------------------------ + */ + + var transition = false; + + var TransitionEndEvent = { + WebkitTransition: 'webkitTransitionEnd', + MozTransition: 'transitionend', + OTransition: 'oTransitionEnd otransitionend', + transition: 'transitionend' + }; + + // shoutout AngusCroll (https://goo.gl/pxwQGp) + function toType(obj) { + return ({}).toString.call(obj).match(/\s([a-zA-Z]+)/)[1].toLowerCase(); + } + + function isElement(obj) { + return (obj[0] || obj).nodeType; + } + + 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); + } + } + }; + } + + function transitionEndTest() { + if (window.QUnit) { + return false; + } + + var el = document.createElement('bootstrap'); + + for (var _name in TransitionEndEvent) { + if (el.style[_name] !== undefined) { + return { end: TransitionEndEvent[_name] }; + } + } + + return false; + } + + 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() { + transition = transitionEndTest(); + + $.fn.emulateTransitionEnd = transitionEndEmulator; + + if (Util.supportsTransitionEnd()) { + $.event.special[Util.TRANSITION_END] = getSpecialTransitionEndEvent(); + } + } + + /** + * -------------------------------------------------------------------------- + * Public Util Api + * -------------------------------------------------------------------------- + */ + + var Util = { + + TRANSITION_END: 'bsTransitionEnd', + + getUID: function getUID(prefix) { + do { + prefix += ~ ~(Math.random() * 1000000); // "~~" 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 = element.getAttribute('href') || ''; + selector = /^#[a-z]/i.test(selector) ? selector : null; + } + + return selector; + }, + + reflow: function reflow(element) { + new Function('bs', 'return bs')(element.offsetHeight); + }, + + triggerTransitionEnd: function triggerTransitionEnd(element) { + $(element).trigger(transition.end); + }, + + supportsTransitionEnd: function supportsTransitionEnd() { + return Boolean(transition); + }, + + typeCheckConfig: function typeCheckConfig(componentName, config, configTypes) { + for (var property in configTypes) { + if (configTypes.hasOwnProperty(property)) { + var expectedTypes = configTypes[property]; + var value = config[property]; + var valueType = undefined; + + if (value && isElement(value)) { + valueType = 'element'; + } else { + valueType = toType(value); + } + + if (!new RegExp(expectedTypes).test(valueType)) { + throw new Error(componentName.toUpperCase() + ': ' + ('Option "' + property + '" provided type "' + valueType + '" ') + ('but expected type "' + expectedTypes + '".')); + } + } + } + } + }; + + setTransitionEndSupport(); + + return Util; +})(jQuery); + +/** + * -------------------------------------------------------------------------- + * Bootstrap (v4.0.0-alpha.2): alert.js + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * -------------------------------------------------------------------------- + */ + +var Alert = (function ($) { + + /** + * ------------------------------------------------------------------------ + * Constants + * ------------------------------------------------------------------------ + */ + + var NAME = 'alert'; + var VERSION = '4.0.0-alpha'; + var DATA_KEY = 'bs.alert'; + var EVENT_KEY = '.' + DATA_KEY; + var DATA_API_KEY = '.data-api'; + var JQUERY_NO_CONFLICT = $.fn[NAME]; + var TRANSITION_DURATION = 150; + + 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', + IN: 'in' + }; + + /** + * ------------------------------------------------------------------------ + * Class Definition + * ------------------------------------------------------------------------ + */ + + var Alert = (function () { + function Alert(element) { + _classCallCheck(this, Alert); + + this._element = element; + } + + /** + * ------------------------------------------------------------------------ + * Data Api implementation + * ------------------------------------------------------------------------ + */ + + // getters + + _createClass(Alert, [{ + key: 'close', + + // public + + value: function close(element) { + element = element || this._element; + + var rootElement = this._getRootElement(element); + var customEvent = this._triggerCloseEvent(rootElement); + + if (customEvent.isDefaultPrevented()) { + return; + } + + this._removeElement(rootElement); + } + }, { + key: 'dispose', + value: function dispose() { + $.removeData(this._element, DATA_KEY); + this._element = null; + } + + // private + + }, { + key: '_getRootElement', + value: function _getRootElement(element) { + var selector = Util.getSelectorFromElement(element); + var parent = false; + + if (selector) { + parent = $(selector)[0]; + } + + if (!parent) { + parent = $(element).closest('.' + ClassName.ALERT)[0]; + } + + return parent; + } + }, { + key: '_triggerCloseEvent', + value: function _triggerCloseEvent(element) { + var closeEvent = $.Event(Event.CLOSE); + + $(element).trigger(closeEvent); + return closeEvent; + } + }, { + key: '_removeElement', + value: function _removeElement(element) { + $(element).removeClass(ClassName.IN); + + if (!Util.supportsTransitionEnd() || !$(element).hasClass(ClassName.FADE)) { + this._destroyElement(element); + return; + } + + $(element).one(Util.TRANSITION_END, $.proxy(this._destroyElement, this, element)).emulateTransitionEnd(TRANSITION_DURATION); + } + }, { + key: '_destroyElement', + value: function _destroyElement(element) { + $(element).detach().trigger(Event.CLOSED).remove(); + } + + // static + + }], [{ + key: '_jQueryInterface', + value: 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); + } + }); + } + }, { + key: '_handleDismiss', + value: function _handleDismiss(alertInstance) { + return function (event) { + if (event) { + event.preventDefault(); + } + + alertInstance.close(this); + }; + } + }, { + key: 'VERSION', + get: function get() { + return VERSION; + } + }]); + + return Alert; + })(); + + $(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; + }; + + return Alert; +})(jQuery); + +/** + * -------------------------------------------------------------------------- + * Bootstrap (v4.0.0-alpha.2): button.js + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * -------------------------------------------------------------------------- + */ + +var Button = (function ($) { + + /** + * ------------------------------------------------------------------------ + * Constants + * ------------------------------------------------------------------------ + */ + + var NAME = 'button'; + var VERSION = '4.0.0-alpha'; + var DATA_KEY = 'bs.button'; + var EVENT_KEY = '.' + DATA_KEY; + var DATA_API_KEY = '.data-api'; + var JQUERY_NO_CONFLICT = $.fn[NAME]; + + var ClassName = { + ACTIVE: 'active', + BUTTON: 'btn', + FOCUS: 'focus' + }; + + var Selector = { + DATA_TOGGLE_CARROT: '[data-toggle^="button"]', + DATA_TOGGLE: '[data-toggle="buttons"]', + INPUT: 'input', + ACTIVE: '.active', + BUTTON: '.btn' + }; + + var Event = { + CLICK_DATA_API: 'click' + EVENT_KEY + DATA_API_KEY, + FOCUS_BLUR_DATA_API: 'focus' + EVENT_KEY + DATA_API_KEY + ' ' + ('blur' + EVENT_KEY + DATA_API_KEY) + }; + + /** + * ------------------------------------------------------------------------ + * Class Definition + * ------------------------------------------------------------------------ + */ + + var Button = (function () { + function Button(element) { + _classCallCheck(this, Button); + + this._element = element; + } + + /** + * ------------------------------------------------------------------------ + * Data Api implementation + * ------------------------------------------------------------------------ + */ + + // getters + + _createClass(Button, [{ + key: 'toggle', + + // public + + value: function toggle() { + var triggerChangeEvent = true; + var rootElement = $(this._element).closest(Selector.DATA_TOGGLE)[0]; + + if (rootElement) { + var input = $(this._element).find(Selector.INPUT)[0]; + + if (input) { + if (input.type === 'radio') { + if (input.checked && $(this._element).hasClass(ClassName.ACTIVE)) { + triggerChangeEvent = false; + } else { + var activeElement = $(rootElement).find(Selector.ACTIVE)[0]; + + if (activeElement) { + $(activeElement).removeClass(ClassName.ACTIVE); + } + } + } + + if (triggerChangeEvent) { + input.checked = !$(this._element).hasClass(ClassName.ACTIVE); + $(this._element).trigger('change'); + } + } + } else { + this._element.setAttribute('aria-pressed', !$(this._element).hasClass(ClassName.ACTIVE)); + } + + if (triggerChangeEvent) { + $(this._element).toggleClass(ClassName.ACTIVE); + } + } + }, { + key: 'dispose', + value: function dispose() { + $.removeData(this._element, DATA_KEY); + this._element = null; + } + + // static + + }], [{ + key: '_jQueryInterface', + value: function _jQueryInterface(config) { + return this.each(function () { + var data = $(this).data(DATA_KEY); + + if (!data) { + data = new Button(this); + $(this).data(DATA_KEY, data); + } + + if (config === 'toggle') { + data[config](); + } + }); + } + }, { + key: 'VERSION', + get: function get() { + return VERSION; + } + }]); + + return Button; + })(); + + $(document).on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE_CARROT, function (event) { + event.preventDefault(); + + var button = event.target; + + if (!$(button).hasClass(ClassName.BUTTON)) { + button = $(button).closest(Selector.BUTTON); + } + + Button._jQueryInterface.call($(button), 'toggle'); + }).on(Event.FOCUS_BLUR_DATA_API, Selector.DATA_TOGGLE_CARROT, function (event) { + var button = $(event.target).closest(Selector.BUTTON)[0]; + $(button).toggleClass(ClassName.FOCUS, /^focus(in)?$/.test(event.type)); + }); + + /** + * ------------------------------------------------------------------------ + * jQuery + * ------------------------------------------------------------------------ + */ + + $.fn[NAME] = Button._jQueryInterface; + $.fn[NAME].Constructor = Button; + $.fn[NAME].noConflict = function () { + $.fn[NAME] = JQUERY_NO_CONFLICT; + return Button._jQueryInterface; + }; + + return Button; +})(jQuery); + +/** + * -------------------------------------------------------------------------- + * Bootstrap (v4.0.0-alpha.2): carousel.js + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * -------------------------------------------------------------------------- + */ + +var Carousel = (function ($) { + + /** + * ------------------------------------------------------------------------ + * Constants + * ------------------------------------------------------------------------ + */ + + var NAME = 'carousel'; + var VERSION = '4.0.0-alpha'; + var DATA_KEY = 'bs.carousel'; + var EVENT_KEY = '.' + DATA_KEY; + var DATA_API_KEY = '.data-api'; + var JQUERY_NO_CONFLICT = $.fn[NAME]; + var TRANSITION_DURATION = 600; + + var Default = { + interval: 5000, + keyboard: true, + slide: false, + pause: 'hover', + wrap: true + }; + + var DefaultType = { + interval: '(number|boolean)', + keyboard: 'boolean', + slide: '(boolean|string)', + pause: '(string|boolean)', + wrap: 'boolean' + }; + + var Direction = { + NEXT: 'next', + PREVIOUS: 'prev' + }; + + var Event = { + SLIDE: 'slide' + EVENT_KEY, + SLID: 'slid' + EVENT_KEY, + KEYDOWN: 'keydown' + EVENT_KEY, + MOUSEENTER: 'mouseenter' + EVENT_KEY, + MOUSELEAVE: 'mouseleave' + EVENT_KEY, + LOAD_DATA_API: 'load' + EVENT_KEY + DATA_API_KEY, + CLICK_DATA_API: 'click' + EVENT_KEY + DATA_API_KEY + }; + + var ClassName = { + CAROUSEL: 'carousel', + ACTIVE: 'active', + SLIDE: 'slide', + RIGHT: 'right', + LEFT: 'left', + ITEM: 'carousel-item' + }; + + var Selector = { + ACTIVE: '.active', + ACTIVE_ITEM: '.active.carousel-item', + ITEM: '.carousel-item', + NEXT_PREV: '.next, .prev', + INDICATORS: '.carousel-indicators', + DATA_SLIDE: '[data-slide], [data-slide-to]', + DATA_RIDE: '[data-ride="carousel"]' + }; + + /** + * ------------------------------------------------------------------------ + * Class Definition + * ------------------------------------------------------------------------ + */ + + var Carousel = (function () { + function Carousel(element, config) { + _classCallCheck(this, Carousel); + + this._items = null; + this._interval = null; + this._activeElement = null; + + this._isPaused = false; + this._isSliding = false; + + this._config = this._getConfig(config); + this._element = $(element)[0]; + this._indicatorsElement = $(this._element).find(Selector.INDICATORS)[0]; + + this._addEventListeners(); + } + + /** + * ------------------------------------------------------------------------ + * Data Api implementation + * ------------------------------------------------------------------------ + */ + + // getters + + _createClass(Carousel, [{ + key: 'next', + + // public + + value: function next() { + if (!this._isSliding) { + this._slide(Direction.NEXT); + } + } + }, { + key: 'nextWhenVisible', + value: function nextWhenVisible() { + // Don't call next when the page isn't visible + if (!document.hidden) { + this.next(); + } + } + }, { + key: 'prev', + value: function prev() { + if (!this._isSliding) { + this._slide(Direction.PREVIOUS); + } + } + }, { + key: 'pause', + value: function pause(event) { + if (!event) { + this._isPaused = true; + } + + if ($(this._element).find(Selector.NEXT_PREV)[0] && Util.supportsTransitionEnd()) { + Util.triggerTransitionEnd(this._element); + this.cycle(true); + } + + clearInterval(this._interval); + this._interval = null; + } + }, { + key: 'cycle', + value: 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($.proxy(document.visibilityState ? this.nextWhenVisible : this.next, this), this._config.interval); + } + } + }, { + key: 'to', + value: function to(index) { + var _this2 = this; + + this._activeElement = $(this._element).find(Selector.ACTIVE_ITEM)[0]; + + var activeIndex = this._getItemIndex(this._activeElement); + + if (index > this._items.length - 1 || index < 0) { + return; + } + + if (this._isSliding) { + $(this._element).one(Event.SLID, function () { + return _this2.to(index); + }); + return; + } + + if (activeIndex === index) { + this.pause(); + this.cycle(); + return; + } + + var direction = index > activeIndex ? Direction.NEXT : Direction.PREVIOUS; + + this._slide(direction, this._items[index]); + } + }, { + key: 'dispose', + value: function dispose() { + $(this._element).off(EVENT_KEY); + $.removeData(this._element, DATA_KEY); + + 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 + + }, { + key: '_getConfig', + value: function _getConfig(config) { + config = $.extend({}, Default, config); + Util.typeCheckConfig(NAME, config, DefaultType); + return config; + } + }, { + key: '_addEventListeners', + value: function _addEventListeners() { + if (this._config.keyboard) { + $(this._element).on(Event.KEYDOWN, $.proxy(this._keydown, this)); + } + + if (this._config.pause === 'hover' && !('ontouchstart' in document.documentElement)) { + $(this._element).on(Event.MOUSEENTER, $.proxy(this.pause, this)).on(Event.MOUSELEAVE, $.proxy(this.cycle, this)); + } + } + }, { + key: '_keydown', + value: function _keydown(event) { + event.preventDefault(); + + if (/input|textarea/i.test(event.target.tagName)) { + return; + } + + switch (event.which) { + case 37: + this.prev();break; + case 39: + this.next();break; + default: + return; + } + } + }, { + key: '_getItemIndex', + value: function _getItemIndex(element) { + this._items = $.makeArray($(element).parent().find(Selector.ITEM)); + return this._items.indexOf(element); + } + }, { + key: '_getItemByDirection', + value: function _getItemByDirection(direction, activeElement) { + var isNextDirection = direction === Direction.NEXT; + var isPrevDirection = direction === Direction.PREVIOUS; + 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.PREVIOUS ? -1 : 1; + var itemIndex = (activeIndex + delta) % this._items.length; + + return itemIndex === -1 ? this._items[this._items.length - 1] : this._items[itemIndex]; + } + }, { + key: '_triggerSlideEvent', + value: function _triggerSlideEvent(relatedTarget, directionalClassname) { + var slideEvent = $.Event(Event.SLIDE, { + relatedTarget: relatedTarget, + direction: directionalClassname + }); + + $(this._element).trigger(slideEvent); + + return slideEvent; + } + }, { + key: '_setActiveIndicatorElement', + value: function _setActiveIndicatorElement(element) { + if (this._indicatorsElement) { + $(this._indicatorsElement).find(Selector.ACTIVE).removeClass(ClassName.ACTIVE); + + var nextIndicator = this._indicatorsElement.children[this._getItemIndex(element)]; + + if (nextIndicator) { + $(nextIndicator).addClass(ClassName.ACTIVE); + } + } + } + }, { + key: '_slide', + value: function _slide(direction, element) { + var _this3 = this; + + var activeElement = $(this._element).find(Selector.ACTIVE_ITEM)[0]; + var nextElement = element || activeElement && this._getItemByDirection(direction, activeElement); + + var isCycling = Boolean(this._interval); + + var directionalClassName = direction === Direction.NEXT ? ClassName.LEFT : ClassName.RIGHT; + + if (nextElement && $(nextElement).hasClass(ClassName.ACTIVE)) { + this._isSliding = false; + return; + } + + var slideEvent = this._triggerSlideEvent(nextElement, directionalClassName); + 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.SLID, { + relatedTarget: nextElement, + direction: directionalClassName + }); + + if (Util.supportsTransitionEnd() && $(this._element).hasClass(ClassName.SLIDE)) { + + $(nextElement).addClass(direction); + + Util.reflow(nextElement); + + $(activeElement).addClass(directionalClassName); + $(nextElement).addClass(directionalClassName); + + $(activeElement).one(Util.TRANSITION_END, function () { + $(nextElement).removeClass(directionalClassName).removeClass(direction); + + $(nextElement).addClass(ClassName.ACTIVE); + + $(activeElement).removeClass(ClassName.ACTIVE).removeClass(direction).removeClass(directionalClassName); + + _this3._isSliding = false; + + setTimeout(function () { + return $(_this3._element).trigger(slidEvent); + }, 0); + }).emulateTransitionEnd(TRANSITION_DURATION); + } else { + $(activeElement).removeClass(ClassName.ACTIVE); + $(nextElement).addClass(ClassName.ACTIVE); + + this._isSliding = false; + $(this._element).trigger(slidEvent); + } + + if (isCycling) { + this.cycle(); + } + } + + // static + + }], [{ + key: '_jQueryInterface', + value: function _jQueryInterface(config) { + return this.each(function () { + var data = $(this).data(DATA_KEY); + var _config = $.extend({}, Default, $(this).data()); + + if (typeof config === 'object') { + $.extend(_config, config); + } + + var action = typeof config === 'string' ? config : _config.slide; + + if (!data) { + data = new Carousel(this, _config); + $(this).data(DATA_KEY, data); + } + + if (typeof config === 'number') { + data.to(config); + } else if (typeof action === 'string') { + if (data[action] === undefined) { + throw new Error('No method named "' + action + '"'); + } + data[action](); + } else if (_config.interval) { + data.pause(); + data.cycle(); + } + }); + } + }, { + key: '_dataApiClickHandler', + value: function _dataApiClickHandler(event) { + var selector = Util.getSelectorFromElement(this); + + if (!selector) { + return; + } + + var target = $(selector)[0]; + + if (!target || !$(target).hasClass(ClassName.CAROUSEL)) { + return; + } + + var config = $.extend({}, $(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).to(slideIndex); + } + + event.preventDefault(); + } + }, { + key: 'VERSION', + get: function get() { + return VERSION; + } + }, { + key: 'Default', + get: function get() { + return Default; + } + }]); + + return Carousel; + })(); + + $(document).on(Event.CLICK_DATA_API, Selector.DATA_SLIDE, Carousel._dataApiClickHandler); + + $(window).on(Event.LOAD_DATA_API, function () { + $(Selector.DATA_RIDE).each(function () { + var $carousel = $(this); + Carousel._jQueryInterface.call($carousel, $carousel.data()); + }); + }); + + /** + * ------------------------------------------------------------------------ + * jQuery + * ------------------------------------------------------------------------ + */ + + $.fn[NAME] = Carousel._jQueryInterface; + $.fn[NAME].Constructor = Carousel; + $.fn[NAME].noConflict = function () { + $.fn[NAME] = JQUERY_NO_CONFLICT; + return Carousel._jQueryInterface; + }; + + return Carousel; +})(jQuery); + +/** + * -------------------------------------------------------------------------- + * Bootstrap (v4.0.0-alpha.2): collapse.js + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * -------------------------------------------------------------------------- + */ + +var Collapse = (function ($) { + + /** + * ------------------------------------------------------------------------ + * Constants + * ------------------------------------------------------------------------ + */ + + var NAME = 'collapse'; + var VERSION = '4.0.0-alpha'; + var DATA_KEY = 'bs.collapse'; + var EVENT_KEY = '.' + DATA_KEY; + var DATA_API_KEY = '.data-api'; + var JQUERY_NO_CONFLICT = $.fn[NAME]; + var TRANSITION_DURATION = 600; + + var Default = { + toggle: true, + parent: '' + }; + + var DefaultType = { + toggle: 'boolean', + parent: 'string' + }; + + var Event = { + SHOW: 'show' + EVENT_KEY, + SHOWN: 'shown' + EVENT_KEY, + HIDE: 'hide' + EVENT_KEY, + HIDDEN: 'hidden' + EVENT_KEY, + CLICK_DATA_API: 'click' + EVENT_KEY + DATA_API_KEY + }; + + var ClassName = { + IN: 'in', + COLLAPSE: 'collapse', + COLLAPSING: 'collapsing', + COLLAPSED: 'collapsed' + }; + + var Dimension = { + WIDTH: 'width', + HEIGHT: 'height' + }; + + var Selector = { + ACTIVES: '.panel > .in, .panel > .collapsing', + DATA_TOGGLE: '[data-toggle="collapse"]' + }; + + /** + * ------------------------------------------------------------------------ + * Class Definition + * ------------------------------------------------------------------------ + */ + + var Collapse = (function () { + function Collapse(element, config) { + _classCallCheck(this, Collapse); + + this._isTransitioning = false; + this._element = element; + this._config = this._getConfig(config); + this._triggerArray = $.makeArray($('[data-toggle="collapse"][href="#' + element.id + '"],' + ('[data-toggle="collapse"][data-target="#' + element.id + '"]'))); + + this._parent = this._config.parent ? this._getParent() : null; + + if (!this._config.parent) { + this._addAriaAndCollapsedClass(this._element, this._triggerArray); + } + + if (this._config.toggle) { + this.toggle(); + } + } + + /** + * ------------------------------------------------------------------------ + * Data Api implementation + * ------------------------------------------------------------------------ + */ + + // getters + + _createClass(Collapse, [{ + key: 'toggle', + + // public + + value: function toggle() { + if ($(this._element).hasClass(ClassName.IN)) { + this.hide(); + } else { + this.show(); + } + } + }, { + key: 'show', + value: function show() { + var _this4 = this; + + if (this._isTransitioning || $(this._element).hasClass(ClassName.IN)) { + return; + } + + var actives = undefined; + var activesData = undefined; + + if (this._parent) { + actives = $.makeArray($(Selector.ACTIVES)); + if (!actives.length) { + actives = null; + } + } + + if (actives) { + activesData = $(actives).data(DATA_KEY); + if (activesData && activesData._isTransitioning) { + return; + } + } + + var startEvent = $.Event(Event.SHOW); + $(this._element).trigger(startEvent); + if (startEvent.isDefaultPrevented()) { + return; + } + + if (actives) { + Collapse._jQueryInterface.call($(actives), 'hide'); + if (!activesData) { + $(actives).data(DATA_KEY, null); + } + } + + var dimension = this._getDimension(); + + $(this._element).removeClass(ClassName.COLLAPSE).addClass(ClassName.COLLAPSING); + + this._element.style[dimension] = 0; + this._element.setAttribute('aria-expanded', true); + + if (this._triggerArray.length) { + $(this._triggerArray).removeClass(ClassName.COLLAPSED).attr('aria-expanded', true); + } + + this.setTransitioning(true); + + var complete = function complete() { + $(_this4._element).removeClass(ClassName.COLLAPSING).addClass(ClassName.COLLAPSE).addClass(ClassName.IN); + + _this4._element.style[dimension] = ''; + + _this4.setTransitioning(false); + + $(_this4._element).trigger(Event.SHOWN); + }; + + if (!Util.supportsTransitionEnd()) { + complete(); + return; + } + + var capitalizedDimension = dimension[0].toUpperCase() + dimension.slice(1); + var scrollSize = 'scroll' + capitalizedDimension; + + $(this._element).one(Util.TRANSITION_END, complete).emulateTransitionEnd(TRANSITION_DURATION); + + this._element.style[dimension] = this._element[scrollSize] + 'px'; + } + }, { + key: 'hide', + value: function hide() { + var _this5 = this; + + if (this._isTransitioning || !$(this._element).hasClass(ClassName.IN)) { + return; + } + + var startEvent = $.Event(Event.HIDE); + $(this._element).trigger(startEvent); + if (startEvent.isDefaultPrevented()) { + return; + } + + var dimension = this._getDimension(); + var offsetDimension = dimension === Dimension.WIDTH ? 'offsetWidth' : 'offsetHeight'; + + this._element.style[dimension] = this._element[offsetDimension] + 'px'; + + Util.reflow(this._element); + + $(this._element).addClass(ClassName.COLLAPSING).removeClass(ClassName.COLLAPSE).removeClass(ClassName.IN); + + this._element.setAttribute('aria-expanded', false); + + if (this._triggerArray.length) { + $(this._triggerArray).addClass(ClassName.COLLAPSED).attr('aria-expanded', false); + } + + this.setTransitioning(true); + + var complete = function complete() { + _this5.setTransitioning(false); + $(_this5._element).removeClass(ClassName.COLLAPSING).addClass(ClassName.COLLAPSE).trigger(Event.HIDDEN); + }; + + this._element.style[dimension] = 0; + + if (!Util.supportsTransitionEnd()) { + complete(); + return; + } + + $(this._element).one(Util.TRANSITION_END, complete).emulateTransitionEnd(TRANSITION_DURATION); + } + }, { + key: 'setTransitioning', + value: function setTransitioning(isTransitioning) { + this._isTransitioning = isTransitioning; + } + }, { + key: 'dispose', + value: function dispose() { + $.removeData(this._element, DATA_KEY); + + this._config = null; + this._parent = null; + this._element = null; + this._triggerArray = null; + this._isTransitioning = null; + } + + // private + + }, { + key: '_getConfig', + value: function _getConfig(config) { + config = $.extend({}, Default, config); + config.toggle = Boolean(config.toggle); // coerce string values + Util.typeCheckConfig(NAME, config, DefaultType); + return config; + } + }, { + key: '_getDimension', + value: function _getDimension() { + var hasWidth = $(this._element).hasClass(Dimension.WIDTH); + return hasWidth ? Dimension.WIDTH : Dimension.HEIGHT; + } + }, { + key: '_getParent', + value: function _getParent() { + var _this6 = this; + + var parent = $(this._config.parent)[0]; + var selector = '[data-toggle="collapse"][data-parent="' + this._config.parent + '"]'; + + $(parent).find(selector).each(function (i, element) { + _this6._addAriaAndCollapsedClass(Collapse._getTargetFromElement(element), [element]); + }); + + return parent; + } + }, { + key: '_addAriaAndCollapsedClass', + value: function _addAriaAndCollapsedClass(element, triggerArray) { + if (element) { + var isOpen = $(element).hasClass(ClassName.IN); + element.setAttribute('aria-expanded', isOpen); + + if (triggerArray.length) { + $(triggerArray).toggleClass(ClassName.COLLAPSED, !isOpen).attr('aria-expanded', isOpen); + } + } + } + + // static + + }], [{ + key: '_getTargetFromElement', + value: function _getTargetFromElement(element) { + var selector = Util.getSelectorFromElement(element); + return selector ? $(selector)[0] : null; + } + }, { + key: '_jQueryInterface', + value: function _jQueryInterface(config) { + return this.each(function () { + var $this = $(this); + var data = $this.data(DATA_KEY); + var _config = $.extend({}, Default, $this.data(), typeof config === 'object' && config); + + if (!data && _config.toggle && /show|hide/.test(config)) { + _config.toggle = false; + } + + if (!data) { + data = new Collapse(this, _config); + $this.data(DATA_KEY, data); + } + + if (typeof config === 'string') { + if (data[config] === undefined) { + throw new Error('No method named "' + config + '"'); + } + data[config](); + } + }); + } + }, { + key: 'VERSION', + get: function get() { + return VERSION; + } + }, { + key: 'Default', + get: function get() { + return Default; + } + }]); + + return Collapse; + })(); + + $(document).on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE, function (event) { + event.preventDefault(); + + var target = Collapse._getTargetFromElement(this); + var data = $(target).data(DATA_KEY); + var config = data ? 'toggle' : $(this).data(); + + Collapse._jQueryInterface.call($(target), config); + }); + + /** + * ------------------------------------------------------------------------ + * jQuery + * ------------------------------------------------------------------------ + */ + + $.fn[NAME] = Collapse._jQueryInterface; + $.fn[NAME].Constructor = Collapse; + $.fn[NAME].noConflict = function () { + $.fn[NAME] = JQUERY_NO_CONFLICT; + return Collapse._jQueryInterface; + }; + + return Collapse; +})(jQuery); + +/** + * -------------------------------------------------------------------------- + * Bootstrap (v4.0.0-alpha.2): dropdown.js + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * -------------------------------------------------------------------------- + */ + +var Dropdown = (function ($) { + + /** + * ------------------------------------------------------------------------ + * Constants + * ------------------------------------------------------------------------ + */ + + var NAME = 'dropdown'; + var VERSION = '4.0.0-alpha'; + var DATA_KEY = 'bs.dropdown'; + var EVENT_KEY = '.' + DATA_KEY; + var DATA_API_KEY = '.data-api'; + var JQUERY_NO_CONFLICT = $.fn[NAME]; + + var Event = { + HIDE: 'hide' + EVENT_KEY, + HIDDEN: 'hidden' + EVENT_KEY, + SHOW: 'show' + EVENT_KEY, + SHOWN: 'shown' + EVENT_KEY, + CLICK: 'click' + EVENT_KEY, + CLICK_DATA_API: 'click' + EVENT_KEY + DATA_API_KEY, + KEYDOWN_DATA_API: 'keydown' + EVENT_KEY + DATA_API_KEY + }; + + var ClassName = { + BACKDROP: 'dropdown-backdrop', + DISABLED: 'disabled', + OPEN: 'open' + }; + + var Selector = { + BACKDROP: '.dropdown-backdrop', + DATA_TOGGLE: '[data-toggle="dropdown"]', + FORM_CHILD: '.dropdown form', + ROLE_MENU: '[role="menu"]', + ROLE_LISTBOX: '[role="listbox"]', + NAVBAR_NAV: '.navbar-nav', + VISIBLE_ITEMS: '[role="menu"] li:not(.disabled) a, ' + '[role="listbox"] li:not(.disabled) a' + }; + + /** + * ------------------------------------------------------------------------ + * Class Definition + * ------------------------------------------------------------------------ + */ + + var Dropdown = (function () { + function Dropdown(element) { + _classCallCheck(this, Dropdown); + + this._element = element; + + this._addEventListeners(); + } + + /** + * ------------------------------------------------------------------------ + * Data Api implementation + * ------------------------------------------------------------------------ + */ + + // getters + + _createClass(Dropdown, [{ + key: 'toggle', + + // public + + value: function toggle() { + if (this.disabled || $(this).hasClass(ClassName.DISABLED)) { + return false; + } + + var parent = Dropdown._getParentFromElement(this); + var isActive = $(parent).hasClass(ClassName.OPEN); + + Dropdown._clearMenus(); + + if (isActive) { + return false; + } + + if ('ontouchstart' in document.documentElement && !$(parent).closest(Selector.NAVBAR_NAV).length) { + + // if mobile we use a backdrop because click events don't delegate + var dropdown = document.createElement('div'); + dropdown.className = ClassName.BACKDROP; + $(dropdown).insertBefore(this); + $(dropdown).on('click', Dropdown._clearMenus); + } + + var relatedTarget = { relatedTarget: this }; + var showEvent = $.Event(Event.SHOW, relatedTarget); + + $(parent).trigger(showEvent); + + if (showEvent.isDefaultPrevented()) { + return false; + } + + this.focus(); + this.setAttribute('aria-expanded', 'true'); + + $(parent).toggleClass(ClassName.OPEN); + $(parent).trigger($.Event(Event.SHOWN, relatedTarget)); + + return false; + } + }, { + key: 'dispose', + value: function dispose() { + $.removeData(this._element, DATA_KEY); + $(this._element).off(EVENT_KEY); + this._element = null; + } + + // private + + }, { + key: '_addEventListeners', + value: function _addEventListeners() { + $(this._element).on(Event.CLICK, this.toggle); + } + + // static + + }], [{ + key: '_jQueryInterface', + value: function _jQueryInterface(config) { + return this.each(function () { + var data = $(this).data(DATA_KEY); + + if (!data) { + $(this).data(DATA_KEY, data = new Dropdown(this)); + } + + if (typeof config === 'string') { + if (data[config] === undefined) { + throw new Error('No method named "' + config + '"'); + } + data[config].call(this); + } + }); + } + }, { + key: '_clearMenus', + value: function _clearMenus(event) { + if (event && event.which === 3) { + return; + } + + var backdrop = $(Selector.BACKDROP)[0]; + if (backdrop) { + backdrop.parentNode.removeChild(backdrop); + } + + var toggles = $.makeArray($(Selector.DATA_TOGGLE)); + + for (var i = 0; i < toggles.length; i++) { + var _parent = Dropdown._getParentFromElement(toggles[i]); + var relatedTarget = { relatedTarget: toggles[i] }; + + if (!$(_parent).hasClass(ClassName.OPEN)) { + continue; + } + + if (event && event.type === 'click' && /input|textarea/i.test(event.target.tagName) && $.contains(_parent, event.target)) { + continue; + } + + var hideEvent = $.Event(Event.HIDE, relatedTarget); + $(_parent).trigger(hideEvent); + if (hideEvent.isDefaultPrevented()) { + continue; + } + + toggles[i].setAttribute('aria-expanded', 'false'); + + $(_parent).removeClass(ClassName.OPEN).trigger($.Event(Event.HIDDEN, relatedTarget)); + } + } + }, { + key: '_getParentFromElement', + value: function _getParentFromElement(element) { + var parent = undefined; + var selector = Util.getSelectorFromElement(element); + + if (selector) { + parent = $(selector)[0]; + } + + return parent || element.parentNode; + } + }, { + key: '_dataApiKeydownHandler', + value: function _dataApiKeydownHandler(event) { + if (!/(38|40|27|32)/.test(event.which) || /input|textarea/i.test(event.target.tagName)) { + return; + } + + event.preventDefault(); + event.stopPropagation(); + + if (this.disabled || $(this).hasClass(ClassName.DISABLED)) { + return; + } + + var parent = Dropdown._getParentFromElement(this); + var isActive = $(parent).hasClass(ClassName.OPEN); + + if (!isActive && event.which !== 27 || isActive && event.which === 27) { + + if (event.which === 27) { + var toggle = $(parent).find(Selector.DATA_TOGGLE)[0]; + $(toggle).trigger('focus'); + } + + $(this).trigger('click'); + return; + } + + var items = $.makeArray($(Selector.VISIBLE_ITEMS)); + + items = items.filter(function (item) { + return item.offsetWidth || item.offsetHeight; + }); + + if (!items.length) { + return; + } + + var index = items.indexOf(event.target); + + if (event.which === 38 && index > 0) { + // up + index--; + } + + if (event.which === 40 && index < items.length - 1) { + // down + index++; + } + + if (! ~index) { + index = 0; + } + + items[index].focus(); + } + }, { + key: 'VERSION', + get: function get() { + return VERSION; + } + }]); + + return Dropdown; + })(); + + $(document).on(Event.KEYDOWN_DATA_API, Selector.DATA_TOGGLE, Dropdown._dataApiKeydownHandler).on(Event.KEYDOWN_DATA_API, Selector.ROLE_MENU, Dropdown._dataApiKeydownHandler).on(Event.KEYDOWN_DATA_API, Selector.ROLE_LISTBOX, Dropdown._dataApiKeydownHandler).on(Event.CLICK_DATA_API, Dropdown._clearMenus).on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE, Dropdown.prototype.toggle).on(Event.CLICK_DATA_API, Selector.FORM_CHILD, function (e) { + e.stopPropagation(); + }); + + /** + * ------------------------------------------------------------------------ + * jQuery + * ------------------------------------------------------------------------ + */ + + $.fn[NAME] = Dropdown._jQueryInterface; + $.fn[NAME].Constructor = Dropdown; + $.fn[NAME].noConflict = function () { + $.fn[NAME] = JQUERY_NO_CONFLICT; + return Dropdown._jQueryInterface; + }; + + return Dropdown; +})(jQuery); + +/** + * -------------------------------------------------------------------------- + * Bootstrap (v4.0.0-alpha.2): modal.js + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * -------------------------------------------------------------------------- + */ + +var Modal = (function ($) { + + /** + * ------------------------------------------------------------------------ + * Constants + * ------------------------------------------------------------------------ + */ + + var NAME = 'modal'; + var VERSION = '4.0.0-alpha'; + var DATA_KEY = 'bs.modal'; + var EVENT_KEY = '.' + DATA_KEY; + var DATA_API_KEY = '.data-api'; + var JQUERY_NO_CONFLICT = $.fn[NAME]; + var TRANSITION_DURATION = 300; + var BACKDROP_TRANSITION_DURATION = 150; + + var Default = { + backdrop: true, + keyboard: true, + focus: true, + show: true + }; + + var DefaultType = { + backdrop: '(boolean|string)', + keyboard: 'boolean', + focus: 'boolean', + show: 'boolean' + }; + + var Event = { + HIDE: 'hide' + EVENT_KEY, + HIDDEN: 'hidden' + EVENT_KEY, + SHOW: 'show' + EVENT_KEY, + SHOWN: 'shown' + EVENT_KEY, + FOCUSIN: 'focusin' + EVENT_KEY, + RESIZE: 'resize' + EVENT_KEY, + CLICK_DISMISS: 'click.dismiss' + EVENT_KEY, + KEYDOWN_DISMISS: 'keydown.dismiss' + EVENT_KEY, + MOUSEUP_DISMISS: 'mouseup.dismiss' + EVENT_KEY, + MOUSEDOWN_DISMISS: 'mousedown.dismiss' + EVENT_KEY, + CLICK_DATA_API: 'click' + EVENT_KEY + DATA_API_KEY + }; + + var ClassName = { + SCROLLBAR_MEASURER: 'modal-scrollbar-measure', + BACKDROP: 'modal-backdrop', + OPEN: 'modal-open', + FADE: 'fade', + IN: 'in' + }; + + var Selector = { + DIALOG: '.modal-dialog', + DATA_TOGGLE: '[data-toggle="modal"]', + DATA_DISMISS: '[data-dismiss="modal"]', + FIXED_CONTENT: '.navbar-fixed-top, .navbar-fixed-bottom, .is-fixed' + }; + + /** + * ------------------------------------------------------------------------ + * Class Definition + * ------------------------------------------------------------------------ + */ + + var Modal = (function () { + function Modal(element, config) { + _classCallCheck(this, Modal); + + this._config = this._getConfig(config); + this._element = element; + this._dialog = $(element).find(Selector.DIALOG)[0]; + this._backdrop = null; + this._isShown = false; + this._isBodyOverflowing = false; + this._ignoreBackdropClick = false; + this._originalBodyPadding = 0; + this._scrollbarWidth = 0; + } + + /** + * ------------------------------------------------------------------------ + * Data Api implementation + * ------------------------------------------------------------------------ + */ + + // getters + + _createClass(Modal, [{ + key: 'toggle', + + // public + + value: function toggle(relatedTarget) { + return this._isShown ? this.hide() : this.show(relatedTarget); + } + }, { + key: 'show', + value: function show(relatedTarget) { + var _this7 = this; + + var showEvent = $.Event(Event.SHOW, { + relatedTarget: relatedTarget + }); + + $(this._element).trigger(showEvent); + + if (this._isShown || showEvent.isDefaultPrevented()) { + return; + } + + this._isShown = true; + + this._checkScrollbar(); + this._setScrollbar(); + + $(document.body).addClass(ClassName.OPEN); + + this._setEscapeEvent(); + this._setResizeEvent(); + + $(this._element).on(Event.CLICK_DISMISS, Selector.DATA_DISMISS, $.proxy(this.hide, this)); + + $(this._dialog).on(Event.MOUSEDOWN_DISMISS, function () { + $(_this7._element).one(Event.MOUSEUP_DISMISS, function (event) { + if ($(event.target).is(_this7._element)) { + _this7._ignoreBackdropClick = true; + } + }); + }); + + this._showBackdrop($.proxy(this._showElement, this, relatedTarget)); + } + }, { + key: 'hide', + value: function hide(event) { + if (event) { + event.preventDefault(); + } + + var hideEvent = $.Event(Event.HIDE); + + $(this._element).trigger(hideEvent); + + if (!this._isShown || hideEvent.isDefaultPrevented()) { + return; + } + + this._isShown = false; + + this._setEscapeEvent(); + this._setResizeEvent(); + + $(document).off(Event.FOCUSIN); + + $(this._element).removeClass(ClassName.IN); + + $(this._element).off(Event.CLICK_DISMISS); + $(this._dialog).off(Event.MOUSEDOWN_DISMISS); + + if (Util.supportsTransitionEnd() && $(this._element).hasClass(ClassName.FADE)) { + + $(this._element).one(Util.TRANSITION_END, $.proxy(this._hideModal, this)).emulateTransitionEnd(TRANSITION_DURATION); + } else { + this._hideModal(); + } + } + }, { + key: 'dispose', + value: function dispose() { + $.removeData(this._element, DATA_KEY); + + $(window).off(EVENT_KEY); + $(document).off(EVENT_KEY); + $(this._element).off(EVENT_KEY); + $(this._backdrop).off(EVENT_KEY); + + this._config = null; + this._element = null; + this._dialog = null; + this._backdrop = null; + this._isShown = null; + this._isBodyOverflowing = null; + this._ignoreBackdropClick = null; + this._originalBodyPadding = null; + this._scrollbarWidth = null; + } + + // private + + }, { + key: '_getConfig', + value: function _getConfig(config) { + config = $.extend({}, Default, config); + Util.typeCheckConfig(NAME, config, DefaultType); + return config; + } + }, { + key: '_showElement', + value: function _showElement(relatedTarget) { + var _this8 = this; + + var transition = Util.supportsTransitionEnd() && $(this._element).hasClass(ClassName.FADE); + + if (!this._element.parentNode || this._element.parentNode.nodeType !== Node.ELEMENT_NODE) { + // don't move modals dom position + document.body.appendChild(this._element); + } + + this._element.style.display = 'block'; + this._element.scrollTop = 0; + + if (transition) { + Util.reflow(this._element); + } + + $(this._element).addClass(ClassName.IN); + + if (this._config.focus) { + this._enforceFocus(); + } + + var shownEvent = $.Event(Event.SHOWN, { + relatedTarget: relatedTarget + }); + + var transitionComplete = function transitionComplete() { + if (_this8._config.focus) { + _this8._element.focus(); + } + $(_this8._element).trigger(shownEvent); + }; + + if (transition) { + $(this._dialog).one(Util.TRANSITION_END, transitionComplete).emulateTransitionEnd(TRANSITION_DURATION); + } else { + transitionComplete(); + } + } + }, { + key: '_enforceFocus', + value: function _enforceFocus() { + var _this9 = this; + + $(document).off(Event.FOCUSIN) // guard against infinite focus loop + .on(Event.FOCUSIN, function (event) { + if (_this9._element !== event.target && !$(_this9._element).has(event.target).length) { + _this9._element.focus(); + } + }); + } + }, { + key: '_setEscapeEvent', + value: function _setEscapeEvent() { + var _this10 = this; + + if (this._isShown && this._config.keyboard) { + $(this._element).on(Event.KEYDOWN_DISMISS, function (event) { + if (event.which === 27) { + _this10.hide(); + } + }); + } else if (!this._isShown) { + $(this._element).off(Event.KEYDOWN_DISMISS); + } + } + }, { + key: '_setResizeEvent', + value: function _setResizeEvent() { + if (this._isShown) { + $(window).on(Event.RESIZE, $.proxy(this._handleUpdate, this)); + } else { + $(window).off(Event.RESIZE); + } + } + }, { + key: '_hideModal', + value: function _hideModal() { + var _this11 = this; + + this._element.style.display = 'none'; + this._showBackdrop(function () { + $(document.body).removeClass(ClassName.OPEN); + _this11._resetAdjustments(); + _this11._resetScrollbar(); + $(_this11._element).trigger(Event.HIDDEN); + }); + } + }, { + key: '_removeBackdrop', + value: function _removeBackdrop() { + if (this._backdrop) { + $(this._backdrop).remove(); + this._backdrop = null; + } + } + }, { + key: '_showBackdrop', + value: function _showBackdrop(callback) { + var _this12 = this; + + var animate = $(this._element).hasClass(ClassName.FADE) ? ClassName.FADE : ''; + + if (this._isShown && this._config.backdrop) { + var doAnimate = Util.supportsTransitionEnd() && animate; + + this._backdrop = document.createElement('div'); + this._backdrop.className = ClassName.BACKDROP; + + if (animate) { + $(this._backdrop).addClass(animate); + } + + $(this._backdrop).appendTo(document.body); + + $(this._element).on(Event.CLICK_DISMISS, function (event) { + if (_this12._ignoreBackdropClick) { + _this12._ignoreBackdropClick = false; + return; + } + if (event.target !== event.currentTarget) { + return; + } + if (_this12._config.backdrop === 'static') { + _this12._element.focus(); + } else { + _this12.hide(); + } + }); + + if (doAnimate) { + Util.reflow(this._backdrop); + } + + $(this._backdrop).addClass(ClassName.IN); + + if (!callback) { + return; + } + + if (!doAnimate) { + callback(); + return; + } + + $(this._backdrop).one(Util.TRANSITION_END, callback).emulateTransitionEnd(BACKDROP_TRANSITION_DURATION); + } else if (!this._isShown && this._backdrop) { + $(this._backdrop).removeClass(ClassName.IN); + + var callbackRemove = function callbackRemove() { + _this12._removeBackdrop(); + if (callback) { + callback(); + } + }; + + if (Util.supportsTransitionEnd() && $(this._element).hasClass(ClassName.FADE)) { + $(this._backdrop).one(Util.TRANSITION_END, callbackRemove).emulateTransitionEnd(BACKDROP_TRANSITION_DURATION); + } 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 + // ---------------------------------------------------------------------- + + }, { + key: '_handleUpdate', + value: function _handleUpdate() { + this._adjustDialog(); + } + }, { + key: '_adjustDialog', + value: 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~'; + } + } + }, { + key: '_resetAdjustments', + value: function _resetAdjustments() { + this._element.style.paddingLeft = ''; + this._element.style.paddingRight = ''; + } + }, { + key: '_checkScrollbar', + value: function _checkScrollbar() { + var fullWindowWidth = window.innerWidth; + if (!fullWindowWidth) { + // workaround for missing window.innerWidth in IE8 + var documentElementRect = document.documentElement.getBoundingClientRect(); + fullWindowWidth = documentElementRect.right - Math.abs(documentElementRect.left); + } + this._isBodyOverflowing = document.body.clientWidth < fullWindowWidth; + this._scrollbarWidth = this._getScrollbarWidth(); + } + }, { + key: '_setScrollbar', + value: function _setScrollbar() { + var bodyPadding = parseInt($(Selector.FIXED_CONTENT).css('padding-right') || 0, 10); + + this._originalBodyPadding = document.body.style.paddingRight || ''; + + if (this._isBodyOverflowing) { + document.body.style.paddingRight = bodyPadding + this._scrollbarWidth + 'px'; + } + } + }, { + key: '_resetScrollbar', + value: function _resetScrollbar() { + document.body.style.paddingRight = this._originalBodyPadding; + } + }, { + key: '_getScrollbarWidth', + value: function _getScrollbarWidth() { + // thx d.walsh + var scrollDiv = document.createElement('div'); + scrollDiv.className = ClassName.SCROLLBAR_MEASURER; + document.body.appendChild(scrollDiv); + var scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth; + document.body.removeChild(scrollDiv); + return scrollbarWidth; + } + + // static + + }], [{ + key: '_jQueryInterface', + value: function _jQueryInterface(config, relatedTarget) { + return this.each(function () { + var data = $(this).data(DATA_KEY); + var _config = $.extend({}, Modal.Default, $(this).data(), typeof config === 'object' && config); + + if (!data) { + data = new Modal(this, _config); + $(this).data(DATA_KEY, data); + } + + if (typeof config === 'string') { + if (data[config] === undefined) { + throw new Error('No method named "' + config + '"'); + } + data[config](relatedTarget); + } else if (_config.show) { + data.show(relatedTarget); + } + }); + } + }, { + key: 'VERSION', + get: function get() { + return VERSION; + } + }, { + key: 'Default', + get: function get() { + return Default; + } + }]); + + return Modal; + })(); + + $(document).on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE, function (event) { + var _this13 = this; + + var target = undefined; + var selector = Util.getSelectorFromElement(this); + + if (selector) { + target = $(selector)[0]; + } + + var config = $(target).data(DATA_KEY) ? 'toggle' : $.extend({}, $(target).data(), $(this).data()); + + if (this.tagName === 'A') { + event.preventDefault(); + } + + var $target = $(target).one(Event.SHOW, function (showEvent) { + if (showEvent.isDefaultPrevented()) { + // only register focus restorer if modal will actually get shown + return; + } + + $target.one(Event.HIDDEN, function () { + if ($(_this13).is(':visible')) { + _this13.focus(); + } + }); + }); + + Modal._jQueryInterface.call($(target), config, this); + }); + + /** + * ------------------------------------------------------------------------ + * jQuery + * ------------------------------------------------------------------------ + */ + + $.fn[NAME] = Modal._jQueryInterface; + $.fn[NAME].Constructor = Modal; + $.fn[NAME].noConflict = function () { + $.fn[NAME] = JQUERY_NO_CONFLICT; + return Modal._jQueryInterface; + }; + + return Modal; +})(jQuery); + +/** + * -------------------------------------------------------------------------- + * Bootstrap (v4.0.0-alpha.2): scrollspy.js + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * -------------------------------------------------------------------------- + */ + +var ScrollSpy = (function ($) { + + /** + * ------------------------------------------------------------------------ + * Constants + * ------------------------------------------------------------------------ + */ + + var NAME = 'scrollspy'; + var VERSION = '4.0.0-alpha'; + var DATA_KEY = 'bs.scrollspy'; + var EVENT_KEY = '.' + DATA_KEY; + var DATA_API_KEY = '.data-api'; + var JQUERY_NO_CONFLICT = $.fn[NAME]; + + var Default = { + offset: 10, + method: 'auto', + target: '' + }; + + var DefaultType = { + offset: 'number', + method: 'string', + target: '(string|element)' + }; + + var Event = { + ACTIVATE: 'activate' + EVENT_KEY, + SCROLL: 'scroll' + EVENT_KEY, + LOAD_DATA_API: 'load' + EVENT_KEY + DATA_API_KEY + }; + + var ClassName = { + DROPDOWN_ITEM: 'dropdown-item', + DROPDOWN_MENU: 'dropdown-menu', + NAV_LINK: 'nav-link', + NAV: 'nav', + ACTIVE: 'active' + }; + + var Selector = { + DATA_SPY: '[data-spy="scroll"]', + ACTIVE: '.active', + LIST_ITEM: '.list-item', + LI: 'li', + LI_DROPDOWN: 'li.dropdown', + NAV_LINKS: '.nav-link', + DROPDOWN: '.dropdown', + DROPDOWN_ITEMS: '.dropdown-item', + DROPDOWN_TOGGLE: '.dropdown-toggle' + }; + + var OffsetMethod = { + OFFSET: 'offset', + POSITION: 'position' + }; + + /** + * ------------------------------------------------------------------------ + * Class Definition + * ------------------------------------------------------------------------ + */ + + var ScrollSpy = (function () { + function ScrollSpy(element, config) { + _classCallCheck(this, ScrollSpy); + + this._element = element; + this._scrollElement = element.tagName === 'BODY' ? window : element; + this._config = this._getConfig(config); + this._selector = this._config.target + ' ' + Selector.NAV_LINKS + ',' + (this._config.target + ' ' + Selector.DROPDOWN_ITEMS); + this._offsets = []; + this._targets = []; + this._activeTarget = null; + this._scrollHeight = 0; + + $(this._scrollElement).on(Event.SCROLL, $.proxy(this._process, this)); + + this.refresh(); + this._process(); + } + + /** + * ------------------------------------------------------------------------ + * Data Api implementation + * ------------------------------------------------------------------------ + */ + + // getters + + _createClass(ScrollSpy, [{ + key: 'refresh', + + // public + + value: function refresh() { + var _this14 = this; + + var autoMethod = this._scrollElement !== this._scrollElement.window ? OffsetMethod.POSITION : OffsetMethod.OFFSET; + + 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 = $.makeArray($(this._selector)); + + targets.map(function (element) { + var target = undefined; + var targetSelector = Util.getSelectorFromElement(element); + + if (targetSelector) { + target = $(targetSelector)[0]; + } + + if (target && (target.offsetWidth || target.offsetHeight)) { + // todo (fat): remove sketch reliance on jQuery position/offset + return [$(target)[offsetMethod]().top + offsetBase, targetSelector]; + } + }).filter(function (item) { + return item; + }).sort(function (a, b) { + return a[0] - b[0]; + }).forEach(function (item) { + _this14._offsets.push(item[0]); + _this14._targets.push(item[1]); + }); + } + }, { + key: 'dispose', + value: function dispose() { + $.removeData(this._element, DATA_KEY); + $(this._scrollElement).off(EVENT_KEY); + + 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 + + }, { + key: '_getConfig', + value: function _getConfig(config) { + config = $.extend({}, Default, config); + + if (typeof config.target !== 'string') { + var id = $(config.target).attr('id'); + if (!id) { + id = Util.getUID(NAME); + $(config.target).attr('id', id); + } + config.target = '#' + id; + } + + Util.typeCheckConfig(NAME, config, DefaultType); + + return config; + } + }, { + key: '_getScrollTop', + value: function _getScrollTop() { + return this._scrollElement === window ? this._scrollElement.scrollY : this._scrollElement.scrollTop; + } + }, { + key: '_getScrollHeight', + value: function _getScrollHeight() { + return this._scrollElement.scrollHeight || Math.max(document.body.scrollHeight, document.documentElement.scrollHeight); + } + }, { + key: '_process', + value: function _process() { + var scrollTop = this._getScrollTop() + this._config.offset; + var scrollHeight = this._getScrollHeight(); + var maxScroll = this._config.offset + scrollHeight - this._scrollElement.offsetHeight; + + if (this._scrollHeight !== scrollHeight) { + this.refresh(); + } + + if (scrollTop >= maxScroll) { + var target = this._targets[this._targets.length - 1]; + + if (this._activeTarget !== target) { + this._activate(target); + } + } + + if (this._activeTarget && scrollTop < this._offsets[0]) { + this._activeTarget = null; + this._clear(); + return; + } + + for (var i = this._offsets.length; i--;) { + var isActiveTarget = this._activeTarget !== this._targets[i] && scrollTop >= this._offsets[i] && (this._offsets[i + 1] === undefined || scrollTop < this._offsets[i + 1]); + + if (isActiveTarget) { + this._activate(this._targets[i]); + } + } + } + }, { + key: '_activate', + value: function _activate(target) { + this._activeTarget = target; + + this._clear(); + + var queries = this._selector.split(','); + queries = queries.map(function (selector) { + return selector + '[data-target="' + target + '"],' + (selector + '[href="' + target + '"]'); + }); + + var $link = $(queries.join(',')); + + if ($link.hasClass(ClassName.DROPDOWN_ITEM)) { + $link.closest(Selector.DROPDOWN).find(Selector.DROPDOWN_TOGGLE).addClass(ClassName.ACTIVE); + $link.addClass(ClassName.ACTIVE); + } else { + // todo (fat) this is kinda sus… + // recursively add actives to tested nav-links + $link.parents(Selector.LI).find(Selector.NAV_LINKS).addClass(ClassName.ACTIVE); + } + + $(this._scrollElement).trigger(Event.ACTIVATE, { + relatedTarget: target + }); + } + }, { + key: '_clear', + value: function _clear() { + $(this._selector).filter(Selector.ACTIVE).removeClass(ClassName.ACTIVE); + } + + // static + + }], [{ + key: '_jQueryInterface', + value: function _jQueryInterface(config) { + return this.each(function () { + var data = $(this).data(DATA_KEY); + var _config = typeof config === 'object' && config || null; + + if (!data) { + data = new ScrollSpy(this, _config); + $(this).data(DATA_KEY, data); + } + + if (typeof config === 'string') { + if (data[config] === undefined) { + throw new Error('No method named "' + config + '"'); + } + data[config](); + } + }); + } + }, { + key: 'VERSION', + get: function get() { + return VERSION; + } + }, { + key: 'Default', + get: function get() { + return Default; + } + }]); + + return ScrollSpy; + })(); + + $(window).on(Event.LOAD_DATA_API, function () { + var scrollSpys = $.makeArray($(Selector.DATA_SPY)); + + for (var i = scrollSpys.length; i--;) { + var $spy = $(scrollSpys[i]); + ScrollSpy._jQueryInterface.call($spy, $spy.data()); + } + }); + + /** + * ------------------------------------------------------------------------ + * jQuery + * ------------------------------------------------------------------------ + */ + + $.fn[NAME] = ScrollSpy._jQueryInterface; + $.fn[NAME].Constructor = ScrollSpy; + $.fn[NAME].noConflict = function () { + $.fn[NAME] = JQUERY_NO_CONFLICT; + return ScrollSpy._jQueryInterface; + }; + + return ScrollSpy; +})(jQuery); + +/** + * -------------------------------------------------------------------------- + * Bootstrap (v4.0.0-alpha.2): tab.js + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * -------------------------------------------------------------------------- + */ + +var Tab = (function ($) { + + /** + * ------------------------------------------------------------------------ + * Constants + * ------------------------------------------------------------------------ + */ + + var NAME = 'tab'; + var VERSION = '4.0.0-alpha'; + var DATA_KEY = 'bs.tab'; + var EVENT_KEY = '.' + DATA_KEY; + var DATA_API_KEY = '.data-api'; + var JQUERY_NO_CONFLICT = $.fn[NAME]; + var TRANSITION_DURATION = 150; + + var Event = { + HIDE: 'hide' + EVENT_KEY, + HIDDEN: 'hidden' + EVENT_KEY, + SHOW: 'show' + EVENT_KEY, + SHOWN: 'shown' + EVENT_KEY, + CLICK_DATA_API: 'click' + EVENT_KEY + DATA_API_KEY + }; + + var ClassName = { + DROPDOWN_MENU: 'dropdown-menu', + ACTIVE: 'active', + FADE: 'fade', + IN: 'in' + }; + + var Selector = { + A: 'a', + LI: 'li', + DROPDOWN: '.dropdown', + UL: 'ul:not(.dropdown-menu)', + FADE_CHILD: '> .nav-item .fade, > .fade', + ACTIVE: '.active', + ACTIVE_CHILD: '> .nav-item > .active, > .active', + DATA_TOGGLE: '[data-toggle="tab"], [data-toggle="pill"]', + DROPDOWN_TOGGLE: '.dropdown-toggle', + DROPDOWN_ACTIVE_CHILD: '> .dropdown-menu .active' + }; + + /** + * ------------------------------------------------------------------------ + * Class Definition + * ------------------------------------------------------------------------ + */ + + var Tab = (function () { + function Tab(element) { + _classCallCheck(this, Tab); + + this._element = element; + } + + /** + * ------------------------------------------------------------------------ + * Data Api implementation + * ------------------------------------------------------------------------ + */ + + // getters + + _createClass(Tab, [{ + key: 'show', + + // public + + value: function show() { + var _this15 = this; + + if (this._element.parentNode && this._element.parentNode.nodeType === Node.ELEMENT_NODE && $(this._element).hasClass(ClassName.ACTIVE)) { + return; + } + + var target = undefined; + var previous = undefined; + var ulElement = $(this._element).closest(Selector.UL)[0]; + var selector = Util.getSelectorFromElement(this._element); + + if (ulElement) { + previous = $.makeArray($(ulElement).find(Selector.ACTIVE)); + previous = previous[previous.length - 1]; + } + + var hideEvent = $.Event(Event.HIDE, { + relatedTarget: this._element + }); + + var showEvent = $.Event(Event.SHOW, { + relatedTarget: previous + }); + + if (previous) { + $(previous).trigger(hideEvent); + } + + $(this._element).trigger(showEvent); + + if (showEvent.isDefaultPrevented() || hideEvent.isDefaultPrevented()) { + return; + } + + if (selector) { + target = $(selector)[0]; + } + + this._activate(this._element, ulElement); + + var complete = function complete() { + var hiddenEvent = $.Event(Event.HIDDEN, { + relatedTarget: _this15._element + }); + + var shownEvent = $.Event(Event.SHOWN, { + relatedTarget: previous + }); + + $(previous).trigger(hiddenEvent); + $(_this15._element).trigger(shownEvent); + }; + + if (target) { + this._activate(target, target.parentNode, complete); + } else { + complete(); + } + } + }, { + key: 'dispose', + value: function dispose() { + $.removeClass(this._element, DATA_KEY); + this._element = null; + } + + // private + + }, { + key: '_activate', + value: function _activate(element, container, callback) { + var active = $(container).find(Selector.ACTIVE_CHILD)[0]; + var isTransitioning = callback && Util.supportsTransitionEnd() && (active && $(active).hasClass(ClassName.FADE) || Boolean($(container).find(Selector.FADE_CHILD)[0])); + + var complete = $.proxy(this._transitionComplete, this, element, active, isTransitioning, callback); + + if (active && isTransitioning) { + $(active).one(Util.TRANSITION_END, complete).emulateTransitionEnd(TRANSITION_DURATION); + } else { + complete(); + } + + if (active) { + $(active).removeClass(ClassName.IN); + } + } + }, { + key: '_transitionComplete', + value: function _transitionComplete(element, active, isTransitioning, callback) { + if (active) { + $(active).removeClass(ClassName.ACTIVE); + + var dropdownChild = $(active).find(Selector.DROPDOWN_ACTIVE_CHILD)[0]; + + if (dropdownChild) { + $(dropdownChild).removeClass(ClassName.ACTIVE); + } + + active.setAttribute('aria-expanded', false); + } + + $(element).addClass(ClassName.ACTIVE); + element.setAttribute('aria-expanded', true); + + if (isTransitioning) { + Util.reflow(element); + $(element).addClass(ClassName.IN); + } else { + $(element).removeClass(ClassName.FADE); + } + + if (element.parentNode && $(element.parentNode).hasClass(ClassName.DROPDOWN_MENU)) { + + var dropdownElement = $(element).closest(Selector.DROPDOWN)[0]; + if (dropdownElement) { + $(dropdownElement).find(Selector.DROPDOWN_TOGGLE).addClass(ClassName.ACTIVE); + } + + element.setAttribute('aria-expanded', true); + } + + if (callback) { + callback(); + } + } + + // static + + }], [{ + key: '_jQueryInterface', + value: function _jQueryInterface(config) { + return this.each(function () { + var $this = $(this); + var data = $this.data(DATA_KEY); + + if (!data) { + data = data = new Tab(this); + $this.data(DATA_KEY, data); + } + + if (typeof config === 'string') { + if (data[config] === undefined) { + throw new Error('No method named "' + config + '"'); + } + data[config](); + } + }); + } + }, { + key: 'VERSION', + get: function get() { + return VERSION; + } + }]); + + return Tab; + })(); + + $(document).on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE, function (event) { + event.preventDefault(); + Tab._jQueryInterface.call($(this), 'show'); + }); + + /** + * ------------------------------------------------------------------------ + * jQuery + * ------------------------------------------------------------------------ + */ + + $.fn[NAME] = Tab._jQueryInterface; + $.fn[NAME].Constructor = Tab; + $.fn[NAME].noConflict = function () { + $.fn[NAME] = JQUERY_NO_CONFLICT; + return Tab._jQueryInterface; + }; + + return Tab; +})(jQuery); + +/* global Tether */ + +/** + * -------------------------------------------------------------------------- + * Bootstrap (v4.0.0-alpha.2): tooltip.js + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * -------------------------------------------------------------------------- + */ + +var Tooltip = (function ($) { + + /** + * Check for Tether dependency + * Tether - http://github.hubspot.com/tether/ + */ + if (window.Tether === undefined) { + throw new Error('Bootstrap tooltips require Tether (http://github.hubspot.com/tether/)'); + } + + /** + * ------------------------------------------------------------------------ + * Constants + * ------------------------------------------------------------------------ + */ + + var NAME = 'tooltip'; + var VERSION = '4.0.0-alpha'; + var DATA_KEY = 'bs.tooltip'; + var EVENT_KEY = '.' + DATA_KEY; + var JQUERY_NO_CONFLICT = $.fn[NAME]; + var TRANSITION_DURATION = 150; + var CLASS_PREFIX = 'bs-tether'; + + var Default = { + animation: true, + template: '', + trigger: 'hover focus', + title: '', + delay: 0, + html: false, + selector: false, + placement: 'top', + offset: '0 0', + constraints: [] + }; + + var DefaultType = { + animation: 'boolean', + template: 'string', + title: '(string|element|function)', + trigger: 'string', + delay: '(number|object)', + html: 'boolean', + selector: '(string|boolean)', + placement: '(string|function)', + offset: 'string', + constraints: 'array' + }; + + var AttachmentMap = { + TOP: 'bottom center', + RIGHT: 'middle left', + BOTTOM: 'top center', + LEFT: 'middle right' + }; + + var HoverState = { + IN: 'in', + OUT: 'out' + }; + + var Event = { + HIDE: 'hide' + EVENT_KEY, + HIDDEN: 'hidden' + EVENT_KEY, + SHOW: 'show' + EVENT_KEY, + SHOWN: 'shown' + EVENT_KEY, + INSERTED: 'inserted' + EVENT_KEY, + CLICK: 'click' + EVENT_KEY, + FOCUSIN: 'focusin' + EVENT_KEY, + FOCUSOUT: 'focusout' + EVENT_KEY, + MOUSEENTER: 'mouseenter' + EVENT_KEY, + MOUSELEAVE: 'mouseleave' + EVENT_KEY + }; + + var ClassName = { + FADE: 'fade', + IN: 'in' + }; + + var Selector = { + TOOLTIP: '.tooltip', + TOOLTIP_INNER: '.tooltip-inner' + }; + + var TetherClass = { + element: false, + enabled: false + }; + + var Trigger = { + HOVER: 'hover', + FOCUS: 'focus', + CLICK: 'click', + MANUAL: 'manual' + }; + + /** + * ------------------------------------------------------------------------ + * Class Definition + * ------------------------------------------------------------------------ + */ + + var Tooltip = (function () { + function Tooltip(element, config) { + _classCallCheck(this, Tooltip); + + // private + this._isEnabled = true; + this._timeout = 0; + this._hoverState = ''; + this._activeTrigger = {}; + this._tether = null; + + // protected + this.element = element; + this.config = this._getConfig(config); + this.tip = null; + + this._setListeners(); + } + + /** + * ------------------------------------------------------------------------ + * jQuery + * ------------------------------------------------------------------------ + */ + + // getters + + _createClass(Tooltip, [{ + key: 'enable', + + // public + + value: function enable() { + this._isEnabled = true; + } + }, { + key: 'disable', + value: function disable() { + this._isEnabled = false; + } + }, { + key: 'toggleEnabled', + value: function toggleEnabled() { + this._isEnabled = !this._isEnabled; + } + }, { + key: 'toggle', + value: function toggle(event) { + 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.IN)) { + this._leave(null, this); + return; + } + + this._enter(null, this); + } + } + }, { + key: 'dispose', + value: function dispose() { + clearTimeout(this._timeout); + + this.cleanupTether(); + + $.removeData(this.element, this.constructor.DATA_KEY); + + $(this.element).off(this.constructor.EVENT_KEY); + + if (this.tip) { + $(this.tip).remove(); + } + + this._isEnabled = null; + this._timeout = null; + this._hoverState = null; + this._activeTrigger = null; + this._tether = null; + + this.element = null; + this.config = null; + this.tip = null; + } + }, { + key: 'show', + value: function show() { + var _this16 = this; + + var showEvent = $.Event(this.constructor.Event.SHOW); + + if (this.isWithContent() && this._isEnabled) { + $(this.element).trigger(showEvent); + + var isInTheDom = $.contains(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.FADE); + } + + var placement = typeof this.config.placement === 'function' ? this.config.placement.call(this, tip, this.element) : this.config.placement; + + var attachment = this._getAttachment(placement); + + $(tip).data(this.constructor.DATA_KEY, this).appendTo(document.body); + + $(this.element).trigger(this.constructor.Event.INSERTED); + + this._tether = new Tether({ + attachment: attachment, + element: tip, + target: this.element, + classes: TetherClass, + classPrefix: CLASS_PREFIX, + offset: this.config.offset, + constraints: this.config.constraints, + addTargetClasses: false + }); + + Util.reflow(tip); + this._tether.position(); + + $(tip).addClass(ClassName.IN); + + var complete = function complete() { + var prevHoverState = _this16._hoverState; + _this16._hoverState = null; + + $(_this16.element).trigger(_this16.constructor.Event.SHOWN); + + if (prevHoverState === HoverState.OUT) { + _this16._leave(null, _this16); + } + }; + + if (Util.supportsTransitionEnd() && $(this.tip).hasClass(ClassName.FADE)) { + $(this.tip).one(Util.TRANSITION_END, complete).emulateTransitionEnd(Tooltip._TRANSITION_DURATION); + return; + } + + complete(); + } + } + }, { + key: 'hide', + value: function hide(callback) { + var _this17 = this; + + var tip = this.getTipElement(); + var hideEvent = $.Event(this.constructor.Event.HIDE); + var complete = function complete() { + if (_this17._hoverState !== HoverState.IN && tip.parentNode) { + tip.parentNode.removeChild(tip); + } + + _this17.element.removeAttribute('aria-describedby'); + $(_this17.element).trigger(_this17.constructor.Event.HIDDEN); + _this17.cleanupTether(); + + if (callback) { + callback(); + } + }; + + $(this.element).trigger(hideEvent); + + if (hideEvent.isDefaultPrevented()) { + return; + } + + $(tip).removeClass(ClassName.IN); + + if (Util.supportsTransitionEnd() && $(this.tip).hasClass(ClassName.FADE)) { + + $(tip).one(Util.TRANSITION_END, complete).emulateTransitionEnd(TRANSITION_DURATION); + } else { + complete(); + } + + this._hoverState = ''; + } + + // protected + + }, { + key: 'isWithContent', + value: function isWithContent() { + return Boolean(this.getTitle()); + } + }, { + key: 'getTipElement', + value: function getTipElement() { + return this.tip = this.tip || $(this.config.template)[0]; + } + }, { + key: 'setContent', + value: function setContent() { + var $tip = $(this.getTipElement()); + + this.setElementContent($tip.find(Selector.TOOLTIP_INNER), this.getTitle()); + + $tip.removeClass(ClassName.FADE).removeClass(ClassName.IN); + + this.cleanupTether(); + } + }, { + key: 'setElementContent', + value: function setElementContent($element, content) { + var html = this.config.html; + if (typeof content === 'object' && (content.nodeType || content.jquery)) { + // content is a DOM node or a jQuery + if (html) { + if (!$(content).parent().is($element)) { + $element.empty().append(content); + } + } else { + $element.text($(content).text()); + } + } else { + $element[html ? 'html' : 'text'](content); + } + } + }, { + key: 'getTitle', + value: 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; + } + }, { + key: 'cleanupTether', + value: function cleanupTether() { + if (this._tether) { + this._tether.destroy(); + } + } + + // private + + }, { + key: '_getAttachment', + value: function _getAttachment(placement) { + return AttachmentMap[placement.toUpperCase()]; + } + }, { + key: '_setListeners', + value: function _setListeners() { + var _this18 = this; + + var triggers = this.config.trigger.split(' '); + + triggers.forEach(function (trigger) { + if (trigger === 'click') { + $(_this18.element).on(_this18.constructor.Event.CLICK, _this18.config.selector, $.proxy(_this18.toggle, _this18)); + } else if (trigger !== Trigger.MANUAL) { + var eventIn = trigger === Trigger.HOVER ? _this18.constructor.Event.MOUSEENTER : _this18.constructor.Event.FOCUSIN; + var eventOut = trigger === Trigger.HOVER ? _this18.constructor.Event.MOUSELEAVE : _this18.constructor.Event.FOCUSOUT; + + $(_this18.element).on(eventIn, _this18.config.selector, $.proxy(_this18._enter, _this18)).on(eventOut, _this18.config.selector, $.proxy(_this18._leave, _this18)); + } + }); + + if (this.config.selector) { + this.config = $.extend({}, this.config, { + trigger: 'manual', + selector: '' + }); + } else { + this._fixTitle(); + } + } + }, { + key: '_fixTitle', + value: 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', ''); + } + } + }, { + key: '_enter', + value: 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.IN) || context._hoverState === HoverState.IN) { + context._hoverState = HoverState.IN; + return; + } + + clearTimeout(context._timeout); + + context._hoverState = HoverState.IN; + + if (!context.config.delay || !context.config.delay.show) { + context.show(); + return; + } + + context._timeout = setTimeout(function () { + if (context._hoverState === HoverState.IN) { + context.show(); + } + }, context.config.delay.show); + } + }, { + key: '_leave', + value: 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); + } + }, { + key: '_isWithActiveTrigger', + value: function _isWithActiveTrigger() { + for (var trigger in this._activeTrigger) { + if (this._activeTrigger[trigger]) { + return true; + } + } + + return false; + } + }, { + key: '_getConfig', + value: function _getConfig(config) { + config = $.extend({}, this.constructor.Default, $(this.element).data(), config); + + if (config.delay && typeof config.delay === 'number') { + config.delay = { + show: config.delay, + hide: config.delay + }; + } + + Util.typeCheckConfig(NAME, config, this.constructor.DefaultType); + + return config; + } + }, { + key: '_getDelegateConfig', + value: 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; + } + + // static + + }], [{ + key: '_jQueryInterface', + value: function _jQueryInterface(config) { + return this.each(function () { + var data = $(this).data(DATA_KEY); + var _config = typeof config === 'object' ? config : null; + + if (!data && /destroy|hide/.test(config)) { + return; + } + + if (!data) { + data = new Tooltip(this, _config); + $(this).data(DATA_KEY, data); + } + + if (typeof config === 'string') { + if (data[config] === undefined) { + throw new Error('No method named "' + config + '"'); + } + data[config](); + } + }); + } + }, { + key: 'VERSION', + get: function get() { + return VERSION; + } + }, { + key: 'Default', + get: function get() { + return Default; + } + }, { + key: 'NAME', + get: function get() { + return NAME; + } + }, { + key: 'DATA_KEY', + get: function get() { + return DATA_KEY; + } + }, { + key: 'Event', + get: function get() { + return Event; + } + }, { + key: 'EVENT_KEY', + get: function get() { + return EVENT_KEY; + } + }, { + key: 'DefaultType', + get: function get() { + return DefaultType; + } + }]); + + return Tooltip; + })(); + + $.fn[NAME] = Tooltip._jQueryInterface; + $.fn[NAME].Constructor = Tooltip; + $.fn[NAME].noConflict = function () { + $.fn[NAME] = JQUERY_NO_CONFLICT; + return Tooltip._jQueryInterface; + }; + + return Tooltip; +})(jQuery); + +/** + * -------------------------------------------------------------------------- + * Bootstrap (v4.0.0-alpha.2): popover.js + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * -------------------------------------------------------------------------- + */ + +var Popover = (function ($) { + + /** + * ------------------------------------------------------------------------ + * Constants + * ------------------------------------------------------------------------ + */ + + var NAME = 'popover'; + var VERSION = '4.0.0-alpha'; + var DATA_KEY = 'bs.popover'; + var EVENT_KEY = '.' + DATA_KEY; + var JQUERY_NO_CONFLICT = $.fn[NAME]; + + var Default = $.extend({}, Tooltip.Default, { + placement: 'right', + trigger: 'click', + content: '', + template: '' + }); + + var DefaultType = $.extend({}, Tooltip.DefaultType, { + content: '(string|element|function)' + }); + + var ClassName = { + FADE: 'fade', + IN: 'in' + }; + + var Selector = { + TITLE: '.popover-title', + CONTENT: '.popover-content', + ARROW: '.popover-arrow' + }; + + var Event = { + HIDE: 'hide' + EVENT_KEY, + HIDDEN: 'hidden' + EVENT_KEY, + SHOW: 'show' + EVENT_KEY, + SHOWN: 'shown' + EVENT_KEY, + INSERTED: 'inserted' + EVENT_KEY, + CLICK: 'click' + EVENT_KEY, + FOCUSIN: 'focusin' + EVENT_KEY, + FOCUSOUT: 'focusout' + EVENT_KEY, + MOUSEENTER: 'mouseenter' + EVENT_KEY, + MOUSELEAVE: 'mouseleave' + EVENT_KEY + }; + + /** + * ------------------------------------------------------------------------ + * Class Definition + * ------------------------------------------------------------------------ + */ + + var Popover = (function (_Tooltip) { + _inherits(Popover, _Tooltip); + + function Popover() { + _classCallCheck(this, Popover); + + _get(Object.getPrototypeOf(Popover.prototype), 'constructor', this).apply(this, arguments); + } + + /** + * ------------------------------------------------------------------------ + * jQuery + * ------------------------------------------------------------------------ + */ + + _createClass(Popover, [{ + key: 'isWithContent', + + // overrides + + value: function isWithContent() { + return this.getTitle() || this._getContent(); + } + }, { + key: 'getTipElement', + value: function getTipElement() { + return this.tip = this.tip || $(this.config.template)[0]; + } + }, { + key: 'setContent', + value: function setContent() { + var $tip = $(this.getTipElement()); + + // we use append for html objects to maintain js events + this.setElementContent($tip.find(Selector.TITLE), this.getTitle()); + this.setElementContent($tip.find(Selector.CONTENT), this._getContent()); + + $tip.removeClass(ClassName.FADE).removeClass(ClassName.IN); + + this.cleanupTether(); + } + + // private + + }, { + key: '_getContent', + value: function _getContent() { + return this.element.getAttribute('data-content') || (typeof this.config.content === 'function' ? this.config.content.call(this.element) : this.config.content); + } + + // static + + }], [{ + key: '_jQueryInterface', + value: function _jQueryInterface(config) { + return this.each(function () { + var data = $(this).data(DATA_KEY); + var _config = typeof config === 'object' ? config : null; + + if (!data && /destroy|hide/.test(config)) { + return; + } + + if (!data) { + data = new Popover(this, _config); + $(this).data(DATA_KEY, data); + } + + if (typeof config === 'string') { + if (data[config] === undefined) { + throw new Error('No method named "' + config + '"'); + } + data[config](); + } + }); + } + }, { + key: 'VERSION', + + // getters + + get: function get() { + return VERSION; + } + }, { + key: 'Default', + get: function get() { + return Default; + } + }, { + key: 'NAME', + get: function get() { + return NAME; + } + }, { + key: 'DATA_KEY', + get: function get() { + return DATA_KEY; + } + }, { + key: 'Event', + get: function get() { + return Event; + } + }, { + key: 'EVENT_KEY', + get: function get() { + return EVENT_KEY; + } + }, { + key: 'DefaultType', + get: function get() { + return DefaultType; + } + }]); + + return Popover; + })(Tooltip); + + $.fn[NAME] = Popover._jQueryInterface; + $.fn[NAME].Constructor = Popover; + $.fn[NAME].noConflict = function () { + $.fn[NAME] = JQUERY_NO_CONFLICT; + return Popover._jQueryInterface; + }; + + return Popover; +})(jQuery); + +}(jQuery); diff --git a/backend/vendor/assets/javascripts/solidus_admin/tether.js b/backend/vendor/assets/javascripts/solidus_admin/tether.js new file mode 100644 index 00000000000..a670e63d668 --- /dev/null +++ b/backend/vendor/assets/javascripts/solidus_admin/tether.js @@ -0,0 +1,1726 @@ +/*! tether 1.2.0 */ + +(function(root, factory) { + if (typeof define === 'function' && define.amd) { + define(factory); + } else if (typeof exports === 'object') { + module.exports = factory(require, exports, module); + } else { + root.Tether = factory(); + } +}(this, function(require, exports, module) { + +'use strict'; + +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; }; })(); + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } + +var TetherBase = undefined; +if (typeof TetherBase === 'undefined') { + TetherBase = { modules: [] }; +} + +function getScrollParent(el) { + // In firefox if the el is inside an iframe with display: none; window.getComputedStyle() will return null; + // https://bugzilla.mozilla.org/show_bug.cgi?id=548397 + var computedStyle = getComputedStyle(el) || {}; + var position = computedStyle.position; + + if (position === 'fixed') { + return el; + } + + var parent = el; + while (parent = parent.parentNode) { + var style = undefined; + try { + style = getComputedStyle(parent); + } catch (err) {} + + if (typeof style === 'undefined' || style === null) { + return parent; + } + + var _style = style; + var overflow = _style.overflow; + var overflowX = _style.overflowX; + var overflowY = _style.overflowY; + + if (/(auto|scroll)/.test(overflow + overflowY + overflowX)) { + if (position !== 'absolute' || ['relative', 'absolute', 'fixed'].indexOf(style.position) >= 0) { + return parent; + } + } + } + + return document.body; +} + +var uniqueId = (function () { + var id = 0; + return function () { + return ++id; + }; +})(); + +var zeroPosCache = {}; +var getOrigin = function getOrigin(doc) { + // getBoundingClientRect is unfortunately too accurate. It introduces a pixel or two of + // jitter as the user scrolls that messes with our ability to detect if two positions + // are equivilant or not. We place an element at the top left of the page that will + // get the same jitter, so we can cancel the two out. + var node = doc._tetherZeroElement; + if (typeof node === 'undefined') { + node = doc.createElement('div'); + node.setAttribute('data-tether-id', uniqueId()); + extend(node.style, { + top: 0, + left: 0, + position: 'absolute' + }); + + doc.body.appendChild(node); + + doc._tetherZeroElement = node; + } + + var id = node.getAttribute('data-tether-id'); + if (typeof zeroPosCache[id] === 'undefined') { + zeroPosCache[id] = {}; + + var rect = node.getBoundingClientRect(); + for (var k in rect) { + // Can't use extend, as on IE9, elements don't resolve to be hasOwnProperty + zeroPosCache[id][k] = rect[k]; + } + + // Clear the cache when this position call is done + defer(function () { + delete zeroPosCache[id]; + }); + } + + return zeroPosCache[id]; +}; + +function getBounds(el) { + var doc = undefined; + if (el === document) { + doc = document; + el = document.documentElement; + } else { + doc = el.ownerDocument; + } + + var docEl = doc.documentElement; + + var box = {}; + // The original object returned by getBoundingClientRect is immutable, so we clone it + // We can't use extend because the properties are not considered part of the object by hasOwnProperty in IE9 + var rect = el.getBoundingClientRect(); + for (var k in rect) { + box[k] = rect[k]; + } + + var origin = getOrigin(doc); + + box.top -= origin.top; + box.left -= origin.left; + + if (typeof box.width === 'undefined') { + box.width = document.body.scrollWidth - box.left - box.right; + } + if (typeof box.height === 'undefined') { + box.height = document.body.scrollHeight - box.top - box.bottom; + } + + box.top = box.top - docEl.clientTop; + box.left = box.left - docEl.clientLeft; + box.right = doc.body.clientWidth - box.width - box.left; + box.bottom = doc.body.clientHeight - box.height - box.top; + + return box; +} + +function getOffsetParent(el) { + return el.offsetParent || document.documentElement; +} + +function getScrollBarSize() { + var inner = document.createElement('div'); + inner.style.width = '100%'; + inner.style.height = '200px'; + + var outer = document.createElement('div'); + extend(outer.style, { + position: 'absolute', + top: 0, + left: 0, + pointerEvents: 'none', + visibility: 'hidden', + width: '200px', + height: '150px', + overflow: 'hidden' + }); + + outer.appendChild(inner); + + document.body.appendChild(outer); + + var widthContained = inner.offsetWidth; + outer.style.overflow = 'scroll'; + var widthScroll = inner.offsetWidth; + + if (widthContained === widthScroll) { + widthScroll = outer.clientWidth; + } + + document.body.removeChild(outer); + + var width = widthContained - widthScroll; + + return { width: width, height: width }; +} + +function extend() { + var out = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0]; + + var args = []; + + Array.prototype.push.apply(args, arguments); + + args.slice(1).forEach(function (obj) { + if (obj) { + for (var key in obj) { + if (({}).hasOwnProperty.call(obj, key)) { + out[key] = obj[key]; + } + } + } + }); + + return out; +} + +function removeClass(el, name) { + if (typeof el.classList !== 'undefined') { + name.split(' ').forEach(function (cls) { + if (cls.trim()) { + el.classList.remove(cls); + } + }); + } else { + var regex = new RegExp('(^| )' + name.split(' ').join('|') + '( |$)', 'gi'); + var className = getClassName(el).replace(regex, ' '); + setClassName(el, className); + } +} + +function addClass(el, name) { + if (typeof el.classList !== 'undefined') { + name.split(' ').forEach(function (cls) { + if (cls.trim()) { + el.classList.add(cls); + } + }); + } else { + removeClass(el, name); + var cls = getClassName(el) + (' ' + name); + setClassName(el, cls); + } +} + +function hasClass(el, name) { + if (typeof el.classList !== 'undefined') { + return el.classList.contains(name); + } + var className = getClassName(el); + return new RegExp('(^| )' + name + '( |$)', 'gi').test(className); +} + +function getClassName(el) { + if (el.className instanceof SVGAnimatedString) { + return el.className.baseVal; + } + return el.className; +} + +function setClassName(el, className) { + el.setAttribute('class', className); +} + +function updateClasses(el, add, all) { + // Of the set of 'all' classes, we need the 'add' classes, and only the + // 'add' classes to be set. + all.forEach(function (cls) { + if (add.indexOf(cls) === -1 && hasClass(el, cls)) { + removeClass(el, cls); + } + }); + + add.forEach(function (cls) { + if (!hasClass(el, cls)) { + addClass(el, cls); + } + }); +} + +var deferred = []; + +var defer = function defer(fn) { + deferred.push(fn); +}; + +var flush = function flush() { + var fn = undefined; + while (fn = deferred.pop()) { + fn(); + } +}; + +var Evented = (function () { + function Evented() { + _classCallCheck(this, Evented); + } + + _createClass(Evented, [{ + key: 'on', + value: function on(event, handler, ctx) { + var once = arguments.length <= 3 || arguments[3] === undefined ? false : arguments[3]; + + if (typeof this.bindings === 'undefined') { + this.bindings = {}; + } + if (typeof this.bindings[event] === 'undefined') { + this.bindings[event] = []; + } + this.bindings[event].push({ handler: handler, ctx: ctx, once: once }); + } + }, { + key: 'once', + value: function once(event, handler, ctx) { + this.on(event, handler, ctx, true); + } + }, { + key: 'off', + value: function off(event, handler) { + if (typeof this.bindings !== 'undefined' && typeof this.bindings[event] !== 'undefined') { + return; + } + + if (typeof handler === 'undefined') { + delete this.bindings[event]; + } else { + var i = 0; + while (i < this.bindings[event].length) { + if (this.bindings[event][i].handler === handler) { + this.bindings[event].splice(i, 1); + } else { + ++i; + } + } + } + } + }, { + key: 'trigger', + value: function trigger(event) { + if (typeof this.bindings !== 'undefined' && this.bindings[event]) { + var i = 0; + + for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { + args[_key - 1] = arguments[_key]; + } + + while (i < this.bindings[event].length) { + var _bindings$event$i = this.bindings[event][i]; + var handler = _bindings$event$i.handler; + var ctx = _bindings$event$i.ctx; + var once = _bindings$event$i.once; + + var context = ctx; + if (typeof context === 'undefined') { + context = this; + } + + handler.apply(context, args); + + if (once) { + this.bindings[event].splice(i, 1); + } else { + ++i; + } + } + } + } + }]); + + return Evented; +})(); + +TetherBase.Utils = { + getScrollParent: getScrollParent, + getBounds: getBounds, + getOffsetParent: getOffsetParent, + extend: extend, + addClass: addClass, + removeClass: removeClass, + hasClass: hasClass, + updateClasses: updateClasses, + defer: defer, + flush: flush, + uniqueId: uniqueId, + Evented: Evented, + getScrollBarSize: getScrollBarSize +}; +/* globals TetherBase, performance */ + +'use strict'; + +var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })(); + +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; }; })(); + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } + +if (typeof TetherBase === 'undefined') { + throw new Error('You must include the utils.js file before tether.js'); +} + +var _TetherBase$Utils = TetherBase.Utils; +var getScrollParent = _TetherBase$Utils.getScrollParent; +var getBounds = _TetherBase$Utils.getBounds; +var getOffsetParent = _TetherBase$Utils.getOffsetParent; +var extend = _TetherBase$Utils.extend; +var addClass = _TetherBase$Utils.addClass; +var removeClass = _TetherBase$Utils.removeClass; +var updateClasses = _TetherBase$Utils.updateClasses; +var defer = _TetherBase$Utils.defer; +var flush = _TetherBase$Utils.flush; +var getScrollBarSize = _TetherBase$Utils.getScrollBarSize; + +function within(a, b) { + var diff = arguments.length <= 2 || arguments[2] === undefined ? 1 : arguments[2]; + + return a + diff >= b && b >= a - diff; +} + +var transformKey = (function () { + if (typeof document === 'undefined') { + return ''; + } + var el = document.createElement('div'); + + var transforms = ['transform', 'webkitTransform', 'OTransform', 'MozTransform', 'msTransform']; + for (var i = 0; i < transforms.length; ++i) { + var key = transforms[i]; + if (el.style[key] !== undefined) { + return key; + } + } +})(); + +var tethers = []; + +var position = function position() { + tethers.forEach(function (tether) { + tether.position(false); + }); + flush(); +}; + +function now() { + if (typeof performance !== 'undefined' && typeof performance.now !== 'undefined') { + return performance.now(); + } + return +new Date(); +} + +(function () { + var lastCall = null; + var lastDuration = null; + var pendingTimeout = null; + + var tick = function tick() { + if (typeof lastDuration !== 'undefined' && lastDuration > 16) { + // We voluntarily throttle ourselves if we can't manage 60fps + lastDuration = Math.min(lastDuration - 16, 250); + + // Just in case this is the last event, remember to position just once more + pendingTimeout = setTimeout(tick, 250); + return; + } + + if (typeof lastCall !== 'undefined' && now() - lastCall < 10) { + // Some browsers call events a little too frequently, refuse to run more than is reasonable + return; + } + + if (typeof pendingTimeout !== 'undefined') { + clearTimeout(pendingTimeout); + pendingTimeout = null; + } + + lastCall = now(); + position(); + lastDuration = now() - lastCall; + }; + + if (typeof window !== 'undefined') { + ['resize', 'scroll', 'touchmove'].forEach(function (event) { + window.addEventListener(event, tick); + }); + } +})(); + +var MIRROR_LR = { + center: 'center', + left: 'right', + right: 'left' +}; + +var MIRROR_TB = { + middle: 'middle', + top: 'bottom', + bottom: 'top' +}; + +var OFFSET_MAP = { + top: 0, + left: 0, + middle: '50%', + center: '50%', + bottom: '100%', + right: '100%' +}; + +var autoToFixedAttachment = function autoToFixedAttachment(attachment, relativeToAttachment) { + var left = attachment.left; + var top = attachment.top; + + if (left === 'auto') { + left = MIRROR_LR[relativeToAttachment.left]; + } + + if (top === 'auto') { + top = MIRROR_TB[relativeToAttachment.top]; + } + + return { left: left, top: top }; +}; + +var attachmentToOffset = function attachmentToOffset(attachment) { + var left = attachment.left; + var top = attachment.top; + + if (typeof OFFSET_MAP[attachment.left] !== 'undefined') { + left = OFFSET_MAP[attachment.left]; + } + + if (typeof OFFSET_MAP[attachment.top] !== 'undefined') { + top = OFFSET_MAP[attachment.top]; + } + + return { left: left, top: top }; +}; + +function addOffset() { + var out = { top: 0, left: 0 }; + + for (var _len = arguments.length, offsets = Array(_len), _key = 0; _key < _len; _key++) { + offsets[_key] = arguments[_key]; + } + + offsets.forEach(function (_ref) { + var top = _ref.top; + var left = _ref.left; + + if (typeof top === 'string') { + top = parseFloat(top, 10); + } + if (typeof left === 'string') { + left = parseFloat(left, 10); + } + + out.top += top; + out.left += left; + }); + + return out; +} + +function offsetToPx(offset, size) { + if (typeof offset.left === 'string' && offset.left.indexOf('%') !== -1) { + offset.left = parseFloat(offset.left, 10) / 100 * size.width; + } + if (typeof offset.top === 'string' && offset.top.indexOf('%') !== -1) { + offset.top = parseFloat(offset.top, 10) / 100 * size.height; + } + + return offset; +} + +var parseOffset = function parseOffset(value) { + var _value$split = value.split(' '); + + var _value$split2 = _slicedToArray(_value$split, 2); + + var top = _value$split2[0]; + var left = _value$split2[1]; + + return { top: top, left: left }; +}; +var parseAttachment = parseOffset; + +var TetherClass = (function () { + function TetherClass(options) { + var _this = this; + + _classCallCheck(this, TetherClass); + + this.position = this.position.bind(this); + + tethers.push(this); + + this.history = []; + + this.setOptions(options, false); + + TetherBase.modules.forEach(function (module) { + if (typeof module.initialize !== 'undefined') { + module.initialize.call(_this); + } + }); + + this.position(); + } + + _createClass(TetherClass, [{ + key: 'getClass', + value: function getClass() { + var key = arguments.length <= 0 || arguments[0] === undefined ? '' : arguments[0]; + var classes = this.options.classes; + + if (typeof classes !== 'undefined' && classes[key]) { + return this.options.classes[key]; + } else if (this.options.classPrefix) { + return this.options.classPrefix + '-' + key; + } else { + return key; + } + } + }, { + key: 'setOptions', + value: function setOptions(options) { + var _this2 = this; + + var pos = arguments.length <= 1 || arguments[1] === undefined ? true : arguments[1]; + + var defaults = { + offset: '0 0', + targetOffset: '0 0', + targetAttachment: 'auto auto', + classPrefix: 'tether' + }; + + this.options = extend(defaults, options); + + var _options = this.options; + var element = _options.element; + var target = _options.target; + var targetModifier = _options.targetModifier; + + this.element = element; + this.target = target; + this.targetModifier = targetModifier; + + if (this.target === 'viewport') { + this.target = document.body; + this.targetModifier = 'visible'; + } else if (this.target === 'scroll-handle') { + this.target = document.body; + this.targetModifier = 'scroll-handle'; + } + + ['element', 'target'].forEach(function (key) { + if (typeof _this2[key] === 'undefined') { + throw new Error('Tether Error: Both element and target must be defined'); + } + + if (typeof _this2[key].jquery !== 'undefined') { + _this2[key] = _this2[key][0]; + } else if (typeof _this2[key] === 'string') { + _this2[key] = document.querySelector(_this2[key]); + } + }); + + addClass(this.element, this.getClass('element')); + if (!(this.options.addTargetClasses === false)) { + addClass(this.target, this.getClass('target')); + } + + if (!this.options.attachment) { + throw new Error('Tether Error: You must provide an attachment'); + } + + this.targetAttachment = parseAttachment(this.options.targetAttachment); + this.attachment = parseAttachment(this.options.attachment); + this.offset = parseOffset(this.options.offset); + this.targetOffset = parseOffset(this.options.targetOffset); + + if (typeof this.scrollParent !== 'undefined') { + this.disable(); + } + + if (this.targetModifier === 'scroll-handle') { + this.scrollParent = this.target; + } else { + this.scrollParent = getScrollParent(this.target); + } + + if (!(this.options.enabled === false)) { + this.enable(pos); + } + } + }, { + key: 'getTargetBounds', + value: function getTargetBounds() { + if (typeof this.targetModifier !== 'undefined') { + if (this.targetModifier === 'visible') { + if (this.target === document.body) { + return { top: pageYOffset, left: pageXOffset, height: innerHeight, width: innerWidth }; + } else { + var bounds = getBounds(this.target); + + var out = { + height: bounds.height, + width: bounds.width, + top: bounds.top, + left: bounds.left + }; + + out.height = Math.min(out.height, bounds.height - (pageYOffset - bounds.top)); + out.height = Math.min(out.height, bounds.height - (bounds.top + bounds.height - (pageYOffset + innerHeight))); + out.height = Math.min(innerHeight, out.height); + out.height -= 2; + + out.width = Math.min(out.width, bounds.width - (pageXOffset - bounds.left)); + out.width = Math.min(out.width, bounds.width - (bounds.left + bounds.width - (pageXOffset + innerWidth))); + out.width = Math.min(innerWidth, out.width); + out.width -= 2; + + if (out.top < pageYOffset) { + out.top = pageYOffset; + } + if (out.left < pageXOffset) { + out.left = pageXOffset; + } + + return out; + } + } else if (this.targetModifier === 'scroll-handle') { + var bounds = undefined; + var target = this.target; + if (target === document.body) { + target = document.documentElement; + + bounds = { + left: pageXOffset, + top: pageYOffset, + height: innerHeight, + width: innerWidth + }; + } else { + bounds = getBounds(target); + } + + var style = getComputedStyle(target); + + var hasBottomScroll = target.scrollWidth > target.clientWidth || [style.overflow, style.overflowX].indexOf('scroll') >= 0 || this.target !== document.body; + + var scrollBottom = 0; + if (hasBottomScroll) { + scrollBottom = 15; + } + + var height = bounds.height - parseFloat(style.borderTopWidth) - parseFloat(style.borderBottomWidth) - scrollBottom; + + var out = { + width: 15, + height: height * 0.975 * (height / target.scrollHeight), + left: bounds.left + bounds.width - parseFloat(style.borderLeftWidth) - 15 + }; + + var fitAdj = 0; + if (height < 408 && this.target === document.body) { + fitAdj = -0.00011 * Math.pow(height, 2) - 0.00727 * height + 22.58; + } + + if (this.target !== document.body) { + out.height = Math.max(out.height, 24); + } + + var scrollPercentage = this.target.scrollTop / (target.scrollHeight - height); + out.top = scrollPercentage * (height - out.height - fitAdj) + bounds.top + parseFloat(style.borderTopWidth); + + if (this.target === document.body) { + out.height = Math.max(out.height, 24); + } + + return out; + } + } else { + return getBounds(this.target); + } + } + }, { + key: 'clearCache', + value: function clearCache() { + this._cache = {}; + } + }, { + key: 'cache', + value: function cache(k, getter) { + // More than one module will often need the same DOM info, so + // we keep a cache which is cleared on each position call + if (typeof this._cache === 'undefined') { + this._cache = {}; + } + + if (typeof this._cache[k] === 'undefined') { + this._cache[k] = getter.call(this); + } + + return this._cache[k]; + } + }, { + key: 'enable', + value: function enable() { + var pos = arguments.length <= 0 || arguments[0] === undefined ? true : arguments[0]; + + if (!(this.options.addTargetClasses === false)) { + addClass(this.target, this.getClass('enabled')); + } + addClass(this.element, this.getClass('enabled')); + this.enabled = true; + + if (this.scrollParent !== document) { + this.scrollParent.addEventListener('scroll', this.position); + } + + if (pos) { + this.position(); + } + } + }, { + key: 'disable', + value: function disable() { + removeClass(this.target, this.getClass('enabled')); + removeClass(this.element, this.getClass('enabled')); + this.enabled = false; + + if (typeof this.scrollParent !== 'undefined') { + this.scrollParent.removeEventListener('scroll', this.position); + } + } + }, { + key: 'destroy', + value: function destroy() { + var _this3 = this; + + this.disable(); + + tethers.forEach(function (tether, i) { + if (tether === _this3) { + tethers.splice(i, 1); + return; + } + }); + } + }, { + key: 'updateAttachClasses', + value: function updateAttachClasses(elementAttach, targetAttach) { + var _this4 = this; + + elementAttach = elementAttach || this.attachment; + targetAttach = targetAttach || this.targetAttachment; + var sides = ['left', 'top', 'bottom', 'right', 'middle', 'center']; + + if (typeof this._addAttachClasses !== 'undefined' && this._addAttachClasses.length) { + // updateAttachClasses can be called more than once in a position call, so + // we need to clean up after ourselves such that when the last defer gets + // ran it doesn't add any extra classes from previous calls. + this._addAttachClasses.splice(0, this._addAttachClasses.length); + } + + if (typeof this._addAttachClasses === 'undefined') { + this._addAttachClasses = []; + } + var add = this._addAttachClasses; + + if (elementAttach.top) { + add.push(this.getClass('element-attached') + '-' + elementAttach.top); + } + if (elementAttach.left) { + add.push(this.getClass('element-attached') + '-' + elementAttach.left); + } + if (targetAttach.top) { + add.push(this.getClass('target-attached') + '-' + targetAttach.top); + } + if (targetAttach.left) { + add.push(this.getClass('target-attached') + '-' + targetAttach.left); + } + + var all = []; + sides.forEach(function (side) { + all.push(_this4.getClass('element-attached') + '-' + side); + all.push(_this4.getClass('target-attached') + '-' + side); + }); + + defer(function () { + if (!(typeof _this4._addAttachClasses !== 'undefined')) { + return; + } + + updateClasses(_this4.element, _this4._addAttachClasses, all); + if (!(_this4.options.addTargetClasses === false)) { + updateClasses(_this4.target, _this4._addAttachClasses, all); + } + + delete _this4._addAttachClasses; + }); + } + }, { + key: 'position', + value: function position() { + var _this5 = this; + + var flushChanges = arguments.length <= 0 || arguments[0] === undefined ? true : arguments[0]; + + // flushChanges commits the changes immediately, leave true unless you are positioning multiple + // tethers (in which case call Tether.Utils.flush yourself when you're done) + + if (!this.enabled) { + return; + } + + this.clearCache(); + + // Turn 'auto' attachments into the appropriate corner or edge + var targetAttachment = autoToFixedAttachment(this.targetAttachment, this.attachment); + + this.updateAttachClasses(this.attachment, targetAttachment); + + var elementPos = this.cache('element-bounds', function () { + return getBounds(_this5.element); + }); + + var width = elementPos.width; + var height = elementPos.height; + + if (width === 0 && height === 0 && typeof this.lastSize !== 'undefined') { + var _lastSize = this.lastSize; + + // We cache the height and width to make it possible to position elements that are + // getting hidden. + width = _lastSize.width; + height = _lastSize.height; + } else { + this.lastSize = { width: width, height: height }; + } + + var targetPos = this.cache('target-bounds', function () { + return _this5.getTargetBounds(); + }); + var targetSize = targetPos; + + // Get an actual px offset from the attachment + var offset = offsetToPx(attachmentToOffset(this.attachment), { width: width, height: height }); + var targetOffset = offsetToPx(attachmentToOffset(targetAttachment), targetSize); + + var manualOffset = offsetToPx(this.offset, { width: width, height: height }); + var manualTargetOffset = offsetToPx(this.targetOffset, targetSize); + + // Add the manually provided offset + offset = addOffset(offset, manualOffset); + targetOffset = addOffset(targetOffset, manualTargetOffset); + + // It's now our goal to make (element position + offset) == (target position + target offset) + var left = targetPos.left + targetOffset.left - offset.left; + var top = targetPos.top + targetOffset.top - offset.top; + + for (var i = 0; i < TetherBase.modules.length; ++i) { + var _module2 = TetherBase.modules[i]; + var ret = _module2.position.call(this, { + left: left, + top: top, + targetAttachment: targetAttachment, + targetPos: targetPos, + elementPos: elementPos, + offset: offset, + targetOffset: targetOffset, + manualOffset: manualOffset, + manualTargetOffset: manualTargetOffset, + scrollbarSize: scrollbarSize, + attachment: this.attachment + }); + + if (ret === false) { + return false; + } else if (typeof ret === 'undefined' || typeof ret !== 'object') { + continue; + } else { + top = ret.top; + left = ret.left; + } + } + + // We describe the position three different ways to give the optimizer + // a chance to decide the best possible way to position the element + // with the fewest repaints. + var next = { + // It's position relative to the page (absolute positioning when + // the element is a child of the body) + page: { + top: top, + left: left + }, + + // It's position relative to the viewport (fixed positioning) + viewport: { + top: top - pageYOffset, + bottom: pageYOffset - top - height + innerHeight, + left: left - pageXOffset, + right: pageXOffset - left - width + innerWidth + } + }; + + var scrollbarSize = undefined; + if (document.body.scrollWidth > window.innerWidth) { + scrollbarSize = this.cache('scrollbar-size', getScrollBarSize); + next.viewport.bottom -= scrollbarSize.height; + } + + if (document.body.scrollHeight > window.innerHeight) { + scrollbarSize = this.cache('scrollbar-size', getScrollBarSize); + next.viewport.right -= scrollbarSize.width; + } + + if (['', 'static'].indexOf(document.body.style.position) === -1 || ['', 'static'].indexOf(document.body.parentElement.style.position) === -1) { + // Absolute positioning in the body will be relative to the page, not the 'initial containing block' + next.page.bottom = document.body.scrollHeight - top - height; + next.page.right = document.body.scrollWidth - left - width; + } + + if (typeof this.options.optimizations !== 'undefined' && this.options.optimizations.moveElement !== false && !(typeof this.targetModifier !== 'undefined')) { + (function () { + var offsetParent = _this5.cache('target-offsetparent', function () { + return getOffsetParent(_this5.target); + }); + var offsetPosition = _this5.cache('target-offsetparent-bounds', function () { + return getBounds(offsetParent); + }); + var offsetParentStyle = getComputedStyle(offsetParent); + var offsetParentSize = offsetPosition; + + var offsetBorder = {}; + ['Top', 'Left', 'Bottom', 'Right'].forEach(function (side) { + offsetBorder[side.toLowerCase()] = parseFloat(offsetParentStyle['border' + side + 'Width']); + }); + + offsetPosition.right = document.body.scrollWidth - offsetPosition.left - offsetParentSize.width + offsetBorder.right; + offsetPosition.bottom = document.body.scrollHeight - offsetPosition.top - offsetParentSize.height + offsetBorder.bottom; + + if (next.page.top >= offsetPosition.top + offsetBorder.top && next.page.bottom >= offsetPosition.bottom) { + if (next.page.left >= offsetPosition.left + offsetBorder.left && next.page.right >= offsetPosition.right) { + // We're within the visible part of the target's scroll parent + var scrollTop = offsetParent.scrollTop; + var scrollLeft = offsetParent.scrollLeft; + + // It's position relative to the target's offset parent (absolute positioning when + // the element is moved to be a child of the target's offset parent). + next.offset = { + top: next.page.top - offsetPosition.top + scrollTop - offsetBorder.top, + left: next.page.left - offsetPosition.left + scrollLeft - offsetBorder.left + }; + } + } + })(); + } + + // We could also travel up the DOM and try each containing context, rather than only + // looking at the body, but we're gonna get diminishing returns. + + this.move(next); + + this.history.unshift(next); + + if (this.history.length > 3) { + this.history.pop(); + } + + if (flushChanges) { + flush(); + } + + return true; + } + + // THE ISSUE + }, { + key: 'move', + value: function move(pos) { + var _this6 = this; + + if (!(typeof this.element.parentNode !== 'undefined')) { + return; + } + + var same = {}; + + for (var type in pos) { + same[type] = {}; + + for (var key in pos[type]) { + var found = false; + + for (var i = 0; i < this.history.length; ++i) { + var point = this.history[i]; + if (typeof point[type] !== 'undefined' && !within(point[type][key], pos[type][key])) { + found = true; + break; + } + } + + if (!found) { + same[type][key] = true; + } + } + } + + var css = { top: '', left: '', right: '', bottom: '' }; + + var transcribe = function transcribe(_same, _pos) { + var hasOptimizations = typeof _this6.options.optimizations !== 'undefined'; + var gpu = hasOptimizations ? _this6.options.optimizations.gpu : null; + if (gpu !== false) { + var yPos = undefined, + xPos = undefined; + if (_same.top) { + css.top = 0; + yPos = _pos.top; + } else { + css.bottom = 0; + yPos = -_pos.bottom; + } + + if (_same.left) { + css.left = 0; + xPos = _pos.left; + } else { + css.right = 0; + xPos = -_pos.right; + } + + css[transformKey] = 'translateX(' + Math.round(xPos) + 'px) translateY(' + Math.round(yPos) + 'px)'; + + if (transformKey !== 'msTransform') { + // The Z transform will keep this in the GPU (faster, and prevents artifacts), + // but IE9 doesn't support 3d transforms and will choke. + css[transformKey] += " translateZ(0)"; + } + } else { + if (_same.top) { + css.top = _pos.top + 'px'; + } else { + css.bottom = _pos.bottom + 'px'; + } + + if (_same.left) { + css.left = _pos.left + 'px'; + } else { + css.right = _pos.right + 'px'; + } + } + }; + + var moved = false; + if ((same.page.top || same.page.bottom) && (same.page.left || same.page.right)) { + css.position = 'absolute'; + transcribe(same.page, pos.page); + } else if ((same.viewport.top || same.viewport.bottom) && (same.viewport.left || same.viewport.right)) { + css.position = 'fixed'; + transcribe(same.viewport, pos.viewport); + } else if (typeof same.offset !== 'undefined' && same.offset.top && same.offset.left) { + (function () { + css.position = 'absolute'; + var offsetParent = _this6.cache('target-offsetparent', function () { + return getOffsetParent(_this6.target); + }); + + if (getOffsetParent(_this6.element) !== offsetParent) { + defer(function () { + _this6.element.parentNode.removeChild(_this6.element); + offsetParent.appendChild(_this6.element); + }); + } + + transcribe(same.offset, pos.offset); + moved = true; + })(); + } else { + css.position = 'absolute'; + transcribe({ top: true, left: true }, pos.page); + } + + if (!moved) { + var offsetParentIsBody = true; + var currentNode = this.element.parentNode; + while (currentNode && currentNode.tagName !== 'BODY') { + if (getComputedStyle(currentNode).position !== 'static') { + offsetParentIsBody = false; + break; + } + + currentNode = currentNode.parentNode; + } + + if (!offsetParentIsBody) { + this.element.parentNode.removeChild(this.element); + document.body.appendChild(this.element); + } + } + + // Any css change will trigger a repaint, so let's avoid one if nothing changed + var writeCSS = {}; + var write = false; + for (var key in css) { + var val = css[key]; + var elVal = this.element.style[key]; + + if (elVal !== '' && val !== '' && ['top', 'left', 'bottom', 'right'].indexOf(key) >= 0) { + elVal = parseFloat(elVal); + val = parseFloat(val); + } + + if (elVal !== val) { + write = true; + writeCSS[key] = val; + } + } + + if (write) { + defer(function () { + extend(_this6.element.style, writeCSS); + }); + } + } + }]); + + return TetherClass; +})(); + +TetherClass.modules = []; + +TetherBase.position = position; + +var Tether = extend(TetherClass, TetherBase); +/* globals TetherBase */ + +'use strict'; + +var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })(); + +var _TetherBase$Utils = TetherBase.Utils; +var getBounds = _TetherBase$Utils.getBounds; +var extend = _TetherBase$Utils.extend; +var updateClasses = _TetherBase$Utils.updateClasses; +var defer = _TetherBase$Utils.defer; + +var BOUNDS_FORMAT = ['left', 'top', 'right', 'bottom']; + +function getBoundingRect(tether, to) { + if (to === 'scrollParent') { + to = tether.scrollParent; + } else if (to === 'window') { + to = [pageXOffset, pageYOffset, innerWidth + pageXOffset, innerHeight + pageYOffset]; + } + + if (to === document) { + to = to.documentElement; + } + + if (typeof to.nodeType !== 'undefined') { + (function () { + var size = getBounds(to); + var pos = size; + var style = getComputedStyle(to); + + to = [pos.left, pos.top, size.width + pos.left, size.height + pos.top]; + + BOUNDS_FORMAT.forEach(function (side, i) { + side = side[0].toUpperCase() + side.substr(1); + if (side === 'Top' || side === 'Left') { + to[i] += parseFloat(style['border' + side + 'Width']); + } else { + to[i] -= parseFloat(style['border' + side + 'Width']); + } + }); + })(); + } + + return to; +} + +TetherBase.modules.push({ + position: function position(_ref) { + var _this = this; + + var top = _ref.top; + var left = _ref.left; + var targetAttachment = _ref.targetAttachment; + + if (!this.options.constraints) { + return true; + } + + var _cache = this.cache('element-bounds', function () { + return getBounds(_this.element); + }); + + var height = _cache.height; + var width = _cache.width; + + if (width === 0 && height === 0 && typeof this.lastSize !== 'undefined') { + var _lastSize = this.lastSize; + + // Handle the item getting hidden as a result of our positioning without glitching + // the classes in and out + width = _lastSize.width; + height = _lastSize.height; + } + + var targetSize = this.cache('target-bounds', function () { + return _this.getTargetBounds(); + }); + + var targetHeight = targetSize.height; + var targetWidth = targetSize.width; + + var allClasses = [this.getClass('pinned'), this.getClass('out-of-bounds')]; + + this.options.constraints.forEach(function (constraint) { + var outOfBoundsClass = constraint.outOfBoundsClass; + var pinnedClass = constraint.pinnedClass; + + if (outOfBoundsClass) { + allClasses.push(outOfBoundsClass); + } + if (pinnedClass) { + allClasses.push(pinnedClass); + } + }); + + allClasses.forEach(function (cls) { + ['left', 'top', 'right', 'bottom'].forEach(function (side) { + allClasses.push(cls + '-' + side); + }); + }); + + var addClasses = []; + + var tAttachment = extend({}, targetAttachment); + var eAttachment = extend({}, this.attachment); + + this.options.constraints.forEach(function (constraint) { + var to = constraint.to; + var attachment = constraint.attachment; + var pin = constraint.pin; + + if (typeof attachment === 'undefined') { + attachment = ''; + } + + var changeAttachX = undefined, + changeAttachY = undefined; + if (attachment.indexOf(' ') >= 0) { + var _attachment$split = attachment.split(' '); + + var _attachment$split2 = _slicedToArray(_attachment$split, 2); + + changeAttachY = _attachment$split2[0]; + changeAttachX = _attachment$split2[1]; + } else { + changeAttachX = changeAttachY = attachment; + } + + var bounds = getBoundingRect(_this, to); + + if (changeAttachY === 'target' || changeAttachY === 'both') { + if (top < bounds[1] && tAttachment.top === 'top') { + top += targetHeight; + tAttachment.top = 'bottom'; + } + + if (top + height > bounds[3] && tAttachment.top === 'bottom') { + top -= targetHeight; + tAttachment.top = 'top'; + } + } + + if (changeAttachY === 'together') { + if (top < bounds[1] && tAttachment.top === 'top') { + if (eAttachment.top === 'bottom') { + top += targetHeight; + tAttachment.top = 'bottom'; + + top += height; + eAttachment.top = 'top'; + } else if (eAttachment.top === 'top') { + top += targetHeight; + tAttachment.top = 'bottom'; + + top -= height; + eAttachment.top = 'bottom'; + } + } + + if (top + height > bounds[3] && tAttachment.top === 'bottom') { + if (eAttachment.top === 'top') { + top -= targetHeight; + tAttachment.top = 'top'; + + top -= height; + eAttachment.top = 'bottom'; + } else if (eAttachment.top === 'bottom') { + top -= targetHeight; + tAttachment.top = 'top'; + + top += height; + eAttachment.top = 'top'; + } + } + + if (tAttachment.top === 'middle') { + if (top + height > bounds[3] && eAttachment.top === 'top') { + top -= height; + eAttachment.top = 'bottom'; + } else if (top < bounds[1] && eAttachment.top === 'bottom') { + top += height; + eAttachment.top = 'top'; + } + } + } + + if (changeAttachX === 'target' || changeAttachX === 'both') { + if (left < bounds[0] && tAttachment.left === 'left') { + left += targetWidth; + tAttachment.left = 'right'; + } + + if (left + width > bounds[2] && tAttachment.left === 'right') { + left -= targetWidth; + tAttachment.left = 'left'; + } + } + + if (changeAttachX === 'together') { + if (left < bounds[0] && tAttachment.left === 'left') { + if (eAttachment.left === 'right') { + left += targetWidth; + tAttachment.left = 'right'; + + left += width; + eAttachment.left = 'left'; + } else if (eAttachment.left === 'left') { + left += targetWidth; + tAttachment.left = 'right'; + + left -= width; + eAttachment.left = 'right'; + } + } else if (left + width > bounds[2] && tAttachment.left === 'right') { + if (eAttachment.left === 'left') { + left -= targetWidth; + tAttachment.left = 'left'; + + left -= width; + eAttachment.left = 'right'; + } else if (eAttachment.left === 'right') { + left -= targetWidth; + tAttachment.left = 'left'; + + left += width; + eAttachment.left = 'left'; + } + } else if (tAttachment.left === 'center') { + if (left + width > bounds[2] && eAttachment.left === 'left') { + left -= width; + eAttachment.left = 'right'; + } else if (left < bounds[0] && eAttachment.left === 'right') { + left += width; + eAttachment.left = 'left'; + } + } + } + + if (changeAttachY === 'element' || changeAttachY === 'both') { + if (top < bounds[1] && eAttachment.top === 'bottom') { + top += height; + eAttachment.top = 'top'; + } + + if (top + height > bounds[3] && eAttachment.top === 'top') { + top -= height; + eAttachment.top = 'bottom'; + } + } + + if (changeAttachX === 'element' || changeAttachX === 'both') { + if (left < bounds[0]) { + if (eAttachment.left === 'right') { + left += width; + eAttachment.left = 'left'; + } else if (eAttachment.left === 'center') { + left += width / 2; + eAttachment.left = 'left'; + } + } + + if (left + width > bounds[2]) { + if (eAttachment.left === 'left') { + left -= width; + eAttachment.left = 'right'; + } else if (eAttachment.left === 'center') { + left -= width / 2; + eAttachment.left = 'right'; + } + } + } + + if (typeof pin === 'string') { + pin = pin.split(',').map(function (p) { + return p.trim(); + }); + } else if (pin === true) { + pin = ['top', 'left', 'right', 'bottom']; + } + + pin = pin || []; + + var pinned = []; + var oob = []; + + if (top < bounds[1]) { + if (pin.indexOf('top') >= 0) { + top = bounds[1]; + pinned.push('top'); + } else { + oob.push('top'); + } + } + + if (top + height > bounds[3]) { + if (pin.indexOf('bottom') >= 0) { + top = bounds[3] - height; + pinned.push('bottom'); + } else { + oob.push('bottom'); + } + } + + if (left < bounds[0]) { + if (pin.indexOf('left') >= 0) { + left = bounds[0]; + pinned.push('left'); + } else { + oob.push('left'); + } + } + + if (left + width > bounds[2]) { + if (pin.indexOf('right') >= 0) { + left = bounds[2] - width; + pinned.push('right'); + } else { + oob.push('right'); + } + } + + if (pinned.length) { + (function () { + var pinnedClass = undefined; + if (typeof _this.options.pinnedClass !== 'undefined') { + pinnedClass = _this.options.pinnedClass; + } else { + pinnedClass = _this.getClass('pinned'); + } + + addClasses.push(pinnedClass); + pinned.forEach(function (side) { + addClasses.push(pinnedClass + '-' + side); + }); + })(); + } + + if (oob.length) { + (function () { + var oobClass = undefined; + if (typeof _this.options.outOfBoundsClass !== 'undefined') { + oobClass = _this.options.outOfBoundsClass; + } else { + oobClass = _this.getClass('out-of-bounds'); + } + + addClasses.push(oobClass); + oob.forEach(function (side) { + addClasses.push(oobClass + '-' + side); + }); + })(); + } + + if (pinned.indexOf('left') >= 0 || pinned.indexOf('right') >= 0) { + eAttachment.left = tAttachment.left = false; + } + if (pinned.indexOf('top') >= 0 || pinned.indexOf('bottom') >= 0) { + eAttachment.top = tAttachment.top = false; + } + + if (tAttachment.top !== targetAttachment.top || tAttachment.left !== targetAttachment.left || eAttachment.top !== _this.attachment.top || eAttachment.left !== _this.attachment.left) { + _this.updateAttachClasses(eAttachment, tAttachment); + } + }); + + defer(function () { + if (!(_this.options.addTargetClasses === false)) { + updateClasses(_this.target, addClasses, allClasses); + } + updateClasses(_this.element, addClasses, allClasses); + }); + + return { top: top, left: left }; + } +}); +/* globals TetherBase */ + +'use strict'; + +var _TetherBase$Utils = TetherBase.Utils; +var getBounds = _TetherBase$Utils.getBounds; +var updateClasses = _TetherBase$Utils.updateClasses; +var defer = _TetherBase$Utils.defer; + +TetherBase.modules.push({ + position: function position(_ref) { + var _this = this; + + var top = _ref.top; + var left = _ref.left; + + var _cache = this.cache('element-bounds', function () { + return getBounds(_this.element); + }); + + var height = _cache.height; + var width = _cache.width; + + var targetPos = this.getTargetBounds(); + + var bottom = top + height; + var right = left + width; + + var abutted = []; + if (top <= targetPos.bottom && bottom >= targetPos.top) { + ['left', 'right'].forEach(function (side) { + var targetPosSide = targetPos[side]; + if (targetPosSide === left || targetPosSide === right) { + abutted.push(side); + } + }); + } + + if (left <= targetPos.right && right >= targetPos.left) { + ['top', 'bottom'].forEach(function (side) { + var targetPosSide = targetPos[side]; + if (targetPosSide === top || targetPosSide === bottom) { + abutted.push(side); + } + }); + } + + var allClasses = []; + var addClasses = []; + + var sides = ['left', 'top', 'right', 'bottom']; + allClasses.push(this.getClass('abutted')); + sides.forEach(function (side) { + allClasses.push(_this.getClass('abutted') + '-' + side); + }); + + if (abutted.length) { + addClasses.push(this.getClass('abutted')); + } + + abutted.forEach(function (side) { + addClasses.push(_this.getClass('abutted') + '-' + side); + }); + + defer(function () { + if (!(_this.options.addTargetClasses === false)) { + updateClasses(_this.target, addClasses, allClasses); + } + updateClasses(_this.element, addClasses, allClasses); + }); + + return true; + } +}); +/* globals TetherBase */ + +'use strict'; + +var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })(); + +TetherBase.modules.push({ + position: function position(_ref) { + var top = _ref.top; + var left = _ref.left; + + if (!this.options.shift) { + return; + } + + var shift = this.options.shift; + if (typeof this.options.shift === 'function') { + shift = this.options.shift.call(this, { top: top, left: left }); + } + + var shiftTop = undefined, + shiftLeft = undefined; + if (typeof shift === 'string') { + shift = shift.split(' '); + shift[1] = shift[1] || shift[0]; + + var _shift = shift; + + var _shift2 = _slicedToArray(_shift, 2); + + shiftTop = _shift2[0]; + shiftLeft = _shift2[1]; + + shiftTop = parseFloat(shiftTop, 10); + shiftLeft = parseFloat(shiftLeft, 10); + } else { + shiftTop = shift.top; + shiftLeft = shift.left; + } + + top += shiftTop; + left += shiftLeft; + + return { top: top, left: left }; + } +}); +return Tether; + +})); diff --git a/backend/vendor/assets/stylesheets/bootstrap/components/_media.scss b/backend/vendor/assets/stylesheets/bootstrap/components/_media.scss deleted file mode 100644 index a6bf7819246..00000000000 --- a/backend/vendor/assets/stylesheets/bootstrap/components/_media.scss +++ /dev/null @@ -1,61 +0,0 @@ -.media { - // Proper spacing between instances of .media - margin-top: 15px; - - &:first-child { - margin-top: 0; - } -} - -.media, -.media-body { - zoom: 1; - overflow: hidden; -} - -.media-body { - width: 10000px; -} - -.media-object { - display: block; -} - -.media-right, -.media > .pull-right { - padding-left: 10px; -} - -.media-left, -.media > .pull-left { - padding-right: 10px; -} - -.media-left, -.media-right, -.media-body { - display: table-cell; - vertical-align: top; -} - -.media-middle { - vertical-align: middle; -} - -.media-bottom { - vertical-align: bottom; -} - -// Reset margins on headings for tighter default spacing -.media-heading { - margin-top: 0; - margin-bottom: 5px; -} - -// Media list variation -// -// Undo default ul/ol styles -.media-list { - padding-left: 0; - list-style: none; -} diff --git a/backend/vendor/assets/stylesheets/solidus_admin/bootstrap/_alert.scss b/backend/vendor/assets/stylesheets/solidus_admin/bootstrap/_alert.scss new file mode 100644 index 00000000000..b9f6c60dad2 --- /dev/null +++ b/backend/vendor/assets/stylesheets/solidus_admin/bootstrap/_alert.scss @@ -0,0 +1,65 @@ +// +// Base styles +// + +.alert { + padding: $alert-padding; + margin-bottom: $spacer-y; + border: $alert-border-width solid transparent; + @include border-radius($alert-border-radius); + + // Improve alignment and spacing of inner content + > p, + > ul { + margin-bottom: 0; + } + > p + p { + margin-top: 5px; + } +} + +// Headings for larger alerts +.alert-heading { + // Specified to prevent conflicts of changing $headings-color + color: inherit; +} + +// Provide class for links that match alerts +.alert-link { + font-weight: $alert-link-font-weight; +} + + +// Dismissible alerts +// +// Expand the right padding and account for the close button's positioning. + +.alert-dismissible { + padding-right: ($alert-padding + 20); + + // Adjust close link position + .close { + position: relative; + top: -2px; + right: -21px; + color: inherit; + } +} + + +// Alternate styles +// +// Generate contextual modifier classes for colorizing the alert. + +.alert-success { + @include alert-variant($alert-success-bg, $alert-success-border, $alert-success-text); +} +.alert-info { + @include alert-variant($alert-info-bg, $alert-info-border, $alert-info-text); +} +.alert-warning { + @include alert-variant($alert-warning-bg, $alert-warning-border, $alert-warning-text); +} +.alert-danger { + @include alert-variant($alert-danger-bg, $alert-danger-border, $alert-danger-text); +} diff --git a/backend/vendor/assets/stylesheets/solidus_admin/bootstrap/_animation.scss b/backend/vendor/assets/stylesheets/solidus_admin/bootstrap/_animation.scss new file mode 100644 index 00000000000..edd7147e51e --- /dev/null +++ b/backend/vendor/assets/stylesheets/solidus_admin/bootstrap/_animation.scss @@ -0,0 +1,27 @@ +.fade { + opacity: 0; + transition: opacity .15s linear; + + &.in { + opacity: 1; + } +} + +.collapse { + display: none; + + &.in { + display: block; + } + // tr&.in { display: table-row; } + // tbody&.in { display: table-row-group; } +} + +.collapsing { + position: relative; + height: 0; + overflow: hidden; + transition-timing-function: ease; + transition-duration: .35s; + transition-property: height; +} diff --git a/backend/vendor/assets/stylesheets/solidus_admin/bootstrap/_breadcrumb.scss b/backend/vendor/assets/stylesheets/solidus_admin/bootstrap/_breadcrumb.scss new file mode 100644 index 00000000000..30af411abbe --- /dev/null +++ b/backend/vendor/assets/stylesheets/solidus_admin/bootstrap/_breadcrumb.scss @@ -0,0 +1,23 @@ +.breadcrumb { + padding: $breadcrumb-padding-vertical $breadcrumb-padding-horizontal; + margin-bottom: $spacer-y; + list-style: none; + background-color: $breadcrumb-bg; + @include border-radius($border-radius); + @include clearfix; + + > li { + float: left; + + + li::before { + padding-right: .5rem; + padding-left: .5rem; + color: $breadcrumb-divider-color; + content: "#{$breadcrumb-divider}"; + } + } + + > .active { + color: $breadcrumb-active-color; + } +} diff --git a/backend/vendor/assets/stylesheets/solidus_admin/bootstrap/_button-group.scss b/backend/vendor/assets/stylesheets/solidus_admin/bootstrap/_button-group.scss new file mode 100644 index 00000000000..7efe144f97d --- /dev/null +++ b/backend/vendor/assets/stylesheets/solidus_admin/bootstrap/_button-group.scss @@ -0,0 +1,224 @@ +// Make the div behave like a button +.btn-group, +.btn-group-vertical { + position: relative; + display: inline-block; + vertical-align: middle; // match .btn alignment given font-size hack above + + > .btn { + position: relative; + float: left; + + // Bring the "active" button to the front + &:focus, + &:active, + &.active { + z-index: 2; + } + @include hover { + z-index: 2; + } + } +} + +// Prevent double borders when buttons are next to each other +.btn-group { + .btn + .btn, + .btn + .btn-group, + .btn-group + .btn, + .btn-group + .btn-group { + margin-left: -$input-btn-border-width; + } +} + +// Optional: Group multiple button groups together for a toolbar +.btn-toolbar { + margin-left: -5px; // Offset the first child's margin + @include clearfix(); + + .btn-group, + .input-group { + float: left; + } + + > .btn, + > .btn-group, + > .input-group { + margin-left: 5px; + } +} + +.btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) { + border-radius: 0; +} + +// Set corners individual because sometimes a single button can be in a .btn-group and we need :first-child and :last-child to both match +.btn-group > .btn:first-child { + margin-left: 0; + + &:not(:last-child):not(.dropdown-toggle) { + @include border-right-radius(0); + } +} +// Need .dropdown-toggle since :last-child doesn't apply given a .dropdown-menu immediately after it +.btn-group > .btn:last-child:not(:first-child), +.btn-group > .dropdown-toggle:not(:first-child) { + @include border-left-radius(0); +} + +// Custom edits for including btn-groups within btn-groups (useful for including dropdown buttons within a btn-group) +.btn-group > .btn-group { + float: left; +} +.btn-group > .btn-group:not(:first-child):not(:last-child) > .btn { + border-radius: 0; +} +.btn-group > .btn-group:first-child:not(:last-child) { + > .btn:last-child, + > .dropdown-toggle { + @include border-right-radius(0); + } +} +.btn-group > .btn-group:last-child:not(:first-child) > .btn:first-child { + @include border-left-radius(0); +} + +// On active and open, don't show outline +.btn-group .dropdown-toggle:active, +.btn-group.open .dropdown-toggle { + outline: 0; +} + + +// Sizing +// +// Remix the default button sizing classes into new ones for easier manipulation. + +.btn-group-sm > .btn { @extend .btn-sm; } +.btn-group-lg > .btn { @extend .btn-lg; } + + +// +// Split button dropdowns +// + +// Give the line between buttons some depth +.btn-group > .btn + .dropdown-toggle { + padding-right: 8px; + padding-left: 8px; +} +.btn-group > .btn-lg + .dropdown-toggle { + padding-right: 12px; + padding-left: 12px; +} + +// The clickable button for toggling the menu +// Remove the gradient and set the same inset shadow as the :active state +.btn-group.open .dropdown-toggle { + @include box-shadow(inset 0 3px 5px rgba(0,0,0,.125)); + + // Show no shadow for `.btn-link` since it has no other button styles. + &.btn-link { + @include box-shadow(none); + } +} + + +// Reposition the caret +.btn .caret { + margin-left: 0; +} +// Carets in other button sizes +.btn-lg .caret { + border-width: $caret-width-lg $caret-width-lg 0; + border-bottom-width: 0; +} +// Upside down carets for .dropup +.dropup .btn-lg .caret { + border-width: 0 $caret-width-lg $caret-width-lg; +} + + + +// +// Vertical button groups +// + +.btn-group-vertical { + > .btn, + > .btn-group, + > .btn-group > .btn { + display: block; + float: none; + width: 100%; + max-width: 100%; + } + + // Clear floats so dropdown menus can be properly placed + > .btn-group { + @include clearfix(); + + > .btn { + float: none; + } + } + + > .btn + .btn, + > .btn + .btn-group, + > .btn-group + .btn, + > .btn-group + .btn-group { + margin-top: -$input-btn-border-width; + margin-left: 0; + } +} + +.btn-group-vertical > .btn { + &:not(:first-child):not(:last-child) { + border-radius: 0; + } + &:first-child:not(:last-child) { + border-top-right-radius: $btn-border-radius; + @include border-bottom-radius(0); + } + &:last-child:not(:first-child) { + border-bottom-left-radius: $btn-border-radius; + @include border-top-radius(0); + } +} +.btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn { + border-radius: 0; +} +.btn-group-vertical > .btn-group:first-child:not(:last-child) { + > .btn:last-child, + > .dropdown-toggle { + @include border-bottom-radius(0); + } +} +.btn-group-vertical > .btn-group:last-child:not(:first-child) > .btn:first-child { + @include border-top-radius(0); +} + + +// Checkbox and radio options +// +// In order to support the browser's form validation feedback, powered by the +// `required` attribute, we have to "hide" the inputs via `clip`. We cannot use +// `display: none;` or `visibility: hidden;` as that also hides the popover. +// Simply visually hiding the inputs via `opacity` would leave them clickable in +// certain cases which is prevented by using `clip` and `pointer-events`. +// This way, we ensure a DOM element is visible to position the popover from. +// +// See https://github.com/twbs/bootstrap/pull/12794 and +// https://github.com/twbs/bootstrap/pull/14559 for more information. + +[data-toggle="buttons"] { + > .btn, + > .btn-group > .btn { + input[type="radio"], + input[type="checkbox"] { + position: absolute; + clip: rect(0,0,0,0); + pointer-events: none; + } + } +} diff --git a/backend/vendor/assets/stylesheets/solidus_admin/bootstrap/_buttons.scss b/backend/vendor/assets/stylesheets/solidus_admin/bootstrap/_buttons.scss new file mode 100644 index 00000000000..73755280fdb --- /dev/null +++ b/backend/vendor/assets/stylesheets/solidus_admin/bootstrap/_buttons.scss @@ -0,0 +1,173 @@ +// +// Base styles +// + +.btn { + display: inline-block; + font-weight: $btn-font-weight; + text-align: center; + white-space: nowrap; + vertical-align: middle; + cursor: pointer; + user-select: none; + border: $input-btn-border-width solid transparent; + @include button-size($btn-padding-y, $btn-padding-x, $font-size-base, $line-height, $btn-border-radius); + @include transition(all .2s ease-in-out); + + &, + &:active, + &.active { + &:focus, + &.focus { + @include tab-focus(); + } + } + + @include hover-focus { + text-decoration: none; + } + &.focus { + text-decoration: none; + } + + &:active, + &.active { + background-image: none; + outline: 0; + @include box-shadow(inset 0 3px 5px rgba(0,0,0,.125)); + } + + &.disabled, + &:disabled { + cursor: $cursor-disabled; + opacity: .65; + @include box-shadow(none); + } +} + +// Future-proof disabling of clicks on `` elements +a.btn.disabled, +fieldset[disabled] a.btn { + pointer-events: none; +} + + +// +// Alternate buttons +// + +.btn-primary { + @include button-variant($btn-primary-color, $btn-primary-bg, $btn-primary-border); +} +.btn-secondary { + @include button-variant($btn-secondary-color, $btn-secondary-bg, $btn-secondary-border); +} +.btn-info { + @include button-variant($btn-info-color, $btn-info-bg, $btn-info-border); +} +.btn-success { + @include button-variant($btn-success-color, $btn-success-bg, $btn-success-border); +} +.btn-warning { + @include button-variant($btn-warning-color, $btn-warning-bg, $btn-warning-border); +} +.btn-danger { + @include button-variant($btn-danger-color, $btn-danger-bg, $btn-danger-border); +} + +// Remove all backgrounds +.btn-primary-outline { + @include button-outline-variant($btn-primary-bg); +} +.btn-secondary-outline { + @include button-outline-variant($btn-secondary-border); +} +.btn-info-outline { + @include button-outline-variant($btn-info-bg); +} +.btn-success-outline { + @include button-outline-variant($btn-success-bg); +} +.btn-warning-outline { + @include button-outline-variant($btn-warning-bg); +} +.btn-danger-outline { + @include button-outline-variant($btn-danger-bg); +} + + +// +// Link buttons +// + +// Make a button look and behave like a link +.btn-link { + font-weight: normal; + color: $link-color; + border-radius: 0; + + &, + &:active, + &.active, + &:disabled { + background-color: transparent; + @include box-shadow(none); + } + &, + &:focus, + &:active { + border-color: transparent; + } + @include hover { + border-color: transparent; + } + @include hover-focus { + color: $link-hover-color; + text-decoration: $link-hover-decoration; + background-color: transparent; + } + &:disabled { + @include hover-focus { + color: $btn-link-disabled-color; + text-decoration: none; + } + } +} + + +// +// Button Sizes +// + +.btn-lg { + // line-height: ensure even-numbered height of button next to large input + @include button-size($btn-padding-y-lg, $btn-padding-x-lg, $font-size-lg, $line-height-lg, $btn-border-radius-lg); +} +.btn-sm { + // line-height: ensure proper height of button next to small input + @include button-size($btn-padding-y-sm, $btn-padding-x-sm, $font-size-sm, $line-height-sm, $btn-border-radius-sm); +} + + +// +// Block button +// + +.btn-block { + display: block; + width: 100%; +} + +// Vertically space out multiple block buttons +.btn-block + .btn-block { + margin-top: 5px; +} + +// Specificity overrides +input[type="submit"], +input[type="reset"], +input[type="button"] { + &.btn-block { + width: 100%; + } +} diff --git a/backend/vendor/assets/stylesheets/solidus_admin/bootstrap/_card.scss b/backend/vendor/assets/stylesheets/solidus_admin/bootstrap/_card.scss new file mode 100644 index 00000000000..ecd797e1f82 --- /dev/null +++ b/backend/vendor/assets/stylesheets/solidus_admin/bootstrap/_card.scss @@ -0,0 +1,292 @@ +// +// Base styles +// + +.card { + position: relative; + display: block; + margin-bottom: $card-spacer-y; + background-color: $card-bg; + border: $card-border-width solid $card-border-color; + @include border-radius($card-border-radius); +} + +.card-block { + padding: $card-spacer-x; +} + +.card-title { + margin-bottom: $card-spacer-y; +} + +.card-subtitle { + margin-top: -($card-spacer-y / 2); + margin-bottom: 0; +} + +.card-text:last-child { + margin-bottom: 0; +} + +// .card-actions { +// padding: $card-spacer-y $card-spacer-x; + +// .card-link + .card-link { +// margin-left: $card-spacer-x; +// } +// } + +.card-link { + @include hover { + text-decoration: none; + } + + + .card-link { + margin-left: $card-spacer-x; + } +} + +@if $enable-rounded { + .card { + > .list-group:first-child { + .list-group-item:first-child { + border-radius: $card-border-radius $card-border-radius 0 0; + } + } + + > .list-group:last-child { + .list-group-item:last-child { + border-radius: 0 0 $card-border-radius $card-border-radius; + } + } + } +} + + +// +// Optional textual caps +// + +.card-header { + padding: $card-spacer-y $card-spacer-x; + background-color: $card-cap-bg; + border-bottom: $card-border-width solid $card-border-color; + + &:first-child { + @include border-radius($card-border-radius-inner $card-border-radius-inner 0 0); + } +} + +.card-footer { + padding: $card-spacer-y $card-spacer-x; + background-color: $card-cap-bg; + border-top: $card-border-width solid $card-border-color; + + &:last-child { + @include border-radius(0 0 $card-border-radius-inner $card-border-radius-inner); + } +} + + +// +// Background variations +// + +.card-primary { + @include card-variant($brand-primary, $brand-primary); +} +.card-success { + @include card-variant($brand-success, $brand-success); +} +.card-info { + @include card-variant($brand-info, $brand-info); +} +.card-warning { + @include card-variant($brand-warning, $brand-warning); +} +.card-danger { + @include card-variant($brand-danger, $brand-danger); +} + +// Remove all backgrounds +.card-primary-outline { + @include card-outline-variant($btn-primary-bg); +} +.card-secondary-outline { + @include card-outline-variant($btn-secondary-border); +} +.card-info-outline { + @include card-outline-variant($btn-info-bg); +} +.card-success-outline { + @include card-outline-variant($btn-success-bg); +} +.card-warning-outline { + @include card-outline-variant($btn-warning-bg); +} +.card-danger-outline { + @include card-outline-variant($btn-danger-bg); +} + +// +// Inverse text within a card for use with dark backgrounds +// + +.card-inverse { + @include card-inverse; +} + +// +// Blockquote +// + +.card-blockquote { + padding: 0; + margin-bottom: 0; + border-left: 0; +} + +// Card image +.card-img { + // margin: -1.325rem; + @include border-radius(.25rem); +} +.card-img-overlay { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + padding: 1.25rem; +} + + + +// Card image caps +.card-img-top { + @include border-radius($card-border-radius-inner $card-border-radius-inner 0 0); +} +.card-img-bottom { + @include border-radius(0 0 $card-border-radius-inner $card-border-radius-inner); +} + + +// +// Card set +// + +@if $enable-flex { + @include media-breakpoint-up(sm) { + .card-deck { + display: flex; + flex-flow: row wrap; + margin-right: -.625rem; + margin-left: -.625rem; + + .card { + flex: 1 0 0; + margin-right: .625rem; + margin-left: .625rem; + } + } + } +} @else { + @include media-breakpoint-up(sm) { + .card-deck { + display: table; + table-layout: fixed; + border-spacing: 1.25rem 0; + + .card { + display: table-cell; + width: 1%; + vertical-align: top; + } + } + .card-deck-wrapper { + margin-right: -1.25rem; + margin-left: -1.25rem; + } + } +} + +// +// Card groups +// + +@include media-breakpoint-up(sm) { + .card-group { + @if $enable-flex { + display: flex; + flex-flow: row wrap; + } @else { + display: table; + width: 100%; + table-layout: fixed; + } + + .card { + @if $enable-flex { + flex: 1 0 0; + } @else { + display: table-cell; + vertical-align: top; + } + + + .card { + margin-left: 0; + border-left: 0; + } + + // Handle rounded corners + @if $enable-rounded { + &:first-child { + @include border-right-radius(0); + + .card-img-top { + border-top-right-radius: 0; + } + .card-img-bottom { + border-bottom-right-radius: 0; + } + } + &:last-child { + @include border-left-radius(0); + + .card-img-top { + border-top-left-radius: 0; + } + .card-img-bottom { + border-bottom-left-radius: 0; + } + } + + &:not(:first-child):not(:last-child) { + border-radius: 0; + + .card-img-top, + .card-img-bottom { + border-radius: 0; + } + } + } + } + } +} + + +// +// Card +// + +@include media-breakpoint-up(sm) { + .card-columns { + column-count: 3; + column-gap: 1.25rem; + + .card { + display: inline-block; + width: 100%; // Don't let them exceed the column width + } + } +} diff --git a/backend/vendor/assets/stylesheets/solidus_admin/bootstrap/_carousel.scss b/backend/vendor/assets/stylesheets/solidus_admin/bootstrap/_carousel.scss new file mode 100644 index 00000000000..bf0ea61d313 --- /dev/null +++ b/backend/vendor/assets/stylesheets/solidus_admin/bootstrap/_carousel.scss @@ -0,0 +1,252 @@ +// Wrapper for the slide container and indicators +.carousel { + position: relative; +} + +.carousel-inner { + position: relative; + width: 100%; + overflow: hidden; + + > .carousel-item { + position: relative; + display: none; + transition: .6s ease-in-out left; + + // Account for jankitude on images + > img, + > a > img { + @extend .img-fluid; + line-height: 1; + } + + // WebKit CSS3 transforms for supported devices + @media all and (transform-3d), (-webkit-transform-3d) { + transition: transform .6s ease-in-out; + backface-visibility: hidden; + perspective: 1000px; + + &.next, + &.active.right { + left: 0; + transform: translate3d(100%, 0, 0); + } + &.prev, + &.active.left { + left: 0; + transform: translate3d(-100%, 0, 0); + } + &.next.left, + &.prev.right, + &.active { + left: 0; + transform: translate3d(0, 0, 0); + } + } + } + + > .active, + > .next, + > .prev { + display: block; + } + + > .active { + left: 0; + } + + > .next, + > .prev { + position: absolute; + top: 0; + width: 100%; + } + + > .next { + left: 100%; + } + > .prev { + left: -100%; + } + > .next.left, + > .prev.right { + left: 0; + } + + > .active.left { + left: -100%; + } + > .active.right { + left: 100%; + } +} + + +// +// Left/right controls for nav +// + +.carousel-control { + position: absolute; + top: 0; + bottom: 0; + left: 0; + width: $carousel-control-width; + font-size: $carousel-control-font-size; + color: $carousel-control-color; + text-align: center; + text-shadow: $carousel-text-shadow; + opacity: $carousel-control-opacity; + // We can't have this transition here because WebKit cancels the carousel + // animation if you trip this while in the middle of another animation. + + // Set gradients for backgrounds + &.left { + @include gradient-horizontal($start-color: rgba(0,0,0,.5), $end-color: rgba(0,0,0,.0001)); + } + &.right { + right: 0; + left: auto; + @include gradient-horizontal($start-color: rgba(0,0,0,.0001), $end-color: rgba(0,0,0,.5)); + } + + // Hover/focus state + @include hover-focus { + color: $carousel-control-color; + text-decoration: none; + outline: 0; + opacity: .9; + } + + // Toggles + .icon-prev, + .icon-next { + position: absolute; + top: 50%; + z-index: 5; + display: inline-block; + width: 20px; + height: 20px; + margin-top: -10px; + font-family: serif; + line-height: 1; + } + .icon-prev { + left: 50%; + margin-left: -10px; + } + .icon-next { + right: 50%; + margin-right: -10px; + } + + .icon-prev { + &::before { + content: "\2039";// SINGLE LEFT-POINTING ANGLE QUOTATION MARK (U+2039) + } + } + .icon-next { + &::before { + content: "\203a";// SINGLE RIGHT-POINTING ANGLE QUOTATION MARK (U+203A) + } + } +} + + +// Optional indicator pips +// +// Add an unordered list with the following class and add a list item for each +// slide your carousel holds. + +.carousel-indicators { + position: absolute; + bottom: 10px; + left: 50%; + z-index: 15; + width: 60%; + padding-left: 0; + margin-left: -30%; + text-align: center; + list-style: none; + + li { + display: inline-block; + width: 10px; + height: 10px; + margin: 1px; + text-indent: -999px; + cursor: pointer; + // IE9 hack for event handling + // + // Internet Explorer 9 does not properly handle clicks on elements with a `background-color` of `transparent`, + // so we use `rgba(0,0,0,0)` instead since it's a non-buggy equivalent. + // See https://developer.mozilla.org/en-US/docs/Web/Events/click#Internet_Explorer + background-color: rgba(0,0,0,0); // IE9 + border: 1px solid $carousel-indicator-border-color; + border-radius: 10px; + } + .active { + width: 12px; + height: 12px; + margin: 0; + background-color: $carousel-indicator-active-bg; + } +} + + +// Optional captions +// +// Hidden by default for smaller viewports. + +.carousel-caption { + position: absolute; + right: 15%; + bottom: 20px; + left: 15%; + z-index: 10; + padding-top: 20px; + padding-bottom: 20px; + color: $carousel-caption-color; + text-align: center; + text-shadow: $carousel-text-shadow; + + .btn { + text-shadow: none; // No shadow for button elements in carousel-caption + } +} + + +// +// Responsive variations +// + +@include media-breakpoint-up(sm) { + // Scale up the controls a smidge + .carousel-control { + .icon-prev, + .icon-next { + width: 30px; + height: 30px; + margin-top: -15px; + font-size: 30px; + } + .icon-prev { + margin-left: -15px; + } + .icon-next { + margin-right: -15px; + } + } + + // Show and left align the captions + .carousel-caption { + right: 20%; + left: 20%; + padding-bottom: 30px; + } + + // Move up the indicators + .carousel-indicators { + bottom: 20px; + } +} diff --git a/backend/vendor/assets/stylesheets/solidus_admin/bootstrap/_close.scss b/backend/vendor/assets/stylesheets/solidus_admin/bootstrap/_close.scss new file mode 100644 index 00000000000..89e68a38177 --- /dev/null +++ b/backend/vendor/assets/stylesheets/solidus_admin/bootstrap/_close.scss @@ -0,0 +1,28 @@ +.close { + float: right; + font-size: ($font-size-base * 1.5); + font-weight: $close-font-weight; + line-height: 1; + color: $close-color; + text-shadow: $close-text-shadow; + opacity: .2; + + @include hover-focus { + color: $close-color; + text-decoration: none; + cursor: pointer; + opacity: .5; + } +} + +// Additional properties for button version +// iOS requires the button element instead of an anchor tag. +// If you want the anchor version, it requires `href="#"`. +// See https://developer.mozilla.org/en-US/docs/Web/Events/click#Safari_Mobile +button.close { + padding: 0; + cursor: pointer; + background: transparent; + border: 0; + -webkit-appearance: none; +} diff --git a/backend/vendor/assets/stylesheets/solidus_admin/bootstrap/_code.scss b/backend/vendor/assets/stylesheets/solidus_admin/bootstrap/_code.scss new file mode 100644 index 00000000000..60bbcae81ee --- /dev/null +++ b/backend/vendor/assets/stylesheets/solidus_admin/bootstrap/_code.scss @@ -0,0 +1,58 @@ +// Inline and block code styles +code, +kbd, +pre, +samp { + font-family: $font-family-monospace; +} + +// Inline code +code { + padding: .2rem .4rem; + font-size: 90%; + color: $code-color; + background-color: $code-bg; + @include border-radius($border-radius); +} + +// User input typically entered via keyboard +kbd { + padding: .2rem .4rem; + font-size: 90%; + color: $kbd-color; + background-color: $kbd-bg; + @include border-radius($border-radius-sm); + @include box-shadow(inset 0 -.1rem 0 rgba(0,0,0,.25)); + + kbd { + padding: 0; + font-size: 100%; + font-weight: $nested-kbd-font-weight; + @include box-shadow(none); + } +} + +// Blocks of code +pre { + display: block; + margin-top: 0; + margin-bottom: 1rem; + font-size: 90%; + line-height: $line-height; + color: $pre-color; + + // Account for some code outputs that place code tags in pre tags + code { + padding: 0; + font-size: inherit; + color: inherit; + background-color: transparent; + border-radius: 0; + } +} + +// Enable scrollable blocks of code +.pre-scrollable { + max-height: $pre-scrollable-max-height; + overflow-y: scroll; +} diff --git a/backend/vendor/assets/stylesheets/solidus_admin/bootstrap/_custom-forms.scss b/backend/vendor/assets/stylesheets/solidus_admin/bootstrap/_custom-forms.scss new file mode 100644 index 00000000000..b418b84d483 --- /dev/null +++ b/backend/vendor/assets/stylesheets/solidus_admin/bootstrap/_custom-forms.scss @@ -0,0 +1,226 @@ +// Embedded icons from Open Iconic. +// Released under MIT and copyright 2014 Waybury. +// http://useiconic.com/open + + +// Checkboxes and radios +// +// Base class takes care of all the key behavioral aspects. + +.c-input { + position: relative; + display: inline; + padding-left: 1.5rem; + color: #555; + cursor: pointer; + + > input { + position: absolute; + z-index: -1; // Put the input behind the label so it doesn't overlay text + opacity: 0; + + &:checked ~ .c-indicator { + color: #fff; + background-color: #0074d9; + @include box-shadow(none); + } + + &:focus ~ .c-indicator { + // the mixin is not used here to make sure there is feedback + box-shadow: 0 0 0 .075rem #fff, 0 0 0 .2rem #0074d9; + } + + &:active ~ .c-indicator { + color: #fff; + background-color: #84c6ff; + @include box-shadow(none); + } + } + + + .c-input { + margin-left: 1rem; + } +} + +// Custom indicator +// +// Generates a shadow element to create our makeshift checkbox/radio background. + +.c-indicator { + position: absolute; + top: 0; + left: 0; + display: block; + width: 1rem; + height: 1rem; + font-size: 65%; + line-height: 1rem; + color: #eee; + text-align: center; + user-select: none; + background-color: #eee; + background-repeat: no-repeat; + background-position: center center; + background-size: 50% 50%; + @include box-shadow(inset 0 .125rem .125rem rgba(0,0,0,.1)); +} + +// Checkboxes +// +// Tweak just a few things for checkboxes. + +.c-checkbox { + .c-indicator { + border-radius: .25rem; + } + + input:checked ~ .c-indicator { + background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4NCjwhLS0gR2VuZXJhdG9yOiBBZG9iZSBJbGx1c3RyYXRvciAxNy4xLjAsIFNWRyBFeHBvcnQgUGx1Zy1JbiAuIFNWRyBWZXJzaW9uOiA2LjAwIEJ1aWxkIDApICAtLT4NCjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+DQo8c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4Ig0KCSB2aWV3Qm94PSIwIDAgOCA4IiBlbmFibGUtYmFja2dyb3VuZD0ibmV3IDAgMCA4IDgiIHhtbDpzcGFjZT0icHJlc2VydmUiPg0KPHBhdGggZmlsbD0iI0ZGRkZGRiIgZD0iTTYuNCwxTDUuNywxLjdMMi45LDQuNUwyLjEsMy43TDEuNCwzTDAsNC40bDAuNywwLjdsMS41LDEuNWwwLjcsMC43bDAuNy0wLjdsMy41LTMuNWwwLjctMC43TDYuNCwxTDYuNCwxeiINCgkvPg0KPC9zdmc+DQo=); + } + + input:indeterminate ~ .c-indicator { + background-color: #0074d9; + background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4NCjwhLS0gR2VuZXJhdG9yOiBBZG9iZSBJbGx1c3RyYXRvciAxNy4xLjAsIFNWRyBFeHBvcnQgUGx1Zy1JbiAuIFNWRyBWZXJzaW9uOiA2LjAwIEJ1aWxkIDApICAtLT4NCjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+DQo8c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4Ig0KCSB3aWR0aD0iOHB4IiBoZWlnaHQ9IjhweCIgdmlld0JveD0iMCAwIDggOCIgZW5hYmxlLWJhY2tncm91bmQ9Im5ldyAwIDAgOCA4IiB4bWw6c3BhY2U9InByZXNlcnZlIj4NCjxwYXRoIGZpbGw9IiNGRkZGRkYiIGQ9Ik0wLDN2Mmg4VjNIMHoiLz4NCjwvc3ZnPg0K); + @include box-shadow(none); + } +} + +// Radios +// +// Tweak just a few things for radios. + +.c-radio { + .c-indicator { + border-radius: 50%; + } + + input:checked ~ .c-indicator { + background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4NCjwhLS0gR2VuZXJhdG9yOiBBZG9iZSBJbGx1c3RyYXRvciAxNy4xLjAsIFNWRyBFeHBvcnQgUGx1Zy1JbiAuIFNWRyBWZXJzaW9uOiA2LjAwIEJ1aWxkIDApICAtLT4NCjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+DQo8c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4Ig0KCSB2aWV3Qm94PSIwIDAgOCA4IiBlbmFibGUtYmFja2dyb3VuZD0ibmV3IDAgMCA4IDgiIHhtbDpzcGFjZT0icHJlc2VydmUiPg0KPHBhdGggZmlsbD0iI0ZGRkZGRiIgZD0iTTQsMUMyLjMsMSwxLDIuMywxLDRzMS4zLDMsMywzczMtMS4zLDMtM1M1LjcsMSw0LDF6Ii8+DQo8L3N2Zz4NCg==); + } +} + + +// Layout options +// +// By default radios and checkboxes are `inline-block` with no additional spacing +// set. Use these optional classes to tweak the layout. + +.c-inputs-stacked { + .c-input { + display: inline; + + &::after { + display: block; + margin-bottom: .25rem; + content: ""; + } + + + .c-input { + margin-left: 0; + } + } +} + + +// Select +// +// Replaces the browser default select with a custom one, mostly pulled from +// http://primercss.io. +// +// Includes IE9-specific hacks (noted by ` \9`). + +.c-select { + display: inline-block; + max-width: 100%; + padding: .375rem 1.75rem .375rem .75rem; + padding-right: .75rem \9; + color: $input-color; + vertical-align: middle; + background: #fff url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAUCAMAAACzvE1FAAAADFBMVEUzMzMzMzMzMzMzMzMKAG/3AAAAA3RSTlMAf4C/aSLHAAAAPElEQVR42q3NMQ4AIAgEQTn//2cLdRKppSGzBYwzVXvznNWs8C58CiussPJj8h6NwgorrKRdTvuV9v16Afn0AYFOB7aYAAAAAElFTkSuQmCC) no-repeat right .75rem center; + background-image: none \9; + background-size: 8px 10px; + border: $input-btn-border-width solid $input-border-color; + // Use vendor prefixes as `appearance` isn't part of the CSS spec. + -moz-appearance: none; + -webkit-appearance: none; + + &:focus { + border-color: #51a7e8; + outline: none; + @include box-shadow(inset 0 1px 2px rgba(0, 0, 0, 0.075), 0 0 5px rgba(81, 167, 232, 0.5)); + } + + // Hides the default caret in IE11 + &::-ms-expand { + opacity: 0; + } +} + +.c-select-sm { + padding-top: 3px; + padding-bottom: 3px; + font-size: 12px; + + &:not([multiple]) { + height: 26px; + min-height: 26px; + } +} + + +// File +// +// Custom file input. + +.file { + position: relative; + display: inline-block; + height: 2.5rem; + cursor: pointer; +} +.file input { + min-width: 14rem; + margin: 0; + filter: alpha(opacity = 0); + opacity: 0; +} +.file-custom { + position: absolute; + top: 0; + right: 0; + left: 0; + z-index: 5; + height: 2.5rem; + padding: .5rem 1rem; + line-height: 1.5; + color: #555; + user-select: none; + background-color: #fff; + border: $input-btn-border-width solid #ddd; + border-radius: .25rem; + @include box-shadow(inset 0 .2rem .4rem rgba(0,0,0,.05)); +} +.file-custom::after { + content: "Choose file..."; +} +.file-custom::before { + position: absolute; + top: -.075rem; + right: -.075rem; + bottom: -.075rem; + z-index: 6; + display: block; + height: 2.5rem; + padding: .5rem 1rem; + line-height: 1.5; + color: #555; + content: "Browse"; + background-color: #eee; + border: $input-btn-border-width solid #ddd; + border-radius: 0 .25rem .25rem 0; +} + +// Focus state +.file input:focus ~ .file-custom { + @include box-shadow(0 0 0 .075rem #fff, 0 0 0 .2rem #0074d9); +} diff --git a/backend/vendor/assets/stylesheets/solidus_admin/bootstrap/_dropdown.scss b/backend/vendor/assets/stylesheets/solidus_admin/bootstrap/_dropdown.scss new file mode 100644 index 00000000000..d9776d59c66 --- /dev/null +++ b/backend/vendor/assets/stylesheets/solidus_admin/bootstrap/_dropdown.scss @@ -0,0 +1,193 @@ +// The dropdown wrapper (`
    `) +.dropup, +.dropdown { + position: relative; +} + +.dropdown-toggle { + // Generate the caret automatically + &::after { + display: inline-block; + width: 0; + height: 0; + margin-right: .25rem; + margin-left: .25rem; + vertical-align: middle; + content: ""; + border-top: $caret-width solid; + border-right: $caret-width solid transparent; + border-left: $caret-width solid transparent; + } + + // Prevent the focus on the dropdown toggle when closing dropdowns + &:focus { + outline: 0; + } +} + +.dropup { + .dropdown-toggle { + &::after { + border-top: 0; + border-bottom: $caret-width solid; + } + } +} + +// The dropdown menu +.dropdown-menu { + position: absolute; + top: 100%; + left: 0; + z-index: $zindex-dropdown; + display: none; // none by default, but block on "open" of the menu + float: left; + min-width: 160px; + padding: 5px 0; + margin: 2px 0 0; // override default ul + font-size: $font-size-base; + color: $body-color; + text-align: left; // Ensures proper alignment if parent has it changed (e.g., modal footer) + list-style: none; + background-color: $dropdown-bg; + background-clip: padding-box; + border: $dropdown-border-width solid $dropdown-border-color; + @include border-radius($border-radius); + @include box-shadow(0 6px 12px rgba(0,0,0,.175)); +} + +// Dividers (basically an `
    `) within the dropdown +.dropdown-divider { + @include nav-divider($dropdown-divider-bg); +} + +// Links, buttons, and more within the dropdown menu +// +// `